· 4 years ago · Dec 28, 2020, 04:38 AM
1Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/npc/unique.html
2IDEA additional info:
3Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
4<+>UTF-8
5===================================================================
6--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/npc/unique.html (date 1601235046883)
7+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/npc/unique.html (date 1601235046883)
8@@ -0,0 +1,17 @@
9+<html><title>%buffer.name%</title><body>
10+
11+<a action="%buffer.bypass_prefix%">Home</a> > Unique > <font color=LEVEL>%unique.name%</font> (%unique.num_buffs%/%buffer.unique_max_buffs%, %unique.num_songs_dances%/%buffer.unique_max_songs_dances%)<br>
12+
13+<center>
14+ <table width=270 cellspacing=0 cellpadding=0>
15+ [FOREACH(buff IN unique.buffs DO
16+ <tr>
17+ <td width=32 height=32><img width=32 height=32 src="%buff.skill_icon%"></td>
18+ <td><button width=238 height=32 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="%buff.skill_name%" action="%buffer.bypass_prefix% unique remove %unique.name% %buff.ident%"></td>
19+ </tr>
20+ <tr><td height=10></td><td></td></tr>
21+ )ENDEACH]
22+ </table>
23+</center>
24+
25+</body></html>
26\ No newline at end of file
27Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/npc/main.html
28IDEA additional info:
29Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
30<+>UTF-8
31===================================================================
32--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/npc/main.html (date 1601235046879)
33+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/npc/main.html (date 1601235046879)
34@@ -0,0 +1,67 @@
35+<html><title>%buffer.name%</title><body><center>
36+
37+<table width=270 cellspacing=0 cellpadding=0>
38+ <tr>
39+ <td><center><button width=130 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Heal Me" action="%buffer.bypass_prefix% target player heal"></center></td>
40+ <td><center><button width=130 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Heal Summon" action="%buffer.bypass_prefix% target summon heal"></center></td>
41+ </tr>
42+</table>
43+
44+<table width=270 cellspacing=0 cellpadding=0>
45+ <tr>
46+ <td><center><button width=130 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Cancel Me" action="%buffer.bypass_prefix% target player cancel"></center></td>
47+ <td><center><button width=130 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Cancel Summon" action="%buffer.bypass_prefix% target summon cancel"></center></td>
48+ </tr>
49+</table><br>
50+
51+<font name=hs12 line=UNDERLINE color=LEVEL>Presets</font><br1>
52+<table width=270 cellspacing=0 cellpadding=0>
53+ <tr>
54+ <td><center><button width=130 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Fighter" action="%buffer.bypass_prefix% target player preset BC_FIGHTER"></center></td>
55+ <td><center><button width=130 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Mage" action="%buffer.bypass_prefix% target player preset BC_MAGE"></center></td>
56+ </tr>
57+</table><br>
58+
59+<font name=hs12 line=UNDERLINE color=LEVEL>Categories</font><br1>
60+<table width=270 cellspacing=0 cellpadding=0>
61+ <tr>
62+ <td><center><button width=130 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Buffs" action="%buffer.bypass_prefix% html category BC_BUFFS"></center></td>
63+ <td><center><button width=130 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Songs" action="%buffer.bypass_prefix% html category BC_SONGS"></center></td>
64+ </tr>
65+ <tr>
66+ <td><center><button width=130 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Dances" action="%buffer.bypass_prefix% html category BC_DANCES"></center></td>
67+ <td><center><button width=130 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Chants" action="%buffer.bypass_prefix% html category BC_CHANTS"></center></td>
68+ </tr>
69+ <tr>
70+ <td><center><button width=130 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Dwarven" action="%buffer.bypass_prefix% html category BC_DWARVEN"></center></td>
71+ <td><center><button width=130 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Resist" action="%buffer.bypass_prefix% html category BC_RESIST"></center></td>
72+ </tr>
73+ <tr>
74+ <td><center><button width=130 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Special" action="%buffer.bypass_prefix% html category BC_SPECIAL"></center></td>
75+ <td><center><button width=130 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Overlord" action="%buffer.bypass_prefix% html category BC_OVERLORD"></center></td>
76+ </tr>
77+</table><br>
78+
79+<font name=hs12 line=UNDERLINE color=LEVEL>Unique</font><br1>
80+<table width=270 cellspacing=0 cellpadding=0>
81+ <tr>
82+ <td><center><combobox width=85 var="unique_selection" list="[FOREACH(unique IN uniques DO %unique.name%;)ENDEACH]"></center></td>
83+ <td><center><button width=85 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Buff Me" action="%buffer.bypass_prefix% target player unique $unique_selection"></center></td>
84+ <td><center><button width=85 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Buff Summon" action="%buffer.bypass_prefix% target summon unique $unique_selection"></center></td>
85+ </tr>
86+ <tr>
87+ <td></td>
88+ <td><center><button width=85 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Inspect" action="%buffer.bypass_prefix% html unique $unique_selection"></center></td>
89+ <td><center><button width=85 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Delete" action="%buffer.bypass_prefix% unique delete $unique_selection"></center></td>
90+ </tr>
91+ <tr>
92+ <td height=15></td><td></td><td></td>
93+ </tr>
94+ <tr>
95+ <td><center><edit width=85 var="unique_new"></center></td>
96+ <td><center><button width=85 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Create Empty" action="%buffer.bypass_prefix% unique create $unique_new"></center></td>
97+ <td><center><button width=85 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="From Buffs" action="%buffer.bypass_prefix% unique create_from_effects $unique_new"></center></td>
98+ </tr>
99+</table>
100+
101+</center></body></html>
102\ No newline at end of file
103Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/npc/category.html
104IDEA additional info:
105Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
106<+>UTF-8
107===================================================================
108--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/npc/category.html (date 1601235046874)
109+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/npc/category.html (date 1601235046874)
110@@ -0,0 +1,42 @@
111+<html><title>%buffer.name%</title><body>
112+
113+<a action="%buffer.bypass_prefix%">Home</a> > Category > <font color=LEVEL>%category.name%</font><br><center>
114+
115+[EXISTS(!active_unique,
116+ <table width=270 cellspacing=0 cellpadding=0>
117+ <tr>
118+ <td><center><combobox width=130 var="unique_selection" list="[FOREACH(unique IN uniques DO %unique.name%;)ENDEACH]"></center></td>
119+ <td><center><button width=130 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Select" action="%buffer.bypass_prefix% unique select $unique_selection"></center></td>
120+ </tr>
121+ </table><br>
122+)ENDEXISTS]
123+[EXISTS(active_unique,
124+ <table width=270 cellspacing=0 cellpadding=0>
125+ <tr>
126+ <td width=135><center><font color=LEVEL>%active_unique.name%</font> (%active_unique.num_buffs%/%buffer.unique_max_buffs%, %active_unique.num_songs_dances%/%buffer.unique_max_songs_dances%)</font></center></td>
127+ <td><center><button width=130 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Deselect" action="%buffer.bypass_prefix% unique deselect"></center></center></td>
128+ </tr>
129+ </table><br>
130+)ENDEXISTS]
131+
132+<table width=270 cellspacing=0 cellpadding=0>
133+ [FOREACH(buff IN category.buffs DO
134+ [EXISTS(active_unique,
135+ [IFCHILDS(active_unique.buffs, skill_id != buff.skill_id THEN
136+ <tr>
137+ <td width=32 height=32><img width=32 height=32 src="%buff.skill_icon%"></td>
138+ <td><button width=238 height=32 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="%buff.skill_name%" action="%buffer.bypass_prefix% unique add %active_unique.name% %category.ident% %buff.ident%"></td>
139+ </tr>
140+ <tr><td height=10></td><td></td></tr>
141+ )ENDIFCHILDS]
142+ )ENDEXISTS]
143+ [EXISTS(!active_unique,
144+ <tr>
145+ <td width=32 height=32><img width=32 height=32 src="%buff.skill_icon%"></td>
146+ <td><button width=238 height=32 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="%buff.skill_name%" action="%buffer.bypass_prefix% target player buff %category.ident% %buff.ident%"></td>
147+ </tr>
148+ <tr><td height=10></td><td></td></tr>
149+ )ENDEXISTS]
150+ )ENDEACH]
151+</table>
152+</center></body></html>
153\ No newline at end of file
154Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/community/main.html
155IDEA additional info:
156Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
157<+>UTF-8
158===================================================================
159--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/community/main.html (date 1601235046870)
160+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/community/main.html (date 1601235046870)
161@@ -0,0 +1,20 @@
162+<html><title>%buffer.name% - Buffer</title><body><center>
163+
164+[INC(data/scripts/Buffer/data/html/community/inc/header.html)ENDINC]
165+
166+<table width=570>
167+ <tr>
168+ <td><center>
169+ <table width=200 cellpadding=0 cellspacing=0>
170+ <tr><td><center><font line="UNDERLINE" name="hs12" color=LEVEL>Categories</font></center></td></tr>
171+ <tr><td height=15></td></tr>
172+ [FOREACH(category IN buffer.categories DO
173+ <tr><td><center><button width=195 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="%category.name%" action="%buffer.bypass_prefix% html category %category.ident%"></center></td></tr>
174+ )ENDEACH]
175+ </table>
176+ </center></td>
177+ [INC(data/scripts/Buffer/data/html/community/inc/active_unique_table.html)ENDINC]
178+ </tr>
179+</table>
180+
181+</center></body></html>
182\ No newline at end of file
183Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/community/category.html
184IDEA additional info:
185Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
186<+>UTF-8
187===================================================================
188--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/community/category.html (date 1601235046866)
189+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/community/category.html (date 1601235046866)
190@@ -0,0 +1,27 @@
191+<html><title>%buffer.name% - Buffer</title><body><center>
192+
193+[INC(data/scripts/Buffer/data/html/community/inc/header.html)ENDINC]
194+
195+<table width=570>
196+ <tr>
197+ <td><center>
198+ <table width=200 cellspacing=0 cellpadding=0>
199+ <tr><td width=32 height=32><button width=32 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="<<" action="%buffer.bypass_prefix% html main"></td><td width=200><center><font line="UNDERLINE" name="hs12" color=LEVEL>%category.name%</font></center></td></tr>
200+ [FOREACH(buff IN category.buffs DO
201+ [EXISTS(active_unique,
202+ [IFCHILDS(active_unique.buffs, skill_id != buff.skill_id THEN
203+ <tr><td height=35><img src="%buff.skill_icon%" width=32 height=32></td><td><center><button width=162 height=32 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="%buff.skill_name%" action="%buffer.bypass_prefix% unique add %active_unique.name% %category.ident% %buff.ident%"></center></td></tr>
204+ )ENDIFCHILDS]
205+ )ENDEXISTS]
206+ [EXISTS(!active_unique,
207+ <tr><td height=35><img src="%buff.skill_icon%" width=32 height=32></td><td><center><button width=162 height=32 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="%buff.skill_name%" action="%buffer.bypass_prefix% target player buff %category.ident% %buff.ident%"></center></td></tr>
208+ )ENDEXISTS]
209+ )ENDEACH]
210+ <tr><td height=32></td><td></td></tr>
211+ </table>
212+ </center></td>
213+ [INC(data/scripts/Buffer/data/html/community/inc/active_unique_table.html)ENDINC]
214+ </tr>
215+</table>
216+
217+</center></body></html>
218\ No newline at end of file
219Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/community/inc/header.html
220IDEA additional info:
221Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
222<+>UTF-8
223===================================================================
224--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/community/inc/header.html (date 1601235046861)
225+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/community/inc/header.html (date 1601235046861)
226@@ -0,0 +1,36 @@
227+<table width=650 cellpadding=0 cellspacing=0>
228+ <tr>
229+ <td><combobox width=160 var="header_unique_selection" list="[FOREACH(unique IN uniques DO %unique.name%;)ENDEACH]" [EXISTS(active_unique, sel="%active_unique.name%")ENDEXISTS]></td>
230+ <td><center><button width=100 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Buff Me" action="%buffer.bypass_prefix% target player unique $header_unique_selection"></center></td>
231+ <td><center><button width=100 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Buff Summon" action="%buffer.bypass_prefix% target summon unique $header_unique_selection"></center></td>
232+ <td width=30></td>
233+ <td><center><button width=115 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Heal Me" action="%buffer.bypass_prefix% target player heal"></center></td>
234+ <td><center><button width=115 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Heal Summon" action="%buffer.bypass_prefix% target summon heal"></center></td>
235+ </tr>
236+ <tr>
237+ <td></td>
238+ <td><center><button width=100 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Select" action="%buffer.bypass_prefix% unique select $header_unique_selection"></center></td>
239+ <td><center><button width=100 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Delete" action="%buffer.bypass_prefix% unique delete $header_unique_selection"></center></td>
240+ <td></td>
241+ <td><center><button width=115 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Cancel Me" action="%buffer.bypass_prefix% target player cancel"></center></td>
242+ <td><center><button width=115 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Cancel Summon" action="%buffer.bypass_prefix% target summon cancel"></center></td>
243+ </tr>
244+ <tr>
245+ <td height=15></td><td></td><td></td><td></td><td></td><td></td>
246+ </tr>
247+ <tr>
248+ <td><edit width=160 var="unique_new"></td>
249+ <td><center><button width=100 height=23 fore="L2UI_CT1.Button_DF" back="L2UI_CT1.Button_DF_Down" value="Create Empty" action="%buffer.bypass_prefix% unique create $unique_new"></center></td>
250+ <td><center><button width=100 height=23 fore="L2UI_CT1.Button_DF" back="L2UI_CT1.Button_DF_Down" value="From Buffs" action="%buffer.bypass_prefix% unique create_from_effects $unique_new"></center></td>
251+ <td></td>
252+ <td></td>
253+ <td></td>
254+ </tr>
255+</table><br><br>
256+<font line="UNDERLINE" name="hs12" color=LEVEL>Presets</font><br1>
257+<table width=400 cellspacing=0 cellpadding=0>
258+ <tr>
259+ <td><center><button width=195 height=23 fore="L2UI_CT1.Button_DF" back="L2UI_CT1.Button_DF_Down" value="Fighter" action="%buffer.bypass_prefix% target player preset BC_FIGHTER"></center></td>
260+ <td><center><button width=195 height=23 fore="L2UI_CT1.Button_DF" back="L2UI_CT1.Button_DF_Down" value="Mage" action="%buffer.bypass_prefix% target player preset BC_MAGE"></center></td>
261+ </tr>
262+</table><br>
263\ No newline at end of file
264Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/community/inc/active_unique_table.html
265IDEA additional info:
266Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
267<+>UTF-8
268===================================================================
269--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/community/inc/active_unique_table.html (date 1601235046856)
270+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/html/community/inc/active_unique_table.html (date 1601235046856)
271@@ -0,0 +1,10 @@
272+[EXISTS(active_unique,
273+<td><center>
274+ <table width=200 cellspacing=0 cellpadding=0>
275+ <tr><td width=168><center><font line="UNDERLINE" name="hs12" color=LEVEL>%active_unique.name% (%active_unique.num_buffs%/%buffer.unique_max_buffs%, %active_unique.num_songs_dances%/%buffer.unique_max_songs_dances%)</font></center></td><td height=32><button width=32 height=23 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="Des." action="%buffer.bypass_prefix% unique deselect"></td></tr>
276+ [FOREACH(buff IN active_unique.buffs DO
277+ <tr><td><center><button width=163 height=32 fore=L2UI_CT1.Button_DF back=L2UI_CT1.Button_DF_Down value="%buff.skill_name%" action="%buffer.bypass_prefix% unique remove %active_unique.name% %buff.ident%"></center></td><td height=35><img src="%buff.skill_icon%" width=32 height=32></td></tr>
278+ )ENDEACH]
279+ </table>
280+</center></td>
281+)ENDEXISTS]
282Index: L2J_Mobius_Classic_Interlude/dist/game/config/Custom/Buffer.ini
283IDEA additional info:
284Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
285<+>UTF-8
286===================================================================
287--- L2J_Mobius_Classic_Interlude/dist/game/config/Custom/Buffer.ini (date 1601235046848)
288+++ L2J_Mobius_Classic_Interlude/dist/game/config/Custom/Buffer.ini (date 1601235046848)
289@@ -0,0 +1,7 @@
290+#=============================================================
291+# Buffer
292+#=============================================================
293+# Also check custom/Buffer/data/xml/buffs.xml
294+
295+# Custom buff duration in minutes
296+BufferOverrideBuffDuration = 120
297Index: L2J_Mobius_Classic_Interlude/dist/game/data/stats/npcs/custom/Buffer.xml
298IDEA additional info:
299Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
300<+>UTF-8
301===================================================================
302--- L2J_Mobius_Classic_Interlude/dist/game/data/stats/npcs/custom/Buffer.xml (date 1601235047052)
303+++ L2J_Mobius_Classic_Interlude/dist/game/data/stats/npcs/custom/Buffer.xml (date 1601235047052)
304@@ -0,0 +1,21 @@
305+<?xml version="1.0" encoding="UTF-8"?>
306+<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../xsd/npcs.xsd">
307+ <npc id="1000006" displayId="9000" type="SchemeBuffer" name="Buffer" usingServerSideName="true" title="" usingServerSideTitle="true">
308+ <race>HUMAN</race>
309+ <sex>FEMALE</sex>
310+ <stats>
311+ <vitals hp="2444.46819" hpRegen="7.5" mp="1345.8" mpRegen="2.7" />
312+ <attack physical="688.86373" magical="470.40463" random="30" critical="4" accuracy="95" attackSpeed="253" type="SWORD" range="40" distance="80" width="120" />
313+ <defence physical="295.91597" magical="216.53847" />
314+ <speed>
315+ <walk ground="50" />
316+ <run ground="120" />
317+ </speed>
318+ </stats>
319+ <status attackable="false" />
320+ <collision>
321+ <radius normal="11" />
322+ <height normal="22.25" />
323+ </collision>
324+ </npc>
325+</list>
326\ No newline at end of file
327Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/UniqueBufflist.java
328IDEA additional info:
329Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
330<+>UTF-8
331===================================================================
332--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/UniqueBufflist.java (date 1601235047047)
333+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/UniqueBufflist.java (date 1601235047047)
334@@ -0,0 +1,96 @@
335+/*
336+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
337+ * Copyright (C) 2015 Christian Buck
338+ *
339+ * This program is free software: you can redistribute it and/or modify
340+ * it under the terms of the GNU General Public License as published by
341+ * the Free Software Foundation, either version 3 of the License, or
342+ * (at your option) any later version.
343+ *
344+ * This program is distributed in the hope that it will be useful,
345+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
346+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
347+ * GNU General Public License for more details.
348+ *
349+ * You should have received a copy of the GNU General Public License
350+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
351+ */
352+package custom.Buffer;
353+
354+import java.util.LinkedList;
355+
356+import org.l2jmobius.gameserver.model.skills.SkillBuffType;
357+
358+import custom.Buffer.util.htmltmpls.HTMLTemplatePlaceholder;
359+
360+/**
361+ * This class is here so we can actually get the name of this list and make placeholder adjustments easily while keeping outside code cleaner
362+ * @author HorridoJoho
363+ */
364+public class UniqueBufflist extends LinkedList<BufferData.Buff>
365+{
366+ private static final long serialVersionUID = -2586607798277226501L;
367+
368+ public final int ulistId;
369+ public final String ulistName;
370+ public int numBuffs;
371+ public int numSongsDances;
372+ public HTMLTemplatePlaceholder placeholder;
373+
374+ UniqueBufflist(int ulistId, String ulistName)
375+ {
376+ this.ulistId = ulistId;
377+ this.ulistName = ulistName;
378+ this.numBuffs = 0;
379+ this.numSongsDances = 0;
380+ this.placeholder = new HTMLTemplatePlaceholder("unique", null).addChild("buffs", null).addChild("name", ulistName).addChild("num_buffs", "0").addChild("num_songs_dances", "0");
381+ }
382+
383+ @Override
384+ public boolean add(BufferData.Buff e)
385+ {
386+ if (super.add(e))
387+ {
388+ if (e.getType() == SkillBuffType.BUFF)
389+ {
390+ ++this.numBuffs;
391+ this.placeholder.getChild("num_buffs").setValue(String.valueOf(Integer.parseInt(this.placeholder.getChild("num_buffs").getValue()) + 1));
392+ }
393+ else
394+ {
395+ ++this.numSongsDances;
396+ this.placeholder.getChild("num_songs_dances").setValue(String.valueOf(Integer.parseInt(this.placeholder.getChild("num_songs_dances").getValue()) + 1));
397+ }
398+ this.placeholder.getChild("buffs").addAliasChild(e.ident, e.placeholder);
399+ return true;
400+ }
401+
402+ return false;
403+ }
404+
405+ @Override
406+ public boolean remove(Object o)
407+ {
408+ if (super.remove(o))
409+ {
410+ switch (((BufferData.Buff) o).getType())
411+ {
412+ case BUFF:
413+ --numBuffs;
414+ break;
415+ case DANCE:
416+ --numSongsDances;
417+ break;
418+ }
419+
420+ this.placeholder = new HTMLTemplatePlaceholder("unique", null).addChild("buffs", null).addChild("name", this.ulistName).addChild("num_buffs", String.valueOf(numBuffs)).addChild("num_songs_dances", String.valueOf(numSongsDances));
421+ for (BufferData.Buff buff : this)
422+ {
423+ this.placeholder.getChild("buffs").addAliasChild(buff.ident, buff.placeholder);
424+ }
425+ return true;
426+ }
427+
428+ return false;
429+ }
430+}
431Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/BufferVoicedCommandHandler.java
432IDEA additional info:
433Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
434<+>UTF-8
435===================================================================
436--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/BufferVoicedCommandHandler.java (date 1601235047043)
437+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/BufferVoicedCommandHandler.java (date 1601235047043)
438@@ -0,0 +1,61 @@
439+/*
440+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
441+ * Copyright (C) 2015 Christian Buck
442+ *
443+ * This program is free software: you can redistribute it and/or modify
444+ * it under the terms of the GNU General Public License as published by
445+ * the Free Software Foundation, either version 3 of the License, or
446+ * (at your option) any later version.
447+ *
448+ * This program is distributed in the hope that it will be useful,
449+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
450+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
451+ * GNU General Public License for more details.
452+ *
453+ * You should have received a copy of the GNU General Public License
454+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
455+ */
456+package custom.Buffer;
457+
458+import org.l2jmobius.gameserver.handler.IVoicedCommandHandler;
459+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
460+
461+/**
462+ * @author HorridoJoho
463+ */
464+public final class BufferVoicedCommandHandler implements IVoicedCommandHandler
465+{
466+ private static final class SingletonHolder
467+ {
468+ protected static final BufferVoicedCommandHandler INSTANCE = new BufferVoicedCommandHandler();
469+ }
470+
471+ public static final String VOICED_COMMAND = "buffer";
472+ private static final String[] _VOICED_COMMAND_LIST =
473+ {
474+ VOICED_COMMAND
475+ };
476+
477+ static BufferVoicedCommandHandler getInstance()
478+ {
479+ return SingletonHolder.INSTANCE;
480+ }
481+
482+ BufferVoicedCommandHandler()
483+ {
484+ }
485+
486+ @Override
487+ public boolean useVoicedCommand(String command, PlayerInstance activeChar, String params)
488+ {
489+ Buffer.getInstance().executeCommand(activeChar, null, params);
490+ return true;
491+ }
492+
493+ @Override
494+ public String[] getVoicedCommandList()
495+ {
496+ return _VOICED_COMMAND_LIST;
497+ }
498+
499+}
500Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/BufferNpcBypassHandler.java
501IDEA additional info:
502Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
503<+>UTF-8
504===================================================================
505--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/BufferNpcBypassHandler.java (date 1601235047039)
506+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/BufferNpcBypassHandler.java (date 1601235047039)
507@@ -0,0 +1,77 @@
508+/*
509+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
510+ * Copyright (C) 2015 Christian Buck
511+ *
512+ * This program is free software: you can redistribute it and/or modify
513+ * it under the terms of the GNU General Public License as published by
514+ * the Free Software Foundation, either version 3 of the License, or
515+ * (at your option) any later version.
516+ *
517+ * This program is distributed in the hope that it will be useful,
518+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
519+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
520+ * GNU General Public License for more details.
521+ *
522+ * You should have received a copy of the GNU General Public License
523+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
524+ */
525+package custom.Buffer;
526+
527+import org.l2jmobius.gameserver.handler.IBypassHandler;
528+import org.l2jmobius.gameserver.model.WorldObject;
529+import org.l2jmobius.gameserver.enums.InstanceType;
530+import org.l2jmobius.gameserver.model.actor.Creature;
531+import org.l2jmobius.gameserver.model.actor.Npc;
532+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
533+
534+/**
535+ * @author HorridoJoho
536+ */
537+public class BufferNpcBypassHandler implements IBypassHandler
538+{
539+ private static final class SingletonHolder
540+ {
541+ protected static final BufferNpcBypassHandler INSTANCE = new BufferNpcBypassHandler();
542+ }
543+
544+ public static final String BYPASS = "BufferNpc";
545+ private static final String[] _BYPASS_LIST = new String[]
546+ {
547+ BYPASS
548+ };
549+
550+ static BufferNpcBypassHandler getInstance()
551+ {
552+ return SingletonHolder.INSTANCE;
553+ }
554+
555+ BufferNpcBypassHandler()
556+ {
557+ }
558+
559+ @Override
560+ public boolean useBypass(String command, PlayerInstance activeChar, Creature target)
561+ {
562+ // If html bypass validation fails
563+ // Other values assumed as a validation pass for now
564+ if (activeChar.validateHtmlAction(command) == -1)
565+ {
566+ return false;
567+ }
568+
569+ WorldObject playerTarget = activeChar.getTarget();
570+ if ((playerTarget == null) || !playerTarget.isInstanceTypes(InstanceType.Npc))
571+ {
572+ return false;
573+ }
574+
575+ Buffer.getInstance().executeCommand(activeChar, (Npc) playerTarget, command.substring(BYPASS.length()).trim());
576+ return true;
577+ }
578+
579+ @Override
580+ public String[] getBypassList()
581+ {
582+ return _BYPASS_LIST;
583+ }
584+}
585Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/BufferItemHandler.java
586IDEA additional info:
587Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
588<+>UTF-8
589===================================================================
590--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/BufferItemHandler.java (date 1601235047035)
591+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/BufferItemHandler.java (date 1601235047035)
592@@ -0,0 +1,56 @@
593+/*
594+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
595+ * Copyright (C) 2015 Christian Buck
596+ *
597+ * This program is free software: you can redistribute it and/or modify
598+ * it under the terms of the GNU General Public License as published by
599+ * the Free Software Foundation, either version 3 of the License, or
600+ * (at your option) any later version.
601+ *
602+ * This program is distributed in the hope that it will be useful,
603+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
604+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
605+ * GNU General Public License for more details.
606+ *
607+ * You should have received a copy of the GNU General Public License
608+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
609+ */
610+package custom.Buffer;
611+
612+import org.l2jmobius.gameserver.handler.IItemHandler;
613+import org.l2jmobius.gameserver.enums.InstanceType;
614+import org.l2jmobius.gameserver.model.actor.Playable;
615+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
616+import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
617+
618+/**
619+ * @author HorridoJoho
620+ */
621+public final class BufferItemHandler implements IItemHandler
622+{
623+ private static final class SingletonHolder
624+ {
625+ protected static final BufferItemHandler INSTANCE = new BufferItemHandler();
626+ }
627+
628+ static BufferItemHandler getInstance()
629+ {
630+ return SingletonHolder.INSTANCE;
631+ }
632+
633+ BufferItemHandler()
634+ {
635+ }
636+
637+ @Override
638+ public boolean useItem(Playable playable, ItemInstance item, boolean forceUse)
639+ {
640+ if (!playable.isInstanceTypes(InstanceType.PlayerInstance))
641+ {
642+ return false;
643+ }
644+
645+ Buffer.getInstance().executeCommand((PlayerInstance) playable, null, null);
646+ return true;
647+ }
648+}
649Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/BufferData.java
650IDEA additional info:
651Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
652<+>UTF-8
653===================================================================
654--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/BufferData.java (date 1601235047030)
655+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/BufferData.java (date 1601235047030)
656@@ -0,0 +1,777 @@
657+/*
658+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
659+ * Copyright (C) 2015 Christian Buck
660+ *
661+ * This program is free software: you can redistribute it and/or modify
662+ * it under the terms of the GNU General Public License as published by
663+ * the Free Software Foundation, either version 3 of the License, or
664+ * (at your option) any later version.
665+ *
666+ * This program is distributed in the hope that it will be useful,
667+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
668+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
669+ * GNU General Public License for more details.
670+ *
671+ * You should have received a copy of the GNU General Public License
672+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
673+ */
674+package custom.Buffer;
675+
676+import java.nio.file.Path;
677+import java.nio.file.Paths;
678+import java.sql.Connection;
679+import java.sql.PreparedStatement;
680+import java.sql.ResultSet;
681+import java.sql.SQLException;
682+import java.sql.Statement;
683+import java.util.Collections;
684+import java.util.HashMap;
685+import java.util.LinkedHashMap;
686+import java.util.List;
687+import java.util.Map;
688+import java.util.Map.Entry;
689+import java.util.concurrent.ConcurrentHashMap;
690+import java.util.logging.Level;
691+import java.util.logging.Logger;
692+
693+import org.w3c.dom.Element;
694+import org.w3c.dom.Node;
695+
696+import custom.Buffer.util.ItemRequirement;
697+import custom.Buffer.util.XMLUtils;
698+import custom.Buffer.util.htmltmpls.HTMLTemplatePlaceholder;
699+
700+import org.l2jmobius.Config;
701+import org.l2jmobius.commons.database.DatabaseFactory;
702+import org.l2jmobius.gameserver.data.xml.impl.NpcData;
703+import org.l2jmobius.gameserver.data.xml.impl.SkillData;
704+import org.l2jmobius.gameserver.datatables.ItemTable;
705+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
706+import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
707+import org.l2jmobius.gameserver.model.items.Item;
708+import org.l2jmobius.gameserver.model.skills.Skill;
709+import org.l2jmobius.gameserver.model.skills.SkillBuffType;
710+
711+/**
712+ * @author HorridoJoho
713+ */
714+final class BufferData
715+{
716+ public static enum HtmlType
717+ {
718+ NPC,
719+ COMMUNITY
720+ }
721+
722+ public final class Buff
723+ {
724+ protected final String ident;
725+ protected final Skill skill;
726+ protected final SkillBuffType type;
727+ protected final Map<String, ItemRequirement> items;
728+ /** HTMLTemplatePlaceholder */
729+ protected final HTMLTemplatePlaceholder placeholder;
730+
731+ protected Buff(String ident, Skill skill, SkillBuffType type, Element elem)
732+ {
733+ this.ident = ident;
734+ this.skill = skill;
735+ this.type = type;
736+ this.items = _parseItems(elem);
737+
738+ this.placeholder = new HTMLTemplatePlaceholder("buff", null);
739+ this.placeholder.addChild("ident", ident).addChild("skill_id", String.valueOf(skill.getId())).addChild("skill_name", skill.getName()).addChild("skill_icon", _getClientSkillIconSource(skill.getId())).addChild("type", type.toString());
740+ if (!this.items.isEmpty())
741+ {
742+ HTMLTemplatePlaceholder itemsPlaceholder = this.placeholder.addChild("items", null).getChild("items");
743+ for (Entry<String, ItemRequirement> item : this.items.entrySet())
744+ {
745+ itemsPlaceholder.addAliasChild(String.valueOf(itemsPlaceholder.getChildsSize()), item.getValue().placeholder);
746+ }
747+ }
748+ }
749+
750+ private Map<String, ItemRequirement> _parseItems(Element elem)
751+ {
752+ Map<String, ItemRequirement> items = new LinkedHashMap<>();
753+ Node curNode = elem.getFirstChild();
754+ while (curNode != null)
755+ {
756+ switch (curNode.getNodeType())
757+ {
758+ case Node.ELEMENT_NODE:
759+ Element curElem = (Element) curNode;
760+ String ident = curElem.getAttribute("ident");
761+ ItemRequirement req = _itemRequirements.get(ident);
762+ if (req == null)
763+ {
764+ _LOGGER.warning("Buffer - buffs.xml: Item requirement with ident " + ident + " does not exists!");
765+ }
766+ else
767+ {
768+ items.put(ident, req);
769+ }
770+ break;
771+ }
772+
773+ curNode = curNode.getNextSibling();
774+ }
775+ return Collections.unmodifiableMap(items);
776+ }
777+
778+ private String _getClientSkillIconSource(int skillId)
779+ {
780+ String format = "";
781+ if (skillId < 100)
782+ {
783+ format = "00" + skillId;
784+ }
785+ else if ((skillId > 99) && (skillId < 1000))
786+ {
787+ format = "0" + skillId;
788+ }
789+ else if (skillId == 1517)
790+ {
791+ format = "1499";
792+ }
793+ else if (skillId == 1518)
794+ {
795+ format = "1502";
796+ }
797+ else
798+ {
799+ if ((skillId > 4698) && (skillId < 4701))
800+ {
801+ format = "1331";
802+ }
803+ else if ((skillId > 4701) && (skillId < 4704))
804+ {
805+ format = "1332";
806+ }
807+ else
808+ {
809+ format = Integer.toString(skillId);
810+ }
811+ }
812+
813+ return "icon.skill" + format;
814+ }
815+
816+ public SkillBuffType getType()
817+ {
818+ return type;
819+ }
820+ }
821+
822+ public final class BuffCategory
823+ {
824+ protected final String ident;
825+ protected final Map<String, Buff> buffs;
826+ /** HTMLTemplatePlaceholder */
827+ protected final HTMLTemplatePlaceholder placeholder;
828+
829+ protected BuffCategory(String ident, String name, Element elem)
830+ {
831+ this.ident = ident;
832+ this.buffs = _parseBuffs(elem);
833+
834+ this.placeholder = new HTMLTemplatePlaceholder("category", null);
835+ this.placeholder.addChild("ident", ident).addChild("name", name);
836+ if (!this.buffs.isEmpty())
837+ {
838+ HTMLTemplatePlaceholder buffsPlaceholder = this.placeholder.addChild("buffs", null).getChild("buffs");
839+ for (Entry<String, Buff> buff : this.buffs.entrySet())
840+ {
841+ buffsPlaceholder.addAliasChild(String.valueOf(buffsPlaceholder.getChildsSize()), buff.getValue().placeholder);
842+ }
843+ }
844+ }
845+
846+ private Map<String, Buff> _parseBuffs(Element elem)
847+ {
848+ Map<String, Buff> buffs = new LinkedHashMap<>();
849+ Node curNode = elem.getFirstChild();
850+ while (curNode != null)
851+ {
852+ switch (curNode.getNodeType())
853+ {
854+ case Node.ELEMENT_NODE:
855+ Element curElem = (Element) curNode;
856+ String ident = curElem.getAttribute("ident");
857+ Buff buff = _buffs.get(ident);
858+ if (buff == null)
859+ {
860+ _LOGGER.warning("Buffer - buff_categories.xml: Buff with ident " + ident + " does not exists!");
861+ }
862+ else
863+ {
864+ buffs.put(ident, buff);
865+ }
866+ break;
867+ }
868+
869+ curNode = curNode.getNextSibling();
870+ }
871+ return Collections.unmodifiableMap(buffs);
872+ }
873+
874+ public Buff getBuff(String buffIdent)
875+ {
876+ return buffs.get(buffIdent);
877+ }
878+ }
879+
880+ public abstract class Buffer
881+ {
882+ /** Can heal a player */
883+ protected final boolean canHeal;
884+ /** Can cancel a player */
885+ protected final boolean canCancel;
886+ /** buff categories */
887+ protected final Map<String, BuffCategory> buffCats;
888+ /** preset bufflists */
889+ protected final Map<String, BuffCategory> presetBufflists;
890+ /** HTMLTemplatePlaceholder */
891+ protected final HTMLTemplatePlaceholder placeholder;
892+
893+ protected Buffer(String xmlFile, String bypassPrefix, String bufferName, Element elem)
894+ {
895+ this.canHeal = Boolean.parseBoolean(elem.getAttribute("can_heal"));
896+ this.canCancel = Boolean.parseBoolean(elem.getAttribute("can_cancel"));
897+ this.buffCats = _parseBuffCats(xmlFile, elem, false);
898+ this.presetBufflists = _parseBuffCats(xmlFile, elem, true);
899+
900+ this.placeholder = new HTMLTemplatePlaceholder("buffer", null);
901+ this.placeholder.addChild("bypass_prefix", "bypass -h " + bypassPrefix).addChild("name", bufferName).addChild("max_unique_lists", String.valueOf(_maxUniqueLists)).addChild("unique_max_buffs", String.valueOf(_uniqueMaxBuffs)).addChild("unique_max_songs_dances", String.valueOf(_uniqueMaxSongsDances));
902+ if (this.canHeal)
903+ {
904+ this.placeholder.addChild("can_heal", null);
905+ }
906+ if (this.canCancel)
907+ {
908+ this.placeholder.addChild("can_cancel", null);
909+ }
910+ if (!this.buffCats.isEmpty())
911+ {
912+ HTMLTemplatePlaceholder buffCatsPlaceholder = this.placeholder.addChild("categories", null).getChild("categories");
913+ for (Entry<String, BuffCategory> buffCat : this.buffCats.entrySet())
914+ {
915+ buffCatsPlaceholder.addAliasChild(String.valueOf(buffCatsPlaceholder.getChildsSize()), buffCat.getValue().placeholder);
916+ }
917+ }
918+ if (!this.presetBufflists.isEmpty())
919+ {
920+ HTMLTemplatePlaceholder presetBufflistsPlaceholder = this.placeholder.addChild("presets", null).getChild("presets");
921+ for (Entry<String, BuffCategory> presetBufflist : this.presetBufflists.entrySet())
922+ {
923+ presetBufflistsPlaceholder.addAliasChild(String.valueOf(presetBufflistsPlaceholder.getChildsSize()), presetBufflist.getValue().placeholder);
924+ }
925+ }
926+ }
927+
928+ private Map<String, BuffCategory> _parseBuffCats(String xmlFile, Element elem, boolean preset)
929+ {
930+ Map<String, BuffCategory> buffCats = new LinkedHashMap<>();
931+ Node curNode = elem.getFirstChild();
932+ while (curNode != null)
933+ {
934+ switch (curNode.getNodeType())
935+ {
936+ case Node.ELEMENT_NODE:
937+ Element curElem = (Element) curNode;
938+ String ident = curElem.getAttribute("ident");
939+ boolean isPreset = Boolean.parseBoolean(curElem.getAttribute("is_preset"));
940+ if (preset != isPreset)
941+ {
942+ break;
943+ }
944+ BuffCategory buffCat = _buffCats.get(ident);
945+ if (buffCat == null)
946+ {
947+ _LOGGER.warning("Buffer - " + xmlFile + ": Buff category with ident " + ident + " does not exists!");
948+ }
949+ else
950+ {
951+ buffCats.put(ident, buffCat);
952+ }
953+ break;
954+ }
955+
956+ curNode = curNode.getNextSibling();
957+ }
958+ return Collections.unmodifiableMap(buffCats);
959+ }
960+
961+ public BuffCategory getBuffCat(String buffCatIdent)
962+ {
963+ return buffCats.get(buffCatIdent);
964+ }
965+
966+ public BuffCategory getPresetBufflist(String presetBufflistIdent)
967+ {
968+ return presetBufflists.get(presetBufflistIdent);
969+ }
970+
971+ public Map<String, BuffCategory> getBuffCats()
972+ {
973+ return buffCats;
974+ }
975+ }
976+
977+ public final class BufferNpc extends Buffer
978+ {
979+ /** npc id */
980+ protected final NpcTemplate npc;
981+
982+ protected BufferNpc(NpcTemplate npc, Element elem)
983+ {
984+ super("buffer_npcs.xml", BufferNpcBypassHandler.BYPASS, npc.getName(), elem);
985+ this.npc = npc;
986+ }
987+ }
988+
989+ public final class VoicedBuffer extends Buffer
990+ {
991+ public final boolean enabled;
992+ public final int requiredItem;
993+
994+ protected VoicedBuffer(Element elem)
995+ {
996+ super("voiced_buffer.xml", "voice ." + BufferVoicedCommandHandler.VOICED_COMMAND, "Voiced Command Buffer", elem);
997+ this.enabled = Boolean.parseBoolean(elem.getAttribute("enabled"));
998+ if (elem.hasAttribute("required_item"))
999+ {
1000+ this.requiredItem = Integer.parseInt(elem.getAttribute("required_item"));
1001+ }
1002+ else
1003+ {
1004+ this.requiredItem = 0;
1005+ }
1006+ }
1007+ }
1008+
1009+ protected static final Logger _LOGGER = Logger.getLogger(BufferData.class.getName());
1010+ private static BufferData _INSTANCE = null;
1011+
1012+ public synchronized static void initInstance() throws Exception
1013+ {
1014+ _INSTANCE = new BufferData();
1015+ }
1016+
1017+ public synchronized static BufferData getInstance()
1018+ {
1019+ return _INSTANCE;
1020+ }
1021+
1022+ private final HtmlType _htmlType;
1023+ private final long _healCooldown;
1024+ protected final int _maxUniqueLists;
1025+ protected final int _uniqueMaxBuffs;
1026+ protected final int _uniqueMaxSongsDances;
1027+ protected final Map<String, ItemRequirement> _itemRequirements = new HashMap<>();
1028+ protected final Map<String, Buff> _buffs = new HashMap<>();
1029+ protected final Map<String, BuffCategory> _buffCats = new HashMap<>();
1030+ private final Map<Integer, BufferNpc> _bufferNpcs = new HashMap<>();
1031+ private final VoicedBuffer _voicedBuffer;
1032+ protected final ConcurrentHashMap<Integer, Map<Integer, UniqueBufflist>> _uniqueBufflists = new ConcurrentHashMap<>();
1033+
1034+ private BufferData() throws Exception
1035+ {
1036+ Path xmlPath = Paths.get(Config.DATAPACK_ROOT.getAbsolutePath(), "data", "scripts", custom.Buffer.Buffer.SCRIPT_SUBFOLDER.toString(), "data", "xml");
1037+ Path xsdPath = Paths.get(xmlPath.toString(), "xsd");
1038+
1039+ Element elem = XMLUtils.CreateDocument(xmlPath.resolve("buffer.xml"), xsdPath.resolve("buffer.xsd")).getDocumentElement();
1040+ _htmlType = HtmlType.valueOf(elem.getAttribute("dialog_type"));
1041+ _healCooldown = Integer.parseInt(elem.getAttribute("heal_cooldown")) * 1000;
1042+ _maxUniqueLists = Integer.parseInt(elem.getAttribute("max_unique_lists"));
1043+ _uniqueMaxBuffs = Integer.parseInt(elem.getAttribute("unique_max_buffs"));
1044+ _uniqueMaxSongsDances = Integer.parseInt(elem.getAttribute("unique_max_songs_dances"));
1045+
1046+ elem = XMLUtils.CreateDocument(xmlPath.resolve("item_requirements.xml"), xsdPath.resolve("item_requirements.xsd")).getDocumentElement();
1047+ _parseItemRequirements(elem);
1048+
1049+ elem = XMLUtils.CreateDocument(xmlPath.resolve("buffs.xml"), xsdPath.resolve("buffs.xsd")).getDocumentElement();
1050+ _parseBuffs(elem);
1051+
1052+ elem = XMLUtils.CreateDocument(xmlPath.resolve("buff_categories.xml"), xsdPath.resolve("buff_categories.xsd")).getDocumentElement();
1053+ _parseBuffCats(elem, _buffCats);
1054+
1055+ elem = XMLUtils.CreateDocument(xmlPath.resolve("buffer_npcs.xml"), xsdPath.resolve("buffer_npcs.xsd")).getDocumentElement();
1056+ _parseBufferNpcs(elem);
1057+
1058+ elem = XMLUtils.CreateDocument(xmlPath.resolve("voiced_buffer.xml"), xsdPath.resolve("voiced_buffer.xsd")).getDocumentElement();
1059+ _voicedBuffer = new VoicedBuffer(elem);
1060+
1061+ _loadUniqueBufflists();
1062+ }
1063+
1064+ private void _parseItemRequirements(Element elem)
1065+ {
1066+ Node curNode = elem.getFirstChild();
1067+ while (curNode != null)
1068+ {
1069+ switch (curNode.getNodeType())
1070+ {
1071+ case Node.ELEMENT_NODE:
1072+ Element curElem = (Element) curNode;
1073+ String ident = curElem.getAttribute("ident");
1074+ int itemId = Integer.parseInt(curElem.getAttribute("id"));
1075+ long itemAmount = Long.parseLong(curElem.getAttribute("amount"));
1076+ Item item = ItemTable.getInstance().getTemplate(itemId);
1077+ if (item == null)
1078+ {
1079+ _LOGGER.warning("Buffer - item_requirements.xml: Item with id " + itemId + " does not exists!");
1080+ }
1081+ else
1082+ {
1083+ _itemRequirements.put(ident, new ItemRequirement(item, itemAmount));
1084+ }
1085+ break;
1086+ }
1087+
1088+ curNode = curNode.getNextSibling();
1089+ }
1090+ }
1091+
1092+ private void _parseBuffs(Element elem)
1093+ {
1094+ Node curNode = elem.getFirstChild();
1095+ while (curNode != null)
1096+ {
1097+ switch (curNode.getNodeType())
1098+ {
1099+ case Node.ELEMENT_NODE:
1100+ Element curElem = (Element) curNode;
1101+ String ident = curElem.getAttribute("ident");
1102+ int skillId = Integer.parseInt(curElem.getAttribute("skill_id"));
1103+ int skillLevel = Integer.parseInt(curElem.getAttribute("skill_level"));
1104+ Skill skill = SkillData.getInstance().getSkill(skillId, skillLevel);
1105+ SkillBuffType buffType = SkillBuffType.valueOf(curElem.getAttribute("type"));
1106+ if (skill == null)
1107+ {
1108+ _LOGGER.warning("Buffer - buffs.xml: Skill with id " + skillId + " and level " + skillLevel + " does not exists!");
1109+ }
1110+ else
1111+ {
1112+ _buffs.put(ident, new Buff(ident, skill, buffType, curElem));
1113+ }
1114+ break;
1115+ }
1116+
1117+ curNode = curNode.getNextSibling();
1118+ }
1119+ }
1120+
1121+ private void _parseBuffCats(Element elem, Map<String, BuffCategory> buffCats)
1122+ {
1123+ Node curNode = elem.getFirstChild();
1124+ while (curNode != null)
1125+ {
1126+ switch (curNode.getNodeType())
1127+ {
1128+ case Node.ELEMENT_NODE:
1129+ Element curElem = (Element) curNode;
1130+ String ident = curElem.getAttribute("ident");
1131+ buffCats.put(ident, new BuffCategory(ident, curElem.getAttribute("name"), curElem));
1132+ break;
1133+ }
1134+
1135+ curNode = curNode.getNextSibling();
1136+ }
1137+ }
1138+
1139+ private void _parseBufferNpcs(Element elem)
1140+ {
1141+ Node curNode = elem.getFirstChild();
1142+ while (curNode != null)
1143+ {
1144+ switch (curNode.getNodeType())
1145+ {
1146+ case Node.ELEMENT_NODE:
1147+ Element curElem = (Element) curNode;
1148+ int npcId = Integer.parseInt(curElem.getAttribute("id"));
1149+ NpcTemplate npc = NpcData.getInstance().getTemplate(npcId);
1150+ if (npc == null)
1151+ {
1152+ _LOGGER.warning("Buffer - buffer_npcs.xml: Npc with id " + npcId + " does not exists!");
1153+ }
1154+ else
1155+ {
1156+ _bufferNpcs.put(npc.getId(), new BufferNpc(npc, curElem));
1157+ }
1158+ break;
1159+ }
1160+
1161+ curNode = curNode.getNextSibling();
1162+ }
1163+ }
1164+
1165+ private void _loadUniqueBufflists() throws Exception
1166+ {
1167+ try (Connection con = DatabaseFactory.getConnection();)
1168+ {
1169+ try (Statement stmt = con.createStatement();
1170+ ResultSet rset = stmt.executeQuery("SELECT id,character_id,list_name FROM buffer_user_lists ORDER BY character_id ASC");)
1171+ {
1172+ while (rset.next())
1173+ {
1174+ int charId = rset.getInt("character_id");
1175+ int ulistId = rset.getInt("id");
1176+ String ulistName = rset.getString("list_name");
1177+
1178+ Map<Integer, UniqueBufflist> ulists = _getPlayersULists(charId);
1179+ ulists.put(ulistId, new UniqueBufflist(ulistId, ulistName));
1180+ }
1181+ }
1182+
1183+ for (Entry<Integer, Map<Integer, UniqueBufflist>> ulists : _uniqueBufflists.entrySet())
1184+ {
1185+ for (Entry<Integer, UniqueBufflist> ulist : ulists.getValue().entrySet())
1186+ {
1187+ try (PreparedStatement stmt = con.prepareStatement("SELECT buff_id FROM buffer_user_list_buffs WHERE user_buff_list_id=?");)
1188+ {
1189+ stmt.setInt(1, ulist.getKey());
1190+ try (ResultSet rs = stmt.executeQuery();)
1191+ {
1192+ while (rs.next())
1193+ {
1194+ String buffIdent = rs.getString("buff_id");
1195+ Buff buff = getBuff(buffIdent);
1196+ if (buff == null)
1197+ {
1198+ _LOGGER.warning("Buffer - Data: Buff with ident does not exists!");
1199+ }
1200+ else
1201+ {
1202+ ulist.getValue().add(buff);
1203+ }
1204+ }
1205+ }
1206+ }
1207+ }
1208+ }
1209+ }
1210+ catch (SQLException sqle)
1211+ {
1212+ throw new SQLException(sqle);
1213+ }
1214+ }
1215+
1216+ private Map<Integer, UniqueBufflist> _getPlayersULists(int playerObjectId)
1217+ {
1218+ Map<Integer, UniqueBufflist> ulists = _uniqueBufflists.get(playerObjectId);
1219+ if (ulists == null)
1220+ {
1221+ ulists = new LinkedHashMap<>();
1222+ _uniqueBufflists.put(playerObjectId, ulists);
1223+ }
1224+
1225+ return ulists;
1226+ }
1227+
1228+ private UniqueBufflist _getPlayersUList(int playerObjectId, String ulistName)
1229+ {
1230+ Map<Integer, UniqueBufflist> ulists = _getPlayersULists(playerObjectId);
1231+ for (Entry<Integer, UniqueBufflist> entry : ulists.entrySet())
1232+ {
1233+ if (entry.getValue().ulistName.equals(ulistName))
1234+ {
1235+ return entry.getValue();
1236+ }
1237+ }
1238+ return null;
1239+ }
1240+
1241+ public boolean createUniqueBufflist(int playerObjectId, String ulistName)
1242+ {
1243+ // prevent duplicate entry
1244+ if (_getPlayersUList(playerObjectId, ulistName) != null)
1245+ {
1246+ return false;
1247+ }
1248+
1249+ try (Connection con = DatabaseFactory.getConnection();
1250+ PreparedStatement stmt = con.prepareStatement("INSERT INTO buffer_user_lists (character_id,list_name) VALUES(?,?)", Statement.RETURN_GENERATED_KEYS);)
1251+ {
1252+ stmt.setInt(1, playerObjectId);
1253+ stmt.setString(2, ulistName);
1254+ stmt.executeUpdate();
1255+ ResultSet rs = stmt.getGeneratedKeys();
1256+ rs.next();
1257+ int newId = rs.getInt(1);
1258+ _getPlayersULists(playerObjectId).put(newId, new UniqueBufflist(newId, ulistName));
1259+ return true;
1260+ }
1261+ catch (SQLException sqle)
1262+ {
1263+ _LOGGER.log(Level.WARNING, "Failed to insert unique bufflist!", sqle);
1264+ return false;
1265+ }
1266+ }
1267+
1268+ public void deleteUniqueBufflist(int playerObjectId, String ulistName)
1269+ {
1270+ UniqueBufflist ulist = _getPlayersUList(playerObjectId, ulistName);
1271+ if (ulist == null)
1272+ {
1273+ return;
1274+ }
1275+
1276+ try (Connection con = DatabaseFactory.getConnection();
1277+ PreparedStatement stmt = con.prepareStatement("DELETE FROM buffer_user_lists WHERE character_id=? AND id=?");)
1278+ {
1279+ stmt.setInt(1, playerObjectId);
1280+ stmt.setInt(2, ulist.ulistId);
1281+ stmt.executeUpdate();
1282+ _getPlayersULists(playerObjectId).remove(ulist.ulistId);
1283+ }
1284+ catch (SQLException sqle)
1285+ {
1286+ _LOGGER.log(Level.WARNING, "Failed to delete unique bufflist!", sqle);
1287+ }
1288+ }
1289+
1290+ public boolean addToUniqueBufflist(int playerObjectId, String ulistName, Buff buff)
1291+ {
1292+ UniqueBufflist ulist = _getPlayersUList(playerObjectId, ulistName);
1293+ // prevent duplicate entry with ulist.contains(buff)
1294+ if ((ulist == null) || ulist.contains(buff) || ((buff.getType() == SkillBuffType.BUFF) && (ulist.numBuffs >= _uniqueMaxBuffs)) || ((buff.getType() == SkillBuffType.DANCE) && (ulist.numSongsDances >= _uniqueMaxSongsDances)))
1295+ {
1296+ return false;
1297+ }
1298+
1299+ try (Connection con = DatabaseFactory.getConnection();
1300+ PreparedStatement stmt = con.prepareStatement("INSERT INTO buffer_user_list_buffs VALUES(?,?)");)
1301+ {
1302+ stmt.setInt(1, ulist.ulistId);
1303+ stmt.setString(2, buff.ident);
1304+ stmt.executeUpdate();
1305+ ulist.add(buff);
1306+ }
1307+ catch (SQLException sqle)
1308+ {
1309+ _LOGGER.log(Level.WARNING, "Failed to insert buff into unique bufflist!", sqle);
1310+ return false;
1311+ }
1312+
1313+ return true;
1314+ }
1315+
1316+ public void removeFromUniqueBufflist(int playerObjectId, String ulistName, Buff buff)
1317+ {
1318+ UniqueBufflist ulist = _getPlayersUList(playerObjectId, ulistName);
1319+ if ((ulist == null) || !ulist.contains(buff))
1320+ {
1321+ return;
1322+ }
1323+
1324+ try (Connection con = DatabaseFactory.getConnection();
1325+ PreparedStatement stmt = con.prepareStatement("DELETE FROM buffer_user_list_buffs WHERE user_buff_list_id=? AND buff_id=?");)
1326+ {
1327+ stmt.setInt(1, ulist.ulistId);
1328+ stmt.setString(2, buff.ident);
1329+ stmt.executeUpdate();
1330+ ulist.remove(buff);
1331+ }
1332+ catch (SQLException sqle)
1333+ {
1334+ _LOGGER.log(Level.WARNING, "Failed to remove buff from unique bufflist!", sqle);
1335+ }
1336+ }
1337+
1338+ public HtmlType getHtmlType()
1339+ {
1340+ return _htmlType;
1341+ }
1342+
1343+ public long getHealCooldown()
1344+ {
1345+ return _healCooldown;
1346+ }
1347+
1348+ public int getMaxUniqueLists()
1349+ {
1350+ return _maxUniqueLists;
1351+ }
1352+
1353+ public int getUniqueMaxBuffs()
1354+ {
1355+ return _uniqueMaxBuffs;
1356+ }
1357+
1358+ public int getUniqueMaxSongsBuffs()
1359+ {
1360+ return _uniqueMaxSongsDances;
1361+ }
1362+
1363+ public Buff getBuff(String buffIdent)
1364+ {
1365+ return _buffs.get(buffIdent);
1366+ }
1367+
1368+ public BuffCategory getBuffCat(String buffCatIdent)
1369+ {
1370+ return _buffCats.get(buffCatIdent);
1371+ }
1372+
1373+ public Map<Integer, BufferNpc> getBufferNpcs()
1374+ {
1375+ return _bufferNpcs;
1376+ }
1377+
1378+ public BufferNpc getBufferNpc(int npcId)
1379+ {
1380+ return _bufferNpcs.get(npcId);
1381+ }
1382+
1383+ public VoicedBuffer getVoicedBuffer()
1384+ {
1385+ return _voicedBuffer;
1386+ }
1387+
1388+ public boolean canHaveMoreBufflists(PlayerInstance player)
1389+ {
1390+ return _getPlayersULists(player.getObjectId()).size() < _maxUniqueLists;
1391+ }
1392+
1393+ public boolean hasUniqueBufflist(int playerObjectId, String ulistName)
1394+ {
1395+ return _getPlayersUList(playerObjectId, ulistName) != null;
1396+ }
1397+
1398+ public List<Buff> getUniqueBufflist(int playerObjectId, String ulistName)
1399+ {
1400+ UniqueBufflist ulist = _getPlayersUList(playerObjectId, ulistName);
1401+ if (ulist == null)
1402+ {
1403+ return null;
1404+ }
1405+ return Collections.unmodifiableList(ulist);
1406+ }
1407+
1408+ public HTMLTemplatePlaceholder getPlayersUListPlaceholder(int playerObjectId, String ulistName)
1409+ {
1410+ UniqueBufflist ulist = _getPlayersUList(playerObjectId, ulistName);
1411+ if (ulist == null)
1412+ {
1413+ return null;
1414+ }
1415+ return ulist.placeholder;
1416+ }
1417+
1418+ public HTMLTemplatePlaceholder getPlayersUListsPlaceholder(int playerObjectId)
1419+ {
1420+ Map<Integer, UniqueBufflist> ulists = _getPlayersULists(playerObjectId);
1421+ if (ulists.isEmpty())
1422+ {
1423+ return null;
1424+ }
1425+
1426+ HTMLTemplatePlaceholder placeholder = new HTMLTemplatePlaceholder("uniques", null);
1427+ for (Entry<Integer, UniqueBufflist> entry : ulists.entrySet())
1428+ {
1429+ placeholder.addAliasChild(String.valueOf(placeholder.getChildsSize()), entry.getValue().placeholder);
1430+ }
1431+ return placeholder;
1432+ }
1433+}
1434Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/Buffer.java
1435IDEA additional info:
1436Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
1437<+>UTF-8
1438===================================================================
1439--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/Buffer.java (date 1601235047025)
1440+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/Buffer.java (date 1601235047025)
1441@@ -0,0 +1,874 @@
1442+/*
1443+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
1444+ * Copyright (C) 2015 Christian Buck
1445+ *
1446+ * This program is free software: you can redistribute it and/or modify
1447+ * it under the terms of the GNU General Public License as published by
1448+ * the Free Software Foundation, either version 3 of the License, or
1449+ * (at your option) any later version.
1450+ *
1451+ * This program is distributed in the hope that it will be useful,
1452+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1453+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1454+ * GNU General Public License for more details.
1455+ *
1456+ * You should have received a copy of the GNU General Public License
1457+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1458+ */
1459+package custom.Buffer;
1460+
1461+import java.nio.file.Path;
1462+import java.nio.file.Paths;
1463+import java.util.Collection;
1464+import java.util.HashMap;
1465+import java.util.List;
1466+import java.util.Locale;
1467+import java.util.Map;
1468+import java.util.Map.Entry;
1469+import java.util.concurrent.ConcurrentHashMap;
1470+import java.util.logging.Level;
1471+import java.util.logging.Logger;
1472+
1473+import ai.AbstractNpcAI;
1474+import custom.Buffer.util.ItemRequirement;
1475+import custom.Buffer.util.htmltmpls.HTMLTemplateParser;
1476+import custom.Buffer.util.htmltmpls.HTMLTemplatePlaceholder;
1477+import custom.Buffer.util.htmltmpls.funcs.ChildsCountFunc;
1478+import custom.Buffer.util.htmltmpls.funcs.ExistsFunc;
1479+import custom.Buffer.util.htmltmpls.funcs.ForeachFunc;
1480+import custom.Buffer.util.htmltmpls.funcs.IfChildsFunc;
1481+import custom.Buffer.util.htmltmpls.funcs.IfFunc;
1482+import custom.Buffer.util.htmltmpls.funcs.IncludeFunc;
1483+
1484+import org.l2jmobius.Config;
1485+import org.l2jmobius.gameserver.enums.HtmlActionScope;
1486+import org.l2jmobius.gameserver.handler.BypassHandler;
1487+import org.l2jmobius.gameserver.handler.ItemHandler;
1488+import org.l2jmobius.gameserver.handler.VoicedCommandHandler;
1489+import org.l2jmobius.gameserver.model.actor.Creature;
1490+import org.l2jmobius.gameserver.model.actor.Npc;
1491+import org.l2jmobius.gameserver.model.actor.Playable;
1492+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
1493+import org.l2jmobius.gameserver.model.skills.BuffInfo;
1494+import org.l2jmobius.gameserver.model.zone.ZoneId;
1495+import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
1496+import org.l2jmobius.gameserver.network.serverpackets.ShowBoard;
1497+import org.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
1498+
1499+/**
1500+ * @author HorridoJoho
1501+ */
1502+public final class Buffer extends AbstractNpcAI
1503+{
1504+ private static final class SingletonHolder
1505+ {
1506+ protected static final Buffer INSTANCE = new Buffer();
1507+ }
1508+
1509+ private static final int MINUTE_IN_SECONDS = 60;
1510+
1511+ private static final Logger _LOGGER = Logger.getLogger(Buffer.class.getName());
1512+ public static final Path SCRIPTS_SUBFOLDER = Paths.get("custom");
1513+ public static final Path SCRIPT_TOP_FOLDER = Paths.get("Buffer");
1514+ public static final Path SCRIPT_SUBFOLDER = Paths.get(SCRIPTS_SUBFOLDER.toString(), SCRIPT_TOP_FOLDER.toString());
1515+
1516+ static Buffer getInstance()
1517+ {
1518+ return SingletonHolder.INSTANCE;
1519+ }
1520+
1521+ public static void main(String[] args)
1522+ {
1523+ try
1524+ {
1525+ BufferData.initInstance();
1526+ }
1527+ catch (Exception ex)
1528+ {
1529+ _LOGGER.log(Level.WARNING, "Buffer - Data: Exception while loading npc buffer data, not registering mod!", ex);
1530+ return;
1531+ }
1532+
1533+ Buffer instance = getInstance();
1534+
1535+ for (Entry<Integer, BufferData.BufferNpc> npc : BufferData.getInstance().getBufferNpcs().entrySet())
1536+ {
1537+ instance.addFirstTalkId(npc.getKey());
1538+ instance.addStartNpc(npc.getKey());
1539+ instance.addTalkId(npc.getKey());
1540+ }
1541+ }
1542+
1543+ private static final ConcurrentHashMap<Integer, Long> _LAST_PLAYABLES_HEAL_TIME = new ConcurrentHashMap<>();
1544+ private static final ConcurrentHashMap<Integer, String> _LAST_PLAYER_HTMLS = new ConcurrentHashMap<>();
1545+ private static final ConcurrentHashMap<Integer, String> _ACTIVE_PLAYER_BUFFLISTS = new ConcurrentHashMap<>();
1546+
1547+ Buffer()
1548+ {
1549+// super(-1, SCRIPT_TOP_FOLDER.toString(), SCRIPTS_SUBFOLDER.toString());
1550+ super();
1551+
1552+ BypassHandler.getInstance().registerHandler(BufferNpcBypassHandler.getInstance());
1553+
1554+ if (BufferData.getInstance().getVoicedBuffer().enabled)
1555+ {
1556+ VoicedCommandHandler.getInstance().registerHandler(BufferVoicedCommandHandler.getInstance());
1557+ ItemHandler.getInstance().registerHandler(BufferItemHandler.getInstance());
1558+ }
1559+ }
1560+
1561+ // ////////////////////////////////////
1562+ // AI METHOD OVERRIDES
1563+ // ////////////////////////////////////
1564+ @Override
1565+ public String onFirstTalk(Npc npc, PlayerInstance player)
1566+ {
1567+ executeCommand(player, npc, null);
1568+ return null;
1569+ }
1570+
1571+ // ///////////////////////////////////
1572+ // UTILITY METHODS
1573+ // ///////////////////////////////////
1574+ private BufferData.Buffer determineBuffer(Npc npc, PlayerInstance player)
1575+ {
1576+ if (npc == null)
1577+ {
1578+ BufferData.VoicedBuffer buffer = BufferData.getInstance().getVoicedBuffer();
1579+ if (!buffer.enabled || ((buffer.requiredItem > 0) && (player.getInventory().getItemByItemId(buffer.requiredItem) == null)))
1580+ {
1581+ return null;
1582+ }
1583+ return buffer;
1584+ }
1585+ return BufferData.getInstance().getBufferNpc(npc.getId());
1586+ }
1587+
1588+ private String generateAdvancedHtml(PlayerInstance player, String path, Map<String, HTMLTemplatePlaceholder> placeholders, BufferData.HtmlType dialogType)
1589+ {
1590+ return HTMLTemplateParser.fromCache(
1591+ Path.of(
1592+ "/data/scripts/" + SCRIPT_SUBFOLDER + "/data/html/" + dialogType.toString().toLowerCase(Locale.ENGLISH) + "/" + path
1593+ ).toString(),
1594+ player,
1595+ placeholders,
1596+ IncludeFunc.INSTANCE,
1597+ IfFunc.INSTANCE,
1598+ ForeachFunc.INSTANCE,
1599+ ExistsFunc.INSTANCE,
1600+ IfChildsFunc.INSTANCE,
1601+ ChildsCountFunc.INSTANCE
1602+ );
1603+ }
1604+
1605+ /**
1606+ * Copy from {@link NpcHtmlMessage}
1607+ * @param activeChar the player
1608+ * @param html the html to check
1609+ */
1610+ private void buildBypassCache(PlayerInstance activeChar, String html)
1611+ {
1612+ if (activeChar == null)
1613+ {
1614+ return;
1615+ }
1616+
1617+ activeChar.clearHtmlActions(HtmlActionScope.NPC_HTML);
1618+ int len = html.length();
1619+ for (int i = 0; i < len; i++)
1620+ {
1621+ int start = html.indexOf("\"bypass ", i);
1622+ int finish = html.indexOf("\"", start + 1);
1623+ if ((start < 0) || (finish < 0))
1624+ {
1625+ break;
1626+ }
1627+
1628+ if (html.substring(start + 8, start + 10).equals("-h"))
1629+ {
1630+ start += 11;
1631+ }
1632+ else
1633+ {
1634+ start += 8;
1635+ }
1636+
1637+ i = finish;
1638+ int finish2 = html.indexOf("$", start);
1639+ if ((finish2 < finish) && (finish2 > 0))
1640+ {
1641+ activeChar.addHtmlAction(HtmlActionScope.NPC_HTML, html.substring(start, finish2).trim());
1642+ }
1643+ else
1644+ {
1645+ activeChar.addHtmlAction(HtmlActionScope.NPC_HTML, html.substring(start, finish).trim());
1646+ }
1647+ }
1648+ }
1649+
1650+ /**
1651+ * Copy from {@link org.l2jmobius.gameserver.communitybbs.Manager.BaseBBSManager}. Modified to allow larger community board htmls.
1652+ * @param player the player to send to
1653+ * @param html the html text
1654+ */
1655+ private void sendBBSHtml(PlayerInstance player, String html)
1656+ {
1657+ buildBypassCache(player, html);
1658+
1659+ if (html.length() < 16250)
1660+ {
1661+ player.sendPacket(new ShowBoard(html, "101"));
1662+ player.sendPacket(new ShowBoard(null, "102"));
1663+ player.sendPacket(new ShowBoard(null, "103"));
1664+ }
1665+ else if (html.length() < (16250 * 2))
1666+ {
1667+ player.sendPacket(new ShowBoard(html.substring(0, 16250), "101"));
1668+ player.sendPacket(new ShowBoard(html.substring(16250), "102"));
1669+ player.sendPacket(new ShowBoard(null, "103"));
1670+ }
1671+ else if (html.length() < (16250 * 3))
1672+ {
1673+ player.sendPacket(new ShowBoard(html.substring(0, 16250), "101"));
1674+ player.sendPacket(new ShowBoard(html.substring(16250, 16250 * 2), "102"));
1675+ player.sendPacket(new ShowBoard(html.substring(16250 * 2), "103"));
1676+ }
1677+ else
1678+ {
1679+ player.sendPacket(new ShowBoard("<html><body><br><center>Error: HTML was too long!</center></body></html>", "101"));
1680+ player.sendPacket(new ShowBoard(null, "102"));
1681+ player.sendPacket(new ShowBoard(null, "103"));
1682+ }
1683+ }
1684+
1685+ private void fillItemAmountMap(Map<Integer, Long> items, BufferData.Buff buff)
1686+ {
1687+ for (Entry<String, ItemRequirement> item : buff.items.entrySet())
1688+ {
1689+ Long amount = items.get(item.getValue().item.getId());
1690+ if (amount == null)
1691+ {
1692+ amount = 0L;
1693+ }
1694+ items.put(item.getValue().item.getId(), amount + item.getValue().amount);
1695+ }
1696+ }
1697+
1698+ private void castBuff(Playable playable, BufferData.Buff buff)
1699+ {
1700+ buff.skill.applyEffects(playable, playable, true, Config.BUFFER_CUSTOM_BUFF_DURATION * MINUTE_IN_SECONDS);
1701+ }
1702+
1703+ // //////////////////////////////////
1704+ // HTML COMMANDS
1705+ // //////////////////////////////////
1706+ private void showAdvancedHtml(PlayerInstance player, BufferData.Buffer buffer, Npc npc, String htmlPath, Map<String, HTMLTemplatePlaceholder> placeholders)
1707+ {
1708+ placeholders.put(buffer.placeholder.getName(), buffer.placeholder);
1709+
1710+ HTMLTemplatePlaceholder ulistsPlaceholder = BufferData.getInstance().getPlayersUListsPlaceholder(player.getObjectId());
1711+ if (ulistsPlaceholder != null)
1712+ {
1713+ placeholders.put(ulistsPlaceholder.getName(), ulistsPlaceholder);
1714+ }
1715+
1716+ String activeUniqueName = _ACTIVE_PLAYER_BUFFLISTS.get(player.getObjectId());
1717+ if (activeUniqueName != null)
1718+ {
1719+ HTMLTemplatePlaceholder ulistPlaceholder = BufferData.getInstance().getPlayersUListPlaceholder(player.getObjectId(), activeUniqueName);
1720+ if (ulistPlaceholder != null)
1721+ {
1722+ placeholders.put("active_unique", ulistPlaceholder);
1723+ }
1724+ }
1725+
1726+ BufferData.HtmlType dialogType = BufferData.getInstance().getHtmlType();
1727+
1728+ String html = generateAdvancedHtml(player, htmlPath, placeholders, dialogType);
1729+ switch (dialogType)
1730+ {
1731+ case NPC:
1732+ player.sendPacket(new NpcHtmlMessage(npc == null ? 0 : npc.getObjectId(), html));
1733+ break;
1734+ case COMMUNITY:
1735+ sendBBSHtml(player, html);
1736+ break;
1737+ }
1738+ }
1739+
1740+ private void htmlShowMain(PlayerInstance player, BufferData.Buffer buffer, Npc npc)
1741+ {
1742+ showAdvancedHtml(player, buffer, npc, "main.html", new HashMap<String, HTMLTemplatePlaceholder>());
1743+ }
1744+
1745+ private void htmlShowCategory(PlayerInstance player, BufferData.Buffer buffer, Npc npc, String categoryIdent)
1746+ {
1747+ BufferData.BuffCategory buffCat = buffer.getBuffCat(categoryIdent);
1748+ if (buffCat == null)
1749+ {
1750+ return;
1751+ }
1752+
1753+ HashMap<String, HTMLTemplatePlaceholder> placeholders = new HashMap<>();
1754+
1755+ placeholders.put("category", buffCat.placeholder);
1756+
1757+ showAdvancedHtml(player, buffer, npc, "category.html", placeholders);
1758+ }
1759+
1760+ private void htmlShowBuff(PlayerInstance player, BufferData.Buffer buffer, Npc npc, String categoryIdent, String buffIdent)
1761+ {
1762+ BufferData.BuffCategory buffCat = buffer.getBuffCat(categoryIdent);
1763+ if (buffCat == null)
1764+ {
1765+ return;
1766+ }
1767+ BufferData.Buff buff = buffCat.getBuff(buffIdent);
1768+ if (buff == null)
1769+ {
1770+ return;
1771+ }
1772+
1773+ HashMap<String, HTMLTemplatePlaceholder> placeholders = new HashMap<>();
1774+
1775+ placeholders.put("category", buffCat.placeholder);
1776+ placeholders.put("buff", buff.placeholder);
1777+
1778+ showAdvancedHtml(player, buffer, npc, "buff.html", placeholders);
1779+ }
1780+
1781+ private void htmlShowPreset(PlayerInstance player, BufferData.Buffer buffer, Npc npc, String presetBufflistIdent)
1782+ {
1783+ BufferData.BuffCategory presetBufflist = buffer.getPresetBufflist(presetBufflistIdent);
1784+ if (presetBufflist == null)
1785+ {
1786+ return;
1787+ }
1788+
1789+ HashMap<String, HTMLTemplatePlaceholder> placeholders = new HashMap<>();
1790+
1791+ placeholders.put("preset", presetBufflist.placeholder);
1792+
1793+ showAdvancedHtml(player, buffer, npc, "preset.html", placeholders);
1794+ }
1795+
1796+ private void htmlShowUnique(PlayerInstance player, BufferData.Buffer buffer, Npc npc, String uniqueName)
1797+ {
1798+ HTMLTemplatePlaceholder uniquePlaceholder = BufferData.getInstance().getPlayersUListPlaceholder(player.getObjectId(), uniqueName);
1799+ if (uniquePlaceholder == null)
1800+ {
1801+ // redirect to main html if uniqueName is not valid, will most likely happen when the player deletes a unique bufflist he is currently viewing
1802+ executeHtmlCommand(player, buffer, npc, "main");
1803+ return;
1804+ }
1805+
1806+ HashMap<String, HTMLTemplatePlaceholder> placeholders = new HashMap<>();
1807+
1808+ placeholders.put(uniquePlaceholder.getName(), uniquePlaceholder);
1809+
1810+ showAdvancedHtml(player, buffer, npc, "unique.html", placeholders);
1811+ }
1812+
1813+ private void executeHtmlCommand(PlayerInstance player, BufferData.Buffer buffer, Npc npc, String command)
1814+ {
1815+ _LAST_PLAYER_HTMLS.put(player.getObjectId(), command);
1816+
1817+ if ("main".equals(command))
1818+ {
1819+ htmlShowMain(player, buffer, npc);
1820+ }
1821+ else if (command.startsWith("category "))
1822+ {
1823+ htmlShowCategory(player, buffer, npc, command.substring(9));
1824+ }
1825+ else if (command.startsWith("preset "))
1826+ {
1827+ htmlShowPreset(player, buffer, npc, command.substring(7));
1828+ }
1829+ else if (command.startsWith("buff "))
1830+ {
1831+ String[] argsSplit = command.substring(5).split(" ", 2);
1832+ if (argsSplit.length != 2)
1833+ {
1834+ return;
1835+ }
1836+ htmlShowBuff(player, buffer, npc, argsSplit[0], argsSplit[1]);
1837+ }
1838+ else if (command.startsWith("unique "))
1839+ {
1840+ htmlShowUnique(player, buffer, npc, command.substring(7));
1841+ }
1842+ else
1843+ {
1844+ // all other malformed bypasses
1845+ htmlShowMain(player, buffer, npc);
1846+ }
1847+ }
1848+
1849+ //
1850+ // ////////////////////////////////
1851+
1852+ // /////////////////////////////////////////////
1853+ // TARGET COMMANDS
1854+ // /////////////////////////////////////////////
1855+ private void targetBuffBuff(PlayerInstance player, Playable target, BufferData.Buffer buffer, String categoryIdent, String buffIdent)
1856+ {
1857+ BufferData.BuffCategory bCat = buffer.getBuffCat(categoryIdent);
1858+ if (bCat == null)
1859+ {
1860+ return;
1861+ }
1862+ BufferData.Buff buff = bCat.getBuff(buffIdent);
1863+ if (buff == null)
1864+ {
1865+ return;
1866+ }
1867+
1868+ if (!buff.items.isEmpty())
1869+ {
1870+ HashMap<Integer, Long> items = new HashMap<>();
1871+ fillItemAmountMap(items, buff);
1872+
1873+ for (Entry<Integer, Long> item : items.entrySet())
1874+ {
1875+ if (player.getInventory().getInventoryItemCount(item.getKey(), 0, true) < item.getValue())
1876+ {
1877+ player.sendMessage("Not enough items!");
1878+ return;
1879+ }
1880+ }
1881+
1882+ for (Entry<Integer, Long> item : items.entrySet())
1883+ {
1884+ player.destroyItemByItemId("Buffer", item.getKey(), item.getValue(), player, true);
1885+ }
1886+ }
1887+
1888+ castBuff(target, buff);
1889+ }
1890+
1891+ private void targetBuffUnique(PlayerInstance player, Playable target, BufferData.Buffer buffer, String uniqueName)
1892+ {
1893+ List<BufferData.Buff> buffs = BufferData.getInstance().getUniqueBufflist(player.getObjectId(), uniqueName);
1894+
1895+ if (buffs != null)
1896+ {
1897+ HashMap<Integer, Long> items = null;
1898+ for (BufferData.Buff buff : buffs)
1899+ {
1900+ if (!buff.items.isEmpty())
1901+ {
1902+ if (items == null)
1903+ {
1904+ items = new HashMap<>();
1905+ }
1906+ fillItemAmountMap(items, buff);
1907+ }
1908+ }
1909+
1910+ if (items != null)
1911+ {
1912+ for (Entry<Integer, Long> item : items.entrySet())
1913+ {
1914+ if (player.getInventory().getInventoryItemCount(item.getKey(), 0, true) < item.getValue())
1915+ {
1916+ player.sendMessage("Not enough items!");
1917+ return;
1918+ }
1919+ }
1920+
1921+ for (Entry<Integer, Long> item : items.entrySet())
1922+ {
1923+ player.destroyItemByItemId("Buffer", item.getKey(), item.getValue(), player, true);
1924+ }
1925+ }
1926+
1927+ for (BufferData.Buff buff : buffs)
1928+ {
1929+ castBuff(target, buff);
1930+ }
1931+ }
1932+ }
1933+
1934+ private void targetBuffPreset(PlayerInstance player, Playable target, BufferData.Buffer buffer, String presetBufflistIdent)
1935+ {
1936+ BufferData.BuffCategory presetBufflist = buffer.getPresetBufflist(presetBufflistIdent);
1937+ if (presetBufflist == null)
1938+ {
1939+ return;
1940+ }
1941+
1942+ Collection<BufferData.Buff> buffs = presetBufflist.buffs.values();
1943+
1944+ if (buffs != null)
1945+ {
1946+ HashMap<Integer, Long> items = null;
1947+ for (BufferData.Buff buff : buffs)
1948+ {
1949+ if (!buff.items.isEmpty())
1950+ {
1951+ if (items == null)
1952+ {
1953+ items = new HashMap<>();
1954+ }
1955+ fillItemAmountMap(items, buff);
1956+ }
1957+ }
1958+
1959+ if (items != null)
1960+ {
1961+ for (Entry<Integer, Long> item : items.entrySet())
1962+ {
1963+ if (player.getInventory().getInventoryItemCount(item.getKey(), 0, true) < item.getValue())
1964+ {
1965+ player.sendMessage("Not enough items!");
1966+ return;
1967+ }
1968+ }
1969+
1970+ for (Entry<Integer, Long> item : items.entrySet())
1971+ {
1972+ player.destroyItemByItemId("Buffer", item.getKey(), item.getValue(), player, true);
1973+ }
1974+ }
1975+
1976+ for (BufferData.Buff buff : buffs)
1977+ {
1978+ castBuff(target, buff);
1979+ }
1980+ }
1981+ }
1982+
1983+ private void targetHeal(PlayerInstance player, Playable target, BufferData.Buffer buffer)
1984+ {
1985+ if (!buffer.canHeal)
1986+ {
1987+ return;
1988+ }
1989+
1990+ // prevent heal spamming, process cooldown on heal target
1991+ Long lastPlayableHealTime = _LAST_PLAYABLES_HEAL_TIME.get(target.getObjectId());
1992+ if (lastPlayableHealTime != null)
1993+ {
1994+ Long elapsedTime = System.currentTimeMillis() - lastPlayableHealTime;
1995+ Long healCooldown = BufferData.getInstance().getHealCooldown();
1996+ if (elapsedTime < healCooldown)
1997+ {
1998+ Long remainingTime = healCooldown - elapsedTime;
1999+ if (target == player)
2000+ {
2001+ player.sendMessage("You can heal yourself again in " + (remainingTime / 1000) + " seconds.");
2002+ }
2003+ else
2004+ {
2005+ player.sendMessage("You can heal your pet again in " + (remainingTime / 1000) + " seconds.");
2006+ }
2007+ return;
2008+ }
2009+ }
2010+
2011+ _LAST_PLAYABLES_HEAL_TIME.put(target.getObjectId(), System.currentTimeMillis());
2012+
2013+ if (player == target)
2014+ {
2015+ player.setCurrentCp(player.getMaxCp());
2016+ }
2017+ target.setCurrentHp(target.getMaxHp());
2018+ target.setCurrentMp(target.getMaxMp());
2019+ target.broadcastStatusUpdate();
2020+ }
2021+
2022+ private void targetCancel(PlayerInstance player, Playable target, BufferData.Buffer buffer)
2023+ {
2024+ if (!buffer.canCancel)
2025+ {
2026+ return;
2027+ }
2028+ target.stopAllEffectsExceptThoseThatLastThroughDeath();
2029+ }
2030+
2031+ private void executeTargetCommand(PlayerInstance player, BufferData.Buffer buffer, String command)
2032+ {
2033+ // /////////////////////////////////
2034+ // first determine the target
2035+ Playable target;
2036+ if (command.startsWith("player "))
2037+ {
2038+ target = player;
2039+ command = command.substring(7);
2040+ }
2041+ else if (command.startsWith("summon "))
2042+ {
2043+ target = player.getPet();
2044+ if (target == null)
2045+ {
2046+ return;
2047+ }
2048+ command = command.substring(7);
2049+ }
2050+ else
2051+ {
2052+ return;
2053+ }
2054+
2055+ // //////////////////////////////////////////
2056+ // run the choosen action on the target
2057+ if (command.startsWith("buff "))
2058+ {
2059+ String[] argsSplit = command.substring(5).split(" ", 2);
2060+ if (argsSplit.length != 2)
2061+ {
2062+ return;
2063+ }
2064+ targetBuffBuff(player, target, buffer, argsSplit[0], argsSplit[1]);
2065+ }
2066+ else if (command.startsWith("unique "))
2067+ {
2068+ targetBuffUnique(player, target, buffer, command.substring(7));
2069+ }
2070+ else if (command.startsWith("preset "))
2071+ {
2072+ targetBuffPreset(player, target, buffer, command.substring(7));
2073+ }
2074+ else if ("heal".equals(command))
2075+ {
2076+ targetHeal(player, target, buffer);
2077+ }
2078+ else if ("cancel".equals(command))
2079+ {
2080+ targetCancel(player, target, buffer);
2081+ }
2082+ }
2083+
2084+ //
2085+ // ////////////////////////////////
2086+
2087+ // ////////////////////////////////
2088+ // UNIQUE COMMANDS
2089+ // ////////////////////////////////
2090+ private boolean uniqueCreate(PlayerInstance player, String uniqueName)
2091+ {
2092+ if (!BufferData.getInstance().canHaveMoreBufflists(player))
2093+ {
2094+ player.sendMessage("Maximum number of unique bufflists reached!");
2095+ return false;
2096+ }
2097+
2098+ // only allow alpha numeric names because we use this name on the htmls
2099+ if (!uniqueName.matches("[A-Za-z0-9]+"))
2100+ {
2101+ return false;
2102+ }
2103+
2104+ return BufferData.getInstance().createUniqueBufflist(player.getObjectId(), uniqueName);
2105+ }
2106+
2107+ private void uniqueDelete(PlayerInstance player, String uniqueName)
2108+ {
2109+ BufferData.getInstance().deleteUniqueBufflist(player.getObjectId(), uniqueName);
2110+ // also remove from active bufflist when it's the deleted
2111+ String activeUniqueName = _ACTIVE_PLAYER_BUFFLISTS.get(player.getObjectId());
2112+ if ((activeUniqueName != null) && activeUniqueName.equals(uniqueName))
2113+ {
2114+ _ACTIVE_PLAYER_BUFFLISTS.remove(player.getObjectId());
2115+ }
2116+ }
2117+
2118+ private void uniqueAdd(PlayerInstance player, BufferData.Buffer buffer, String uniqueName, String categoryIdent, String buffIdent)
2119+ {
2120+ BufferData.BuffCategory bCat = buffer.getBuffCat(categoryIdent);
2121+ if (bCat == null)
2122+ {
2123+ return;
2124+ }
2125+ BufferData.Buff buff = bCat.getBuff(buffIdent);
2126+ if (buff == null)
2127+ {
2128+ return;
2129+ }
2130+
2131+ BufferData.getInstance().addToUniqueBufflist(player.getObjectId(), uniqueName, buff);
2132+ }
2133+
2134+ private void uniqueRemove(PlayerInstance player, String uniqueName, String buffIdent)
2135+ {
2136+ BufferData.Buff buff = BufferData.getInstance().getBuff(buffIdent);
2137+ if (buff == null)
2138+ {
2139+ return;
2140+ }
2141+
2142+ BufferData.getInstance().removeFromUniqueBufflist(player.getObjectId(), uniqueName, buff);
2143+ }
2144+
2145+ private void uniqueSelect(PlayerInstance player, String uniqueName)
2146+ {
2147+ if (BufferData.getInstance().hasUniqueBufflist(player.getObjectId(), uniqueName))
2148+ {
2149+ _ACTIVE_PLAYER_BUFFLISTS.put(player.getObjectId(), uniqueName);
2150+ }
2151+ }
2152+
2153+ private void uniqueDeselect(PlayerInstance player)
2154+ {
2155+ _ACTIVE_PLAYER_BUFFLISTS.remove(player.getObjectId());
2156+ }
2157+
2158+ private void executeUniqueCommand(PlayerInstance player, BufferData.Buffer buffer, String command)
2159+ {
2160+ if (command.startsWith("create "))
2161+ {
2162+ uniqueCreate(player, command.substring(7));
2163+ }
2164+ else if (command.startsWith("create_from_effects "))
2165+ {
2166+ String uniqueName = command.substring(20);
2167+ if (!uniqueCreate(player, uniqueName))
2168+ {
2169+ return;
2170+ }
2171+
2172+ final Collection<BuffInfo> buffs = player.getEffectList().getEffects();
2173+ for (final BuffInfo effect : buffs)
2174+ {
2175+ for (Entry<String, BufferData.BuffCategory> buffCatEntry : buffer.buffCats.entrySet())
2176+ {
2177+ boolean added = false;
2178+
2179+ for (Entry<String, BufferData.Buff> buffEntry : buffCatEntry.getValue().buffs.entrySet())
2180+ {
2181+ final BufferData.Buff buff = buffEntry.getValue();
2182+
2183+ if (buff.skill.getId() == effect.getSkill().getId())
2184+ {
2185+ uniqueAdd(player, buffer, uniqueName, buffCatEntry.getKey(), buff.ident);
2186+ added = true;
2187+ break;
2188+ }
2189+ }
2190+
2191+ if (added)
2192+ {
2193+ break;
2194+ }
2195+ }
2196+ }
2197+ }
2198+ else if (command.startsWith("delete "))
2199+ {
2200+ uniqueDelete(player, command.substring(7));
2201+ }
2202+ else if (command.startsWith("add "))
2203+ {
2204+ String[] argsSplit = command.substring(4).split(" ", 3);
2205+ if (argsSplit.length != 3)
2206+ {
2207+ return;
2208+ }
2209+ uniqueAdd(player, buffer, argsSplit[0], argsSplit[1], argsSplit[2]);
2210+ }
2211+ else if (command.startsWith("remove "))
2212+ {
2213+ String[] argsSplit = command.substring(7).split(" ", 2);
2214+ if (argsSplit.length != 2)
2215+ {
2216+ return;
2217+ }
2218+ uniqueRemove(player, argsSplit[0], argsSplit[1]);
2219+ }
2220+ else if (command.startsWith("select "))
2221+ {
2222+ uniqueSelect(player, command.substring(7));
2223+ }
2224+ else if (command.startsWith("deselect"))
2225+ {
2226+ uniqueDeselect(player);
2227+ }
2228+ }
2229+
2230+ //
2231+ // ////////////////////////////////
2232+
2233+ private static boolean isInsideAnyZoneOf(Creature character, ZoneId first, ZoneId... more)
2234+ {
2235+ if (character.isInsideZone(first))
2236+ {
2237+ return true;
2238+ }
2239+
2240+ if (more != null)
2241+ {
2242+ for (ZoneId zone : more)
2243+ {
2244+ if (character.isInsideZone(zone))
2245+ {
2246+ return true;
2247+ }
2248+ }
2249+ }
2250+
2251+ return false;
2252+ }
2253+
2254+ void executeCommand(PlayerInstance player, Npc npc, String command)
2255+ {
2256+ if (isInsideAnyZoneOf(player, ZoneId.PVP, ZoneId.SIEGE, ZoneId.WATER, ZoneId.JAIL, ZoneId.DANGER_AREA))
2257+ {
2258+ player.sendMessage("The buffer cannot be used here.");
2259+ return;
2260+ }
2261+ else if (player.isOnEvent() || (player.getBlockCheckerArena() != -1) || player.isInOlympiadMode())
2262+ {
2263+ player.sendMessage("The buffer cannot be used in events.");
2264+ return;
2265+ }
2266+
2267+ else if (player.isInDuel() || (player.getPvpFlag() == 1))
2268+ {
2269+ player.sendMessage("The buffer cannot be used in duells or pvp.");
2270+ return;
2271+ }
2272+
2273+ else if (AttackStanceTaskManager.getInstance().hasAttackStanceTask(player))
2274+ {
2275+ player.sendMessage("The buffer cannot be used while in combat.");
2276+ return;
2277+ }
2278+
2279+ BufferData.Buffer buffer = determineBuffer(npc, player);
2280+ if (buffer == null)
2281+ {
2282+ // not an authorized npc or npc is null and voiced buffer is disabled
2283+ return;
2284+ }
2285+
2286+ if ((command == null) || command.isEmpty())
2287+ {
2288+ command = "html main";
2289+ }
2290+
2291+ if (command.startsWith("html "))
2292+ {
2293+ executeHtmlCommand(player, buffer, npc, command.substring(5));
2294+ }
2295+ else
2296+ {
2297+ if (command.startsWith("target "))
2298+ {
2299+ executeTargetCommand(player, buffer, command.substring(7));
2300+ }
2301+ else if (command.startsWith("unique "))
2302+ {
2303+ executeUniqueCommand(player, buffer, command.substring(7));
2304+ }
2305+
2306+ // display last html again
2307+ // since somebody could use the chat as a command line(eg.: .buffer target player heal), we check if the player has opened a html before
2308+ String lastHtmlCommand = _LAST_PLAYER_HTMLS.get(player.getObjectId());
2309+ if (lastHtmlCommand != null)
2310+ {
2311+ executeHtmlCommand(player, buffer, npc, _LAST_PLAYER_HTMLS.get(player.getObjectId()));
2312+ }
2313+ }
2314+ }
2315+}
2316Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/XMLUtils.java
2317IDEA additional info:
2318Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
2319<+>UTF-8
2320===================================================================
2321--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/XMLUtils.java (date 1601235047018)
2322+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/XMLUtils.java (date 1601235047018)
2323@@ -0,0 +1,45 @@
2324+/*
2325+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
2326+ * Copyright (C) 2015 Christian Buck
2327+ *
2328+ * This program is free software: you can redistribute it and/or modify
2329+ * it under the terms of the GNU General Public License as published by
2330+ * the Free Software Foundation, either version 3 of the License, or
2331+ * (at your option) any later version.
2332+ *
2333+ * This program is distributed in the hope that it will be useful,
2334+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2335+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2336+ * GNU General Public License for more details.
2337+ *
2338+ * You should have received a copy of the GNU General Public License
2339+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2340+ */
2341+package custom.Buffer.util;
2342+
2343+import java.io.IOException;
2344+import java.nio.file.Path;
2345+
2346+import javax.xml.parsers.DocumentBuilderFactory;
2347+import javax.xml.parsers.ParserConfigurationException;
2348+
2349+import org.w3c.dom.Document;
2350+import org.xml.sax.SAXException;
2351+
2352+/**
2353+ * @author HorridoJoho
2354+ */
2355+public class XMLUtils
2356+{
2357+ public static Document CreateDocument(Path xml, Path xsd) throws SAXException, IOException, ParserConfigurationException
2358+ {
2359+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
2360+ factory.setValidating(true);
2361+ factory.setNamespaceAware(true);
2362+ factory.setIgnoringComments(true);
2363+ factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
2364+ if (xsd != null)
2365+ factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource", xsd.toString());
2366+ return factory.newDocumentBuilder().parse(xml.toString());
2367+ }
2368+}
2369Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/ItemRequirement.java
2370IDEA additional info:
2371Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
2372<+>UTF-8
2373===================================================================
2374--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/ItemRequirement.java (date 1601235047012)
2375+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/ItemRequirement.java (date 1601235047012)
2376@@ -0,0 +1,43 @@
2377+/*
2378+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
2379+ * Copyright (C) 2015 Christian Buck
2380+ *
2381+ * This program is free software: you can redistribute it and/or modify
2382+ * it under the terms of the GNU General Public License as published by
2383+ * the Free Software Foundation, either version 3 of the License, or
2384+ * (at your option) any later version.
2385+ *
2386+ * This program is distributed in the hope that it will be useful,
2387+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2388+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2389+ * GNU General Public License for more details.
2390+ *
2391+ * You should have received a copy of the GNU General Public License
2392+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2393+ */
2394+package custom.Buffer.util;
2395+
2396+import custom.Buffer.util.htmltmpls.HTMLTemplatePlaceholder;
2397+
2398+import org.l2jmobius.gameserver.model.items.Item;
2399+
2400+/**
2401+ * @author HorridoJoho
2402+ */
2403+public final class ItemRequirement
2404+{
2405+ /** Item id */
2406+ public final Item item;
2407+ /** Item amount */
2408+ public final long amount;
2409+ /** HTMLTemplatePlaceholder */
2410+ public final HTMLTemplatePlaceholder placeholder;
2411+
2412+ public ItemRequirement(final Item item, final long amount)
2413+ {
2414+ this.item = item;
2415+ this.amount = amount;
2416+ this.placeholder = new HTMLTemplatePlaceholder("item_requirement", null);
2417+ this.placeholder.addChild("id", String.valueOf(item.getId())).addChild("icon", item.getIcon()).addChild("name", item.getName()).addChild("amount", String.valueOf(amount));
2418+ }
2419+}
2420Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/HTMLTemplateUtils.java
2421IDEA additional info:
2422Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
2423<+>UTF-8
2424===================================================================
2425--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/HTMLTemplateUtils.java (date 1601235047008)
2426+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/HTMLTemplateUtils.java (date 1601235047008)
2427@@ -0,0 +1,151 @@
2428+/*
2429+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
2430+ * Copyright (C) 2015 Christian Buck
2431+ *
2432+ * This program is free software: you can redistribute it and/or modify
2433+ * it under the terms of the GNU General Public License as published by
2434+ * the Free Software Foundation, either version 3 of the License, or
2435+ * (at your option) any later version.
2436+ *
2437+ * This program is distributed in the hope that it will be useful,
2438+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2439+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2440+ * GNU General Public License for more details.
2441+ *
2442+ * You should have received a copy of the GNU General Public License
2443+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2444+ */
2445+package custom.Buffer.util.htmltmpls;
2446+
2447+import java.util.Map;
2448+import java.util.regex.Pattern;
2449+
2450+/**
2451+ * @author HorridoJoho
2452+ */
2453+public final class HTMLTemplateUtils
2454+{
2455+ public static int findSequenceEnd(StringBuilder string, int startOffset, HTMLTemplateFunc func)
2456+ {
2457+ int dept = 0;
2458+ String seqStart = func.getSequenceStart();
2459+ String seqEnd = func.getSequenceEnd();
2460+ String escapedSeqStart = "\\" + seqStart;
2461+ String escapedSeqEnd = "\\" + seqEnd;
2462+
2463+ while (true)
2464+ {
2465+ int endSeqOffset = string.indexOf(seqEnd, startOffset);
2466+ if (endSeqOffset == -1)
2467+ {
2468+ return -1; // there is no sequence end to find
2469+ }
2470+
2471+ int escapedSeqStartOffset = string.indexOf(escapedSeqStart, startOffset);
2472+ int escapedSeqEndOffset = string.indexOf(escapedSeqEnd, startOffset);
2473+ int startSeqOffset = string.indexOf(seqStart, startOffset);
2474+
2475+ if (((endSeqOffset < startSeqOffset) || (startSeqOffset == -1)) && ((endSeqOffset < escapedSeqStartOffset) || (escapedSeqStartOffset == -1)) && ((endSeqOffset < escapedSeqEndOffset) || (escapedSeqEndOffset == -1)))
2476+ {
2477+ if (dept == 0)
2478+ {
2479+ return endSeqOffset + seqEnd.length();
2480+ }
2481+
2482+ --dept;
2483+ startOffset = endSeqOffset + seqEnd.length();
2484+ }
2485+ else if ((startSeqOffset != -1) && (startSeqOffset < endSeqOffset) && ((startSeqOffset < escapedSeqStartOffset) || (escapedSeqStartOffset == -1)) && ((startSeqOffset < escapedSeqEndOffset) || (escapedSeqEndOffset == -1)))
2486+ {
2487+ startOffset = startSeqOffset + seqStart.length();
2488+ ++dept;
2489+ }
2490+ else if ((escapedSeqStartOffset != -1) && ((escapedSeqStartOffset < escapedSeqEndOffset) || (escapedSeqEndOffset == -1)))
2491+ {
2492+ startOffset += escapedSeqStartOffset + escapedSeqStart.length();
2493+ }
2494+ else if ((escapedSeqEndOffset != -1) && ((escapedSeqEndOffset < escapedSeqStartOffset) || (escapedSeqStartOffset != -1)))
2495+ {
2496+ startOffset += escapedSeqEndOffset + escapedSeqEnd.length();
2497+ }
2498+ }
2499+ }
2500+
2501+ /**
2502+ * Searches the placeholder specified by placeholderString inside the placeholders map
2503+ * @param placeholderString placeholder to search for
2504+ * @param placeholders map with the placeholders available
2505+ * @return the placeholder if found, null otherwise
2506+ */
2507+ public static HTMLTemplatePlaceholder getPlaceholder(String placeholderString, Map<String, HTMLTemplatePlaceholder> placeholders)
2508+ {
2509+ if (placeholders == null)
2510+ {
2511+ return null;
2512+ }
2513+
2514+ String[] placeholderParts = placeholderString.split(Pattern.quote("."));
2515+ HTMLTemplatePlaceholder placeholder = null;
2516+ for (String placeholderPart : placeholderParts)
2517+ {
2518+ if (placeholder == null)
2519+ {
2520+ placeholder = placeholders.get(placeholderPart);
2521+ if (placeholder == null)
2522+ {
2523+ break;
2524+ }
2525+ }
2526+ else
2527+ {
2528+ placeholder = placeholder.getChild(placeholderPart);
2529+ if (placeholder == null)
2530+ {
2531+ break;
2532+ }
2533+ }
2534+ }
2535+ return placeholder;
2536+ }
2537+
2538+ /**
2539+ * Get the value of the placeholder specified by placeholderString
2540+ * @param placeholderString the placeholder to get the value from
2541+ * @param placeholders placeholder map to search in
2542+ * @return the value of the found placeholder
2543+ * @throws Exception the placeholder was not found or the value is null
2544+ */
2545+ public static String getPlaceholderValue(String placeholderString, Map<String, HTMLTemplatePlaceholder> placeholders) throws Exception
2546+ {
2547+ HTMLTemplatePlaceholder placeholder = getPlaceholder(placeholderString, placeholders);
2548+ if (placeholder == null)
2549+ {
2550+ throw new Exception();
2551+ }
2552+
2553+ String value = placeholder.getValue();
2554+ if (value == null)
2555+ {
2556+ throw new Exception();
2557+ }
2558+
2559+ return value;
2560+ }
2561+
2562+ /**
2563+ * Get the childs of the placeholder specified by placeholderString in an unmodifyable map
2564+ * @param placeholderString the placeholder to get the childs from
2565+ * @param placeholders placeholder map to search in
2566+ * @return the childs in an unmodifyable map of the found placeholder
2567+ * @throws Exception the placeholder was not found
2568+ */
2569+ public static Map<String, HTMLTemplatePlaceholder> getPlaceholderChilds(String placeholderString, Map<String, HTMLTemplatePlaceholder> placeholders) throws Exception
2570+ {
2571+ HTMLTemplatePlaceholder placeholder = getPlaceholder(placeholderString, placeholders);
2572+ if (placeholder == null)
2573+ {
2574+ throw new Exception();
2575+ }
2576+ return placeholder.getChilds();
2577+ }
2578+}
2579Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/HTMLTemplatePlaceholder.java
2580IDEA additional info:
2581Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
2582<+>UTF-8
2583===================================================================
2584--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/HTMLTemplatePlaceholder.java (date 1601235047004)
2585+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/HTMLTemplatePlaceholder.java (date 1601235047004)
2586@@ -0,0 +1,139 @@
2587+/*
2588+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
2589+ * Copyright (C) 2015 Christian Buck
2590+ *
2591+ * This program is free software: you can redistribute it and/or modify
2592+ * it under the terms of the GNU General Public License as published by
2593+ * the Free Software Foundation, either version 3 of the License, or
2594+ * (at your option) any later version.
2595+ *
2596+ * This program is distributed in the hope that it will be useful,
2597+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2598+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2599+ * GNU General Public License for more details.
2600+ *
2601+ * You should have received a copy of the GNU General Public License
2602+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2603+ */
2604+package custom.Buffer.util.htmltmpls;
2605+
2606+import java.util.Collections;
2607+import java.util.LinkedHashMap;
2608+import java.util.Map;
2609+
2610+/**
2611+ * This is the class for the buildin value placeholders.<br>
2612+ * It has a name, a value and can contain child placeholders.<br>
2613+ * To reference the value of a placeholder in a template document<br>
2614+ * you use <b>%placeholder_name%</b>. To reference the value of a child<br>
2615+ * placeholder you use <b>%placeholder_name.child_placeholder_name%.</b>
2616+ * @author HorridoJoho
2617+ */
2618+public final class HTMLTemplatePlaceholder
2619+{
2620+ /** the name of this placeholder */
2621+ private final String _name;
2622+ /** the value of this placeholder */
2623+ private volatile String _value;
2624+ /** the child placeholders of this placeholder */
2625+ private final Map<String, HTMLTemplatePlaceholder> _childs;
2626+
2627+ /**
2628+ * Public constructor to create a new placeholder
2629+ * @param name the name of the new placeholder
2630+ * @param value the value of the new placeholder
2631+ */
2632+ public HTMLTemplatePlaceholder(String name, String value)
2633+ {
2634+ this(name, value, new LinkedHashMap<String, HTMLTemplatePlaceholder>());
2635+ }
2636+
2637+ /**
2638+ * Private constructor to create alias placeholders of other placeholders
2639+ * @param name the name of the alias placeholder
2640+ * @param value the value of the alias placeholder
2641+ * @param childs the childs of the alias placeholder
2642+ */
2643+ private HTMLTemplatePlaceholder(String name, String value, Map<String, HTMLTemplatePlaceholder> childs)
2644+ {
2645+ _name = name;
2646+ _value = value;
2647+ _childs = childs;
2648+ }
2649+
2650+ /**
2651+ * Creates an alias for this placeholder.<br>
2652+ * An alias placeholder will hold the reference to the childs map from the original placeholder. This means, adding a new child to the alias will also add the child to the original placeholder and vice versa.
2653+ * @param name name of the alias placeholder
2654+ * @return the newly created alias placeholder
2655+ */
2656+ public HTMLTemplatePlaceholder createAlias(String name)
2657+ {
2658+ return new HTMLTemplatePlaceholder(name, _value, _childs);
2659+ }
2660+
2661+ /**
2662+ * Adds a child placeholder to this placeholder.
2663+ * @param name the name of the new child placeholder
2664+ * @param value the value of the new child placeholder
2665+ * @return this placeholder
2666+ */
2667+ public HTMLTemplatePlaceholder addChild(String name, String value)
2668+ {
2669+ _childs.put(name, new HTMLTemplatePlaceholder(name, value));
2670+ return this;
2671+ }
2672+
2673+ public HTMLTemplatePlaceholder addAliasChild(String aliasName, HTMLTemplatePlaceholder placeholder)
2674+ {
2675+ _childs.put(aliasName, placeholder.createAlias(aliasName));
2676+ return this;
2677+ }
2678+
2679+ public void setValue(String value)
2680+ {
2681+ _value = value;
2682+ }
2683+
2684+ /**
2685+ * @return the name of this placeholder
2686+ */
2687+ public String getName()
2688+ {
2689+ return _name;
2690+ }
2691+
2692+ /**
2693+ * @return the value of this placeholder
2694+ */
2695+ public String getValue()
2696+ {
2697+ return _value;
2698+ }
2699+
2700+ /**
2701+ * Method to get a child placeholder of this placeholder by name
2702+ * @param name the name of the child placeholder to find
2703+ * @return the child placeholder
2704+ */
2705+ public HTMLTemplatePlaceholder getChild(String name)
2706+ {
2707+ return HTMLTemplateUtils.getPlaceholder(name, _childs);
2708+ }
2709+
2710+ /**
2711+ * @return the child placeholder map of this placeholder as unmodifyable map
2712+ */
2713+ public Map<String, HTMLTemplatePlaceholder> getChilds()
2714+ {
2715+ return Collections.unmodifiableMap(_childs);
2716+ }
2717+
2718+ /**
2719+ * @return the count of child placeholders in this placeholder
2720+ */
2721+ public int getChildsSize()
2722+ {
2723+ return _childs.size();
2724+ }
2725+}
2726\ No newline at end of file
2727Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/HTMLTemplateParser.java
2728IDEA additional info:
2729Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
2730<+>UTF-8
2731===================================================================
2732--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/HTMLTemplateParser.java (date 1601235046998)
2733+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/HTMLTemplateParser.java (date 1601235046998)
2734@@ -0,0 +1,187 @@
2735+/*
2736+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
2737+ * Copyright (C) 2015 Christian Buck
2738+ *
2739+ * This program is free software: you can redistribute it and/or modify
2740+ * it under the terms of the GNU General Public License as published by
2741+ * the Free Software Foundation, either version 3 of the License, or
2742+ * (at your option) any later version.
2743+ *
2744+ * This program is distributed in the hope that it will be useful,
2745+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2746+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2747+ * GNU General Public License for more details.
2748+ *
2749+ * You should have received a copy of the GNU General Public License
2750+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2751+ */
2752+package custom.Buffer.util.htmltmpls;
2753+
2754+import java.util.Collections;
2755+import java.util.HashMap;
2756+import java.util.Map;
2757+import java.util.Map.Entry;
2758+import java.util.regex.Matcher;
2759+import java.util.regex.Pattern;
2760+
2761+import org.l2jmobius.gameserver.cache.HtmCache;
2762+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
2763+
2764+/**
2765+ * @author HorridoJoho
2766+ */
2767+public final class HTMLTemplateParser
2768+{
2769+ /** pattern to find placeholder references */
2770+ private static final Pattern _PLACEHOLDER_PATTERN = Pattern.compile("%[a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)*%");
2771+
2772+ public static String fromCache(String path, Map<String, HTMLTemplatePlaceholder> placeholders, HTMLTemplateFunc... funcs)
2773+ {
2774+ return fromCache(path, null, placeholders, funcs);
2775+ }
2776+
2777+ public static String fromCache(String path, PlayerInstance player, Map<String, HTMLTemplatePlaceholder> placeholders, HTMLTemplateFunc... funcs)
2778+ {
2779+ String string = HtmCache.getInstance().getHtm(player, path);
2780+ if (string == null)
2781+ return null;
2782+ StringBuilder builder = new StringBuilder(string);
2783+ fromStringBuilder(builder, player, placeholders, funcs);
2784+ return builder.toString();
2785+ }
2786+
2787+ /**
2788+ * Method to process a template. The string is directly modifyed and will contain the results of the template processing.
2789+ * @param string the template content
2790+ * @param player the player the template is processed for
2791+ * @param placeholders a map of placeholders(map has to be modifyable)
2792+ * @param funcs the functions to use while processing the template
2793+ */
2794+ public static void fromStringBuilder(StringBuilder string, PlayerInstance player, Map<String, HTMLTemplatePlaceholder> placeholders, HTMLTemplateFunc... funcs)
2795+ {
2796+ // System.out.println("fromStringBuilder(" + string + ") {");
2797+ if (string == null)
2798+ return;
2799+
2800+ int indexOfOffset = 0;
2801+
2802+ while (indexOfOffset < string.length() - 1)
2803+ {
2804+ // System.out.println("-------------------------------------------");
2805+ // System.out.println("indexOfOffset=" + indexOfOffset);
2806+ // find the first position of a placeholder or a custom func
2807+ Matcher placeholderMatcher = _PLACEHOLDER_PATTERN.matcher(string);
2808+ int nextFuncStartOffset = -1;
2809+ int nextFuncEndOffset = -1;
2810+ if (placeholderMatcher.find(indexOfOffset))
2811+ {
2812+ nextFuncStartOffset = placeholderMatcher.start();
2813+ nextFuncEndOffset = placeholderMatcher.end();
2814+ }
2815+
2816+ HTMLTemplateFunc nextFunc = null;
2817+ for (HTMLTemplateFunc func : funcs)
2818+ {
2819+ int funcOffset = string.indexOf(func.getSequenceStart(), indexOfOffset);
2820+ if (funcOffset > -1 && (nextFuncStartOffset == -1 || funcOffset < nextFuncStartOffset))
2821+ {
2822+ nextFuncStartOffset = funcOffset;
2823+ nextFuncEndOffset = HTMLTemplateUtils.findSequenceEnd(string, nextFuncStartOffset + func.getSequenceStart().length(), func);
2824+ nextFunc = func;
2825+ }
2826+ }
2827+
2828+ // System.out.println("nextFuncStartOffset=" + nextFuncStartOffset + "\nnextFuncEndOffset=" + nextFuncEndOffset + "\nfunc?" + (nextFunc != null));
2829+
2830+ if (nextFuncStartOffset == -1)
2831+ {
2832+ break;
2833+ }
2834+ else if (nextFunc == null)
2835+ {
2836+ String placeholderString = placeholderMatcher.group().substring(1, placeholderMatcher.group().length() - 1);
2837+ // System.out.println("Placeholder: " + placeholderString);
2838+ HTMLTemplatePlaceholder placeholder = HTMLTemplateUtils.getPlaceholder(placeholderString, placeholders);
2839+
2840+ if (placeholder != null)
2841+ {
2842+ // System.out.println("Value: " + placeholder.getValue());
2843+ string.replace(nextFuncStartOffset, nextFuncEndOffset, placeholder.getValue());
2844+ // 2 !!! placeholder replacement can contain more placeholders and func sequences start so we set the index to search to the start of the placeholder
2845+ indexOfOffset = nextFuncStartOffset;
2846+ }
2847+ else
2848+ // skip placeholder?
2849+ {
2850+ // if placeholder can not be found, just remove it from the string
2851+ // 1 <<< string.delete(nextFuncStartOffset, nextFuncEndOffset);
2852+
2853+ // 2 !!! l2j compatible mode, we don't want to manually add things like %objectId% placeholders all the time
2854+ indexOfOffset += placeholderMatcher.end() - placeholderMatcher.start();
2855+ }
2856+
2857+ // placeholder replacement can contain more placeholders and func sequences start so we set the index to search to the start of the placeholder
2858+ // 1 <<< indexOfOffset = nextFuncStartOffset;
2859+ }
2860+ else
2861+ {
2862+ if (nextFuncEndOffset == -1)
2863+ {
2864+ // this is to ignore the starting sequnces which have no ending sequence
2865+ ++indexOfOffset;
2866+ }
2867+ else
2868+ {
2869+ // System.out.println("Func: " + nextFunc.getClass().getName());
2870+
2871+ StringBuilder content = new StringBuilder(string.subSequence(nextFuncStartOffset + nextFunc.getSequenceStart().length(), nextFuncEndOffset - nextFunc.getSequenceEnd().length()));
2872+
2873+ // the func needs preprocessing?
2874+ if (nextFunc.requiresPreprocessing())
2875+ {
2876+ fromStringBuilder(content, player, placeholders, funcs);
2877+ }
2878+
2879+ Map<String, HTMLTemplatePlaceholder> tmpPlaceholders = nextFunc.handle(content, player, placeholders == null ? null : Collections.unmodifiableMap(placeholders), funcs);
2880+
2881+ // add new entries and replace entries(temp)
2882+ if (tmpPlaceholders != null)
2883+ {
2884+ for (HTMLTemplatePlaceholder newPlaceholder : tmpPlaceholders.values())
2885+ {
2886+ if (placeholders == null)
2887+ {
2888+ placeholders = new HashMap<>();
2889+ }
2890+ tmpPlaceholders.put(newPlaceholder.getName(), placeholders.put(newPlaceholder.getName(), newPlaceholder));
2891+ }
2892+ }
2893+
2894+ fromStringBuilder(content, player, placeholders, funcs);
2895+ string.replace(nextFuncStartOffset, nextFuncEndOffset, content.toString());
2896+
2897+ // remove entries which were new and restore old entries
2898+ if (tmpPlaceholders != null && placeholders != null)
2899+ {
2900+ for (Entry<String, HTMLTemplatePlaceholder> oldPlaceholder : tmpPlaceholders.entrySet())
2901+ {
2902+ if (oldPlaceholder.getValue() == null)
2903+ {
2904+ placeholders.remove(oldPlaceholder.getKey());
2905+ }
2906+ else
2907+ {
2908+ placeholders.put(oldPlaceholder.getKey(), oldPlaceholder.getValue());
2909+ }
2910+ }
2911+ }
2912+
2913+ // set the current offset to the next func sequence start found, replaced content can contain more placeholders and funcs
2914+ indexOfOffset = nextFuncStartOffset;
2915+ }
2916+ }
2917+ }
2918+
2919+ // System.out.println("}");
2920+ }
2921+}
2922\ No newline at end of file
2923Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/HTMLTemplateFunc.java
2924IDEA additional info:
2925Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
2926<+>UTF-8
2927===================================================================
2928--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/HTMLTemplateFunc.java (date 1601235046992)
2929+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/HTMLTemplateFunc.java (date 1601235046992)
2930@@ -0,0 +1,91 @@
2931+/*
2932+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
2933+ * Copyright (C) 2015 Christian Buck
2934+ *
2935+ * This program is free software: you can redistribute it and/or modify
2936+ * it under the terms of the GNU General Public License as published by
2937+ * the Free Software Foundation, either version 3 of the License, or
2938+ * (at your option) any later version.
2939+ *
2940+ * This program is distributed in the hope that it will be useful,
2941+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2942+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2943+ * GNU General Public License for more details.
2944+ *
2945+ * You should have received a copy of the GNU General Public License
2946+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2947+ */
2948+package custom.Buffer.util.htmltmpls;
2949+
2950+import java.util.Map;
2951+
2952+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
2953+
2954+/**
2955+ * This class represents a template function.<br>
2956+ * It has a sequence start and end.<br>
2957+ * ----- Example -----<br>
2958+ * -- startSequence = "INC"<br>
2959+ * -- endSequence = "ENDINC"<br>
2960+ * We have a template file template.tmpl: [INC(template2.tmpl)ENDINC]<br>
2961+ * Now when the handlers {@link #handle(StringBuilder, PlayerInstance, Map, HTMLTemplateFunc[])} method is called, contents will contain "template2.tmpl"<br>
2962+ * @author HorridoJoho
2963+ */
2964+public abstract class HTMLTemplateFunc
2965+{
2966+ /** how the function sequence starts */
2967+ private final String _sequenceStart;
2968+ /** how the function sequence ends */
2969+ private final String _sequenceEnd;
2970+ /** flag to determine if the template function needs processing of it's contents before contents are passed to the {@link #handle(StringBuilder, PlayerInstance, Map, HTMLTemplateFunc[])} method */
2971+ private final boolean _requiresPreprocessing;
2972+
2973+ /**
2974+ * Protected constructor for template function implementations. In a template document
2975+ * @param sequenceStart how the template function sequence starts (in a template document you use [sequenceStart(
2976+ * @param sequenceEnd how the template function sequence starts (in a template document you use )sequenceEnd]
2977+ * @param requiresPreprocessing flag to determine if the template function needs processing of it's contents before contents are passed to the {@link #handle(StringBuilder, PlayerInstance, Map, HTMLTemplateFunc[])}
2978+ */
2979+ protected HTMLTemplateFunc(String sequenceStart, String sequenceEnd, boolean requiresPreprocessing)
2980+ {
2981+ _sequenceStart = "[" + sequenceStart + "(";
2982+ _sequenceEnd = ")" + sequenceEnd + "]";
2983+ _requiresPreprocessing = requiresPreprocessing;
2984+ }
2985+
2986+ /**
2987+ * @return the sequence this function starts with in a template document
2988+ */
2989+ public final String getSequenceStart()
2990+ {
2991+ return _sequenceStart;
2992+ }
2993+
2994+ /**
2995+ * @return the sequence this function ends with in a template document
2996+ */
2997+ public final String getSequenceEnd()
2998+ {
2999+ return _sequenceEnd;
3000+ }
3001+
3002+ /**
3003+ * @return true when the handler needs the contents preprocessed by the template engine before it is passed to the {@link #handle(StringBuilder, PlayerInstance, Map, HTMLTemplateFunc[])} metod, false otherwise
3004+ */
3005+ public final boolean requiresPreprocessing()
3006+ {
3007+ return _requiresPreprocessing;
3008+ }
3009+
3010+ /**
3011+ * Called by template parser to give the function the possibility to<br>
3012+ * create new placeholders and modify the contents of the function<br>
3013+ * in the template document.
3014+ * @param content the content which can be modified by the handler
3015+ * @param player the player the template is processed for
3016+ * @param placeholders the currently avilable placeholders as unmodifyable map
3017+ * @param funcs supported functions the template is parsed with
3018+ * @return placeholder to add to the currently available placeholders, added before the content is processed after this call, and removed again after content processing
3019+ */
3020+ public abstract Map<String, HTMLTemplatePlaceholder> handle(StringBuilder content, PlayerInstance player, Map<String, HTMLTemplatePlaceholder> placeholders, HTMLTemplateFunc[] funcs);
3021+}
3022\ No newline at end of file
3023Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/IncludeFunc.java
3024IDEA additional info:
3025Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
3026<+>UTF-8
3027===================================================================
3028--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/IncludeFunc.java (date 1601235046987)
3029+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/IncludeFunc.java (date 1601235046987)
3030@@ -0,0 +1,54 @@
3031+/*
3032+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
3033+ * Copyright (C) 2015 Christian Buck
3034+ *
3035+ * This program is free software: you can redistribute it and/or modify
3036+ * it under the terms of the GNU General Public License as published by
3037+ * the Free Software Foundation, either version 3 of the License, or
3038+ * (at your option) any later version.
3039+ *
3040+ * This program is distributed in the hope that it will be useful,
3041+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3042+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3043+ * GNU General Public License for more details.
3044+ *
3045+ * You should have received a copy of the GNU General Public License
3046+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3047+ */
3048+package custom.Buffer.util.htmltmpls.funcs;
3049+
3050+import java.util.HashMap;
3051+import java.util.Map;
3052+
3053+import custom.Buffer.util.htmltmpls.HTMLTemplateFunc;
3054+import custom.Buffer.util.htmltmpls.HTMLTemplatePlaceholder;
3055+
3056+import org.l2jmobius.gameserver.cache.HtmCache;
3057+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
3058+
3059+/**
3060+ * @author HorridoJoho
3061+ */
3062+public final class IncludeFunc extends HTMLTemplateFunc
3063+{
3064+ public static final IncludeFunc INSTANCE = new IncludeFunc();
3065+
3066+ private IncludeFunc()
3067+ {
3068+ super("INC", "ENDINC", true);
3069+ }
3070+
3071+ @Override
3072+ public HashMap<String, HTMLTemplatePlaceholder> handle(StringBuilder content, PlayerInstance player, Map<String, HTMLTemplatePlaceholder> placeholders, HTMLTemplateFunc[] funcs)
3073+ {
3074+ String fileContent = HtmCache.getInstance().getHtm(player, content.toString());
3075+ if (fileContent != null)
3076+ {
3077+ content.ensureCapacity(fileContent.length());
3078+ content.setLength(0);
3079+ content.append(fileContent);
3080+ }
3081+
3082+ return null;
3083+ }
3084+}
3085Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/IfFunc.java
3086IDEA additional info:
3087Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
3088<+>UTF-8
3089===================================================================
3090--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/IfFunc.java (date 1601235046983)
3091+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/IfFunc.java (date 1601235046983)
3092@@ -0,0 +1,147 @@
3093+/*
3094+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
3095+ * Copyright (C) 2015 Christian Buck
3096+ *
3097+ * This program is free software: you can redistribute it and/or modify
3098+ * it under the terms of the GNU General Public License as published by
3099+ * the Free Software Foundation, either version 3 of the License, or
3100+ * (at your option) any later version.
3101+ *
3102+ * This program is distributed in the hope that it will be useful,
3103+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3104+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3105+ * GNU General Public License for more details.
3106+ *
3107+ * You should have received a copy of the GNU General Public License
3108+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3109+ */
3110+package custom.Buffer.util.htmltmpls.funcs;
3111+
3112+import java.util.HashMap;
3113+import java.util.Map;
3114+import java.util.regex.Matcher;
3115+import java.util.regex.Pattern;
3116+
3117+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
3118+
3119+import custom.Buffer.util.htmltmpls.HTMLTemplateFunc;
3120+import custom.Buffer.util.htmltmpls.HTMLTemplatePlaceholder;
3121+import custom.Buffer.util.htmltmpls.HTMLTemplateUtils;
3122+
3123+/**
3124+ * This class implements the following function syntax:<br>
3125+ * [IF(placeholder_name == "text in string" THEN text when the condition matches)ENDIF]<br>
3126+ * [IF(placeholder_name == another_placeholder_name THEN text when the condition matches)ENDIF]<br>
3127+ * [IF(int_placeholder_name > another_int_placeholder_name THEN text when the condition matches)ENDIF]<br>
3128+ * <br>
3129+ * First is always a placeholder name.<br>
3130+ * <br>
3131+ * Second comes one of the following operators:<br>
3132+ * <, >, <=, >=, !=, ==, STARTS_WITH or ENDS_WITH, where <, >, <= and >= are only to be used with placeholders/strings<br>
3133+ * which have a numeric value.<br>
3134+ * <br>
3135+ * Third comes either a placeholder name or a string("text in string").<br>
3136+ * <br>
3137+ * After the "THEN" word comes the text to place in the content when the condition is met.
3138+ * @author HorridoJoho
3139+ */
3140+public final class IfFunc extends HTMLTemplateFunc
3141+{
3142+ public static final IfFunc INSTANCE = new IfFunc();
3143+
3144+ private static final Pattern _LVALUE_PATTERN = Pattern.compile("\\s*[a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)*");
3145+ private static final Pattern _OP_PATTERN = Pattern.compile("\\s*(<|>|<=|>=|==|!=|\\sENDS_WITH\\s|\\sSTARTS_WITH\\s)\\s*");
3146+ private static final Pattern _RVALUE_PATTERN = Pattern.compile("([a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)*|\"(\\\\.|\\\\\\s|\\s|[^\\\\\"])*\")");
3147+ private static final Pattern _THEN_PATTERN = Pattern.compile("\\s*\\sTHEN\\s");
3148+
3149+ private static Matcher _getMatcher(Pattern pattern, StringBuilder content, int findIndex) throws Exception
3150+ {
3151+ Matcher m = pattern.matcher(content);
3152+ if (!m.find(findIndex) || m.start() > findIndex)
3153+ throw new Exception();
3154+
3155+ return m;
3156+ }
3157+
3158+ private IfFunc()
3159+ {
3160+ super("IF", "ENDIF", false);
3161+ }
3162+
3163+ @Override
3164+ public HashMap<String, HTMLTemplatePlaceholder> handle(StringBuilder content, PlayerInstance player, Map<String, HTMLTemplatePlaceholder> placeholders, HTMLTemplateFunc[] funcs)
3165+ {
3166+ try
3167+ {
3168+ Matcher matcher = _getMatcher(_LVALUE_PATTERN, content, 0);
3169+ String lValue = HTMLTemplateUtils.getPlaceholderValue(matcher.group().trim(), placeholders);
3170+ int findIndex = matcher.end();
3171+
3172+ matcher = _getMatcher(_OP_PATTERN, content, findIndex);
3173+ String op = matcher.group().trim();
3174+ findIndex = matcher.end();
3175+
3176+ matcher = _getMatcher(_RVALUE_PATTERN, content, findIndex);
3177+ String rValue = matcher.group();
3178+ if (rValue.charAt(0) == '"')
3179+ {
3180+ rValue = rValue.substring(1, rValue.length() - 1);
3181+ }
3182+ else
3183+ {
3184+ rValue = HTMLTemplateUtils.getPlaceholderValue(rValue, placeholders);
3185+ }
3186+ findIndex = matcher.end();
3187+
3188+ matcher = _getMatcher(_THEN_PATTERN, content, findIndex);
3189+ findIndex = matcher.end();
3190+
3191+ boolean ok = false;
3192+ switch (op)
3193+ {
3194+ case "<":
3195+ ok = Integer.parseInt(lValue) < Integer.parseInt(rValue);
3196+ break;
3197+ case ">":
3198+ ok = Integer.parseInt(lValue) > Integer.parseInt(rValue);
3199+ break;
3200+ case "<=":
3201+ ok = Integer.parseInt(lValue) <= Integer.parseInt(rValue);
3202+ break;
3203+ case ">=":
3204+ ok = Integer.parseInt(lValue) >= Integer.parseInt(rValue);
3205+ break;
3206+ case "==":
3207+ ok = lValue.equals(rValue);
3208+ break;
3209+ case "!=":
3210+ ok = !lValue.equals(rValue);
3211+ break;
3212+ case "ENDS_WITH":
3213+ ok = lValue.endsWith(rValue);
3214+ break;
3215+ case "STARTS_WITH":
3216+ ok = lValue.startsWith(rValue);
3217+ break;
3218+ }
3219+
3220+ if (ok)
3221+ {
3222+ // this ensures only the replacement content is left
3223+ content.delete(0, findIndex);
3224+ }
3225+ else
3226+ {
3227+ // condition is not met, no content to show
3228+ content.setLength(0);
3229+ return null;
3230+ }
3231+ }
3232+ catch (Exception e)
3233+ {
3234+ content.setLength(0);
3235+ }
3236+
3237+ return null;
3238+ }
3239+}
3240Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/IfChildsFunc.java
3241IDEA additional info:
3242Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
3243<+>UTF-8
3244===================================================================
3245--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/IfChildsFunc.java (date 1601235046979)
3246+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/IfChildsFunc.java (date 1601235046979)
3247@@ -0,0 +1,155 @@
3248+/*
3249+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
3250+ * Copyright (C) 2015 Christian Buck
3251+ *
3252+ * This program is free software: you can redistribute it and/or modify
3253+ * it under the terms of the GNU General Public License as published by
3254+ * the Free Software Foundation, either version 3 of the License, or
3255+ * (at your option) any later version.
3256+ *
3257+ * This program is distributed in the hope that it will be useful,
3258+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3259+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3260+ * GNU General Public License for more details.
3261+ *
3262+ * You should have received a copy of the GNU General Public License
3263+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3264+ */
3265+package custom.Buffer.util.htmltmpls.funcs;
3266+
3267+import java.util.HashMap;
3268+import java.util.Map;
3269+import java.util.Map.Entry;
3270+import java.util.regex.Matcher;
3271+import java.util.regex.Pattern;
3272+
3273+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
3274+
3275+import custom.Buffer.util.htmltmpls.HTMLTemplateFunc;
3276+import custom.Buffer.util.htmltmpls.HTMLTemplatePlaceholder;
3277+import custom.Buffer.util.htmltmpls.HTMLTemplateUtils;
3278+
3279+/**
3280+ * @author HorridoJoho
3281+ */
3282+public final class IfChildsFunc extends HTMLTemplateFunc
3283+{
3284+ public static final IfChildsFunc INSTANCE = new IfChildsFunc();
3285+
3286+ private static final Pattern _CHILDS_OF_PLACEHOLDER_PATTERN = Pattern.compile("\\s*[a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)*\\s*,");
3287+ private static final Pattern _CHILD_PLACEHOLDER_PATTERN = Pattern.compile("\\s*[a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)*");
3288+ private static final Pattern _OP_PATTERN = Pattern.compile("\\s*(<|>|<=|>=|==|!=|\\sENDS_WITH\\s|\\sSTARTS_WITH\\s)\\s*");
3289+ private static final Pattern _RVALUE_PATTERN = Pattern.compile("([a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)*|\"(\\\\.|\\\\\\s|\\s|[^\\\\\"])*\")");
3290+ private static final Pattern _THEN_PATTERN = Pattern.compile("\\s*\\sTHEN\\s");
3291+
3292+ private static Matcher _getMatcher(Pattern pattern, StringBuilder content, int findIndex) throws Exception
3293+ {
3294+ Matcher m = pattern.matcher(content);
3295+ if (!m.find(findIndex) || m.start() > findIndex)
3296+ throw new Exception();
3297+
3298+ return m;
3299+ }
3300+
3301+ private IfChildsFunc()
3302+ {
3303+ super("IFCHILDS", "ENDIFCHILDS", false);
3304+ }
3305+
3306+ @Override
3307+ public HashMap<String, HTMLTemplatePlaceholder> handle(StringBuilder content, PlayerInstance player, Map<String, HTMLTemplatePlaceholder> placeholders, HTMLTemplateFunc[] funcs)
3308+ {
3309+ try
3310+ {
3311+ Matcher matcher = _getMatcher(_CHILDS_OF_PLACEHOLDER_PATTERN, content, 0);
3312+ String childsPlaceholderString = matcher.group().substring(0, matcher.group().length() - 1);
3313+ HTMLTemplatePlaceholder childsPlaceholder = HTMLTemplateUtils.getPlaceholder(childsPlaceholderString, placeholders);
3314+ if (childsPlaceholder == null)
3315+ {
3316+ content.setLength(0);
3317+ return null;
3318+ }
3319+
3320+ matcher = _getMatcher(_CHILD_PLACEHOLDER_PATTERN, content, matcher.end());
3321+ String childPlaceholderString = matcher.group().trim();
3322+ int findIndex = matcher.end();
3323+
3324+ matcher = _getMatcher(_OP_PATTERN, content, findIndex);
3325+ String op = matcher.group().trim();
3326+ findIndex = matcher.end();
3327+
3328+ matcher = _getMatcher(_RVALUE_PATTERN, content, findIndex);
3329+ String rValue = matcher.group();
3330+ if (rValue.charAt(0) == '"')
3331+ {
3332+ rValue = rValue.substring(1, rValue.length() - 1);
3333+ }
3334+ else
3335+ {
3336+ rValue = HTMLTemplateUtils.getPlaceholderValue(rValue, placeholders);
3337+ }
3338+ findIndex = matcher.end();
3339+
3340+ matcher = _getMatcher(_THEN_PATTERN, content, findIndex);
3341+ findIndex = matcher.end();
3342+
3343+ for (Entry<String, HTMLTemplatePlaceholder> entry : childsPlaceholder.getChilds().entrySet())
3344+ {
3345+ HTMLTemplatePlaceholder childPlaceholder = entry.getValue().getChild(childPlaceholderString);
3346+ if (childPlaceholder == null)
3347+ continue;
3348+
3349+ try
3350+ {
3351+ boolean ok = false;
3352+ switch (op)
3353+ {
3354+ case "<":
3355+ ok = Integer.parseInt(childPlaceholder.getValue()) < Integer.parseInt(rValue);
3356+ break;
3357+ case ">":
3358+ ok = Integer.parseInt(childPlaceholder.getValue()) > Integer.parseInt(rValue);
3359+ break;
3360+ case "<=":
3361+ ok = Integer.parseInt(childPlaceholder.getValue()) <= Integer.parseInt(rValue);
3362+ break;
3363+ case ">=":
3364+ ok = Integer.parseInt(childPlaceholder.getValue()) >= Integer.parseInt(rValue);
3365+ break;
3366+ case "==":
3367+ ok = childPlaceholder.getValue().equals(rValue);
3368+ break;
3369+ case "!=":
3370+ ok = !childPlaceholder.getValue().equals(rValue);
3371+ break;
3372+ case "ENDS_WITH":
3373+ ok = childPlaceholder.getValue().endsWith(rValue);
3374+ break;
3375+ case "STARTS_WITH":
3376+ ok = childPlaceholder.getValue().startsWith(rValue);
3377+ break;
3378+ }
3379+
3380+ if (!ok)
3381+ {
3382+ // condition is not met, no content to show
3383+ content.setLength(0);
3384+ return null;
3385+ }
3386+ }
3387+ catch (Exception e)
3388+ {
3389+ // on an exception the types are incompatible with the operator, this function ignores such cases
3390+ }
3391+ }
3392+
3393+ content.delete(0, findIndex);
3394+ }
3395+ catch (Exception e)
3396+ {
3397+ content.setLength(0);
3398+ }
3399+
3400+ return null;
3401+ }
3402+}
3403Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/ForeachFunc.java
3404IDEA additional info:
3405Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
3406<+>UTF-8
3407===================================================================
3408--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/ForeachFunc.java (date 1601235046974)
3409+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/ForeachFunc.java (date 1601235046974)
3410@@ -0,0 +1,107 @@
3411+/*
3412+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
3413+ * Copyright (C) 2015 Christian Buck
3414+ *
3415+ * This program is free software: you can redistribute it and/or modify
3416+ * it under the terms of the GNU General Public License as published by
3417+ * the Free Software Foundation, either version 3 of the License, or
3418+ * (at your option) any later version.
3419+ *
3420+ * This program is distributed in the hope that it will be useful,
3421+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3422+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3423+ * GNU General Public License for more details.
3424+ *
3425+ * You should have received a copy of the GNU General Public License
3426+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3427+ */
3428+package custom.Buffer.util.htmltmpls.funcs;
3429+
3430+import java.util.HashMap;
3431+import java.util.Map;
3432+import java.util.Map.Entry;
3433+import java.util.regex.Matcher;
3434+import java.util.regex.Pattern;
3435+
3436+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
3437+
3438+import custom.Buffer.util.htmltmpls.HTMLTemplateFunc;
3439+import custom.Buffer.util.htmltmpls.HTMLTemplateParser;
3440+import custom.Buffer.util.htmltmpls.HTMLTemplatePlaceholder;
3441+import custom.Buffer.util.htmltmpls.HTMLTemplateUtils;
3442+
3443+/**
3444+ * This class implements the following function syntax:<br>
3445+ * [FOREACH(alias_placeholder_name IN placeholder_name DO text per iteration)ENDEACH]<br>
3446+ * <br>
3447+ * This construct is able to iterate over the childs of the "placeholder_name" placeholder.<br>
3448+ * For each child in this placeholder, the text after "DO" is placed in the content.<br>
3449+ * The current child is placed as an alias toplevel placeholder. This means, in this example<br>
3450+ * you can use %alias_placeholder_name% inside the foreach block.
3451+ * @author HorridoJoho
3452+ */
3453+public final class ForeachFunc extends HTMLTemplateFunc
3454+{
3455+ public static final ForeachFunc INSTANCE = new ForeachFunc();
3456+
3457+ private static final Pattern _FIRST_PLACEHOLDER_PATTERN = Pattern.compile("\\s*[a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)*");
3458+ private static final Pattern _IN_PATTERN = Pattern.compile("\\s*\\sIN\\s");
3459+ private static final Pattern _SECOND_PLACEHOLDER_PATTERN = Pattern.compile("\\s*[a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)*");
3460+ private static final Pattern _DO_PATTERN = Pattern.compile("\\s*\\sDO\\s");
3461+
3462+ private static Matcher _getMatcher(Pattern pattern, StringBuilder content, int findIndex) throws Exception
3463+ {
3464+ Matcher m = pattern.matcher(content);
3465+ if (!m.find(findIndex) || m.start() > findIndex)
3466+ throw new Exception();
3467+
3468+ return m;
3469+ }
3470+
3471+ private ForeachFunc()
3472+ {
3473+ super("FOREACH", "ENDEACH", false);
3474+ }
3475+
3476+ @Override
3477+ public HashMap<String, HTMLTemplatePlaceholder> handle(StringBuilder content, PlayerInstance player, Map<String, HTMLTemplatePlaceholder> placeholders, HTMLTemplateFunc[] funcs)
3478+ {
3479+ try
3480+ {
3481+ Matcher matcher = _getMatcher(_FIRST_PLACEHOLDER_PATTERN, content, 0);
3482+ String aliasPlaceholderName = matcher.group().trim();
3483+ int findIndex = matcher.end();
3484+
3485+ matcher = _getMatcher(_IN_PATTERN, content, findIndex);
3486+ findIndex = matcher.end();
3487+
3488+ matcher = _getMatcher(_SECOND_PLACEHOLDER_PATTERN, content, findIndex);
3489+ Map<String, HTMLTemplatePlaceholder> childPlaceholders = HTMLTemplateUtils.getPlaceholderChilds(matcher.group().trim(), placeholders);
3490+ findIndex = matcher.end();
3491+
3492+ matcher = _getMatcher(_DO_PATTERN, content, findIndex);
3493+ findIndex = matcher.end();
3494+
3495+ content.delete(0, findIndex);
3496+ HashMap<String, HTMLTemplatePlaceholder> newPlaceholders = new HashMap<>();
3497+ newPlaceholders.putAll(placeholders);
3498+ StringBuilder orgContent = new StringBuilder(content);
3499+ StringBuilder modContent = new StringBuilder(content.length());
3500+ content.setLength(0);
3501+ // we don't need to save an overwritten placeholder, we create our own map
3502+ for (Entry<String, HTMLTemplatePlaceholder> childPlaceholder : childPlaceholders.entrySet())
3503+ {
3504+ modContent.setLength(0);
3505+ modContent.append(orgContent);
3506+ newPlaceholders.put(aliasPlaceholderName, childPlaceholder.getValue().createAlias(aliasPlaceholderName));
3507+ HTMLTemplateParser.fromStringBuilder(modContent, player, newPlaceholders, funcs);
3508+ content.append(modContent);
3509+ }
3510+ }
3511+ catch (Exception e)
3512+ {
3513+ content.setLength(0);
3514+ }
3515+ return null;
3516+ }
3517+}
3518Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/ExistsFunc.java
3519IDEA additional info:
3520Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
3521<+>UTF-8
3522===================================================================
3523--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/ExistsFunc.java (date 1601235046968)
3524+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/ExistsFunc.java (date 1601235046968)
3525@@ -0,0 +1,94 @@
3526+/*
3527+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
3528+ * Copyright (C) 2015 Christian Buck
3529+ *
3530+ * This program is free software: you can redistribute it and/or modify
3531+ * it under the terms of the GNU General Public License as published by
3532+ * the Free Software Foundation, either version 3 of the License, or
3533+ * (at your option) any later version.
3534+ *
3535+ * This program is distributed in the hope that it will be useful,
3536+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3537+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3538+ * GNU General Public License for more details.
3539+ *
3540+ * You should have received a copy of the GNU General Public License
3541+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3542+ */
3543+package custom.Buffer.util.htmltmpls.funcs;
3544+
3545+import java.util.Map;
3546+import java.util.regex.Matcher;
3547+import java.util.regex.Pattern;
3548+
3549+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
3550+
3551+import custom.Buffer.util.htmltmpls.HTMLTemplateFunc;
3552+import custom.Buffer.util.htmltmpls.HTMLTemplatePlaceholder;
3553+import custom.Buffer.util.htmltmpls.HTMLTemplateUtils;
3554+
3555+/**
3556+ * @author HorridoJoho
3557+ */
3558+public final class ExistsFunc extends HTMLTemplateFunc
3559+{
3560+ public static final ExistsFunc INSTANCE = new ExistsFunc();
3561+
3562+ private static final Pattern _NEGATE_PATTERN = Pattern.compile("\\s*!\\s*");
3563+ private static final Pattern _PLACEHOLDER_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)*\\s*,");
3564+
3565+ private ExistsFunc()
3566+ {
3567+ super("EXISTS", "ENDEXISTS", false);
3568+ }
3569+
3570+ private static Matcher _getMatcher(Pattern pattern, StringBuilder content, int findIndex) throws Exception
3571+ {
3572+ Matcher m = pattern.matcher(content);
3573+ if (!m.find(findIndex) || m.start() > findIndex)
3574+ throw new Exception();
3575+
3576+ return m;
3577+ }
3578+
3579+ @Override
3580+ public Map<String, HTMLTemplatePlaceholder> handle(StringBuilder content, PlayerInstance player, Map<String, HTMLTemplatePlaceholder> placeholders, HTMLTemplateFunc[] funcs)
3581+ {
3582+ try
3583+ {
3584+ boolean negate = false;
3585+ Matcher m = null;
3586+
3587+ try
3588+ {
3589+ m = _getMatcher(_NEGATE_PATTERN, content, 0);
3590+ negate = true;
3591+ }
3592+ catch (Exception e)
3593+ {
3594+ // ignore this exception, negate is optional
3595+ }
3596+
3597+ if (m != null)
3598+ m = _getMatcher(_PLACEHOLDER_PATTERN, content, m.end());
3599+ else
3600+ m = _getMatcher(_PLACEHOLDER_PATTERN, content, 0);
3601+
3602+ HTMLTemplatePlaceholder placeholder = HTMLTemplateUtils.getPlaceholder(m.group().substring(0, m.group().length() - 1).trim(), placeholders);
3603+ if ((placeholder == null && !negate) || (placeholder != null && negate))
3604+ {
3605+ content.setLength(0);
3606+ return null;
3607+ }
3608+
3609+ content.delete(0, m.end());
3610+ }
3611+ catch (Exception e)
3612+ {
3613+ content.setLength(0);
3614+ }
3615+
3616+ return null;
3617+ }
3618+
3619+}
3620Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/ChildsCountFunc.java
3621IDEA additional info:
3622Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
3623<+>UTF-8
3624===================================================================
3625--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/ChildsCountFunc.java (date 1601235046963)
3626+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/util/htmltmpls/funcs/ChildsCountFunc.java (date 1601235046963)
3627@@ -0,0 +1,52 @@
3628+/*
3629+ * This file is part of YANModPack: https://github.com/HorridoJoho/YANModPack
3630+ * Copyright (C) 2015 Christian Buck
3631+ *
3632+ * This program is free software: you can redistribute it and/or modify
3633+ * it under the terms of the GNU General Public License as published by
3634+ * the Free Software Foundation, either version 3 of the License, or
3635+ * (at your option) any later version.
3636+ *
3637+ * This program is distributed in the hope that it will be useful,
3638+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3639+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3640+ * GNU General Public License for more details.
3641+ *
3642+ * You should have received a copy of the GNU General Public License
3643+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3644+ */
3645+package custom.Buffer.util.htmltmpls.funcs;
3646+
3647+import java.util.Map;
3648+
3649+import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
3650+
3651+import custom.Buffer.util.htmltmpls.HTMLTemplateFunc;
3652+import custom.Buffer.util.htmltmpls.HTMLTemplatePlaceholder;
3653+import custom.Buffer.util.htmltmpls.HTMLTemplateUtils;
3654+
3655+/**
3656+ * @author HorridoJoho
3657+ */
3658+public final class ChildsCountFunc extends HTMLTemplateFunc
3659+{
3660+ public static final ChildsCountFunc INSTANCE = new ChildsCountFunc();
3661+
3662+ protected ChildsCountFunc()
3663+ {
3664+ super("CHILDSCOUNT", "ENDCHILDSCOUNT", false);
3665+ }
3666+
3667+ @Override
3668+ public Map<String, HTMLTemplatePlaceholder> handle(StringBuilder content, PlayerInstance player, Map<String, HTMLTemplatePlaceholder> placeholders, HTMLTemplateFunc[] funcs)
3669+ {
3670+ HTMLTemplatePlaceholder placeholder = HTMLTemplateUtils.getPlaceholder(content.toString(), placeholders);
3671+ content.setLength(0);
3672+ if (placeholder != null)
3673+ {
3674+ content.append(String.valueOf(placeholder.getChildsSize()));
3675+ }
3676+ return null;
3677+ }
3678+
3679+}
3680Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/sql/buffer_data.sql
3681IDEA additional info:
3682Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
3683<+>UTF-8
3684===================================================================
3685--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/sql/buffer_data.sql (date 1601235046958)
3686+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/sql/buffer_data.sql (date 1601235046958)
3687@@ -0,0 +1,15 @@
3688+CREATE TABLE `buffer_user_list_buffs` (
3689+ `user_buff_list_id` int(10) unsigned NOT NULL,
3690+ `buff_id` varchar(255) NOT NULL,
3691+ PRIMARY KEY (`user_buff_list_id`,`buff_id`),
3692+ CONSTRAINT `buffer_user_list_buffs_ibfk_1` FOREIGN KEY (`user_buff_list_id`) REFERENCES `buffer_user_lists` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
3693+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3694+
3695+CREATE TABLE `buffer_user_lists` (
3696+ `id` int(10) unsigned PRIMARY KEY AUTO_INCREMENT NOT NULL ,
3697+ `character_id` int(10) unsigned NOT NULL,
3698+ `list_name` varchar(255) NOT NULL,
3699+ UNIQUE KEY `character_id` (`character_id`,`list_name`),
3700+ CONSTRAINT `buffer_user_lists_ibfk_1` FOREIGN KEY (`character_id`) REFERENCES `characters` (`charId`) ON DELETE CASCADE ON UPDATE CASCADE
3701+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3702+
3703Index: L2J_Mobius_Classic_Interlude/java/org/l2jmobius/Config.java
3704IDEA additional info:
3705Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
3706<+>UTF-8
3707===================================================================
3708--- L2J_Mobius_Classic_Interlude/java/org/l2jmobius/Config.java (revision 9230173172baed1192322bacd625ea32cc78f981)
3709+++ L2J_Mobius_Classic_Interlude/java/org/l2jmobius/Config.java (date 1601235348455)
3710@@ -142,10 +142,11 @@
3711 private static final String CUSTOM_SCREEN_WELCOME_MESSAGE_CONFIG_FILE = "./config/Custom/ScreenWelcomeMessage.ini";
3712 private static final String CUSTOM_SELL_BUFFS_CONFIG_FILE = "./config/Custom/SellBuffs.ini";
3713 private static final String CUSTOM_SERVER_TIME_CONFIG_FILE = "./config/Custom/ServerTime.ini";
3714- private static final String CUSTOM_SCHEME_BUFFER_CONFIG_FILE = "./config/Custom/ShemeBuffer.ini";
3715+ private static final String CUSTOM_SCHEME_BUFFER_CONFIG_FILE = "./config/Custom/SchemeBuffer.ini";
3716 private static final String CUSTOM_STARTING_LOCATION_CONFIG_FILE = "./config/Custom/StartingLocation.ini";
3717 private static final String CUSTOM_VOTE_REWARD_CONFIG_FILE = "./config/Custom/VoteReward.ini";
3718 private static final String CUSTOM_WALKER_BOT_PROTECTION_CONFIG_FILE = "./config/Custom/WalkerBotProtection.ini";
3719+ private static final String CUSTOM_BUFFER_CONFIG_FILE = "./config/Custom/Buffer.ini";
3720
3721 // --------------------------------------------------
3722 // Variable Definitions
3723@@ -1267,6 +1268,8 @@
3724 public static Map<Integer, Integer> L2TOP_REWARD = new HashMap<>();
3725 public static int L2TOP_DUALBOXES_ALLOWED;
3726 public static boolean ALLOW_L2TOP_GAME_SERVER_REPORT;
3727+
3728+ public static int BUFFER_CUSTOM_BUFF_DURATION;
3729
3730 /**
3731 * This class initializes all global variables for configuration.<br>
3732@@ -3413,6 +3416,9 @@
3733 // Load WalkerBotProtection config file (if exists)
3734 final PropertiesParser WalkerBotProtection = new PropertiesParser(CUSTOM_WALKER_BOT_PROTECTION_CONFIG_FILE);
3735 L2WALKER_PROTECTION = WalkerBotProtection.getBoolean("L2WalkerProtection", false);
3736+
3737+ final PropertiesParser BufferProperties = new PropertiesParser(CUSTOM_BUFFER_CONFIG_FILE);
3738+ BUFFER_CUSTOM_BUFF_DURATION = BufferProperties.getInt("BufferOverrideBuffDuration", 0);
3739 }
3740 else if (SERVER_MODE == ServerMode.LOGIN)
3741 {
3742Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/voiced_buffer.xml
3743IDEA additional info:
3744Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
3745<+>UTF-8
3746===================================================================
3747--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/voiced_buffer.xml (date 1601235046951)
3748+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/voiced_buffer.xml (date 1601235046951)
3749@@ -0,0 +1,20 @@
3750+<?xml version="1.0" encoding="utf-8"?>
3751+<!-- ATTRIBUTES
3752+ enabled - true|false
3753+ required_item - id of the item required in the players inventory to use the voiced buffer
3754+ can_heal - true|false - enable/disable heal for voiced buffer
3755+ can_cancel - true|false - enable/disable cancel for voiced buffer
3756+ -->
3757+<voiced_buffer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/voiced_buffer.xsd" enabled="true" required_item="0" can_heal="true" can_cancel="true">
3758+ <buff_cat ident="BC_FIGHTER" is_preset="true"/>
3759+ <buff_cat ident="BC_MAGE" is_preset="true"/>
3760+
3761+ <buff_cat ident="BC_BUFFS" is_preset="false"/>
3762+ <buff_cat ident="BC_SONGS" is_preset="false"/>
3763+ <buff_cat ident="BC_DANCES" is_preset="false"/>
3764+ <buff_cat ident="BC_CHANTS" is_preset="false"/>
3765+ <buff_cat ident="BC_DWARVEN" is_preset="false"/>
3766+ <buff_cat ident="BC_RESIST" is_preset="false"/>
3767+ <buff_cat ident="BC_SPECIAL" is_preset="false"/>
3768+ <buff_cat ident="BC_OVERLORD" is_preset="false"/>
3769+</voiced_buffer>
3770\ No newline at end of file
3771Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/item_requirements.xml
3772IDEA additional info:
3773Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
3774<+>UTF-8
3775===================================================================
3776--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/item_requirements.xml (date 1601235046945)
3777+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/item_requirements.xml (date 1601235046945)
3778@@ -0,0 +1,8 @@
3779+<?xml version="1.0" encoding="utf-8"?>
3780+<item_requirements xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/item_requirements.xsd">
3781+ <item ident="ADENA_1" id="57" amount="1"/>
3782+ <item ident="ADENA_10" id="57" amount="10"/>
3783+ <item ident="ADENA_100" id="57" amount="100"/>
3784+ <item ident="ADENA_1000" id="57" amount="1000"/>
3785+ <item ident="ADENA_10000" id="57" amount="10000"/>
3786+</item_requirements>
3787\ No newline at end of file
3788Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/buffs.xml
3789IDEA additional info:
3790Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
3791<+>UTF-8
3792===================================================================
3793--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/buffs.xml (date 1601235046934)
3794+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/buffs.xml (date 1601235046934)
3795@@ -0,0 +1,390 @@
3796+<?xml version="1.0" encoding="utf-8"?>
3797+<buffs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="./xsd/buffs.xsd">
3798+ <!-- Buffs -->
3799+ <buff ident="BUFF_0" skill_id="1036" skill_level="2" type="BUFF">
3800+ <item ident="ADENA_100"/>
3801+ </buff>
3802+ <buff ident="BUFF_1" skill_id="1040" skill_level="3" type="BUFF">
3803+ <item ident="ADENA_100"/>
3804+ </buff>
3805+ <buff ident="BUFF_2" skill_id="1043" skill_level="1" type="BUFF">
3806+ <item ident="ADENA_100"/>
3807+ </buff>
3808+ <buff ident="BUFF_3" skill_id="1044" skill_level="3" type="BUFF">
3809+ <item ident="ADENA_100"/>
3810+ </buff>
3811+ <buff ident="BUFF_4" skill_id="1045" skill_level="6" type="BUFF">
3812+ <item ident="ADENA_100"/>
3813+ </buff>
3814+ <buff ident="BUFF_5" skill_id="1047" skill_level="4" type="BUFF">
3815+ <item ident="ADENA_100"/>
3816+ </buff>
3817+ <buff ident="BUFF_6" skill_id="1048" skill_level="6" type="BUFF">
3818+ <item ident="ADENA_100"/>
3819+ </buff>
3820+ <buff ident="BUFF_7" skill_id="1059" skill_level="3" type="BUFF">
3821+ <item ident="ADENA_100"/>
3822+ </buff>
3823+ <buff ident="BUFF_8" skill_id="1068" skill_level="3" type="BUFF">
3824+ <item ident="ADENA_100"/>
3825+ </buff>
3826+ <buff ident="BUFF_9" skill_id="1077" skill_level="3" type="BUFF">
3827+ <item ident="ADENA_100"/>
3828+ </buff>
3829+ <buff ident="BUFF_10" skill_id="1085" skill_level="3" type="BUFF">
3830+ <item ident="ADENA_100"/>
3831+ </buff>
3832+ <buff ident="BUFF_11" skill_id="1086" skill_level="2" type="BUFF">
3833+ <item ident="ADENA_100"/>
3834+ </buff>
3835+ <buff ident="BUFF_12" skill_id="1087" skill_level="3" type="BUFF">
3836+ <item ident="ADENA_100"/>
3837+ </buff>
3838+ <buff ident="BUFF_13" skill_id="1204" skill_level="2" type="BUFF">
3839+ <item ident="ADENA_100"/>
3840+ </buff>
3841+ <buff ident="BUFF_14" skill_id="1242" skill_level="3" type="BUFF">
3842+ <item ident="ADENA_100"/>
3843+ </buff>
3844+ <buff ident="BUFF_15" skill_id="1243" skill_level="6" type="BUFF">
3845+ <item ident="ADENA_100"/>
3846+ </buff>
3847+ <buff ident="BUFF_16" skill_id="1257" skill_level="3" type="BUFF">
3848+ <item ident="ADENA_100"/>
3849+ </buff>
3850+ <buff ident="BUFF_17" skill_id="1268" skill_level="4" type="BUFF">
3851+ <item ident="ADENA_100"/>
3852+ </buff>
3853+ <buff ident="BUFF_18" skill_id="1303" skill_level="2" type="BUFF">
3854+ <item ident="ADENA_100"/>
3855+ </buff>
3856+ <buff ident="BUFF_19" skill_id="1304" skill_level="3" type="BUFF">
3857+ <item ident="ADENA_100"/>
3858+ </buff>
3859+ <buff ident="BUFF_20" skill_id="1307" skill_level="3" type="BUFF">
3860+ <item ident="ADENA_100"/>
3861+ </buff>
3862+ <buff ident="BUFF_21" skill_id="1311" skill_level="6" type="BUFF">
3863+ <item ident="ADENA_100"/>
3864+ </buff>
3865+ <buff ident="BUFF_22" skill_id="1397" skill_level="3" type="BUFF">
3866+ <item ident="ADENA_100"/>
3867+ </buff>
3868+ <buff ident="BUFF_23" skill_id="1460" skill_level="1" type="BUFF">
3869+ <item ident="ADENA_100"/>
3870+ </buff>
3871+ <buff ident="BUFF_24" skill_id="1232" skill_level="3" type="BUFF">
3872+ <item ident="ADENA_100"/>
3873+ </buff>
3874+ <buff ident="BUFF_25" skill_id="1238" skill_level="3" type="BUFF">
3875+ <item ident="ADENA_100"/>
3876+ </buff>
3877+ <buff ident="BUFF_26" skill_id="1086" skill_level="2" type="BUFF">
3878+ <item ident="ADENA_100"/>
3879+ </buff>
3880+
3881+ <!-- Songs -->
3882+ <buff ident="SONG_0" skill_id="264" skill_level="1" type="DANCE">
3883+ <item ident="ADENA_100"/>
3884+ </buff>
3885+ <buff ident="SONG_1" skill_id="265" skill_level="1" type="DANCE">
3886+ <item ident="ADENA_100"/>
3887+ </buff>
3888+ <buff ident="SONG_2" skill_id="266" skill_level="1" type="DANCE">
3889+ <item ident="ADENA_100"/>
3890+ </buff>
3891+ <buff ident="SONG_3" skill_id="267" skill_level="1" type="DANCE">
3892+ <item ident="ADENA_100"/>
3893+ </buff>
3894+ <buff ident="SONG_4" skill_id="268" skill_level="1" type="DANCE">
3895+ <item ident="ADENA_100"/>
3896+ </buff>
3897+ <buff ident="SONG_5" skill_id="269" skill_level="1" type="DANCE">
3898+ <item ident="ADENA_100"/>
3899+ </buff>
3900+ <buff ident="SONG_6" skill_id="270" skill_level="1" type="DANCE">
3901+ <item ident="ADENA_100"/>
3902+ </buff>
3903+ <buff ident="SONG_7" skill_id="304" skill_level="1" type="DANCE">
3904+ <item ident="ADENA_100"/>
3905+ </buff>
3906+ <buff ident="SONG_8" skill_id="305" skill_level="1" type="DANCE">
3907+ <item ident="ADENA_100"/>
3908+ </buff>
3909+ <buff ident="SONG_9" skill_id="306" skill_level="1" type="DANCE">
3910+ <item ident="ADENA_100"/>
3911+ </buff>
3912+ <buff ident="SONG_10" skill_id="308" skill_level="1" type="DANCE">
3913+ <item ident="ADENA_100"/>
3914+ </buff>
3915+ <buff ident="SONG_11" skill_id="349" skill_level="1" type="DANCE">
3916+ <item ident="ADENA_100"/>
3917+ </buff>
3918+ <buff ident="SONG_12" skill_id="363" skill_level="1" type="DANCE">
3919+ <item ident="ADENA_100"/>
3920+ </buff>
3921+ <buff ident="SONG_13" skill_id="364" skill_level="1" type="DANCE">
3922+ <item ident="ADENA_100"/>
3923+ </buff>
3924+ <buff ident="SONG_14" skill_id="529" skill_level="1" type="DANCE">
3925+ <item ident="ADENA_100"/>
3926+ </buff>
3927+ <buff ident="SONG_15" skill_id="764" skill_level="1" type="DANCE">
3928+ <item ident="ADENA_100"/>
3929+ </buff>
3930+ <buff ident="SONG_16" skill_id="914" skill_level="1" type="DANCE">
3931+ <item ident="ADENA_100"/>
3932+ </buff>
3933+
3934+ <!-- Dances -->
3935+ <buff ident="DANCE_0" skill_id="271" skill_level="1" type="DANCE">
3936+ <item ident="ADENA_100"/>
3937+ </buff>
3938+ <buff ident="DANCE_1" skill_id="272" skill_level="1" type="DANCE">
3939+ <item ident="ADENA_100"/>
3940+ </buff>
3941+ <buff ident="DANCE_2" skill_id="273" skill_level="1" type="DANCE">
3942+ <item ident="ADENA_100"/>
3943+ </buff>
3944+ <buff ident="DANCE_3" skill_id="274" skill_level="1" type="DANCE">
3945+ <item ident="ADENA_100"/>
3946+ </buff>
3947+ <buff ident="DANCE_4" skill_id="275" skill_level="1" type="DANCE">
3948+ <item ident="ADENA_100"/>
3949+ </buff>
3950+ <buff ident="DANCE_5" skill_id="276" skill_level="1" type="DANCE">
3951+ <item ident="ADENA_100"/>
3952+ </buff>
3953+ <buff ident="DANCE_6" skill_id="277" skill_level="1" type="DANCE">
3954+ <item ident="ADENA_100"/>
3955+ </buff>
3956+ <buff ident="DANCE_7" skill_id="307" skill_level="1" type="DANCE">
3957+ <item ident="ADENA_100"/>
3958+ </buff>
3959+ <buff ident="DANCE_8" skill_id="309" skill_level="1" type="DANCE">
3960+ <item ident="ADENA_100"/>
3961+ </buff>
3962+ <buff ident="DANCE_9" skill_id="310" skill_level="1" type="DANCE">
3963+ <item ident="ADENA_100"/>
3964+ </buff>
3965+ <buff ident="DANCE_10" skill_id="311" skill_level="1" type="DANCE">
3966+ <item ident="ADENA_100"/>
3967+ </buff>
3968+ <buff ident="DANCE_11" skill_id="365" skill_level="1" type="DANCE">
3969+ <item ident="ADENA_100"/>
3970+ </buff>
3971+ <buff ident="DANCE_12" skill_id="366" skill_level="1" type="DANCE">
3972+ <item ident="ADENA_100"/>
3973+ </buff>
3974+ <buff ident="DANCE_13" skill_id="530" skill_level="1" type="DANCE">
3975+ <item ident="ADENA_100"/>
3976+ </buff>
3977+ <buff ident="DANCE_14" skill_id="765" skill_level="1" type="DANCE">
3978+ <item ident="ADENA_100"/>
3979+ </buff>
3980+ <buff ident="DANCE_15" skill_id="915" skill_level="1" type="DANCE">
3981+ <item ident="ADENA_100"/>
3982+ </buff>
3983+
3984+ <!-- Chants -->
3985+ <buff ident="CHANT_0" skill_id="1002" skill_level="3" type="BUFF">
3986+ <item ident="ADENA_100"/>
3987+ </buff>
3988+ <buff ident="CHANT_1" skill_id="1006" skill_level="3" type="BUFF">
3989+ <item ident="ADENA_100"/>
3990+ </buff>
3991+ <buff ident="CHANT_2" skill_id="1007" skill_level="3" type="BUFF">
3992+ <item ident="ADENA_100"/>
3993+ </buff>
3994+ <buff ident="CHANT_3" skill_id="1009" skill_level="3" type="BUFF">
3995+ <item ident="ADENA_100"/>
3996+ </buff>
3997+ <buff ident="CHANT_4" skill_id="1251" skill_level="2" type="BUFF">
3998+ <item ident="ADENA_100"/>
3999+ </buff>
4000+ <buff ident="CHANT_5" skill_id="1252" skill_level="3" type="BUFF">
4001+ <item ident="ADENA_100"/>
4002+ </buff>
4003+ <buff ident="CHANT_6" skill_id="1253" skill_level="3" type="BUFF">
4004+ <item ident="ADENA_100"/>
4005+ </buff>
4006+ <buff ident="CHANT_7" skill_id="1284" skill_level="3" type="BUFF">
4007+ <item ident="ADENA_100"/>
4008+ </buff>
4009+ <buff ident="CHANT_8" skill_id="1308" skill_level="3" type="BUFF">
4010+ <item ident="ADENA_100"/>
4011+ </buff>
4012+ <buff ident="CHANT_9" skill_id="1309" skill_level="3" type="BUFF">
4013+ <item ident="ADENA_100"/>
4014+ </buff>
4015+ <buff ident="CHANT_10" skill_id="1310" skill_level="4" type="BUFF">
4016+ <item ident="ADENA_100"/>
4017+ </buff>
4018+ <buff ident="CHANT_11" skill_id="1362" skill_level="1" type="BUFF">
4019+ <item ident="ADENA_100"/>
4020+ </buff>
4021+
4022+ <!-- Dwarven -->
4023+ <buff ident="DWARVEN_0" skill_id="825" skill_level="1" type="BUFF">
4024+ <item ident="ADENA_100"/>
4025+ </buff>
4026+ <buff ident="DWARVEN_1" skill_id="826" skill_level="1" type="BUFF">
4027+ <item ident="ADENA_100"/>
4028+ </buff>
4029+ <buff ident="DWARVEN_2" skill_id="827" skill_level="1" type="BUFF">
4030+ <item ident="ADENA_100"/>
4031+ </buff>
4032+ <buff ident="DWARVEN_3" skill_id="828" skill_level="1" type="BUFF">
4033+ <item ident="ADENA_100"/>
4034+ </buff>
4035+ <buff ident="DWARVEN_4" skill_id="829" skill_level="1" type="BUFF">
4036+ <item ident="ADENA_100"/>
4037+ </buff>
4038+ <buff ident="DWARVEN_5" skill_id="830" skill_level="1" type="BUFF">
4039+ <item ident="ADENA_100"/>
4040+ </buff>
4041+
4042+ <!-- Resist -->
4043+ <buff ident="RESIST_0" skill_id="1461" skill_level="1" type="BUFF">
4044+ <item ident="ADENA_100"/>
4045+ </buff>
4046+ <buff ident="RESIST_1" skill_id="1032" skill_level="3" type="BUFF">
4047+ <item ident="ADENA_100"/>
4048+ </buff>
4049+ <buff ident="RESIST_2" skill_id="1033" skill_level="3" type="BUFF">
4050+ <item ident="ADENA_100"/>
4051+ </buff>
4052+ <buff ident="RESIST_3" skill_id="1035" skill_level="4" type="BUFF">
4053+ <item ident="ADENA_100"/>
4054+ </buff>
4055+ <buff ident="RESIST_4" skill_id="1078" skill_level="6" type="BUFF">
4056+ <item ident="ADENA_100"/>
4057+ </buff>
4058+ <buff ident="RESIST_5" skill_id="1182" skill_level="3" type="BUFF">
4059+ <item ident="ADENA_100"/>
4060+ </buff>
4061+ <buff ident="RESIST_6" skill_id="1189" skill_level="3" type="BUFF">
4062+ <item ident="ADENA_100"/>
4063+ </buff>
4064+ <buff ident="RESIST_7" skill_id="1191" skill_level="3" type="BUFF">
4065+ <item ident="ADENA_100"/>
4066+ </buff>
4067+ <buff ident="RESIST_8" skill_id="1259" skill_level="4" type="BUFF">
4068+ <item ident="ADENA_100"/>
4069+ </buff>
4070+ <buff ident="RESIST_9" skill_id="1352" skill_level="1" type="BUFF">
4071+ <item ident="ADENA_100"/>
4072+ </buff>
4073+ <buff ident="RESIST_10" skill_id="1353" skill_level="1" type="BUFF">
4074+ <item ident="ADENA_100"/>
4075+ </buff>
4076+ <buff ident="RESIST_11" skill_id="1354" skill_level="1" type="BUFF">
4077+ <item ident="ADENA_100"/>
4078+ </buff>
4079+ <buff ident="RESIST_12" skill_id="1392" skill_level="3" type="BUFF">
4080+ <item ident="ADENA_100"/>
4081+ </buff>
4082+ <buff ident="RESIST_13" skill_id="1393" skill_level="3" type="BUFF">
4083+ <item ident="ADENA_100"/>
4084+ </buff>
4085+
4086+ <!-- Special -->
4087+ <buff ident="SPECIAL_0" skill_id="1323" skill_level="1" type="BUFF">
4088+ <item ident="ADENA_100"/>
4089+ </buff>
4090+ <buff ident="SPECIAL_1" skill_id="1388" skill_level="3" type="BUFF">
4091+ <item ident="ADENA_100"/>
4092+ </buff>
4093+ <buff ident="SPECIAL_2" skill_id="1389" skill_level="3" type="BUFF">
4094+ <item ident="ADENA_100"/>
4095+ </buff>
4096+ <buff ident="SPECIAL_3" skill_id="1499" skill_level="1" type="BUFF">
4097+ <item ident="ADENA_100"/>
4098+ </buff>
4099+ <buff ident="SPECIAL_4" skill_id="1500" skill_level="1" type="BUFF">
4100+ <item ident="ADENA_100"/>
4101+ </buff>
4102+ <buff ident="SPECIAL_5" skill_id="1501" skill_level="1" type="BUFF">
4103+ <item ident="ADENA_100"/>
4104+ </buff>
4105+ <buff ident="SPECIAL_6" skill_id="1502" skill_level="1" type="BUFF">
4106+ <item ident="ADENA_100"/>
4107+ </buff>
4108+ <buff ident="SPECIAL_7" skill_id="1503" skill_level="1" type="BUFF">
4109+ <item ident="ADENA_100"/>
4110+ </buff>
4111+ <buff ident="SPECIAL_8" skill_id="1504" skill_level="1" type="BUFF">
4112+ <item ident="ADENA_100"/>
4113+ </buff>
4114+ <buff ident="SPECIAL_9" skill_id="1519" skill_level="1" type="BUFF">
4115+ <item ident="ADENA_100"/>
4116+ </buff>
4117+ <buff ident="SPECIAL_10" skill_id="1062" skill_level="2" type="BUFF">
4118+ <item ident="ADENA_100"/>
4119+ </buff>
4120+ <buff ident="SPECIAL_11" skill_id="1355" skill_level="1" type="BUFF">
4121+ <item ident="ADENA_100"/>
4122+ </buff>
4123+ <buff ident="SPECIAL_12" skill_id="1356" skill_level="1" type="BUFF">
4124+ <item ident="ADENA_100"/>
4125+ </buff>
4126+ <buff ident="SPECIAL_13" skill_id="1357" skill_level="1" type="BUFF">
4127+ <item ident="ADENA_100"/>
4128+ </buff>
4129+ <buff ident="SPECIAL_14" skill_id="1363" skill_level="1" type="BUFF">
4130+ <item ident="ADENA_100"/>
4131+ </buff>
4132+ <buff ident="SPECIAL_15" skill_id="1413" skill_level="1" type="BUFF">
4133+ <item ident="ADENA_100"/>
4134+ </buff>
4135+ <buff ident="SPECIAL_16" skill_id="1457" skill_level="1" type="BUFF">
4136+ <item ident="ADENA_100"/>
4137+ </buff>
4138+ <buff ident="SPECIAL_17" skill_id="1261" skill_level="2" type="BUFF">
4139+ <item ident="ADENA_100"/>
4140+ </buff>
4141+ <buff ident="SPECIAL_18" skill_id="1415" skill_level="1" type="BUFF">
4142+ <item ident="ADENA_100"/>
4143+ </buff>
4144+ <buff ident="SPECIAL_19" skill_id="1416" skill_level="8" type="BUFF">
4145+ <item ident="ADENA_100"/>
4146+ </buff>
4147+ <buff ident="SPECIAL_20" skill_id="1542" skill_level="1" type="BUFF">
4148+ <item ident="ADENA_100"/>
4149+ </buff>
4150+ <buff ident="SPECIAL_21" skill_id="1414" skill_level="1" type="BUFF">
4151+ <item ident="ADENA_100"/>
4152+ </buff>
4153+
4154+ <!-- Overlord -->
4155+ <buff ident="OVERLORD_0" skill_id="1003" skill_level="3" type="BUFF">
4156+ <item ident="ADENA_100"/>
4157+ </buff>
4158+ <buff ident="OVERLORD_1" skill_id="1004" skill_level="3" type="BUFF">
4159+ <item ident="ADENA_100"/>
4160+ </buff>
4161+ <buff ident="OVERLORD_2" skill_id="1005" skill_level="3" type="BUFF">
4162+ <item ident="ADENA_100"/>
4163+ </buff>
4164+ <buff ident="OVERLORD_3" skill_id="1008" skill_level="3" type="BUFF">
4165+ <item ident="ADENA_100"/>
4166+ </buff>
4167+ <buff ident="OVERLORD_4" skill_id="1249" skill_level="3" type="BUFF">
4168+ <item ident="ADENA_100"/>
4169+ </buff>
4170+ <buff ident="OVERLORD_5" skill_id="1250" skill_level="3" type="BUFF">
4171+ <item ident="ADENA_100"/>
4172+ </buff>
4173+ <buff ident="OVERLORD_6" skill_id="1260" skill_level="3" type="BUFF">
4174+ <item ident="ADENA_100"/>
4175+ </buff>
4176+ <buff ident="OVERLORD_7" skill_id="1282" skill_level="2" type="BUFF">
4177+ <item ident="ADENA_100"/>
4178+ </buff>
4179+ <buff ident="OVERLORD_8" skill_id="1364" skill_level="1" type="BUFF">
4180+ <item ident="ADENA_100"/>
4181+ </buff>
4182+ <buff ident="OVERLORD_9" skill_id="1365" skill_level="1" type="BUFF">
4183+ <item ident="ADENA_100"/>
4184+ </buff>
4185+</buffs>
4186\ No newline at end of file
4187Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/buffer_npcs.xml
4188IDEA additional info:
4189Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
4190<+>UTF-8
4191===================================================================
4192--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/buffer_npcs.xml (date 1601235046928)
4193+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/buffer_npcs.xml (date 1601235046928)
4194@@ -0,0 +1,16 @@
4195+<?xml version="1.0" encoding="utf-8"?>
4196+<buffer_npcs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/buffer_npcs.xsd">
4197+ <buffer_npc id="1000006" can_heal="true" can_cancel="true">
4198+ <buff_cat ident="BC_FIGHTER" is_preset="true"/>
4199+ <buff_cat ident="BC_MAGE" is_preset="true"/>
4200+
4201+ <buff_cat ident="BC_BUFFS" is_preset="false"/>
4202+ <buff_cat ident="BC_SONGS" is_preset="false"/>
4203+ <buff_cat ident="BC_DANCES" is_preset="false"/>
4204+ <buff_cat ident="BC_CHANTS" is_preset="false"/>
4205+ <buff_cat ident="BC_DWARVEN" is_preset="false"/>
4206+ <buff_cat ident="BC_RESIST" is_preset="false"/>
4207+ <buff_cat ident="BC_SPECIAL" is_preset="false"/>
4208+ <buff_cat ident="BC_OVERLORD" is_preset="false"/>
4209+ </buffer_npc>
4210+</buffer_npcs>
4211\ No newline at end of file
4212Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/buffer.xml
4213IDEA additional info:
4214Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
4215<+>UTF-8
4216===================================================================
4217--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/buffer.xml (date 1601235046924)
4218+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/buffer.xml (date 1601235046924)
4219@@ -0,0 +1,7 @@
4220+<?xml version="1.0" encoding="utf-8"?>
4221+<!-- dialog_type: NPC, COMMUNITY -->
4222+<!-- heal_cooldown: minimum seconds between heal usage -->
4223+<!-- max_unique_list: number of maximum unique bufflists per player -->
4224+<!-- unique_max_buffs: maximum number of BUFFS on a players unique bufflist -->
4225+<!-- unique_max_songs_dances: maximum number of SONGS_DANCES on a players unique bufflist -->
4226+<buffer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/buffer.xsd" dialog_type="NPC" heal_cooldown="60" max_unique_lists="5" unique_max_buffs="24" unique_max_songs_dances="12"/>
4227\ No newline at end of file
4228Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/buff_categories.xml
4229IDEA additional info:
4230Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
4231<+>UTF-8
4232===================================================================
4233--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/buff_categories.xml (date 1601235046916)
4234+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/buff_categories.xml (date 1601235046916)
4235@@ -0,0 +1,219 @@
4236+<?xml version="1.0" encoding="utf-8"?>
4237+<buff_cats xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/buff_categories.xsd">
4238+ <buff_cat ident="BC_FIGHTER" name="Fighter">
4239+ <buff ident="BUFF_17"/>
4240+ <buff ident="SPECIAL_1"/>
4241+ <buff ident="SPECIAL_3"/>
4242+ <buff ident="SPECIAL_4"/>
4243+ <buff ident="SPECIAL_5"/>
4244+ <buff ident="SPECIAL_6"/>
4245+ <buff ident="SPECIAL_8"/>
4246+ <buff ident="SPECIAL_9"/>
4247+ <buff ident="SPECIAL_14"/>
4248+ <buff ident="SPECIAL_17"/>
4249+ <buff ident="SPECIAL_18"/>
4250+ <buff ident="SPECIAL_19"/>
4251+ <buff ident="SPECIAL_20"/>
4252+ <buff ident="RESIST_0"/>
4253+ <buff ident="RESIST_3"/>
4254+ <buff ident="RESIST_8"/>
4255+ <buff ident="RESIST_9"/>
4256+ <buff ident="RESIST_10"/>
4257+ <buff ident="RESIST_12"/>
4258+ <buff ident="RESIST_13"/>
4259+ <buff ident="DANCE_0"/>
4260+ <buff ident="DANCE_1"/>
4261+ <buff ident="DANCE_3"/>
4262+ <buff ident="DANCE_4"/>
4263+ <buff ident="DANCE_15"/>
4264+ <buff ident="SONG_0"/>
4265+ <buff ident="SONG_2"/>
4266+ <buff ident="SONG_3"/>
4267+ <buff ident="SONG_4"/>
4268+ <buff ident="SONG_5"/>
4269+ <buff ident="SONG_7"/>
4270+ <buff ident="SONG_11"/>
4271+ </buff_cat>
4272+
4273+ <buff_cat ident="BC_MAGE" name="Mage">
4274+ <buff ident="BUFF_17"/>
4275+ <buff ident="SPECIAL_2"/>
4276+ <buff ident="SPECIAL_3"/>
4277+ <buff ident="SPECIAL_4"/>
4278+ <buff ident="SPECIAL_5"/>
4279+ <buff ident="SPECIAL_8"/>
4280+ <buff ident="SPECIAL_15"/>
4281+ <buff ident="SPECIAL_17"/>
4282+ <buff ident="SPECIAL_18"/>
4283+ <buff ident="SPECIAL_19"/>
4284+ <buff ident="SPECIAL_20"/>
4285+ <buff ident="RESIST_0"/>
4286+ <buff ident="RESIST_3"/>
4287+ <buff ident="RESIST_4"/>
4288+ <buff ident="RESIST_8"/>
4289+ <buff ident="RESIST_9"/>
4290+ <buff ident="RESIST_10"/>
4291+ <buff ident="RESIST_12"/>
4292+ <buff ident="RESIST_13"/>
4293+ <buff ident="DANCE_2"/>
4294+ <buff ident="DANCE_5"/>
4295+ <buff ident="DANCE_11"/>
4296+ <buff ident="DANCE_15"/>
4297+ <buff ident="SONG_0"/>
4298+ <buff ident="SONG_1"/>
4299+ <buff ident="SONG_2"/>
4300+ <buff ident="SONG_3"/>
4301+ <buff ident="SONG_4"/>
4302+ <buff ident="SONG_7"/>
4303+ <buff ident="SONG_8"/>
4304+ <buff ident="SONG_11"/>
4305+ </buff_cat>
4306+
4307+ <buff_cat ident="BC_BUFFS" name="Buffs">
4308+ <buff ident="BUFF_0"/>
4309+ <buff ident="BUFF_1"/>
4310+ <buff ident="BUFF_2"/>
4311+ <buff ident="BUFF_3"/>
4312+ <buff ident="BUFF_4"/>
4313+ <buff ident="BUFF_5"/>
4314+ <buff ident="BUFF_6"/>
4315+ <buff ident="BUFF_7"/>
4316+ <buff ident="BUFF_8"/>
4317+ <buff ident="BUFF_9"/>
4318+ <buff ident="BUFF_10"/>
4319+ <buff ident="BUFF_11"/>
4320+ <buff ident="BUFF_12"/>
4321+ <buff ident="BUFF_13"/>
4322+ <buff ident="BUFF_14"/>
4323+ <buff ident="BUFF_15"/>
4324+ <buff ident="BUFF_16"/>
4325+ <buff ident="BUFF_17"/>
4326+ <buff ident="BUFF_18"/>
4327+ <buff ident="BUFF_19"/>
4328+ <buff ident="BUFF_20"/>
4329+ <buff ident="BUFF_21"/>
4330+ <buff ident="BUFF_22"/>
4331+ <buff ident="BUFF_23"/>
4332+ <buff ident="BUFF_24"/>
4333+ <buff ident="BUFF_25"/>
4334+ <buff ident="BUFF_26"/>
4335+ </buff_cat>
4336+
4337+ <buff_cat ident="BC_SONGS" name="Songs">
4338+ <buff ident="SONG_0"/>
4339+ <buff ident="SONG_1"/>
4340+ <buff ident="SONG_2"/>
4341+ <buff ident="SONG_3"/>
4342+ <buff ident="SONG_4"/>
4343+ <buff ident="SONG_5"/>
4344+ <buff ident="SONG_6"/>
4345+ <buff ident="SONG_7"/>
4346+ <buff ident="SONG_8"/>
4347+ <buff ident="SONG_9"/>
4348+ <buff ident="SONG_10"/>
4349+ <buff ident="SONG_11"/>
4350+ <buff ident="SONG_12"/>
4351+ <buff ident="SONG_13"/>
4352+ <buff ident="SONG_14"/>
4353+ <buff ident="SONG_15"/>
4354+ <buff ident="SONG_16"/>
4355+ </buff_cat>
4356+
4357+ <buff_cat ident="BC_DANCES" name="Dances">
4358+ <buff ident="DANCE_0"/>
4359+ <buff ident="DANCE_1"/>
4360+ <buff ident="DANCE_2"/>
4361+ <buff ident="DANCE_3"/>
4362+ <buff ident="DANCE_4"/>
4363+ <buff ident="DANCE_5"/>
4364+ <buff ident="DANCE_6"/>
4365+ <buff ident="DANCE_7"/>
4366+ <buff ident="DANCE_8"/>
4367+ <buff ident="DANCE_9"/>
4368+ <buff ident="DANCE_10"/>
4369+ <buff ident="DANCE_11"/>
4370+ <buff ident="DANCE_12"/>
4371+ <buff ident="DANCE_13"/>
4372+ <buff ident="DANCE_14"/>
4373+ <buff ident="DANCE_15"/>
4374+ </buff_cat>
4375+
4376+ <buff_cat ident="BC_CHANTS" name="Chants">
4377+ <buff ident="CHANT_0"/>
4378+ <buff ident="CHANT_1"/>
4379+ <buff ident="CHANT_2"/>
4380+ <buff ident="CHANT_3"/>
4381+ <buff ident="CHANT_4"/>
4382+ <buff ident="CHANT_5"/>
4383+ <buff ident="CHANT_6"/>
4384+ <buff ident="CHANT_7"/>
4385+ <buff ident="CHANT_8"/>
4386+ <buff ident="CHANT_9"/>
4387+ <buff ident="CHANT_10"/>
4388+ <buff ident="CHANT_11"/>
4389+ </buff_cat>
4390+
4391+ <buff_cat ident="BC_DWARVEN" name="Dwarven">
4392+ <buff ident="DWARVEN_0"/>
4393+ <buff ident="DWARVEN_1"/>
4394+ <buff ident="DWARVEN_2"/>
4395+ <buff ident="DWARVEN_3"/>
4396+ <buff ident="DWARVEN_4"/>
4397+ <buff ident="DWARVEN_5"/>
4398+ </buff_cat>
4399+
4400+ <buff_cat ident="BC_RESIST" name="Resist">
4401+ <buff ident="RESIST_0"/>
4402+ <buff ident="RESIST_1"/>
4403+ <buff ident="RESIST_2"/>
4404+ <buff ident="RESIST_3"/>
4405+ <buff ident="RESIST_4"/>
4406+ <buff ident="RESIST_5"/>
4407+ <buff ident="RESIST_6"/>
4408+ <buff ident="RESIST_7"/>
4409+ <buff ident="RESIST_8"/>
4410+ <buff ident="RESIST_9"/>
4411+ <buff ident="RESIST_10"/>
4412+ <buff ident="RESIST_11"/>
4413+ <buff ident="RESIST_12"/>
4414+ <buff ident="RESIST_13"/>
4415+ </buff_cat>
4416+
4417+ <buff_cat ident="BC_SPECIAL" name="Special">
4418+ <buff ident="SPECIAL_0"/>
4419+ <buff ident="SPECIAL_1"/>
4420+ <buff ident="SPECIAL_2"/>
4421+ <buff ident="SPECIAL_3"/>
4422+ <buff ident="SPECIAL_4"/>
4423+ <buff ident="SPECIAL_5"/>
4424+ <buff ident="SPECIAL_6"/>
4425+ <buff ident="SPECIAL_7"/>
4426+ <buff ident="SPECIAL_8"/>
4427+ <buff ident="SPECIAL_9"/>
4428+ <buff ident="SPECIAL_10"/>
4429+ <buff ident="SPECIAL_11"/>
4430+ <buff ident="SPECIAL_12"/>
4431+ <buff ident="SPECIAL_13"/>
4432+ <buff ident="SPECIAL_14"/>
4433+ <buff ident="SPECIAL_15"/>
4434+ <buff ident="SPECIAL_16"/>
4435+ <buff ident="SPECIAL_17"/>
4436+ <buff ident="SPECIAL_18"/>
4437+ <buff ident="SPECIAL_19"/>
4438+ <buff ident="SPECIAL_20"/>
4439+ <buff ident="SPECIAL_21"/>
4440+ </buff_cat>
4441+
4442+ <buff_cat ident="BC_OVERLORD" name="Overlord">
4443+ <buff ident="OVERLORD_0"/>
4444+ <buff ident="OVERLORD_1"/>
4445+ <buff ident="OVERLORD_2"/>
4446+ <buff ident="OVERLORD_3"/>
4447+ <buff ident="OVERLORD_4"/>
4448+ <buff ident="OVERLORD_5"/>
4449+ <buff ident="OVERLORD_6"/>
4450+ <buff ident="OVERLORD_7"/>
4451+ <buff ident="OVERLORD_8"/>
4452+ <buff ident="OVERLORD_9"/>
4453+ </buff_cat>
4454+</buff_cats>
4455\ No newline at end of file
4456Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/voiced_buffer.xsd
4457IDEA additional info:
4458Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
4459<+>UTF-8
4460===================================================================
4461--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/voiced_buffer.xsd (date 1601235046912)
4462+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/voiced_buffer.xsd (date 1601235046912)
4463@@ -0,0 +1,19 @@
4464+<?xml version="1.0" encoding="UTF-8"?>
4465+<schema xmlns="http://www.w3.org/2001/XMLSchema">
4466+ <element name="voiced_buffer">
4467+ <complexType>
4468+ <sequence maxOccurs="1" minOccurs="1">
4469+ <element name="buff_cat" maxOccurs="unbounded" minOccurs="0">
4470+ <complexType>
4471+ <attribute name="ident" type="NCName" use="required"/>
4472+ <attribute name="is_preset" type="boolean" use="required"/>
4473+ </complexType>
4474+ </element>
4475+ </sequence>
4476+ <attribute name="enabled" type="boolean" use="required"/>
4477+ <attribute name="required_item" type="integer" use="optional"/>
4478+ <attribute name="can_heal" type="boolean" use="required"/>
4479+ <attribute name="can_cancel" type="boolean" use="required"/>
4480+ </complexType>
4481+ </element>
4482+</schema>
4483\ No newline at end of file
4484Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/item_requirements.xsd
4485IDEA additional info:
4486Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
4487<+>UTF-8
4488===================================================================
4489--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/item_requirements.xsd (date 1601235046907)
4490+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/item_requirements.xsd (date 1601235046907)
4491@@ -0,0 +1,16 @@
4492+<?xml version="1.0" encoding="UTF-8"?>
4493+<schema xmlns="http://www.w3.org/2001/XMLSchema">
4494+ <element name="item_requirements">
4495+ <complexType>
4496+ <sequence maxOccurs="1" minOccurs="1">
4497+ <element name="item" maxOccurs="unbounded" minOccurs="0">
4498+ <complexType>
4499+ <attribute name="ident" type="ID" use="required"/>
4500+ <attribute name="id" type="positiveInteger" use="required"/>
4501+ <attribute name="amount" type="positiveInteger" use="required"/>
4502+ </complexType>
4503+ </element>
4504+ </sequence>
4505+ </complexType>
4506+ </element>
4507+</schema>
4508\ No newline at end of file
4509Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/buffs.xsd
4510IDEA additional info:
4511Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
4512<+>UTF-8
4513===================================================================
4514--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/buffs.xsd (date 1601235046903)
4515+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/buffs.xsd (date 1601235046903)
4516@@ -0,0 +1,31 @@
4517+<?xml version="1.0" encoding="UTF-8"?>
4518+<schema xmlns="http://www.w3.org/2001/XMLSchema">
4519+ <element name="buffs">
4520+ <complexType>
4521+ <sequence maxOccurs="1" minOccurs="1">
4522+ <element name="buff" maxOccurs="unbounded" minOccurs="0">
4523+ <complexType>
4524+ <sequence maxOccurs="1" minOccurs="1">
4525+ <element name="item" maxOccurs="unbounded" minOccurs="0">
4526+ <complexType>
4527+ <attribute name="ident" type="NCName" use="required"/>
4528+ </complexType>
4529+ </element>
4530+ </sequence>
4531+ <attribute name="ident" type="ID" use="required"/>
4532+ <attribute name="skill_id" type="positiveInteger" use="required"/>
4533+ <attribute name="skill_level" type="positiveInteger" use="required"/>
4534+ <attribute name="type" use="required">
4535+ <simpleType>
4536+ <restriction base="string">
4537+ <enumeration value="BUFF"/>
4538+ <enumeration value="DANCE"/>
4539+ </restriction>
4540+ </simpleType>
4541+ </attribute>
4542+ </complexType>
4543+ </element>
4544+ </sequence>
4545+ </complexType>
4546+ </element>
4547+</schema>
4548\ No newline at end of file
4549Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/buffer_npcs.xsd
4550IDEA additional info:
4551Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
4552<+>UTF-8
4553===================================================================
4554--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/buffer_npcs.xsd (date 1601235046895)
4555+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/buffer_npcs.xsd (date 1601235046895)
4556@@ -0,0 +1,24 @@
4557+<?xml version="1.0" encoding="UTF-8"?>
4558+<schema xmlns="http://www.w3.org/2001/XMLSchema">
4559+ <element name="buffer_npcs">
4560+ <complexType>
4561+ <sequence maxOccurs="1" minOccurs="1">
4562+ <element name="buffer_npc" maxOccurs="unbounded" minOccurs="0">
4563+ <complexType>
4564+ <sequence maxOccurs="1" minOccurs="1">
4565+ <element name="buff_cat" maxOccurs="unbounded" minOccurs="0">
4566+ <complexType>
4567+ <attribute name="ident" type="NCName" use="required"/>
4568+ <attribute name="is_preset" type="boolean" use="required"/>
4569+ </complexType>
4570+ </element>
4571+ </sequence>
4572+ <attribute name="id" type="positiveInteger" use="required"/>
4573+ <attribute name="can_heal" type="boolean" use="required"/>
4574+ <attribute name="can_cancel" type="boolean" use="required"/>
4575+ </complexType>
4576+ </element>
4577+ </sequence>
4578+ </complexType>
4579+ </element>
4580+</schema>
4581\ No newline at end of file
4582Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/buffer.xsd
4583IDEA additional info:
4584Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
4585<+>UTF-8
4586===================================================================
4587--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/buffer.xsd (date 1601235046891)
4588+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/buffer.xsd (date 1601235046891)
4589@@ -0,0 +1,20 @@
4590+<?xml version="1.0" encoding="UTF-8"?>
4591+<schema xmlns="http://www.w3.org/2001/XMLSchema">
4592+ <element name="buffer">
4593+ <complexType>
4594+ <attribute name="dialog_type" use="required">
4595+ <simpleType>
4596+ <restriction base="string">
4597+ <enumeration value="NPC"/>
4598+ <enumeration value="TUTORIAL"/>
4599+ <enumeration value="COMMUNITY"/>
4600+ </restriction>
4601+ </simpleType>
4602+ </attribute>
4603+ <attribute name="heal_cooldown" type="positiveInteger" use="required"/>
4604+ <attribute name="max_unique_lists" type="positiveInteger" use="required"/>
4605+ <attribute name="unique_max_buffs" type="positiveInteger" use="required"/>
4606+ <attribute name="unique_max_songs_dances" type="positiveInteger" use="required"/>
4607+ </complexType>
4608+ </element>
4609+</schema>
4610\ No newline at end of file
4611Index: L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/buff_categories.xsd
4612IDEA additional info:
4613Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
4614<+>UTF-8
4615===================================================================
4616--- L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/buff_categories.xsd (date 1601235046887)
4617+++ L2J_Mobius_Classic_Interlude/dist/game/data/scripts/custom/Buffer/data/xml/xsd/buff_categories.xsd (date 1601235046887)
4618@@ -0,0 +1,22 @@
4619+<?xml version="1.0" encoding="UTF-8"?>
4620+<schema xmlns="http://www.w3.org/2001/XMLSchema">
4621+ <element name="buff_cats">
4622+ <complexType>
4623+ <sequence maxOccurs="1" minOccurs="1">
4624+ <element name="buff_cat" maxOccurs="unbounded" minOccurs="0">
4625+ <complexType>
4626+ <sequence maxOccurs="1" minOccurs="1">
4627+ <element name="buff" maxOccurs="unbounded" minOccurs="0">
4628+ <complexType>
4629+ <attribute name="ident" type="NCName" use="required"/>
4630+ </complexType>
4631+ </element>
4632+ </sequence>
4633+ <attribute name="ident" type="ID" use="required"/>
4634+ <attribute name="name" type="string" use="required"/>
4635+ </complexType>
4636+ </element>
4637+ </sequence>
4638+ </complexType>
4639+ </element>
4640+</schema>
4641\ No newline at end of file
4642diff --git L2J_Mobius_Classic_Interlude/dist/game/config/Custom/ShemeBuffer.ini L2J_Mobius_Classic_Interlude/dist/game/config/Custom/SchemeBuffer.ini
4643rename from L2J_Mobius_Classic_Interlude/dist/game/config/Custom/ShemeBuffer.ini
4644rename to L2J_Mobius_Classic_Interlude/dist/game/config/Custom/SchemeBuffer.ini
4645