Advertisement
Guest User

Untitled

a guest
Nov 23rd, 2014
470
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 92.81 KB | None | 0 0
  1. Index: java/l2f/gameserver/handler/voicecommands/VoicedCommandHandler.java
  2. ===================================================================
  3. --- java/l2f/gameserver/handler/voicecommands/VoicedCommandHandler.java (revision 109)
  4. +++ java/l2f/gameserver/handler/voicecommands/VoicedCommandHandler.java (working copy)
  5. @@ -10,6 +10,7 @@
  6. import l2f.gameserver.handler.voicecommands.impl.Debug;
  7. import l2f.gameserver.handler.voicecommands.impl.Hellbound;
  8. import l2f.gameserver.handler.voicecommands.impl.Offline;
  9. +import l2f.gameserver.handler.voicecommands.impl.OfflineBuffs;
  10. import l2f.gameserver.handler.voicecommands.impl.Online;
  11. import l2f.gameserver.handler.voicecommands.impl.Password;
  12. import l2f.gameserver.handler.voicecommands.impl.RefferalSystem;
  13. @@ -25,14 +26,14 @@
  14. public class VoicedCommandHandler extends AbstractHolder
  15. {
  16. private static final VoicedCommandHandler _instance = new VoicedCommandHandler();
  17. -
  18. +
  19. public static VoicedCommandHandler getInstance()
  20. {
  21. return _instance;
  22. }
  23. -
  24. +
  25. private final Map<String, IVoicedCommandHandler> _datatable = new HashMap<>();
  26. -
  27. +
  28. private VoicedCommandHandler()
  29. {
  30. registerVoicedCommandHandler(new Atod());
  31. @@ -52,8 +53,9 @@
  32. registerVoicedCommandHandler(new ReportBot());
  33. registerVoicedCommandHandler(new res());
  34. registerVoicedCommandHandler(new RewardVote());
  35. + registerVoicedCommandHandler(new OfflineBuffs());
  36. }
  37. -
  38. +
  39. public void registerVoicedCommandHandler(IVoicedCommandHandler handler)
  40. {
  41. String[] ids = handler.getVoicedCommandList();
  42. @@ -62,7 +64,7 @@
  43. _datatable.put(element, handler);
  44. }
  45. }
  46. -
  47. +
  48. public IVoicedCommandHandler getVoicedCommandHandler(String voicedCommand)
  49. {
  50. String command = voicedCommand;
  51. @@ -70,16 +72,16 @@
  52. {
  53. command = voicedCommand.substring(0, voicedCommand.indexOf(" "));
  54. }
  55. -
  56. +
  57. return _datatable.get(command);
  58. }
  59. -
  60. +
  61. @Override
  62. public int size()
  63. {
  64. return _datatable.size();
  65. }
  66. -
  67. +
  68. @Override
  69. public void clear()
  70. {
  71. Index: java/l2f/gameserver/Config.java
  72. ===================================================================
  73. --- java/l2f/gameserver/Config.java (revision 109)
  74. +++ java/l2f/gameserver/Config.java (working copy)
  75. @@ -103,7 +103,7 @@
  76. public static final String DEFENSE_TOWNS_CONFIG_FILE = "config/events/DefenseTowns.properties";
  77. public static final String VIKTORINA_CONFIG_FILE = "config/events/Victorina.properties";
  78. public static final String PVP_MOD_CONFIG_FILE = "config/mod/PvPmod.properties";
  79. -
  80. + public static final String BUFF_STORE_CONFIG_FILE = "config/OfflineBuffer.properties";
  81. /** Community PvP */
  82. public static final String BOARD_MANAGER_CONFIG_FILE = "config/CommunityPvP/board_manager.properties";
  83.  
  84. @@ -1729,7 +1729,16 @@
  85.  
  86. public static boolean LOAD_CUSTOM_SPAWN;
  87. public static boolean SAVE_GM_SPAWN;
  88. -
  89. + public static boolean BUFF_STORE_MP_ENABLED;
  90. + public static boolean BUFF_STORE_ENABLED;
  91. + public static double BUFF_STORE_MP_CONSUME_MULTIPLIER;
  92. + public static boolean BUFF_STORE_ITEM_CONSUME_ENABLED;
  93. + public static int BUFF_STORE_NAME_COLOR;
  94. + public static int BUFF_STORE_TITLE_COLOR;
  95. + public static int BUFF_STORE_OFFLINE_NAME_COLOR;
  96. + public static List<Integer> BUFF_STORE_ALLOWED_CLASS_LIST;
  97. + public static List<Integer> BUFF_STORE_FORBIDDEN_SKILL_LIST;
  98. +
  99. public static void loadServerConfig()
  100. {
  101. ExProperties serverSettings = load(CONFIGURATION_FILE);
  102. @@ -3699,7 +3708,40 @@
  103. EVENT_CtF_DISALLOWED_SKILLS = eventCaptureTheFlagSettings.getProperty("CtF_DisallowedSkills", "").trim().replaceAll(" ", "").split(";");
  104.  
  105. }
  106. -
  107. +
  108. + public static void loadBuffStoreConfig()
  109. + {
  110. + ExProperties buffStoreConfig = load(BUFF_STORE_CONFIG_FILE);
  111. +
  112. + BUFF_STORE_ENABLED = buffStoreConfig.getProperty("BuffStoreEnabled", false);
  113. + BUFF_STORE_MP_ENABLED = buffStoreConfig.getProperty("BuffStoreMpEnabled", true);
  114. + BUFF_STORE_MP_CONSUME_MULTIPLIER = buffStoreConfig.getProperty("BuffStoreMpConsumeMultiplier", 1.0D);
  115. + BUFF_STORE_ITEM_CONSUME_ENABLED = buffStoreConfig.getProperty("BuffStoreItemConsumeEnabled", true);
  116. +
  117. + BUFF_STORE_NAME_COLOR = Integer.decode("0x" + buffStoreConfig.getProperty("BuffStoreNameColor", "808080")).intValue();
  118. + BUFF_STORE_TITLE_COLOR = Integer.decode("0x" + buffStoreConfig.getProperty("BuffStoreTitleColor", "808080")).intValue();
  119. + BUFF_STORE_OFFLINE_NAME_COLOR = Integer.decode("0x" + buffStoreConfig.getProperty("BuffStoreOfflineNameColor", "808080")).intValue();
  120. +
  121. + String[] classes = buffStoreConfig.getProperty("BuffStoreAllowedClassList", "").split(",");
  122. + BUFF_STORE_ALLOWED_CLASS_LIST = new ArrayList();
  123. + if (classes.length > 0)
  124. + {
  125. + for (String classId : classes)
  126. + {
  127. + BUFF_STORE_ALLOWED_CLASS_LIST.add(Integer.valueOf(Integer.parseInt(classId)));
  128. + }
  129. + }
  130. + String[] skills = buffStoreConfig.getProperty("BuffStoreForbiddenSkillList", "").split(",");
  131. + BUFF_STORE_FORBIDDEN_SKILL_LIST = new ArrayList();
  132. + if (skills.length > 0)
  133. + {
  134. + for (String skillId : skills)
  135. + {
  136. + BUFF_STORE_FORBIDDEN_SKILL_LIST.add(Integer.valueOf(Integer.parseInt(skillId)));
  137. + }
  138. + }
  139. + }
  140. +
  141. public static void load()
  142. {
  143. loadServerConfig();
  144. @@ -3745,6 +3787,7 @@
  145. loadAcc_moveConfig();
  146. loadTeamVSTeamSettings();
  147. loadCaptureTheFlagSettings();
  148. + loadBuffStoreConfig();
  149. }
  150.  
  151. private Config()
  152. Index: java/l2f/gameserver/model/base/ClassId.java
  153. ===================================================================
  154. --- java/l2f/gameserver/model/base/ClassId.java (revision 109)
  155. +++ java/l2f/gameserver/model/base/ClassId.java (working copy)
  156. @@ -1,20 +1,21 @@
  157. package l2f.gameserver.model.base;
  158.  
  159. +import l2f.gameserver.model.Player;
  160. +import l2f.gameserver.network.serverpackets.components.CustomMessage;
  161. +
  162. /**
  163. - * This class defines all classes (ex : human fighter, darkFighter...) that a player can chose.<BR><BR>
  164. - *
  165. - * Data :<BR><BR>
  166. - * <li>id : The Identifier of the class</li>
  167. - * <li>isMage : True if the class is a mage class</li>
  168. - * <li>race : The race of this class</li>
  169. - * <li>parent : The parent ClassId for male or null if this class is the root</li>
  170. - * <li>parent2 : The parent2 ClassId for female or null if parent2 like parent</li>
  171. - * <li>level : The child level of this Class</li><BR><BR>
  172. + * This class defines all classes (ex : human fighter, darkFighter...) that a player can chose.<BR>
  173. + * <BR>
  174. + * Data :<BR>
  175. + * <BR>
  176. + * <li>id : The Identifier of the class</li> <li>isMage : True if the class is a mage class</li> <li>race : The race of this class</li> <li>parent : The parent ClassId for male or null if this class is the root</li> <li>parent2 : The parent2 ClassId for female or null if parent2 like parent</li> <li>
  177. + * level : The child level of this Class</li><BR>
  178. + * <BR>
  179. */
  180. public enum ClassId
  181. {
  182. fighter(0, false, Race.human, null, null, 1, null),
  183. -
  184. +
  185. warrior(1, false, Race.human, fighter, null, 2, null),
  186. gladiator(2, false, Race.human, warrior, null, 3, ClassType2.Warrior),
  187. warlord(3, false, Race.human, warrior, null, 3, ClassType2.Warrior),
  188. @@ -24,7 +25,7 @@
  189. rogue(7, false, Race.human, fighter, null, 2, null),
  190. treasureHunter(8, false, Race.human, rogue, null, 3, ClassType2.Rogue),
  191. hawkeye(9, false, Race.human, rogue, null, 3, ClassType2.Rogue),
  192. -
  193. +
  194. mage(10, true, Race.human, null, null, 1, null),
  195. wizard(11, true, Race.human, mage, null, 2, null),
  196. sorceror(12, true, Race.human, wizard, null, 3, ClassType2.Wizard),
  197. @@ -33,7 +34,7 @@
  198. cleric(15, true, Race.human, mage, null, 2, null),
  199. bishop(16, true, Race.human, cleric, null, 3, ClassType2.Healer),
  200. prophet(17, true, Race.human, cleric, null, 3, ClassType2.Enchanter),
  201. -
  202. +
  203. elvenFighter(18, false, Race.elf, null, null, 1, null),
  204. elvenKnight(19, false, Race.elf, elvenFighter, null, 2, null),
  205. templeKnight(20, false, Race.elf, elvenKnight, null, 3, ClassType2.Knight),
  206. @@ -41,14 +42,14 @@
  207. elvenScout(22, false, Race.elf, elvenFighter, null, 2, null),
  208. plainsWalker(23, false, Race.elf, elvenScout, null, 3, ClassType2.Rogue),
  209. silverRanger(24, false, Race.elf, elvenScout, null, 3, ClassType2.Rogue),
  210. -
  211. +
  212. elvenMage(25, true, Race.elf, null, null, 1, null),
  213. elvenWizard(26, true, Race.elf, elvenMage, null, 2, null),
  214. spellsinger(27, true, Race.elf, elvenWizard, null, 3, ClassType2.Wizard),
  215. elementalSummoner(28, true, Race.elf, elvenWizard, null, 3, ClassType2.Summoner),
  216. oracle(29, true, Race.elf, elvenMage, null, 2, null),
  217. elder(30, true, Race.elf, oracle, null, 3, ClassType2.Healer),
  218. -
  219. +
  220. darkFighter(31, false, Race.darkelf, null, null, 1, null),
  221. palusKnight(32, false, Race.darkelf, darkFighter, null, 2, null),
  222. shillienKnight(33, false, Race.darkelf, palusKnight, null, 3, ClassType2.Knight),
  223. @@ -56,36 +57,33 @@
  224. assassin(35, false, Race.darkelf, darkFighter, null, 2, null),
  225. abyssWalker(36, false, Race.darkelf, assassin, null, 3, ClassType2.Rogue),
  226. phantomRanger(37, false, Race.darkelf, assassin, null, 3, ClassType2.Rogue),
  227. -
  228. +
  229. darkMage(38, true, Race.darkelf, null, null, 1, null),
  230. darkWizard(39, true, Race.darkelf, darkMage, null, 2, null),
  231. spellhowler(40, true, Race.darkelf, darkWizard, null, 3, ClassType2.Wizard),
  232. phantomSummoner(41, true, Race.darkelf, darkWizard, null, 3, ClassType2.Summoner),
  233. shillienOracle(42, true, Race.darkelf, darkMage, null, 2, null),
  234. shillienElder(43, true, Race.darkelf, shillienOracle, null, 3, ClassType2.Healer),
  235. -
  236. +
  237. orcFighter(44, false, Race.orc, null, null, 1, null),
  238. orcRaider(45, false, Race.orc, orcFighter, null, 2, null),
  239. destroyer(46, false, Race.orc, orcRaider, null, 3, ClassType2.Warrior),
  240. orcMonk(47, false, Race.orc, orcFighter, null, 2, null),
  241. tyrant(48, false, Race.orc, orcMonk, null, 3, ClassType2.Warrior),
  242. -
  243. +
  244. orcMage(49, true, Race.orc, null, null, 1, null),
  245. orcShaman(50, true, Race.orc, orcMage, null, 2, null),
  246. overlord(51, true, Race.orc, orcShaman, null, 3, ClassType2.Enchanter),
  247. warcryer(52, true, Race.orc, orcShaman, null, 3, ClassType2.Enchanter),
  248. -
  249. +
  250. dwarvenFighter(53, false, Race.dwarf, null, null, 1, null),
  251. scavenger(54, false, Race.dwarf, dwarvenFighter, null, 2, null),
  252. bountyHunter(55, false, Race.dwarf, scavenger, null, 3, ClassType2.Warrior),
  253. artisan(56, false, Race.dwarf, dwarvenFighter, null, 2, null),
  254. warsmith(57, false, Race.dwarf, artisan, null, 3, ClassType2.Warrior),
  255. -
  256. +
  257. /*
  258. - * Dummy Entries (id's already in decimal format)
  259. - * btw FU NCSoft for the amount of work you put me
  260. - * through to do this!!
  261. - * <START>
  262. + * Dummy Entries (id's already in decimal format) btw FU NCSoft for the amount of work you put me through to do this!! <START>
  263. */
  264. dummyEntry1(58, false, null, null, null, 0, null),
  265. dummyEntry2(59, false, null, null, null, 0, null),
  266. @@ -118,10 +116,9 @@
  267. dummyEntry29(86, false, null, null, null, 0, null),
  268. dummyEntry30(87, false, null, null, null, 0, null),
  269. /*
  270. - * <END>
  271. - * Of Dummy entries
  272. + * <END> Of Dummy entries
  273. */
  274. -
  275. +
  276. duelist(88, false, Race.human, gladiator, null, 4, ClassType2.Warrior),
  277. dreadnought(89, false, Race.human, warlord, null, 4, ClassType2.Warrior),
  278. phoenixKnight(90, false, Race.human, paladin, null, 4, ClassType2.Knight),
  279. @@ -133,7 +130,7 @@
  280. arcanaLord(96, true, Race.human, warlock, null, 4, ClassType2.Summoner),
  281. cardinal(97, true, Race.human, bishop, null, 4, ClassType2.Healer),
  282. hierophant(98, true, Race.human, prophet, null, 4, ClassType2.Enchanter),
  283. -
  284. +
  285. evaTemplar(99, false, Race.elf, templeKnight, null, 4, ClassType2.Knight),
  286. swordMuse(100, false, Race.elf, swordSinger, null, 4, ClassType2.Enchanter),
  287. windRider(101, false, Race.elf, plainsWalker, null, 4, ClassType2.Rogue),
  288. @@ -141,7 +138,7 @@
  289. mysticMuse(103, true, Race.elf, spellsinger, null, 4, ClassType2.Wizard),
  290. elementalMaster(104, true, Race.elf, elementalSummoner, null, 4, ClassType2.Summoner),
  291. evaSaint(105, true, Race.elf, elder, null, 4, ClassType2.Healer),
  292. -
  293. +
  294. shillienTemplar(106, false, Race.darkelf, shillienKnight, null, 4, ClassType2.Knight),
  295. spectralDancer(107, false, Race.darkelf, bladedancer, null, 4, ClassType2.Enchanter),
  296. ghostHunter(108, false, Race.darkelf, abyssWalker, null, 4, ClassType2.Rogue),
  297. @@ -149,20 +146,20 @@
  298. stormScreamer(110, true, Race.darkelf, spellhowler, null, 4, ClassType2.Wizard),
  299. spectralMaster(111, true, Race.darkelf, phantomSummoner, null, 4, ClassType2.Summoner),
  300. shillienSaint(112, true, Race.darkelf, shillienElder, null, 4, ClassType2.Healer),
  301. -
  302. +
  303. titan(113, false, Race.orc, destroyer, null, 4, ClassType2.Warrior),
  304. grandKhauatari(114, false, Race.orc, tyrant, null, 4, ClassType2.Warrior),
  305. dominator(115, true, Race.orc, overlord, null, 4, ClassType2.Enchanter),
  306. doomcryer(116, true, Race.orc, warcryer, null, 4, ClassType2.Enchanter),
  307. -
  308. +
  309. fortuneSeeker(117, false, Race.dwarf, bountyHunter, null, 4, ClassType2.Warrior),
  310. maestro(118, false, Race.dwarf, warsmith, null, 4, ClassType2.Warrior),
  311. -
  312. +
  313. dummyEntry31(119, false, null, null, null, 0, null),
  314. dummyEntry32(120, false, null, null, null, 0, null),
  315. dummyEntry33(121, false, null, null, null, 0, null),
  316. dummyEntry34(122, false, null, null, null, 0, null),
  317. -
  318. +
  319. /**
  320. * Kamael
  321. */
  322. @@ -180,30 +177,38 @@
  323. trickster(134, false, Race.kamael, arbalester, null, 4, ClassType2.Rogue),
  324. inspector(135, false, Race.kamael, trooper, warder, 3, ClassType2.Enchanter),
  325. judicator(136, false, Race.kamael, inspector, null, 4, ClassType2.Enchanter);
  326. -
  327. +
  328. public static final ClassId[] VALUES = values();
  329. -
  330. +
  331. /** The Identifier of the Class<?> */
  332. private final int _id;
  333. -
  334. +
  335. /** True if the class is a mage class */
  336. private final boolean _isMage;
  337. -
  338. +
  339. /** The Race object of the class */
  340. private final Race _race;
  341. -
  342. +
  343. /** The parent ClassId for male or null if this class is a root */
  344. private final ClassId _parent;
  345. -
  346. +
  347. /** The parent2 ClassId for female or null if parent2 class is parent */
  348. private final ClassId _parent2;
  349. -
  350. +
  351. private final ClassType2 _type2;
  352. -
  353. +
  354. private final int _level;
  355. -
  356. +
  357. /**
  358. - * Constructor<?> of ClassId.<BR><BR>
  359. + * Constructor<?> of ClassId.<BR>
  360. + * <BR>
  361. + * @param id
  362. + * @param isMage
  363. + * @param race
  364. + * @param parent
  365. + * @param parent2
  366. + * @param level
  367. + * @param classType2
  368. */
  369. private ClassId(int id, boolean isMage, Race race, ClassId parent, ClassId parent2, int level, ClassType2 classType2)
  370. {
  371. @@ -215,83 +220,102 @@
  372. _level = level;
  373. _type2 = classType2;
  374. }
  375. -
  376. +
  377. /**
  378. - * Return the Identifier of the Class.<BR><BR>
  379. + * Return the Identifier of the Class.<BR>
  380. + * <BR>
  381. + * @return
  382. */
  383. public final int getId()
  384. {
  385. return _id;
  386. }
  387. -
  388. +
  389. /**
  390. - * Return True if the class is a mage class.<BR><BR>
  391. + * Return True if the class is a mage class.<BR>
  392. + * <BR>
  393. + * @return
  394. */
  395. public final boolean isMage()
  396. {
  397. return _isMage;
  398. }
  399. -
  400. +
  401. /**
  402. - * Return the Race object of the class.<BR><BR>
  403. + * Return the Race object of the class.<BR>
  404. + * <BR>
  405. + * @return
  406. */
  407. public final Race getRace()
  408. {
  409. return _race;
  410. }
  411. -
  412. +
  413. /**
  414. - * Return True if this Class<?> is a child of the selected ClassId.<BR><BR>
  415. - *
  416. + * Return True if this Class<?> is a child of the selected ClassId.<BR>
  417. + * <BR>
  418. * @param cid The parent ClassId to check
  419. + * @return
  420. */
  421. public final boolean childOf(ClassId cid)
  422. {
  423. - if(_parent == null)
  424. + if (_parent == null)
  425. + {
  426. return false;
  427. -
  428. - if(_parent == cid || _parent2 == cid)
  429. + }
  430. +
  431. + if ((_parent == cid) || (_parent2 == cid))
  432. + {
  433. return true;
  434. -
  435. + }
  436. +
  437. return _parent.childOf(cid);
  438. -
  439. +
  440. }
  441. -
  442. +
  443. /**
  444. - * Return True if this Class<?> is equal to the selected ClassId or a child of the selected ClassId.<BR><BR>
  445. - *
  446. + * Return True if this Class<?> is equal to the selected ClassId or a child of the selected ClassId.<BR>
  447. + * <BR>
  448. * @param cid The parent ClassId to check
  449. + * @return
  450. */
  451. public final boolean equalsOrChildOf(ClassId cid)
  452. {
  453. - return this == cid || childOf(cid);
  454. + return (this == cid) || childOf(cid);
  455. }
  456. -
  457. +
  458. /**
  459. - * Return the child level of this Class<?> (0=root, 1=child leve 1...).<BR><BR>
  460. - *
  461. - * @param cid The parent ClassId to check
  462. + * Return the child level of this Class<?> (0=root, 1=child leve 1...).<BR>
  463. + * <BR>
  464. + * @return
  465. */
  466. public final int level()
  467. {
  468. - if(_parent == null)
  469. + if (_parent == null)
  470. + {
  471. return 0;
  472. -
  473. + }
  474. +
  475. return 1 + _parent.level();
  476. }
  477. -
  478. +
  479. public final ClassId getParent(int sex)
  480. {
  481. - return sex == 0 || _parent2 == null ? _parent : _parent2;
  482. + return (sex == 0) || (_parent2 == null) ? _parent : _parent2;
  483. }
  484. -
  485. +
  486. public final int getLevel()
  487. {
  488. return _level;
  489. }
  490. -
  491. +
  492. public ClassType2 getType2()
  493. {
  494. return _type2;
  495. }
  496. +
  497. + public final String getName(Player player)
  498. + {
  499. + return new CustomMessage("l2s.gameserver.model.base.ClassId.name." + getId(), player, new Object[0]).toString();
  500. + }
  501. }
  502. \ No newline at end of file
  503. Index: dist/gameserver/data/zone/buff_store_only.xml
  504. ===================================================================
  505. --- dist/gameserver/data/zone/buff_store_only.xml (revision 0)
  506. +++ dist/gameserver/data/zone/buff_store_only.xml (working copy)
  507. @@ -0,0 +1,44 @@
  508. +<?xml version='1.0' encoding='utf-8'?>
  509. +<!DOCTYPE list SYSTEM "zone.dtd">
  510. +<list>
  511. + <zone name="[aden_buff_store_only_1]" type="buff_store_only">
  512. + <polygon>
  513. + <coords loc="147699 27395 -2260 -2180" />
  514. + <coords loc="148579 27394 -2260 -2180" />
  515. + <coords loc="148570 26577 -2260 -2180" />
  516. + <coords loc="147709 26572 -2260 -2180" />
  517. + </polygon>
  518. + </zone>
  519. + <zone name="[giran_buff_store_only_1]" type="buff_store_only">
  520. + <polygon>
  521. + <coords loc="83895 148084 -3460 -3360" />
  522. + <coords loc="83976 148080 -3460 -3360" />
  523. + <coords loc="83976 148002 -3460 -3360" />
  524. + <coords loc="84255 147995 -3460 -3360" />
  525. + <coords loc="84262 148074 -3460 -3360" />
  526. + <coords loc="84341 148073 -3460 -3360" />
  527. + <coords loc="84346 148348 -3460 -3360" />
  528. + <coords loc="84263 148356 -3460 -3360" />
  529. + <coords loc="84262 148467 -3460 -3360" />
  530. + <coords loc="83989 148461 -3460 -3360" />
  531. + <coords loc="83979 148359 -3460 -3360" />
  532. + <coords loc="83895 148360 -3460 -3360" />
  533. + </polygon>
  534. + </zone>
  535. + <zone name="[giran_buff_store_only_2]" type="buff_store_only">
  536. + <polygon>
  537. + <coords loc="83894 149163 -3460 -3360" />
  538. + <coords loc="83979 149163 -3460 -3360" />
  539. + <coords loc="83977 149241 -3460 -3360" />
  540. + <coords loc="84265 149243 -3460 -3360" />
  541. + <coords loc="84258 149164 -3460 -3360" />
  542. + <coords loc="84340 149159 -3460 -3360" />
  543. + <coords loc="84340 148886 -3460 -3360" />
  544. + <coords loc="84264 148879 -3460 -3360" />
  545. + <coords loc="84258 148781 -3460 -3360" />
  546. + <coords loc="83992 148781 -3460 -3360" />
  547. + <coords loc="83993 148869 -3460 -3360" />
  548. + <coords loc="83896 148878 -3460 -3360" />
  549. + </polygon>
  550. + </zone>
  551. +</list>
  552. \ No newline at end of file
  553. Index: java/l2f/gameserver/GameServer.java
  554. ===================================================================
  555. --- java/l2f/gameserver/GameServer.java (revision 109)
  556. +++ java/l2f/gameserver/GameServer.java (working copy)
  557. @@ -68,6 +68,7 @@
  558. import l2f.gameserver.tables.FakePlayersTable;
  559. import l2f.gameserver.tables.FishTable;
  560. import l2f.gameserver.tables.LevelUpTable;
  561. +import l2f.gameserver.tables.OfflineBuffersTable;
  562. import l2f.gameserver.tables.PetSkillsTable;
  563. import l2f.gameserver.tables.SkillTreeTable;
  564. import l2f.gameserver.taskmanager.ItemsAutoDestroy;
  565. @@ -85,7 +86,7 @@
  566. {
  567. public static final int AUTH_SERVER_PROTOCOL = 2;
  568. private static final Logger _log = LoggerFactory.getLogger(GameServer.class);
  569. -
  570. +
  571. public class GameServerListenerList extends ListenerList<GameServer>
  572. {
  573. public void onStart()
  574. @@ -98,7 +99,7 @@
  575. }
  576. }
  577. }
  578. -
  579. +
  580. public void onShutdown()
  581. {
  582. for (Listener<GameServer> listener : getListeners())
  583. @@ -110,31 +111,31 @@
  584. }
  585. }
  586. }
  587. -
  588. +
  589. public static GameServer _instance;
  590. -
  591. +
  592. private final SelectorThread<GameClient> _selectorThreads[];
  593. private TelnetServer statusServer;
  594. private final Version version;
  595. private final GameServerListenerList _listeners;
  596. -
  597. +
  598. private final int _serverStarted;
  599. -
  600. +
  601. public SelectorThread<GameClient>[] getSelectorThreads()
  602. {
  603. return _selectorThreads;
  604. }
  605. -
  606. +
  607. public int time()
  608. {
  609. return (int) (System.currentTimeMillis() / 1000);
  610. }
  611. -
  612. +
  613. public int uptime()
  614. {
  615. return time() - _serverStarted;
  616. }
  617. -
  618. +
  619. @SuppressWarnings("unchecked")
  620. public GameServer() throws Exception
  621. {
  622. @@ -142,9 +143,9 @@
  623. _instance = this;
  624. _serverStarted = time();
  625. _listeners = new GameServerListenerList();
  626. -
  627. +
  628. new File("./log/").mkdir();
  629. -
  630. +
  631. version = new Version(GameServer.class);
  632. // Initialize config
  633. Config.load();
  634. @@ -153,16 +154,16 @@
  635. // Initialize database
  636. Class.forName(Config.DATABASE_DRIVER).newInstance();
  637. DatabaseFactory.getInstance().getConnection().close();
  638. -
  639. +
  640. IdFactory _idFactory = IdFactory.getInstance();
  641. if (!_idFactory.isInitialized())
  642. {
  643. _log.error("Could not read object IDs from DB. Please Check Your Data.");
  644. throw new Exception("Could not initialize the ID factory");
  645. }
  646. -
  647. +
  648. CacheManager.getInstance();
  649. -
  650. +
  651. ThreadPoolManager.getInstance();
  652. Scripts.getInstance();
  653. GeoEngine.load();
  654. @@ -223,45 +224,48 @@
  655. ResidenceHolder.getInstance().callInit();
  656. EventHolder.getInstance().callInit();
  657. _log.info("==================================================");
  658. -
  659. +
  660. CastleManorManager.getInstance();
  661. -
  662. +
  663. Runtime.getRuntime().addShutdownHook(Shutdown.getInstance());
  664. -
  665. +
  666. _log.info("IdFactory: Free ObjectID's remaining: " + IdFactory.getInstance().size());
  667. -
  668. +
  669. CoupleManager.getInstance();
  670. -
  671. +
  672. if (Config.ALT_FISH_CHAMPIONSHIP_ENABLED)
  673. {
  674. FishingChampionShipManager.getInstance();
  675. }
  676. -
  677. +
  678. HellboundManager.getInstance();
  679. -
  680. +
  681. NaiaTowerManager.getInstance();
  682. NaiaCoreManager.getInstance();
  683. -
  684. +
  685. SoDManager.getInstance();
  686. SoIManager.getInstance();
  687. BloodAltarManager.getInstance();
  688. -
  689. +
  690. MiniGameScoreManager.getInstance();
  691. -
  692. +
  693. L2TopManager.getInstance();
  694. -
  695. + if (Config.BUFF_STORE_ENABLED)
  696. + {
  697. + OfflineBuffersTable.getInstance().restoreOfflineBuffers();
  698. + }
  699. MMOTopManager.getInstance();
  700. Protection.Init();
  701. SMSWayToPay.getInstance();
  702. -
  703. +
  704. Shutdown.getInstance().schedule(Config.RESTART_AT_TIME, Shutdown.RESTART);
  705. _log.info("GameServer Started");
  706. _log.info("Maximum Numbers of Connected Players: " + Config.MAXIMUM_ONLINE_USERS);
  707. -
  708. +
  709. GamePacketHandler gph = new GamePacketHandler();
  710. -
  711. +
  712. InetAddress serverAddr = Config.GAMESERVER_HOSTNAME.equalsIgnoreCase("*") ? null : InetAddress.getByName(Config.GAMESERVER_HOSTNAME);
  713. -
  714. +
  715. _selectorThreads = new SelectorThread[Config.PORTS_GAME.length];
  716. for (int i = 0; i < Config.PORTS_GAME.length; i++)
  717. {
  718. @@ -270,16 +274,16 @@
  719. _selectorThreads[i].start();
  720. }
  721. AuthServerCommunication.getInstance().start();
  722. -
  723. +
  724. if (Config.SERVICES_OFFLINE_TRADE_RESTORE_AFTER_RESTART)
  725. {
  726. ThreadPoolManager.getInstance().schedule(new RestoreOfflineTraders(), 30000L);
  727. }
  728. -
  729. +
  730. ThreadPoolManager.getInstance().scheduleAtFixedRate(new AutoAnnounce(), 60000, 60000);
  731. -
  732. +
  733. getListeners().onStart();
  734. -
  735. +
  736. if (Config.IS_TELNET_ENABLED)
  737. {
  738. statusServer = new TelnetServer();
  739. @@ -288,7 +292,7 @@
  740. {
  741. _log.info("Telnet server is currently disabled.");
  742. }
  743. -
  744. +
  745. _log.info("=================================================");
  746. String memUsage = new StringBuilder().append(StatsUtils.getMemUsage()).toString();
  747. for (String line : memUsage.split("\n"))
  748. @@ -297,27 +301,27 @@
  749. }
  750. _log.info("=================================================");
  751. }
  752. -
  753. +
  754. public GameServerListenerList getListeners()
  755. {
  756. return _listeners;
  757. }
  758. -
  759. +
  760. public static GameServer getInstance()
  761. {
  762. return _instance;
  763. }
  764. -
  765. +
  766. public <T extends GameListener> boolean addListener(T listener)
  767. {
  768. return _listeners.add(listener);
  769. }
  770. -
  771. +
  772. public <T extends GameListener> boolean removeListener(T listener)
  773. {
  774. return _listeners.remove(listener);
  775. }
  776. -
  777. +
  778. public static void checkFreePorts()
  779. {
  780. boolean binded = false;
  781. @@ -354,17 +358,17 @@
  782. }
  783. }
  784. }
  785. -
  786. +
  787. public static void main(String[] args) throws Exception
  788. {
  789. new GameServer();
  790. }
  791. -
  792. +
  793. public Version getVersion()
  794. {
  795. return version;
  796. }
  797. -
  798. +
  799. public TelnetServer getStatusServer()
  800. {
  801. return statusServer;
  802. Index: dist/gameserver/config/OfflineBuffer.properties
  803. ===================================================================
  804. --- dist/gameserver/config/OfflineBuffer.properties (revision 0)
  805. +++ dist/gameserver/config/OfflineBuffer.properties (working copy)
  806. @@ -0,0 +1,33 @@
  807. +# ---------------------------------------------------------------------------
  808. +# Buff Store System
  809. +# ---------------------------------------------------------------------------
  810. +
  811. +# Enable / Disable Sell Buff System
  812. +BuffStoreEnabled = True
  813. +
  814. +# If enabled then the buffer will consume his own mp for each buff sold
  815. +BuffStoreMpEnabled = True
  816. +
  817. +# Multiplier to control the mp consumed for each buff sold
  818. +# 1.0 is 100% of the original mp consume. Smaller value is less consume
  819. +BuffStoreMpConsumeMultiplier = 1.0
  820. +
  821. +# Enable specific skill item consume. Example: Skill Chant of Victory using Spirit Ore.
  822. +BuffStoreItemConsumeEnabled = True
  823. +
  824. +# Allowed class ids that can put their buffs on sale
  825. +# Format: class ids separated by commas
  826. +BuffStoreAllowedClassList = 15,16,97,17,98,29,30,105,42,43,112,50,116,51,115,100,21,107,34,94,103
  827. +
  828. +# Forbidden skill list, that cannot be put on sale
  829. +# Put all the skill ids separated by commas
  830. +BuffStoreForbiddenSkillList = 765,915,989,1507,1410,1411,764,914,988,327,1323,1325,1326,1327,1531,1427
  831. +
  832. +# Title Color of the store
  833. +BuffStoreTitleColor = 3427e1
  834. +
  835. +# Name Color of the store when its online
  836. +BuffStoreNameColor = ffffff
  837. +
  838. +# Name Color of the store when it goes offline
  839. +BuffStoreOfflineNameColor = 808080
  840. \ No newline at end of file
  841. Index: java/l2f/gameserver/network/clientpackets/Logout.java
  842. ===================================================================
  843. --- java/l2f/gameserver/network/clientpackets/Logout.java (revision 109)
  844. +++ java/l2f/gameserver/network/clientpackets/Logout.java (working copy)
  845. @@ -11,73 +11,85 @@
  846. {
  847. @Override
  848. protected void readImpl()
  849. - {}
  850. -
  851. + {
  852. + }
  853. +
  854. @Override
  855. protected void runImpl()
  856. {
  857. Player activeChar = getClient().getActiveChar();
  858. - if(activeChar == null)
  859. + if (activeChar == null)
  860. + {
  861. return;
  862. -
  863. + }
  864. +
  865. // Dont allow leaving if player is fighting
  866. - if(activeChar.isInCombat())
  867. + if (activeChar.isInCombat())
  868. {
  869. activeChar.sendPacket(SystemMsg.YOU_CANNOT_EXIT_THE_GAME_WHILE_IN_COMBAT);
  870. activeChar.sendActionFailed();
  871. return;
  872. }
  873. -
  874. - if(activeChar.isFishing())
  875. +
  876. + if (activeChar.isFishing())
  877. {
  878. activeChar.sendPacket(SystemMsg.YOU_CANNOT_DO_THAT_WHILE_FISHING_2);
  879. activeChar.sendActionFailed();
  880. return;
  881. }
  882. -
  883. - if(activeChar.isBlocked() && !activeChar.isFlying()) // Разрешаем выходить из игры если используется сервис HireWyvern. Вернет в начальную точку.
  884. +
  885. + if (activeChar.isBlocked() && !activeChar.isFlying()) // Разрешаем выходить из игры если используется сервис HireWyvern. Вернет в начальную точку.
  886. {
  887. activeChar.sendMessage(new CustomMessage("l2f.gameserver.clientpackets.Logout.OutOfControl", activeChar));
  888. activeChar.sendActionFailed();
  889. return;
  890. }
  891. -
  892. - if(activeChar.isFestivalParticipant())
  893. - if(SevenSignsFestival.getInstance().isFestivalInitialized())
  894. +
  895. + if (activeChar.isFestivalParticipant())
  896. + {
  897. + if (SevenSignsFestival.getInstance().isFestivalInitialized())
  898. {
  899. activeChar.sendMessage("You cannot log out while you are a participant in a festival.");
  900. activeChar.sendActionFailed();
  901. return;
  902. }
  903. -
  904. - if(activeChar.isInOlympiadMode())
  905. + }
  906. +
  907. + if (activeChar.isInOlympiadMode())
  908. {
  909. activeChar.sendMessage(new CustomMessage("l2f.gameserver.clientpackets.Logout.Olympiad", activeChar));
  910. activeChar.sendActionFailed();
  911. return;
  912. }
  913. -
  914. - if(activeChar.getVar("isPvPevents") != null)
  915. +
  916. + if (activeChar.getVar("isPvPevents") != null)
  917. {
  918. activeChar.sendMessage(activeChar.isLangRus() ? "Вы не можите выйти во время участия в ивенте!" : "You can follow any responses did not leave while participating in the event!");
  919. activeChar.sendActionFailed();
  920. return;
  921. }
  922. -
  923. - if(activeChar.isInStoreMode() && !activeChar.isInZone(Zone.ZoneType.offshore) && Config.SERVICES_OFFLINE_TRADE_ALLOW_OFFSHORE)
  924. +
  925. + if (activeChar.isInStoreMode() && !activeChar.isInZone(Zone.ZoneType.offshore) && Config.SERVICES_OFFLINE_TRADE_ALLOW_OFFSHORE)
  926. {
  927. activeChar.sendMessage(new CustomMessage("trade.OfflineNoTradeZoneOnlyOffshore", activeChar));
  928. activeChar.sendActionFailed();
  929. return;
  930. }
  931. -
  932. - if(activeChar.isInObserverMode())
  933. +
  934. + if (activeChar.isInObserverMode())
  935. {
  936. activeChar.sendMessage(new CustomMessage("l2f.gameserver.clientpackets.Logout.Observer", activeChar));
  937. activeChar.sendActionFailed();
  938. return;
  939. }
  940. -
  941. + if (activeChar.isInBuffStore())
  942. + {
  943. + activeChar.offlineBuffStore();
  944. + }
  945. + else
  946. + {
  947. + activeChar.kick();
  948. + }
  949. activeChar.logout();
  950. }
  951. }
  952. \ No newline at end of file
  953. Index: java/l2f/gameserver/utils/Util.java
  954. ===================================================================
  955. --- java/l2f/gameserver/utils/Util.java (revision 109)
  956. +++ java/l2f/gameserver/utils/Util.java (working copy)
  957. @@ -17,12 +17,11 @@
  958. import l2f.gameserver.Config;
  959. import l2f.gameserver.model.reward.RewardList;
  960.  
  961. -
  962. public class Util
  963. {
  964. static final String PATTERN = "0.0000000000E00";
  965. static final DecimalFormat df;
  966. -
  967. +
  968. /**
  969. * Форматтер для адены.<br>
  970. * Locale.KOREA заставляет его фортматировать через ",".<br>
  971. @@ -30,7 +29,7 @@
  972. * Для форматирования через "." убрать с аргументов Locale.FRANCE
  973. */
  974. private static NumberFormat adenaFormatter;
  975. -
  976. +
  977. static
  978. {
  979. adenaFormatter = NumberFormat.getIntegerInstance(Locale.FRANCE);
  980. @@ -38,7 +37,7 @@
  981. df.applyPattern(PATTERN);
  982. df.setPositivePrefix("+");
  983. }
  984. -
  985. +
  986. /**
  987. * Проверяет строку на соответсвие регулярному выражению
  988. * @param text Строка-источник
  989. @@ -52,27 +51,35 @@
  990. {
  991. pattern = Pattern.compile(template);
  992. }
  993. - catch(PatternSyntaxException e) // invalid template
  994. + catch (PatternSyntaxException e) // invalid template
  995. {
  996. e.printStackTrace();
  997. }
  998. - if(pattern == null)
  999. + if (pattern == null)
  1000. + {
  1001. return false;
  1002. + }
  1003. Matcher regexp = pattern.matcher(text);
  1004. return regexp.matches();
  1005. }
  1006. -
  1007. +
  1008. public static String formatDouble(double x, String nanString, boolean forceExponents)
  1009. {
  1010. - if(Double.isNaN(x))
  1011. + if (Double.isNaN(x))
  1012. + {
  1013. return nanString;
  1014. - if(forceExponents)
  1015. + }
  1016. + if (forceExponents)
  1017. + {
  1018. return df.format(x);
  1019. - if((long) x == x)
  1020. + }
  1021. + if ((long) x == x)
  1022. + {
  1023. return String.valueOf((long) x);
  1024. + }
  1025. return String.valueOf(x);
  1026. }
  1027. -
  1028. +
  1029. /**
  1030. * Return amount of adena formatted with " " delimiter
  1031. * @param amount
  1032. @@ -82,14 +89,18 @@
  1033. {
  1034. return adenaFormatter.format(amount);
  1035. }
  1036. -
  1037. +
  1038. /**
  1039. * форматирует время в секундах в дни/часы/минуты/секунды
  1040. + * @param time
  1041. + * @return
  1042. */
  1043. public static String formatTime(int time)
  1044. {
  1045. - if(time == 0)
  1046. + if (time == 0)
  1047. + {
  1048. return "now";
  1049. + }
  1050. time = Math.abs(time);
  1051. String ret = "";
  1052. long numDays = time / 86400;
  1053. @@ -99,257 +110,326 @@
  1054. long numMins = time / 60;
  1055. time -= numMins * 60;
  1056. long numSeconds = time;
  1057. - if(numDays > 0)
  1058. + if (numDays > 0)
  1059. + {
  1060. ret += numDays + "d ";
  1061. - if(numHours > 0)
  1062. + }
  1063. + if (numHours > 0)
  1064. + {
  1065. ret += numHours + "h ";
  1066. - if(numMins > 0)
  1067. + }
  1068. + if (numMins > 0)
  1069. + {
  1070. ret += numMins + "m ";
  1071. - if(numSeconds > 0)
  1072. + }
  1073. + if (numSeconds > 0)
  1074. + {
  1075. ret += numSeconds + "s";
  1076. + }
  1077. return ret.trim();
  1078. }
  1079. -
  1080. +
  1081. /**
  1082. - * Инструмент для подсчета выпавших вещей с учетом рейтов.
  1083. - * Возвращает 0 если шанс не прошел, либо количество если прошел.
  1084. - * Корректно обрабатывает шансы превышающие 100%.
  1085. - * Шанс в 1:1000000 (L2Drop.MAX_CHANCE)
  1086. + * Инструмент для подсчета выпавших вещей с учетом рейтов. Возвращает 0 если шанс не прошел, либо количество если прошел. Корректно обрабатывает шансы превышающие 100%. Шанс в 1:1000000 (L2Drop.MAX_CHANCE)
  1087. + * @param min
  1088. + * @param max
  1089. + * @param calcChance
  1090. + * @param rate
  1091. + * @return
  1092. */
  1093. public static long rollDrop(long min, long max, double calcChance, boolean rate)
  1094. {
  1095. - if(calcChance <= 0 || min <= 0 || max <= 0)
  1096. + if ((calcChance <= 0) || (min <= 0) || (max <= 0))
  1097. + {
  1098. return 0;
  1099. + }
  1100. int dropmult = 1;
  1101. - if(rate)
  1102. + if (rate)
  1103. + {
  1104. calcChance *= Config.RATE_DROP_ITEMS;
  1105. - if(calcChance > RewardList.MAX_CHANCE)
  1106. - if(calcChance % RewardList.MAX_CHANCE == 0) // если кратен 100% то тупо умножаем количество
  1107. + }
  1108. + if (calcChance > RewardList.MAX_CHANCE)
  1109. + {
  1110. + if ((calcChance % RewardList.MAX_CHANCE) == 0)
  1111. + {
  1112. dropmult = (int) (calcChance / RewardList.MAX_CHANCE);
  1113. + }
  1114. else
  1115. {
  1116. dropmult = (int) Math.ceil(calcChance / RewardList.MAX_CHANCE); // множитель равен шанс / 100% округление вверх
  1117. calcChance = calcChance / dropmult; // шанс равен шанс / множитель
  1118. }
  1119. + }
  1120. return Rnd.chance(calcChance / 10000.) ? Rnd.get(min * dropmult, max * dropmult) : 0;
  1121. }
  1122. -
  1123. +
  1124. public static int packInt(int[] a, int bits) throws Exception
  1125. {
  1126. int m = 32 / bits;
  1127. - if(a.length > m)
  1128. + if (a.length > m)
  1129. + {
  1130. throw new Exception("Overflow");
  1131. -
  1132. + }
  1133. +
  1134. int result = 0;
  1135. int next;
  1136. int mval = (int) Math.pow(2, bits);
  1137. - for(int i = 0; i < m; i++)
  1138. + for (int i = 0; i < m; i++)
  1139. {
  1140. result <<= bits;
  1141. - if(a.length > i)
  1142. + if (a.length > i)
  1143. {
  1144. next = a[i];
  1145. - if(next >= mval || next < 0)
  1146. + if ((next >= mval) || (next < 0))
  1147. + {
  1148. throw new Exception("Overload, value is out of range");
  1149. + }
  1150. }
  1151. else
  1152. + {
  1153. next = 0;
  1154. + }
  1155. result += next;
  1156. }
  1157. return result;
  1158. }
  1159. -
  1160. +
  1161. public static long packLong(int[] a, int bits) throws Exception
  1162. {
  1163. int m = 64 / bits;
  1164. - if(a.length > m)
  1165. + if (a.length > m)
  1166. + {
  1167. throw new Exception("Overflow");
  1168. -
  1169. + }
  1170. +
  1171. long result = 0;
  1172. int next;
  1173. int mval = (int) Math.pow(2, bits);
  1174. - for(int i = 0; i < m; i++)
  1175. + for (int i = 0; i < m; i++)
  1176. {
  1177. result <<= bits;
  1178. - if(a.length > i)
  1179. + if (a.length > i)
  1180. {
  1181. next = a[i];
  1182. - if(next >= mval || next < 0)
  1183. + if ((next >= mval) || (next < 0))
  1184. + {
  1185. throw new Exception("Overload, value is out of range");
  1186. + }
  1187. }
  1188. else
  1189. + {
  1190. next = 0;
  1191. + }
  1192. result += next;
  1193. }
  1194. return result;
  1195. }
  1196. -
  1197. +
  1198. public static int[] unpackInt(int a, int bits)
  1199. {
  1200. int m = 32 / bits;
  1201. int mval = (int) Math.pow(2, bits);
  1202. int[] result = new int[m];
  1203. int next;
  1204. - for(int i = m; i > 0; i--)
  1205. + for (int i = m; i > 0; i--)
  1206. {
  1207. next = a;
  1208. a = a >> bits;
  1209. - result[i - 1] = next - a * mval;
  1210. + result[i - 1] = next - (a * mval);
  1211. }
  1212. return result;
  1213. }
  1214. -
  1215. +
  1216. public static int[] unpackLong(long a, int bits)
  1217. {
  1218. int m = 64 / bits;
  1219. int mval = (int) Math.pow(2, bits);
  1220. int[] result = new int[m];
  1221. long next;
  1222. - for(int i = m; i > 0; i--)
  1223. + for (int i = m; i > 0; i--)
  1224. {
  1225. next = a;
  1226. a = a >> bits;
  1227. - result[i - 1] = (int) (next - a * mval);
  1228. + result[i - 1] = (int) (next - (a * mval));
  1229. }
  1230. return result;
  1231. }
  1232. -
  1233. +
  1234. public static float[] parseCommaSeparatedFloatArray(String s)
  1235. {
  1236. if (s.isEmpty())
  1237. + {
  1238. return new float[0];
  1239. + }
  1240. String[] tmp = s.replaceAll(",", ";").replaceAll("\\n", ";").split(";");
  1241. float[] val = new float[tmp.length];
  1242. for (int i = 0; i < tmp.length; i++)
  1243. + {
  1244. val[i] = Float.parseFloat(tmp[i]);
  1245. + }
  1246. return val;
  1247. }
  1248. -
  1249. +
  1250. public static int[] parseCommaSeparatedIntegerArray(String s)
  1251. {
  1252. if (s.isEmpty())
  1253. + {
  1254. return new int[0];
  1255. + }
  1256. String[] tmp = s.replaceAll(",", ";").replaceAll("\\n", ";").split(";");
  1257. int[] val = new int[tmp.length];
  1258. for (int i = 0; i < tmp.length; i++)
  1259. + {
  1260. val[i] = Integer.parseInt(tmp[i]);
  1261. + }
  1262. return val;
  1263. }
  1264. -
  1265. +
  1266. public static long[] parseCommaSeparatedLongArray(String s)
  1267. {
  1268. if (s.isEmpty())
  1269. + {
  1270. return new long[0];
  1271. + }
  1272. String[] tmp = s.replaceAll(",", ";").replaceAll("\\n", ";").split(";");
  1273. long[] val = new long[tmp.length];
  1274. for (int i = 0; i < tmp.length; i++)
  1275. + {
  1276. val[i] = Long.parseLong(tmp[i]);
  1277. + }
  1278. return val;
  1279. }
  1280. -
  1281. +
  1282. public static long[][] parseStringForDoubleArray(String s)
  1283. {
  1284. String[] temp = s.replaceAll("\\n", ";").split(";");
  1285. long[][] val = new long[temp.length][];
  1286. -
  1287. +
  1288. for (int i = 0; i < temp.length; i++)
  1289. + {
  1290. val[i] = parseCommaSeparatedLongArray(temp[i]);
  1291. + }
  1292. return val;
  1293. }
  1294. -
  1295. - /** Just alias */
  1296. +
  1297. + /**
  1298. + * Just alias
  1299. + * @param glueStr
  1300. + * @param strings
  1301. + * @param startIdx
  1302. + * @param maxCount
  1303. + * @return
  1304. + */
  1305. public static String joinStrings(String glueStr, String[] strings, int startIdx, int maxCount)
  1306. {
  1307. return Strings.joinStrings(glueStr, strings, startIdx, maxCount);
  1308. }
  1309. -
  1310. - /** Just alias */
  1311. +
  1312. + /**
  1313. + * Just alias
  1314. + * @param glueStr
  1315. + * @param strings
  1316. + * @param startIdx
  1317. + * @return
  1318. + */
  1319. public static String joinStrings(String glueStr, String[] strings, int startIdx)
  1320. {
  1321. return Strings.joinStrings(glueStr, strings, startIdx, -1);
  1322. }
  1323. -
  1324. +
  1325. public static boolean isNumber(String s)
  1326. {
  1327. try
  1328. {
  1329. Double.parseDouble(s);
  1330. }
  1331. - catch(NumberFormatException e)
  1332. + catch (NumberFormatException e)
  1333. {
  1334. return false;
  1335. }
  1336. return true;
  1337. }
  1338. -
  1339. +
  1340. public static String dumpObject(Object o, boolean simpleTypes, boolean parentFields, boolean ignoreStatics)
  1341. {
  1342. Class<?> cls = o.getClass();
  1343. String val, type, result = "[" + (simpleTypes ? cls.getSimpleName() : cls.getName()) + "\n";
  1344. Object fldObj;
  1345. - List<Field> fields = new ArrayList<Field>();
  1346. - while(cls != null)
  1347. + List<Field> fields = new ArrayList<>();
  1348. + while (cls != null)
  1349. {
  1350. - for(Field fld : cls.getDeclaredFields())
  1351. - if(!fields.contains(fld))
  1352. + for (Field fld : cls.getDeclaredFields())
  1353. + {
  1354. + if (!fields.contains(fld))
  1355. {
  1356. - if(ignoreStatics && Modifier.isStatic(fld.getModifiers()))
  1357. + if (ignoreStatics && Modifier.isStatic(fld.getModifiers()))
  1358. + {
  1359. continue;
  1360. + }
  1361. fields.add(fld);
  1362. }
  1363. + }
  1364. cls = cls.getSuperclass();
  1365. - if(!parentFields)
  1366. + if (!parentFields)
  1367. + {
  1368. break;
  1369. + }
  1370. }
  1371. -
  1372. - for(Field fld : fields)
  1373. +
  1374. + for (Field fld : fields)
  1375. {
  1376. fld.setAccessible(true);
  1377. try
  1378. {
  1379. fldObj = fld.get(o);
  1380. - if(fldObj == null)
  1381. + if (fldObj == null)
  1382. + {
  1383. val = "NULL";
  1384. + }
  1385. else
  1386. + {
  1387. val = fldObj.toString();
  1388. + }
  1389. }
  1390. - catch(Throwable e)
  1391. + catch (Throwable e)
  1392. {
  1393. e.printStackTrace();
  1394. val = "<ERROR>";
  1395. }
  1396. type = simpleTypes ? fld.getType().getSimpleName() : fld.getType().toString();
  1397. -
  1398. +
  1399. result += String.format("\t%s [%s] = %s;\n", fld.getName(), type, val);
  1400. }
  1401. -
  1402. +
  1403. result += "]\n";
  1404. return result;
  1405. }
  1406. -
  1407. +
  1408. private static Pattern _pattern = Pattern.compile("<!--TEMPLET(\\d+)(.*?)TEMPLET-->", Pattern.DOTALL);
  1409. -
  1410. +
  1411. public static HashMap<Integer, String> parseTemplate(String html)
  1412. {
  1413. Matcher m = _pattern.matcher(html);
  1414. - HashMap<Integer, String> tpls = new HashMap<Integer, String>();
  1415. - while(m.find())
  1416. + HashMap<Integer, String> tpls = new HashMap<>();
  1417. + while (m.find())
  1418. {
  1419. tpls.put(Integer.parseInt(m.group(1)), m.group(2));
  1420. html = html.replace(m.group(0), "");
  1421. }
  1422. -
  1423. +
  1424. tpls.put(0, html);
  1425. return tpls;
  1426. }
  1427. -
  1428. +
  1429. public static boolean isDigit(String text)
  1430. {
  1431. if (text == null)
  1432. + {
  1433. return false;
  1434. + }
  1435. return text.matches("[0-9]+");
  1436. }
  1437. -
  1438. +
  1439. /**
  1440. * @param raw
  1441. * @return
  1442. @@ -358,37 +438,37 @@
  1443. {
  1444. return printData(raw, raw.length);
  1445. }
  1446. -
  1447. +
  1448. public static String fillHex(int data, int digits)
  1449. {
  1450. String number = Integer.toHexString(data);
  1451. - for(int i = number.length(); i < digits; i++)
  1452. + for (int i = number.length(); i < digits; i++)
  1453. {
  1454. number = "0" + number;
  1455. }
  1456. return number;
  1457. }
  1458. -
  1459. +
  1460. public static String printData(byte[] data, int len)
  1461. {
  1462. StringBuffer result = new StringBuffer();
  1463. int counter = 0;
  1464. - for(int i = 0; i < len; i++)
  1465. + for (int i = 0; i < len; i++)
  1466. {
  1467. - if(counter % 16 == 0)
  1468. + if ((counter % 16) == 0)
  1469. {
  1470. result.append(fillHex(i, 4) + ": ");
  1471. }
  1472. result.append(fillHex(data[i] & 0xff, 2) + " ");
  1473. counter++;
  1474. - if(counter == 16)
  1475. + if (counter == 16)
  1476. {
  1477. result.append(" ");
  1478. int charpoint = i - 15;
  1479. - for(int a = 0; a < 16; a++)
  1480. + for (int a = 0; a < 16; a++)
  1481. {
  1482. int t1 = data[charpoint++];
  1483. - if(t1 > 0x1f && t1 < 0x80)
  1484. + if ((t1 > 0x1f) && (t1 < 0x80))
  1485. {
  1486. result.append((char) t1);
  1487. }
  1488. @@ -402,17 +482,17 @@
  1489. }
  1490. }
  1491. int rest = data.length % 16;
  1492. - if(rest > 0)
  1493. + if (rest > 0)
  1494. {
  1495. - for(int i = 0; i < 17 - rest; i++)
  1496. + for (int i = 0; i < (17 - rest); i++)
  1497. {
  1498. result.append(" ");
  1499. }
  1500. int charpoint = data.length - rest;
  1501. - for(int a = 0; a < rest; a++)
  1502. + for (int a = 0; a < rest; a++)
  1503. {
  1504. int t1 = data[charpoint++];
  1505. - if(t1 > 0x1f && t1 < 0x80)
  1506. + if ((t1 > 0x1f) && (t1 < 0x80))
  1507. {
  1508. result.append((char) t1);
  1509. }
  1510. @@ -425,15 +505,52 @@
  1511. }
  1512. return result.toString();
  1513. }
  1514. -
  1515. +
  1516. public static byte[] generateHex(int size)
  1517. {
  1518. byte[] array = new byte[size];
  1519. Random rnd = new Random();
  1520. - for(int i = 0; i < size; i++)
  1521. + for (int i = 0; i < size; i++)
  1522. {
  1523. array[i] = (byte) rnd.nextInt(256);
  1524. }
  1525. return array;
  1526. }
  1527. +
  1528. + public static String convertToLineagePriceFormat(double price)
  1529. + {
  1530. + if (price < 10000.0D)
  1531. + {
  1532. + return Math.round(price) + "a";
  1533. + }
  1534. + if (price < 1000000.0D)
  1535. + {
  1536. + return reduceDecimals(price / 1000.0D, 1) + "k";
  1537. + }
  1538. + if (price < 1000000000.0D)
  1539. + {
  1540. + return reduceDecimals(price / 1000.0D / 1000.0D, 1) + "kk";
  1541. + }
  1542. + return reduceDecimals(price / 1000.0D / 1000.0D / 1000.0D, 1) + "kkk";
  1543. + }
  1544. +
  1545. + public static String reduceDecimals(double original, int nDecim)
  1546. + {
  1547. + return reduceDecimals(original, nDecim, false);
  1548. + }
  1549. +
  1550. + public static String reduceDecimals(double original, int nDecim, boolean round)
  1551. + {
  1552. + String decimals = "#";
  1553. + if (nDecim > 0)
  1554. + {
  1555. + decimals = decimals + ".";
  1556. + for (int i = 0; i < nDecim; i++)
  1557. + {
  1558. + decimals = decimals + "#";
  1559. + }
  1560. + }
  1561. + DecimalFormat df = new DecimalFormat(decimals);
  1562. + return df.format(round ? Math.round(original) : original).replace(",", ".");
  1563. + }
  1564. }
  1565. \ No newline at end of file
  1566. Index: dist/gameserver/data/html-en/command/buffstore/buff_store_buffer.htm
  1567. ===================================================================
  1568. --- dist/gameserver/data/html-en/command/buffstore/buff_store_buffer.htm (revision 0)
  1569. +++ dist/gameserver/data/html-en/command/buffstore/buff_store_buffer.htm (working copy)
  1570. @@ -0,0 +1,69 @@
  1571. +<html><head><title>%bufferName% Store</title>
  1572. +<body>
  1573. + <img src=L2UI.SquareGray width=275 height=1>
  1574. + <table width=275 height=30 bgcolor=7d9399>
  1575. + <tr>
  1576. + <td height=10></td>
  1577. + </tr>
  1578. + <tr>
  1579. + <td fixwidth=275 align=center>
  1580. + <font name=hs12>%bufferClass% Lvl %bufferLvl%+</font>
  1581. + </td>
  1582. + </tr>
  1583. + <tr>
  1584. + <td height=10></td>
  1585. + </tr>
  1586. + </table>
  1587. + <img src=L2UI.SquareGray width=275 height=1>
  1588. + <table width=275 height=30 bgcolor=444a45>
  1589. + <tr>
  1590. + <td height=10></td>
  1591. + </tr>
  1592. + <tr>
  1593. + <td fixwidth=275 align=center>
  1594. + Buff Price: <font color=f3ef8e>%buffPrice%</font>
  1595. + </td>
  1596. + </tr>
  1597. + <tr>
  1598. + <td height=10></td>
  1599. + </tr>
  1600. + </table>
  1601. + <img src=L2UI.SquareGray width=275 height=1>
  1602. + <table cellpadding=0>
  1603. + <tr>
  1604. + <td height=10></td>
  1605. + </tr>
  1606. + %buffs%
  1607. + </table>
  1608. + <img src=L2UI.SquareGray width=270 height=1>
  1609. + <table fixwidth=270 height=30 bgcolor=171612>
  1610. + <tr>
  1611. + <td height=5></td>
  1612. + </tr>
  1613. + <tr>
  1614. + <td width=110 align=right>
  1615. + %previousPageButton%
  1616. + </td>
  1617. + <td width=50 align=center>
  1618. + %pageCount%
  1619. + </td>
  1620. + <td width=105>
  1621. + %nextPageButton%
  1622. + </td>
  1623. + </tr>
  1624. + </table>
  1625. + <img src=L2UI.SquareGray width=270 height=1>
  1626. + <br>
  1627. + <table width=250>
  1628. + <tr>
  1629. + <td width=150>
  1630. + <button value="For Player" action="bypass -h BuffStore bufflist %bufferId% player %page%" width=120 height=22 back=L2UI_ct1.button_df fore=L2UI_ct1.button_df>
  1631. + </td>
  1632. + <td>
  1633. + <button value="For Summon" action="bypass -h BuffStore bufflist %bufferId% summon %page%" width=120 height=22 back=L2UI_ct1.button_df fore=L2UI_ct1.button_df>
  1634. + </td>
  1635. + </tr>
  1636. + </table>
  1637. + <br>
  1638. +</body>
  1639. +</html>
  1640. \ No newline at end of file
  1641. Index: java/l2f/gameserver/instancemanager/OfflineBufferManager.java
  1642. ===================================================================
  1643. --- java/l2f/gameserver/instancemanager/OfflineBufferManager.java (revision 0)
  1644. +++ java/l2f/gameserver/instancemanager/OfflineBufferManager.java (working copy)
  1645. @@ -0,0 +1,388 @@
  1646. +package l2f.gameserver.instancemanager;
  1647. +
  1648. +import java.util.HashMap;
  1649. +import java.util.Iterator;
  1650. +import java.util.List;
  1651. +import java.util.Map;
  1652. +import java.util.StringTokenizer;
  1653. +import java.util.concurrent.ConcurrentHashMap;
  1654. +import java.util.logging.Logger;
  1655. +
  1656. +import l2f.gameserver.Config;
  1657. +import l2f.gameserver.model.Player;
  1658. +import l2f.gameserver.model.Skill;
  1659. +import l2f.gameserver.model.Zone;
  1660. +import l2f.gameserver.model.base.ClassId;
  1661. +import l2f.gameserver.model.entity.olympiad.Olympiad;
  1662. +import l2f.gameserver.network.serverpackets.NpcHtmlMessage;
  1663. +import l2f.gameserver.tables.SkillTable;
  1664. +import l2f.gameserver.utils.PositionUtils;
  1665. +import l2f.gameserver.utils.TradeHelper;
  1666. +import l2f.gameserver.utils.Util;
  1667. +
  1668. +public class OfflineBufferManager
  1669. +{
  1670. + protected static final Logger _log = Logger.getLogger(OfflineBufferManager.class.getName());
  1671. + private static final int MAX_INTERACT_DISTANCE = 100;
  1672. + private final Map<Integer, BufferData> _buffStores;
  1673. +
  1674. + public OfflineBufferManager()
  1675. + {
  1676. + this._buffStores = new ConcurrentHashMap();
  1677. + }
  1678. +
  1679. + public Map<Integer, BufferData> getBuffStores()
  1680. + {
  1681. + return this._buffStores;
  1682. + }
  1683. +
  1684. + public void processBypass(Player player, String command)
  1685. + {
  1686. + StringTokenizer st = new StringTokenizer(command, " ");
  1687. + st.nextToken();
  1688. + switch (st.nextToken())
  1689. + {
  1690. + case "setstore":
  1691. + try
  1692. + {
  1693. + int price = Integer.parseInt(st.nextToken());
  1694. + String title = st.nextToken();
  1695. + while (st.hasMoreTokens())
  1696. + {
  1697. + title = title + " " + st.nextToken();
  1698. + }
  1699. + title = title.trim();
  1700. + if (!this._buffStores.containsKey(Integer.valueOf(player.getObjectId())))
  1701. + {
  1702. + if (player.getPrivateStoreType() != 0)
  1703. + {
  1704. + player.sendMessage(player.isLangRus() ? "У вас уже есть магазин" : "You already have a store");
  1705. + }
  1706. + else if (!Config.BUFF_STORE_ALLOWED_CLASS_LIST.contains(Integer.valueOf(player.getClassId().getId())))
  1707. + {
  1708. + player.sendMessage(player.isLangRus() ? "Вашей профессии нельзя открывать магазин бафов" : "Your profession is not allowed to set an Buff Store");
  1709. + }
  1710. + else if (TradeHelper.checksIfCanOpenStore(player, 20))
  1711. + {
  1712. + if ((title.isEmpty()) || (title.length() >= 29))
  1713. + {
  1714. + player.sendMessage(player.isLangRus() ? "Максимальное кол-во символов до 29, используйте титул по короче!" : "You must put a title for this store and it must have less than 29 characters");
  1715. + throw new Exception();
  1716. + }
  1717. + if ((price < 1) || (price > 10000000))
  1718. + {
  1719. + player.sendMessage(player.isLangRus() ? "Цена для каждого баффа должна быть между 1-10кк Аден" : "The price for each buff must be between 1 and 10kk");
  1720. + throw new Exception();
  1721. + }
  1722. + if ((!player.isGM()) && (!player.isInZone(Zone.ZoneType.buff_store_only)))
  1723. + {
  1724. + player.sendMessage(player.isLangRus() ? "Вы не можете открыть магазин тут, поищите специальные места где можно открывать магазин!" : "You can't put a buff store here. Look for special designated zones or clan halls");
  1725. + throw new Exception();
  1726. + }
  1727. + if ((player.isAlikeDead()) || (player.isInOlympiadMode()) || (player.isMounted()) || (player.isCastingNow()) || (player.getOlympiadObserveGame() != null) || (player.getOlympiadGame() != null) || (Olympiad.isRegisteredInComp(player)))
  1728. + {
  1729. + player.sendMessage(player.isLangRus() ? "Вы не соблюдаете правила открытие магазина, попробуйте позже!" : "You don't meet the required conditions to put a buff store right now");
  1730. + throw new Exception();
  1731. + }
  1732. + BufferData buffer = new BufferData(player, title, price, null);
  1733. + for (Skill skill : player.getAllSkills())
  1734. + {
  1735. + if ((skill.isActive()) && (skill.getSkillType() == Skill.SkillType.BUFF) && (!skill.isHeroic()) && (skill.getTargetType() != Skill.SkillTargetType.TARGET_SELF) && (skill.getTargetType() != Skill.SkillTargetType.TARGET_PET) && ((!player.getClassId().equalsOrChildOf(ClassId.doomcryer)) || (skill.getTargetType() != Skill.SkillTargetType.TARGET_CLAN)) && ((!player.getClassId().equalsOrChildOf(ClassId.dominator)) || ((skill.getTargetType() != Skill.SkillTargetType.TARGET_PARTY) && (skill.getTargetType() != Skill.SkillTargetType.TARGET_ONE))) && (!Config.BUFF_STORE_FORBIDDEN_SKILL_LIST.contains(Integer.valueOf(skill.getId()))))
  1736. + {
  1737. + buffer.getBuffs().put(Integer.valueOf(skill.getId()), skill);
  1738. + }
  1739. + }
  1740. + if (buffer.getBuffs().isEmpty())
  1741. + {
  1742. + player.sendMessage(player.isLangRus() ? "У вас нет не одного баффа который вы бы могли продать." : "You don't have any available buff to put on sale in the store");
  1743. + throw new Exception();
  1744. + }
  1745. + this._buffStores.put(Integer.valueOf(player.getObjectId()), buffer);
  1746. + player.sitDown(null);
  1747. + player.setTitleColor(Config.BUFF_STORE_TITLE_COLOR);
  1748. + player.setTitle(title);
  1749. + player.setNameColor(Config.BUFF_STORE_NAME_COLOR);
  1750. + player.broadcastUserInfo(true);
  1751. + player.setPrivateStoreType(20);
  1752. + player.sendMessage(player.isLangRus() ? "Ваш магазин был успешно установлен!" : "Your Buff Store was set succesfully");
  1753. + }
  1754. + }
  1755. + }
  1756. + catch (NumberFormatException e)
  1757. + {
  1758. + player.sendMessage("The price for each buff must be between 1 and 10kk");
  1759. + NpcHtmlMessage html = new NpcHtmlMessage(0);
  1760. + html.setFile("command/buffstore/buff_store_create.htm");
  1761. + player.sendPacket(html);
  1762. + }
  1763. + catch (Exception e)
  1764. + {
  1765. + NpcHtmlMessage html = new NpcHtmlMessage(0);
  1766. + html.setFile("command/buffstore/buff_store_create.htm");
  1767. + player.sendPacket(html);
  1768. + }
  1769. + case "stopstore":
  1770. + if (player.getPrivateStoreType() != 20)
  1771. + {
  1772. + player.sendMessage(player.isLangRus() ? "У вас нет магазина на данный момент!" : "You dont have any store set right now");
  1773. + }
  1774. + else
  1775. + {
  1776. + this._buffStores.remove(Integer.valueOf(player.getObjectId()));
  1777. + player.setPrivateStoreType(0);
  1778. + player.standUp();
  1779. +
  1780. + player.setTitleColor(16777079);
  1781. + player.setTitle("");
  1782. + player.setNameColor(Config.NORMAL_NAME_COLOUR);
  1783. + player.broadcastUserInfo(true);
  1784. +
  1785. + player.sendMessage("Your Buff Store was removed succesfuly");
  1786. + }
  1787. + break;
  1788. + case "bufflist":
  1789. + try
  1790. + {
  1791. + int playerId = Integer.parseInt(st.nextToken());
  1792. + boolean isPlayer = st.hasMoreTokens() ? st.nextToken().equalsIgnoreCase("player") : true;
  1793. + int page = st.hasMoreTokens() ? Integer.parseInt(st.nextToken()) : 0;
  1794. + BufferData buffer = _buffStores.get(Integer.valueOf(playerId));
  1795. + if (buffer != null)
  1796. + {
  1797. + if (PositionUtils.calculateDistance(player, buffer.getOwner(), true) <= 100.0D)
  1798. + {
  1799. + if ((!isPlayer) && (player.getPet() == null))
  1800. + {
  1801. + player.sendMessage(player.isLangRus() ? "У вас нет активных самонов на данный момент!" : "You don't have any active summon right now");
  1802. + showStoreWindow(player, buffer, !isPlayer, page);
  1803. + }
  1804. + else
  1805. + {
  1806. + showStoreWindow(player, buffer, isPlayer, page);
  1807. + }
  1808. + }
  1809. + }
  1810. + }
  1811. + catch (Exception e)
  1812. + {
  1813. + e.printStackTrace();
  1814. + }
  1815. + case "purchasebuff":
  1816. + try
  1817. + {
  1818. + int playerId = Integer.parseInt(st.nextToken());
  1819. + boolean isPlayer = st.hasMoreTokens() ? st.nextToken().equalsIgnoreCase("player") : true;
  1820. + int buffId = Integer.parseInt(st.nextToken());
  1821. + int page = st.hasMoreTokens() ? Integer.parseInt(st.nextToken()) : 0;
  1822. + BufferData buffer = this._buffStores.get(Integer.valueOf(playerId));
  1823. + if (buffer != null)
  1824. + {
  1825. + if (buffer.getBuffs().containsKey(Integer.valueOf(buffId)))
  1826. + {
  1827. + if (PositionUtils.calculateDistance(player, buffer.getOwner(), true) <= 100.0D)
  1828. + {
  1829. + if ((!isPlayer) && (player.getPet() == null))
  1830. + {
  1831. + player.sendMessage(player.isLangRus() ? "У вас нет активных самонов на данный момент!" : "You don't have any active summon right now");
  1832. + showStoreWindow(player, buffer, !isPlayer, page);
  1833. + }
  1834. + else if ((player.getPvpFlag() > 0) || (player.isInCombat()) || (player.getKarma() > 0) || (player.isAlikeDead()) || (player.isInJail()) || (player.isInOlympiadMode()) || (player.isCursedWeaponEquipped()) || (player.isInStoreMode()) || (player.isInTrade()) || (player.getEnchantScroll() != null) || (player.isFishing()))
  1835. + {
  1836. + player.sendMessage("You don't meet the required conditions to use the buffer right now");
  1837. + }
  1838. + else
  1839. + {
  1840. + double buffMpCost = Config.BUFF_STORE_MP_ENABLED ? buffer.getBuffs().get(Integer.valueOf(buffId)).getMpConsume() * Config.BUFF_STORE_MP_CONSUME_MULTIPLIER : 0.0D;
  1841. + if ((buffMpCost > 0.0D) && (buffer.getOwner().getCurrentMp() < buffMpCost))
  1842. + {
  1843. + player.sendMessage(player.isLangRus() ? "У владельца недостаточно МП =(" : "This store doesn't have enough mp to give sell you this buff");
  1844. + showStoreWindow(player, buffer, isPlayer, page);
  1845. + }
  1846. + else
  1847. + {
  1848. + int buffPrice = (player.getClanId() == buffer.getOwner().getClanId()) && (player.getClanId() != 0) ? 0 : buffer.getBuffPrice();
  1849. + if ((buffPrice > 0) && (player.getAdena() < buffPrice))
  1850. + {
  1851. + player.sendMessage(player.isLangRus() ? "У вас не достаточно Адены!" : "You don't have enough adena to purchase a buff");
  1852. + }
  1853. + else if ((buffPrice > 0) && (!player.reduceAdena(buffPrice, true)))
  1854. + {
  1855. + player.sendMessage(player.isLangRus() ? "У вас не достаточно Адены!" : "You don't have enough adena to purchase a buff");
  1856. + }
  1857. + else
  1858. + {
  1859. + if (buffPrice > 0)
  1860. + {
  1861. + buffer.getOwner().addAdena(buffPrice, true);
  1862. + }
  1863. + if (buffMpCost > 0.0D)
  1864. + {
  1865. + buffer.getOwner().reduceCurrentMp(buffMpCost, null);
  1866. + }
  1867. + if (isPlayer)
  1868. + {
  1869. + buffer.getBuffs().get(Integer.valueOf(buffId)).getEffects(player, player, false, false);
  1870. + }
  1871. + else
  1872. + {
  1873. + buffer.getBuffs().get(Integer.valueOf(buffId)).getEffects(player.getPet(), player.getPet(), false, false);
  1874. + }
  1875. + player.sendMessage("You have bought " + buffer.getBuffs().get(Integer.valueOf(buffId)).getName() + " from " + player.getName());
  1876. + showStoreWindow(player, buffer, isPlayer, page);
  1877. + }
  1878. + }
  1879. + }
  1880. + }
  1881. + }
  1882. + }
  1883. + }
  1884. + catch (Exception e)
  1885. + {
  1886. + }
  1887. + }
  1888. + }
  1889. +
  1890. + private void showStoreWindow(Player player, BufferData buffer, boolean isForPlayer, int page)
  1891. + {
  1892. + NpcHtmlMessage html = new NpcHtmlMessage(0);
  1893. + html.setFile("command/buffstore/buff_store_buffer.htm");
  1894. +
  1895. + int MAX_ENTRANCES_PER_ROW = 7;
  1896. + double entrancesSize = buffer.getBuffs().size();
  1897. + int maxPage = (int) Math.ceil(entrancesSize / 7.0D) - 1;
  1898. + int currentPage = Math.min(maxPage, page);
  1899. +
  1900. + StringBuilder buffList = new StringBuilder();
  1901. + Iterator<Skill> it = buffer.getBuffs().values().iterator();
  1902. + int i = 0;
  1903. + boolean changeColor = false;
  1904. + while (it.hasNext())
  1905. + {
  1906. + if (i < (currentPage * 7))
  1907. + {
  1908. + it.next();
  1909. + i++;
  1910. + }
  1911. + else
  1912. + {
  1913. + if (i >= ((currentPage * 7) + 7))
  1914. + {
  1915. + break;
  1916. + }
  1917. + Skill buff = it.next();
  1918. + int baseMaxLvl = SkillTable.getInstance().getBaseLevel(buff.getId());
  1919. +
  1920. + buffList.append("<tr>");
  1921. + buffList.append("<td fixwidth=300>");
  1922. + buffList.append("<table height=36 cellspacing=-1 bgcolor=" + (changeColor ? "171612" : "23221e") + ">");
  1923. + buffList.append("<tr>");
  1924. + buffList.append("<td width=42 valign=top><button value=\"\" action=\"bypass -h BuffStore purchasebuff " + buffer.getOwner().getObjectId() + " " + (isForPlayer ? "player" : "summon") + " " + buff.getId() + " " + currentPage + "\" width=32 height=32 back=" + buff.getIcon() + " fore=" + buff.getIcon() + "></td>");
  1925. + if (buff.getLevel() > baseMaxLvl)
  1926. + {
  1927. + int enchantType = (buff.getLevel() - baseMaxLvl) / buff.getEnchantLevelCount();
  1928. + int enchantLvl = (buff.getLevel() - baseMaxLvl) % buff.getEnchantLevelCount();
  1929. + enchantLvl = enchantLvl == 0 ? buff.getEnchantLevelCount() : enchantLvl;
  1930. + buffList.append("<td fixwidth=240>" + buff.getName() + " <font color=a3a3a3>Lv</font> <font color=ae9978>" + baseMaxLvl + "</font>");
  1931. + buffList.append(" <font color=ffd969>+" + enchantLvl + " " + (enchantType >= 3 ? "Power" : enchantType >= 2 ? "Cost" : "Time") + "</font></td>");
  1932. + }
  1933. + else
  1934. + {
  1935. + buffList.append("<td fixwidth=240>" + buff.getName() + " <font color=a3a3a3>Lv</font> <font color=ae9978>" + buff.getLevel() + "</font></td>");
  1936. + }
  1937. + buffList.append("</tr>");
  1938. + buffList.append("</table>");
  1939. + buffList.append("</td>");
  1940. + buffList.append("</tr>");
  1941. + buffList.append("<tr>");
  1942. + buffList.append("<td height=10></td>");
  1943. + buffList.append("</tr>");
  1944. + i++;
  1945. + changeColor = !changeColor;
  1946. + }
  1947. + }
  1948. + String previousPageButton;
  1949. + if (currentPage > 0)
  1950. + {
  1951. + previousPageButton = "<button value=\"\" width=16 height=16 action=\"bypass -h BuffStore bufflist " + buffer.getOwner().getObjectId() + " " + (isForPlayer ? "player" : "summon") + " " + (currentPage - 1) + "\" fore=L2UI_CH3.shortcut_prev_down back=L2UI_CH3.shortcut_prev>";
  1952. + }
  1953. + else
  1954. + {
  1955. + previousPageButton = "<button value=\"\" width=16 height=16 action=\"\" fore=L2UI_CH3.shortcut_prev_down back=L2UI_CH3.shortcut_prev>";
  1956. + }
  1957. + String nextPageButton;
  1958. + if (currentPage < maxPage)
  1959. + {
  1960. + nextPageButton = "<button value=\"\" width=16 height=16 action=\"bypass -h BuffStore bufflist " + buffer.getOwner().getObjectId() + " " + (isForPlayer ? "player" : "summon") + " " + (currentPage + 1) + "\" fore=L2UI_CH3.shortcut_next_down back=L2UI_CH3.shortcut_next>";
  1961. + }
  1962. + else
  1963. + {
  1964. + nextPageButton = "<button value=\"\" width=16 height=16 action=\"\" fore=L2UI_CH3.shortcut_next_down back=L2UI_CH3.shortcut_next>";
  1965. + }
  1966. + html.replace("%bufferId%", String.valueOf(buffer.getOwner().getObjectId()));
  1967. + html.replace("%bufferClass%", String.valueOf(buffer.getOwner().getClassId().getName(buffer.getOwner())));
  1968. + html.replace("%bufferLvl%", String.valueOf((buffer.getOwner().getLevel() >= 76) && (buffer.getOwner().getLevel() < 80) ? 76 : buffer.getOwner().getLevel() >= 84 ? 84 : Math.round(buffer.getOwner().getLevel() / 10) * 10));
  1969. + html.replace("%bufferName%", buffer.getOwner().getName());
  1970. + html.replace("%bufferMp%", String.valueOf((int) buffer.getOwner().getCurrentMp()));
  1971. + html.replace("%buffPrice%", String.valueOf(Util.convertToLineagePriceFormat(buffer.getBuffPrice())));
  1972. + html.replace("%target%", isForPlayer ? "Player" : "Summon");
  1973. + html.replace("%page%", String.valueOf(currentPage));
  1974. + html.replace("%buffs%", buffList.toString());
  1975. + html.replace("%previousPageButton%", String.valueOf(previousPageButton));
  1976. +
  1977. + html.replace("%nextPageButton%", nextPageButton);
  1978. + html.replace("%pageCount%", currentPage + 1 + "/" + (maxPage + 1));
  1979. + player.sendPacket(html);
  1980. + }
  1981. +
  1982. + public static OfflineBufferManager getInstance()
  1983. + {
  1984. + return SingletonHolder._instance;
  1985. + }
  1986. +
  1987. + private static class SingletonHolder
  1988. + {
  1989. + protected static final OfflineBufferManager _instance = new OfflineBufferManager();
  1990. + }
  1991. +
  1992. + public static class BufferData
  1993. + {
  1994. + private final Player _owner;
  1995. + private final String _saleTitle;
  1996. + private final int _buffPrice;
  1997. + private final Map<Integer, Skill> _buffs = new HashMap();
  1998. +
  1999. + public BufferData(Player player, String title, int price, List<Skill> buffs)
  2000. + {
  2001. + this._owner = player;
  2002. + this._saleTitle = title;
  2003. + this._buffPrice = price;
  2004. + if (buffs != null)
  2005. + {
  2006. + for (Skill buff : buffs)
  2007. + {
  2008. + this._buffs.put(Integer.valueOf(buff.getId()), buff);
  2009. + }
  2010. + }
  2011. + }
  2012. +
  2013. + public Player getOwner()
  2014. + {
  2015. + return this._owner;
  2016. + }
  2017. +
  2018. + public String getSaleTitle()
  2019. + {
  2020. + return this._saleTitle;
  2021. + }
  2022. +
  2023. + public int getBuffPrice()
  2024. + {
  2025. + return this._buffPrice;
  2026. + }
  2027. +
  2028. + public Map<Integer, Skill> getBuffs()
  2029. + {
  2030. + return this._buffs;
  2031. + }
  2032. + }
  2033. +}
  2034. Index: dist/gameserver/data/html-en/command/buffstore/buff_store.htm
  2035. ===================================================================
  2036. --- dist/gameserver/data/html-en/command/buffstore/buff_store.htm (revision 0)
  2037. +++ dist/gameserver/data/html-en/command/buffstore/buff_store.htm (working copy)
  2038. @@ -0,0 +1,16 @@
  2039. +<!-- HTML Buff Store en el Panel -->
  2040. +<html noscrollbar><head><title>Buff Store</title><body scroll="no">
  2041. +<table border=0 cellpadding=0 cellspacing=0 width=292 height=358 background=L2UI_CH3.refinewnd_back_Pattern>
  2042. +<tr><td valign="top" align="center">
  2043. + <table border=0 cellpadding=0 cellspacing=0>
  2044. + <tr><td height=20></td></tr>
  2045. + <tr><td align=center><font color=91785a name=GameDefault>Buff Store</font></td></tr>
  2046. + <tr><td height=30></td></tr>
  2047. + <tr><td fixwidth=260><font color=b5b5b5>This new system allows you to sell your buffing services to other players easily.<br></font></td></tr>
  2048. + <tr><td fixwidth=260><font color=b5b5b5>It behaves almost exactly like a private store, but instead of items the players can buy the buffs you have to offer.<br></font></td></tr>
  2049. + <tr><td fixwidth=260><font color=b5b5b5>You can set the price you will charge for every buff and a title for your store</font></td></tr>
  2050. + <tr><td height=40></td></tr>
  2051. + <tr><td align=center><button value="%link%" action="%bypass%" width=200 height=31 back=L2UI_CT1.OlympiadWnd_DF_Watch_Down fore=L2UI_CT1.OlympiadWnd_DF_Watch></td></tr>
  2052. + </table>
  2053. +</td></tr></table>
  2054. +</body></html>
  2055. \ No newline at end of file
  2056. Index: java/l2f/gameserver/handler/voicecommands/impl/OfflineBuffs.java
  2057. ===================================================================
  2058. --- java/l2f/gameserver/handler/voicecommands/impl/OfflineBuffs.java (revision 0)
  2059. +++ java/l2f/gameserver/handler/voicecommands/impl/OfflineBuffs.java (working copy)
  2060. @@ -0,0 +1,54 @@
  2061. +package l2f.gameserver.handler.voicecommands.impl;
  2062. +
  2063. +import l2f.gameserver.Config;
  2064. +import l2f.gameserver.handler.voicecommands.IVoicedCommandHandler;
  2065. +import l2f.gameserver.model.Player;
  2066. +import l2f.gameserver.network.serverpackets.NpcHtmlMessage;
  2067. +import l2f.gameserver.scripts.Functions;
  2068. +
  2069. +public class OfflineBuffs extends Functions implements IVoicedCommandHandler
  2070. +{
  2071. + private static final String[] VOICED_COMMANDS =
  2072. + {
  2073. + "buffstore"
  2074. + };
  2075. +
  2076. + @Override
  2077. + public boolean useVoicedCommand(String command, Player activeChar, String params)
  2078. + {
  2079. + try
  2080. + {
  2081. + if (!Config.BUFF_STORE_ALLOWED_CLASS_LIST.contains(Integer.valueOf(activeChar.getClassId().getId())))
  2082. + {
  2083. + activeChar.sendMessage("Your profession is not allowed to set an Buff Store");
  2084. + return false;
  2085. + }
  2086. + NpcHtmlMessage html = new NpcHtmlMessage(0);
  2087. + html.setFile("command/buffstore/buff_store.htm");
  2088. + if (activeChar.getPrivateStoreType() == 20)
  2089. + {
  2090. + html.replace("%link%", activeChar.isLangRus() ? "Остановить продажу" : "Stop Store");
  2091. + html.replace("%bypass%", "bypass -h BuffStore stopstore");
  2092. + }
  2093. + else
  2094. + {
  2095. + html.replace("%link%", activeChar.isLangRus() ? "Создать продажу" : "Create Store");
  2096. + html.replace("%bypass%", "bypass -h player_help command/buffstore/buff_store_create.htm");
  2097. + }
  2098. + activeChar.sendPacket(html);
  2099. +
  2100. + return true;
  2101. + }
  2102. + catch (Exception e)
  2103. + {
  2104. + activeChar.sendMessage("Use: .buffstore");
  2105. + }
  2106. + return false;
  2107. + }
  2108. +
  2109. + @Override
  2110. + public String[] getVoicedCommandList()
  2111. + {
  2112. + return VOICED_COMMANDS;
  2113. + }
  2114. +}
  2115. Index: java/l2f/gameserver/network/clientpackets/EnterWorld.java
  2116. ===================================================================
  2117. --- java/l2f/gameserver/network/clientpackets/EnterWorld.java (revision 109)
  2118. +++ java/l2f/gameserver/network/clientpackets/EnterWorld.java (working copy)
  2119. @@ -77,6 +77,7 @@
  2120. import l2f.gameserver.network.serverpackets.components.ChatType;
  2121. import l2f.gameserver.network.serverpackets.components.SystemMsg;
  2122. import l2f.gameserver.skills.AbnormalEffect;
  2123. +import l2f.gameserver.tables.OfflineBuffersTable;
  2124. import l2f.gameserver.tables.SkillTable;
  2125. import l2f.gameserver.templates.item.ItemTemplate;
  2126. import l2f.gameserver.utils.GameStats;
  2127. @@ -95,30 +96,30 @@
  2128. public class EnterWorld extends L2GameClientPacket
  2129. {
  2130. private static final Object _lock = new Object();
  2131. -
  2132. +
  2133. private static final Logger _log = LoggerFactory.getLogger(EnterWorld.class);
  2134. -
  2135. +
  2136. @Override
  2137. protected void readImpl()
  2138. {
  2139. // readS(); - client always sends the string "narcasse"
  2140. }
  2141. -
  2142. +
  2143. @Override
  2144. protected void runImpl()
  2145. {
  2146. GameClient client = getClient();
  2147. Player activeChar = client.getActiveChar();
  2148. -
  2149. +
  2150. if (activeChar == null)
  2151. {
  2152. client.closeNow(false);
  2153. return;
  2154. }
  2155. -
  2156. +
  2157. int MyObjectId = activeChar.getObjectId();
  2158. Long MyStoreId = activeChar.getStoredId();
  2159. -
  2160. +
  2161. synchronized (_lock)// TODO [G1ta0] Th is for garbage, and why is it
  2162. // here
  2163. {
  2164. @@ -142,15 +143,15 @@
  2165. }
  2166. }
  2167. }
  2168. -
  2169. +
  2170. GameStats.incrementPlayerEnterGame();
  2171. // if(ConfigProtection.ALLOW_FGUARD)
  2172. // {
  2173. // ProtectionManager.SendSpecialSting(client);
  2174. // }
  2175. +
  2176. + boolean first = activeChar.entering;
  2177.  
  2178. - boolean first = activeChar.entering;
  2179. -
  2180. if (first)
  2181. {
  2182. activeChar.setOnlineStatus(true);
  2183. @@ -158,11 +159,11 @@
  2184. {
  2185. activeChar.setInvisibleType(InvisibleType.NORMAL);
  2186. }
  2187. -
  2188. +
  2189. activeChar.setNonAggroTime(Long.MAX_VALUE);
  2190. activeChar.spawnMe();
  2191. activeChar.setPendingOlyEnd(false);
  2192. -
  2193. +
  2194. if (activeChar.isInStoreMode())
  2195. {
  2196. if (!TradeHelper.checksIfCanOpenStore(activeChar, activeChar.getPrivateStoreType()))
  2197. @@ -172,32 +173,32 @@
  2198. activeChar.broadcastCharInfo();
  2199. }
  2200. }
  2201. -
  2202. +
  2203. activeChar.setRunning();
  2204. activeChar.standUp();
  2205. activeChar.startTimers();
  2206. }
  2207. -
  2208. +
  2209. activeChar.sendPacket(new ExBR_PremiumState(activeChar, activeChar.hasBonus()));
  2210. -
  2211. +
  2212. activeChar.getMacroses().sendUpdate();
  2213. activeChar.sendPacket(new SSQInfo(), new HennaInfo(activeChar));
  2214. activeChar.sendItemList(false);
  2215. activeChar.sendPacket(new ShortCutInit(activeChar), new SkillList(activeChar), new SkillCoolTime(activeChar));
  2216. activeChar.sendPacket(SystemMsg.WELCOME_TO_THE_WORLD_OF_LINEAGE_II);
  2217. -
  2218. +
  2219. // New char is Hero
  2220. if (Config.NEW_CHAR_IS_HERO)
  2221. {
  2222. activeChar.setHero(true);
  2223. }
  2224. -
  2225. +
  2226. // New char is NOBLE
  2227. if (Config.NEW_CHAR_IS_NOBLE)
  2228. {
  2229. activeChar.setNoble(true);
  2230. }
  2231. -
  2232. +
  2233. if (Config.HTML_WELCOME)
  2234. {
  2235. String html = HtmCache.getInstance().getNotNull("welcome.htm", activeChar);
  2236. @@ -205,28 +206,28 @@
  2237. msg.setHtml(Strings.bbParse(html));
  2238. activeChar.sendPacket(msg);
  2239. }
  2240. -
  2241. +
  2242. Announcements.getInstance().showAnnouncements(activeChar);
  2243. -
  2244. +
  2245. if (first)
  2246. {
  2247. activeChar.getListeners().onEnter();
  2248. }
  2249. -
  2250. +
  2251. SevenSigns.getInstance().sendCurrentPeriodMsg(activeChar);
  2252. -
  2253. +
  2254. if (first && (activeChar.getCreateTime() > 0))
  2255. {
  2256. Calendar create = Calendar.getInstance();
  2257. create.setTimeInMillis(activeChar.getCreateTime());
  2258. Calendar now = Calendar.getInstance();
  2259. -
  2260. +
  2261. int day = create.get(Calendar.DAY_OF_MONTH);
  2262. if ((create.get(Calendar.MONTH) == Calendar.FEBRUARY) && (day == 29))
  2263. {
  2264. day = 28;
  2265. }
  2266. -
  2267. +
  2268. int myBirthdayReceiveYear = activeChar.getVarInt(Player.MY_BIRTHDAY_RECEIVE_YEAR, 0);
  2269. if ((create.get(Calendar.MONTH) == now.get(Calendar.MONTH)) && (create.get(Calendar.DAY_OF_MONTH) == day))
  2270. {
  2271. @@ -239,60 +240,60 @@
  2272. mail.setReceiverName(activeChar.getName());
  2273. mail.setTopic(StringHolder.getInstance().getNotNull(activeChar, "birthday.title"));
  2274. mail.setBody(StringHolder.getInstance().getNotNull(activeChar, "birthday.text"));
  2275. -
  2276. +
  2277. ItemInstance item = ItemFunctions.createItem(21169);
  2278. item.setLocation(ItemInstance.ItemLocation.MAIL);
  2279. item.setCount(1L);
  2280. item.save();
  2281. -
  2282. +
  2283. mail.addAttachment(item);
  2284. mail.setUnread(true);
  2285. mail.setType(Mail.SenderType.BIRTHDAY);
  2286. mail.setExpireTime((720 * 3600) + (int) (System.currentTimeMillis() / 1000L));
  2287. mail.save();
  2288. -
  2289. +
  2290. activeChar.setVar(Player.MY_BIRTHDAY_RECEIVE_YEAR, String.valueOf(now.get(Calendar.YEAR)), -1);
  2291. }
  2292. }
  2293. }
  2294. -
  2295. +
  2296. if (activeChar.getClan() != null)
  2297. {
  2298. notifyClanMembers(activeChar);
  2299. -
  2300. +
  2301. activeChar.sendPacket(activeChar.getClan().listAll());
  2302. activeChar.sendPacket(new PledgeShowInfoUpdate(activeChar.getClan()), new PledgeSkillList(activeChar.getClan()));
  2303. }
  2304. -
  2305. +
  2306. // engage and notify Partner
  2307. if (first && Config.ALLOW_WEDDING)
  2308. {
  2309. CoupleManager.getInstance().engage(activeChar);
  2310. CoupleManager.getInstance().notifyPartner(activeChar);
  2311. }
  2312. -
  2313. +
  2314. if (Config.ENABLE_AUTO_HUNTING_REPORT)
  2315. {
  2316. AutoHuntingManager.getInstance().onEnter(activeChar);
  2317. }
  2318. -
  2319. +
  2320. if (first)
  2321. {
  2322. activeChar.getFriendList().notifyFriends(true);
  2323. loadTutorial(activeChar);
  2324. activeChar.restoreDisableSkills();
  2325. }
  2326. -
  2327. +
  2328. sendPacket(new L2FriendList(activeChar), new ExStorageMaxCount(activeChar), new QuestList(activeChar), new ExBasicActionList(activeChar), new EtcStatusUpdate(activeChar));
  2329. -
  2330. +
  2331. activeChar.checkHpMessages(activeChar.getMaxHp(), activeChar.getCurrentHp());
  2332. activeChar.checkDayNightMessages();
  2333. -
  2334. +
  2335. if (Config.PETITIONING_ALLOWED)
  2336. {
  2337. PetitionManager.getInstance().checkPetitionMessages(activeChar);
  2338. }
  2339. -
  2340. +
  2341. if (!first)
  2342. {
  2343. if (activeChar.isCastingNow())
  2344. @@ -305,31 +306,31 @@
  2345. sendPacket(new MagicSkillUse(activeChar, castingTarget, castingSkill.getId(), castingSkill.getLevel(), (int) (animationEndTime - System.currentTimeMillis()), 0));
  2346. }
  2347. }
  2348. -
  2349. +
  2350. if (activeChar.isInBoat())
  2351. {
  2352. activeChar.sendPacket(activeChar.getBoat().getOnPacket(activeChar, activeChar.getInBoatPosition()));
  2353. }
  2354. -
  2355. +
  2356. if (activeChar.isMoving || activeChar.isFollow)
  2357. {
  2358. sendPacket(activeChar.movePacket());
  2359. }
  2360. -
  2361. +
  2362. if (activeChar.getMountNpcId() != 0)
  2363. {
  2364. sendPacket(new Ride(activeChar));
  2365. }
  2366. -
  2367. +
  2368. if (activeChar.isFishing())
  2369. {
  2370. activeChar.stopFishing();
  2371. }
  2372. }
  2373. -
  2374. +
  2375. activeChar.entering = false;
  2376. activeChar.sendUserInfo(true);
  2377. -
  2378. +
  2379. if (activeChar.isSitting())
  2380. {
  2381. activeChar.sendPacket(new ChangeWaitType(activeChar, ChangeWaitType.WT_SITTING));
  2382. @@ -349,17 +350,17 @@
  2383. sendPacket(new RecipeShopMsg(activeChar));
  2384. }
  2385. }
  2386. -
  2387. +
  2388. if (activeChar.isDead())
  2389. {
  2390. sendPacket(new Die(activeChar));
  2391. }
  2392. -
  2393. +
  2394. activeChar.unsetVar("offline");
  2395. -
  2396. +
  2397. // just in case
  2398. activeChar.sendActionFailed();
  2399. -
  2400. +
  2401. if (first && activeChar.isGM() && Config.SAVE_GM_EFFECTS && activeChar.getPlayerAccess().CanUseGMCommand)
  2402. {
  2403. // silence
  2404. @@ -399,25 +400,32 @@
  2405. {
  2406. period /= 1000; // to seconds
  2407. period /= 60; // to minutes
  2408. -
  2409. +
  2410. activeChar.sendPacket(new Say2(0, ChatType.TELL, "Administration", "Sit left " + TimeUtils.minutesToFullString((int) period)));
  2411. }
  2412. }
  2413. PlayerMessageStack.getInstance().CheckMessages(activeChar);
  2414. -
  2415. +
  2416. sendPacket(ClientSetTime.STATIC, new ExSetCompassZoneCode(activeChar));
  2417. -
  2418. +
  2419. Pair<Integer, OnAnswerListener> entry = activeChar.getAskListener(false);
  2420. if ((entry != null) && (entry.getValue() instanceof ReviveAnswerListener))
  2421. {
  2422. sendPacket(new ConfirmDlg(SystemMsg.C1_IS_MAKING_AN_ATTEMPT_TO_RESURRECT_YOU_IF_YOU_CHOOSE_THIS_PATH_S2_EXPERIENCE_WILL_BE_RETURNED_FOR_YOU, 0).addString("Other player").addString("some"));
  2423. }
  2424. -
  2425. +
  2426. if (activeChar.isCursedWeaponEquipped())
  2427. {
  2428. CursedWeaponsManager.getInstance().showUsageTime(activeChar, activeChar.getCursedWeaponEquippedId());
  2429. }
  2430. -
  2431. + if (first)
  2432. + {
  2433. + activeChar.sendUserInfo();
  2434. + if (Config.BUFF_STORE_ENABLED)
  2435. + {
  2436. + OfflineBuffersTable.getInstance().onLogin(activeChar);
  2437. + }
  2438. + }
  2439. if (!first)
  2440. {
  2441. // Characters left while viewing
  2442. @@ -440,12 +448,12 @@
  2443. {
  2444. World.showObjectsToPlayer(activeChar);
  2445. }
  2446. -
  2447. +
  2448. if (activeChar.getPet() != null)
  2449. {
  2450. sendPacket(new PetInfo(activeChar.getPet()));
  2451. }
  2452. -
  2453. +
  2454. if (activeChar.isInParty())
  2455. {
  2456. Summon member_pet;
  2457. @@ -453,7 +461,7 @@
  2458. // we do all actions before adding member to a list, this speeds
  2459. // things up a little
  2460. sendPacket(new PartySmallWindowAll(activeChar.getParty(), activeChar));
  2461. -
  2462. +
  2463. for (Player member : activeChar.getParty().getPartyMembers())
  2464. {
  2465. if (member != activeChar)
  2466. @@ -463,11 +471,11 @@
  2467. {
  2468. sendPacket(new PartySpelled(member_pet, true));
  2469. }
  2470. -
  2471. +
  2472. sendPacket(RelationChanged.update(activeChar, member, activeChar));
  2473. }
  2474. }
  2475. -
  2476. +
  2477. // If the party is in the CC, the newcomer send the package open
  2478. // the CC
  2479. if (activeChar.getParty().isInCommandChannel())
  2480. @@ -475,12 +483,12 @@
  2481. sendPacket(ExMPCCOpen.STATIC);
  2482. }
  2483. }
  2484. -
  2485. +
  2486. for (int shotId : activeChar.getAutoSoulShot())
  2487. {
  2488. sendPacket(new ExAutoSoulShot(shotId, true));
  2489. }
  2490. -
  2491. +
  2492. for (Effect e : activeChar.getEffectList().getAllFirstEffects())
  2493. {
  2494. if (e.getSkill().isToggle())
  2495. @@ -488,39 +496,39 @@
  2496. sendPacket(new MagicSkillLaunched(activeChar.getObjectId(), e.getSkill().getId(), e.getSkill().getLevel(), activeChar));
  2497. }
  2498. }
  2499. -
  2500. +
  2501. activeChar.broadcastCharInfo();
  2502. }
  2503. else
  2504. {
  2505. activeChar.sendUserInfo(); // Display right in clan
  2506. }
  2507. -
  2508. +
  2509. activeChar.updateEffectIcons();
  2510. activeChar.updateStats();
  2511. -
  2512. +
  2513. if (Config.ALT_PCBANG_POINTS_ENABLED)
  2514. {
  2515. activeChar.sendPacket(new ExPCCafePointInfo(activeChar, 0, 1, 2, 12));
  2516. }
  2517. -
  2518. +
  2519. if (!activeChar.getPremiumItemList().isEmpty())
  2520. {
  2521. activeChar.sendPacket(Config.GOODS_INVENTORY_ENABLED ? ExGoodsInventoryChangedNotify.STATIC : ExNotifyPremiumItem.STATIC);
  2522. }
  2523. -
  2524. +
  2525. if (activeChar.getVarB("HeroPeriod") && Config.SERVICES_HERO_SELL_ENABLED)
  2526. {
  2527. activeChar.setHero(true);
  2528. }
  2529. -
  2530. +
  2531. activeChar.sendVoteSystemInfo();
  2532. activeChar.sendPacket(new ExReceiveShowPostFriend(activeChar));
  2533. activeChar.getNevitSystem().onEnterWorld();
  2534. -
  2535. +
  2536. checkNewMail(activeChar);
  2537. }
  2538. -
  2539. +
  2540. private static void notifyClanMembers(Player activeChar)
  2541. {
  2542. Clan clan = activeChar.getClan();
  2543. @@ -529,15 +537,15 @@
  2544. {
  2545. return;
  2546. }
  2547. -
  2548. +
  2549. UnitMember member = subUnit.getUnitMember(activeChar.getObjectId());
  2550. if (member == null)
  2551. {
  2552. return;
  2553. }
  2554. -
  2555. +
  2556. member.setPlayerInstance(activeChar, false);
  2557. -
  2558. +
  2559. int sponsor = activeChar.getSponsor();
  2560. int apprentice = activeChar.getApprentice();
  2561. L2GameServerPacket msg = new SystemMessage2(SystemMsg.CLAN_MEMBER_S1_HAS_LOGGED_INTO_GAME).addName(activeChar);
  2562. @@ -558,29 +566,29 @@
  2563. clanMember.sendPacket(msg);
  2564. }
  2565. }
  2566. -
  2567. +
  2568. if (!activeChar.isClanLeader())
  2569. {
  2570. return;
  2571. }
  2572. -
  2573. +
  2574. ClanHall clanHall = clan.getHasHideout() > 0 ? ResidenceHolder.getInstance().getResidence(ClanHall.class, clan.getHasHideout()) : null;
  2575. - if ((clanHall == null) || (clanHall.getAuctionLength() != 0))
  2576. - {
  2577. - return;
  2578. - }
  2579. -
  2580. + if ((clanHall == null) || (clanHall.getAuctionLength() != 0))
  2581. + {
  2582. + return;
  2583. + }
  2584. +
  2585. if (clanHall.getSiegeEvent().getClass() != ClanHallAuctionEvent.class)
  2586. - {
  2587. - return;
  2588. - }
  2589. -
  2590. + {
  2591. + return;
  2592. + }
  2593. +
  2594. if (clan.getWarehouse().getCountOf(ItemTemplate.ITEM_ID_ADENA) < clanHall.getRentalFee())
  2595. - {
  2596. - activeChar.sendPacket(new SystemMessage2(SystemMsg.PAYMENT_FOR_YOUR_CLAN_HALL_HAS_NOT_BEEN_MADE_PLEASE_ME_PAYMENT_TO_YOUR_CLAN_WAREHOUSE_BY_S1_TOMORROW).addLong(clanHall.getRentalFee()));
  2597. - }
  2598. + {
  2599. + activeChar.sendPacket(new SystemMessage2(SystemMsg.PAYMENT_FOR_YOUR_CLAN_HALL_HAS_NOT_BEEN_MADE_PLEASE_ME_PAYMENT_TO_YOUR_CLAN_WAREHOUSE_BY_S1_TOMORROW).addLong(clanHall.getRentalFee()));
  2600. + }
  2601. }
  2602. -
  2603. +
  2604. private void loadTutorial(Player player)
  2605. {
  2606. Quest q = QuestManager.getQuest(255);
  2607. @@ -589,7 +597,7 @@
  2608. player.processQuestEvent(q.getName(), "UC", null);
  2609. }
  2610. }
  2611. -
  2612. +
  2613. private void checkNewMail(Player activeChar)
  2614. {
  2615. for (Mail mail : MailDAO.getInstance().getReceivedMailByOwnerId(activeChar.getObjectId()))
  2616. Index: dist/gameserver/data/html-en/command/buffstore/buff_store_create.htm
  2617. ===================================================================
  2618. --- dist/gameserver/data/html-en/command/buffstore/buff_store_create.htm (revision 0)
  2619. +++ dist/gameserver/data/html-en/command/buffstore/buff_store_create.htm (working copy)
  2620. @@ -0,0 +1,20 @@
  2621. +<!-- HTML Buff Store en el Panel -->
  2622. +<html noscrollbar><head><title>Buff Store</title><body scroll="no">
  2623. +<table border=0 cellpadding=0 cellspacing=0 width=292 height=358 background=L2UI_CH3.refinewnd_back_Pattern>
  2624. +<tr><td valign="top" align="center">
  2625. + <table border=0 cellpadding=0 cellspacing=0>
  2626. + <tr><td height=20></td></tr>
  2627. + <tr><td align=center><font color=91785a name=GameDefault>Buff Store</font></td></tr>
  2628. + <tr><td height=20></td></tr>
  2629. + <tr><td fixwidth=260><font color=b5b5b5>Here you can set a Private Buff Store.<br></font></td></tr>
  2630. + <tr><td fixwidth=260><font color=b5b5b5>Other players will be able to purchase your buffs directly from an interface when clicking on you.<br></font></td></tr>
  2631. + <tr><td fixwidth=260><font color=b5b5b5>Set the title of your store and the price you want to charge for every buff you sell and you are done.<br></font></td></tr>
  2632. + <tr><td height=5></td></tr>
  2633. + <tr><td align=center>Title: <multiedit var="title" width=220 height=15></td></tr>
  2634. + <tr><td height=15></td></tr>
  2635. + <tr><td align=center>Price: <edit type="number" var="price" width=160 height=15></td></tr>
  2636. + <tr><td height=25></td></tr>
  2637. + <tr><td align=center><button value="Create Store" action="bypass -h BuffStore setstore $price $title" width=200 height=31 back=L2UI_CT1.OlympiadWnd_DF_Watch_Down fore=L2UI_CT1.OlympiadWnd_DF_Watch></td></tr>
  2638. + </table>
  2639. +</td></tr></table>
  2640. +</body></html>
  2641. \ No newline at end of file
  2642. Index: java/l2f/gameserver/model/Zone.java
  2643. ===================================================================
  2644. --- java/l2f/gameserver/model/Zone.java (revision 109)
  2645. +++ java/l2f/gameserver/model/Zone.java (working copy)
  2646. @@ -64,6 +64,7 @@
  2647. dummy,
  2648. offshore,
  2649. epic,
  2650. + buff_store_only,
  2651. }
  2652.  
  2653. public enum ZoneTarget
  2654. @@ -138,7 +139,7 @@
  2655. }
  2656.  
  2657. @Override
  2658. - public void runImpl() throws Exception
  2659. + public void runImpl()
  2660. {
  2661. if (!isActive())
  2662. {
  2663. @@ -258,8 +259,8 @@
  2664. private final Lock readLock = lock.readLock();
  2665. private final Lock writeLock = lock.writeLock();
  2666.  
  2667. - private final List<Creature> _objects = new LazyArrayList<Creature>(32);
  2668. - private final Map<Creature, ZoneTimer> _zoneTimers = new ConcurrentHashMap<Creature, ZoneTimer>();
  2669. + private final List<Creature> _objects = new LazyArrayList<>(32);
  2670. + private final Map<Creature, ZoneTimer> _zoneTimers = new ConcurrentHashMap<>();
  2671.  
  2672. /**
  2673. * Ордер в зонах, с ним мы и добавляем/убираем статы. TODO: сравнить ордер с оффом, пока от фонаря
  2674. @@ -498,6 +499,10 @@
  2675.  
  2676. if (actor.isPlayer())
  2677. {
  2678. + if (getType() == ZoneType.buff_store_only)
  2679. + {
  2680. + actor.sendMessage("You have entered a Buff Store Only Zone");
  2681. + }
  2682. if (getEnteringMessageId() != 0)
  2683. {
  2684. actor.sendPacket(new SystemMessage2(SystemMsg.valueOf(getEnteringMessageId())));
  2685. @@ -550,6 +555,10 @@
  2686.  
  2687. if (actor.isPlayer())
  2688. {
  2689. + if (getType() == ZoneType.buff_store_only)
  2690. + {
  2691. + actor.sendMessage("You have left the Buff Store Only Zone");
  2692. + }
  2693. if ((getLeavingMessageId() != 0) && actor.isPlayer())
  2694. {
  2695. actor.sendPacket(new SystemMessage2(SystemMsg.valueOf(getLeavingMessageId())));
  2696. @@ -664,7 +673,7 @@
  2697. * @param cha персонаж
  2698. * @return подошел ли
  2699. */
  2700. - private boolean checkTarget(Creature cha)
  2701. + boolean checkTarget(Creature cha)
  2702. {
  2703. switch (getZoneTarget())
  2704. {
  2705. @@ -722,7 +731,7 @@
  2706.  
  2707. public List<Player> getInsidePlayers()
  2708. {
  2709. - List<Player> result = new LazyArrayList<Player>();
  2710. + List<Player> result = new LazyArrayList<>();
  2711. readLock.lock();
  2712. try
  2713. {
  2714. @@ -744,7 +753,7 @@
  2715.  
  2716. public List<Playable> getInsidePlayables()
  2717. {
  2718. - List<Playable> result = new LazyArrayList<Playable>();
  2719. + List<Playable> result = new LazyArrayList<>();
  2720. readLock.lock();
  2721. try
  2722. {
  2723. @@ -766,7 +775,7 @@
  2724.  
  2725. public List<NpcInstance> getInsideNpcs()
  2726. {
  2727. - List<NpcInstance> result = new LazyArrayList<NpcInstance>();
  2728. + List<NpcInstance> result = new LazyArrayList<>();
  2729. readLock.lock();
  2730. try
  2731. {
  2732. Index: java/l2f/gameserver/model/Player.java
  2733. ===================================================================
  2734. --- java/l2f/gameserver/model/Player.java (revision 109)
  2735. +++ java/l2f/gameserver/model/Player.java (working copy)
  2736. @@ -81,6 +81,7 @@
  2737. import l2f.gameserver.instancemanager.CursedWeaponsManager;
  2738. import l2f.gameserver.instancemanager.DimensionalRiftManager;
  2739. import l2f.gameserver.instancemanager.MatchingRoomManager;
  2740. +import l2f.gameserver.instancemanager.OfflineBufferManager;
  2741. import l2f.gameserver.instancemanager.QuestManager;
  2742. import l2f.gameserver.instancemanager.ReflectionManager;
  2743. import l2f.gameserver.instancemanager.games.HandysBlockCheckerManager;
  2744. @@ -267,6 +268,7 @@
  2745. import l2f.gameserver.stats.Stats;
  2746. import l2f.gameserver.stats.funcs.FuncTemplate;
  2747. import l2f.gameserver.tables.ClanTable;
  2748. +import l2f.gameserver.tables.OfflineBuffersTable;
  2749. import l2f.gameserver.tables.PetDataTable;
  2750. import l2f.gameserver.tables.SkillTable;
  2751. import l2f.gameserver.tables.SkillTreeTable;
  2752. @@ -334,7 +336,7 @@
  2753. public static final int STORE_PRIVATE_MANUFACTURE = 5;
  2754. public static final int STORE_OBSERVING_GAMES = 7;
  2755. public static final int STORE_PRIVATE_SELL_PACKAGE = 8;
  2756. -
  2757. + public static final int STORE_PRIVATE_BUFF = 20;
  2758. public static final int RANK_VAGABOND = 0;
  2759. public static final int RANK_VASSAL = 1;
  2760. public static final int RANK_HEIR = 2;
  2761. @@ -3523,6 +3525,10 @@
  2762. sendPacket(new RecipeShopSellList(this, temp));
  2763. sendActionFailed();
  2764. }
  2765. + else if (temp.getPrivateStoreType() == STORE_PRIVATE_BUFF)
  2766. + {
  2767. + OfflineBufferManager.getInstance().processBypass(this, "BuffStore bufflist " + temp.getObjectId());
  2768. + }
  2769. sendActionFailed();
  2770. }
  2771. else if (getAI().getIntention() != CtrlIntention.AI_INTENTION_INTERACT)
  2772. @@ -7278,7 +7284,84 @@
  2773. {
  2774. return _partyMatchingVisible;
  2775. }
  2776. -
  2777. +
  2778. + public boolean isInBuffStore()
  2779. + {
  2780. + return getPrivateStoreType() == 20;
  2781. + }
  2782. +
  2783. + public void offlineBuffStore()
  2784. + {
  2785. + if (this._connection != null)
  2786. + {
  2787. + this._connection.setActiveChar(null);
  2788. + this._connection.close(ServerClose.STATIC);
  2789. + setNetConnection(null);
  2790. + }
  2791. + setOfflineMode(true);
  2792. +
  2793. + Party party = getParty();
  2794. + if (party != null)
  2795. + {
  2796. + if (isFestivalParticipant())
  2797. + {
  2798. + party.broadcastMessageToPartyMembers(getName() + " has been removed from the upcoming festival.");
  2799. + }
  2800. + leaveParty();
  2801. + }
  2802. + if (getPet() != null)
  2803. + {
  2804. + getPet().unSummon();
  2805. + }
  2806. + CursedWeaponsManager.getInstance().doLogout(this);
  2807. + if ((isInOlympiadMode()) || (getOlympiadGame() != null))
  2808. + {
  2809. + Olympiad.logoutPlayer(this);
  2810. + }
  2811. + if (isInObserverMode())
  2812. + {
  2813. + if (getOlympiadObserveGame() == null)
  2814. + {
  2815. + leaveObserverMode();
  2816. + }
  2817. + else
  2818. + {
  2819. + leaveOlympiadObserverMode(true);
  2820. + }
  2821. + this._observerMode.set(0);
  2822. + }
  2823. + setNameColor(Config.BUFF_STORE_OFFLINE_NAME_COLOR);
  2824. + broadcastCharInfo();
  2825. +
  2826. + OfflineBuffersTable.getInstance().onLogout(this);
  2827. +
  2828. + stopWaterTask();
  2829. + stopBonusTask();
  2830. + stopHourlyTask();
  2831. + stopVitalityTask();
  2832. + stopPcBangPointsTask();
  2833. + stopAutoSaveTask();
  2834. + stopRecomBonusTask(true);
  2835. + stopQuestTimers();
  2836. + getNevitSystem().stopTasksOnLogout();
  2837. + try
  2838. + {
  2839. + getInventory().store();
  2840. + }
  2841. + catch (Throwable t)
  2842. + {
  2843. + _log.error("Error while storing Player Inventory", t);
  2844. + }
  2845. + try
  2846. + {
  2847. + store(false);
  2848. + }
  2849. + catch (Throwable t)
  2850. + {
  2851. + _log.error("Error while storing Player", t);
  2852. + }
  2853. + }
  2854. +
  2855. public void enterOlympiadObserverMode(Location loc, OlympiadGame game, Reflection reflect)
  2856. {
  2857. WorldRegion observerRegion = World.getRegion(loc);
  2858. Index: java/l2f/gameserver/tables/OfflineBuffersTable.java
  2859. ===================================================================
  2860. --- java/l2f/gameserver/tables/OfflineBuffersTable.java (revision 0)
  2861. +++ java/l2f/gameserver/tables/OfflineBuffersTable.java (working copy)
  2862. @@ -0,0 +1,197 @@
  2863. +package l2f.gameserver.tables;
  2864. +
  2865. +import java.sql.Connection;
  2866. +import java.sql.PreparedStatement;
  2867. +import java.sql.ResultSet;
  2868. +import java.util.Collection;
  2869. +
  2870. +import l2f.commons.dbutils.DbUtils;
  2871. +import l2f.gameserver.Config;
  2872. +import l2f.gameserver.database.DatabaseFactory;
  2873. +import l2f.gameserver.instancemanager.OfflineBufferManager;
  2874. +import l2f.gameserver.model.Player;
  2875. +import l2f.gameserver.model.Skill;
  2876. +
  2877. +import org.slf4j.Logger;
  2878. +import org.slf4j.LoggerFactory;
  2879. +
  2880. +public class OfflineBuffersTable
  2881. +{
  2882. + private static final Logger _log = LoggerFactory.getLogger(OfflineBuffersTable.class);
  2883. +
  2884. + public void restoreOfflineBuffers()
  2885. + {
  2886. + _log.info(getClass().getSimpleName() + ": Loading offline buffers...");
  2887. +
  2888. + Connection con = null;
  2889. + PreparedStatement statement = null;
  2890. + ResultSet rset = null;
  2891. + try
  2892. + {
  2893. + con = DatabaseFactory.getInstance().getConnection();
  2894. +
  2895. + statement = con.prepareStatement("SELECT * FROM character_offline_buffers WHERE charId > 0");
  2896. + rset = statement.executeQuery();
  2897. + int nBuffers = 0;
  2898. + while (rset.next())
  2899. + {
  2900. + Player player = null;
  2901. + try
  2902. + {
  2903. + player = Player.restore(rset.getInt("charId"));
  2904. + if (player != null)
  2905. + {
  2906. + player.setOfflineMode(true);
  2907. + player.setIsOnline(true);
  2908. + player.updateOnlineStatus();
  2909. + player.spawnMe();
  2910. + if ((player.getClan() != null) && (player.getClan().getAnyMember(player.getObjectId()) != null))
  2911. + {
  2912. + player.getClan().getAnyMember(player.getObjectId()).setPlayerInstance(player, false);
  2913. + }
  2914. + OfflineBufferManager.BufferData buffer = new OfflineBufferManager.BufferData(player, rset.getString("title"), rset.getInt("price"), null);
  2915. +
  2916. + statement = con.prepareStatement("SELECT * FROM character_offline_buffer_buffs WHERE charId = ?");
  2917. + try
  2918. + {
  2919. + statement.setInt(1, player.getObjectId());
  2920. + rset = statement.executeQuery();
  2921. + try
  2922. + {
  2923. + if (rset.next())
  2924. + {
  2925. + String[] skillIds = rset.getString("skillIds").split(",");
  2926. + for (String skillId : skillIds)
  2927. + {
  2928. + Skill skill = player.getKnownSkill(Integer.parseInt(skillId));
  2929. + if (skill != null)
  2930. + {
  2931. + buffer.getBuffs().put(Integer.valueOf(skill.getId()), skill);
  2932. + }
  2933. + }
  2934. + }
  2935. + }
  2936. + catch (Exception e)
  2937. + {
  2938. + e.printStackTrace();
  2939. + }
  2940. + }
  2941. + catch (Exception e)
  2942. + {
  2943. + e.printStackTrace();
  2944. + }
  2945. + OfflineBufferManager.getInstance().getBuffStores().put(Integer.valueOf(player.getObjectId()), buffer);
  2946. + player.sitDown(null);
  2947. + player.setTitleColor(Config.BUFF_STORE_TITLE_COLOR);
  2948. + player.setTitle(buffer.getSaleTitle());
  2949. + player.setNameColor(Config.BUFF_STORE_OFFLINE_NAME_COLOR);
  2950. + player.setPrivateStoreType(20);
  2951. + player.broadcastUserInfo(true);
  2952. + nBuffers++;
  2953. + }
  2954. + }
  2955. + catch (Exception e)
  2956. + {
  2957. + _log.warn(getClass().getSimpleName() + ": Error loading buffer: " + player, e);
  2958. + if (player != null)
  2959. + {
  2960. + player.deleteMe();
  2961. + }
  2962. + }
  2963. + }
  2964. + _log.info(getClass().getSimpleName() + ": Loaded: " + nBuffers + " offline buffer(s)");
  2965. + }
  2966. + catch (Exception e)
  2967. + {
  2968. + e.printStackTrace();
  2969. + }
  2970. + finally
  2971. + {
  2972. + DbUtils.closeQuietly(con, statement, rset);
  2973. + }
  2974. + }
  2975. +
  2976. + public synchronized void onLogin(Player trader)
  2977. + {
  2978. + Connection con = null;
  2979. + PreparedStatement statement = null;
  2980. + try
  2981. + {
  2982. + con = DatabaseFactory.getInstance().getConnection();
  2983. + OfflineBufferManager.getInstance().getBuffStores().remove(Integer.valueOf(trader.getObjectId()));
  2984. + statement = con.prepareStatement("DELETE FROM character_offline_buffers WHERE charId=?");
  2985. + statement.setInt(1, trader.getObjectId());
  2986. + statement.executeUpdate();
  2987. +
  2988. + statement = con.prepareStatement("DELETE FROM character_offline_buffer_buffs WHERE charId=?");
  2989. + statement.setInt(1, trader.getObjectId());
  2990. + statement.executeUpdate();
  2991. + }
  2992. + catch (Exception e)
  2993. + {
  2994. + e.printStackTrace();
  2995. + }
  2996. + finally
  2997. + {
  2998. + DbUtils.closeQuietly(con, statement);
  2999. + }
  3000. + }
  3001. +
  3002. + public synchronized void onLogout(Player trader)
  3003. + {
  3004. + OfflineBufferManager.BufferData buffer = OfflineBufferManager.getInstance().getBuffStores().get(Integer.valueOf(trader.getObjectId()));
  3005. + if (buffer == null)
  3006. + {
  3007. + return;
  3008. + }
  3009. + Connection con = null;
  3010. + PreparedStatement statement = null;
  3011. + try
  3012. + {
  3013. + con = DatabaseFactory.getInstance().getConnection();
  3014. + statement = con.prepareStatement("REPLACE INTO character_offline_buffers VALUES (?,?,?)");
  3015. +
  3016. + statement.setInt(1, trader.getObjectId());
  3017. + statement.setInt(2, buffer.getBuffPrice());
  3018. + statement.setString(3, buffer.getSaleTitle());
  3019. + statement.executeUpdate();
  3020. +
  3021. + statement = con.prepareStatement("REPLACE INTO character_offline_buffer_buffs VALUES (?,?)");
  3022. + statement.setInt(1, trader.getObjectId());
  3023. + statement.setString(2, joinAllSkillsToString(buffer.getBuffs().values()));
  3024. + statement.executeUpdate();
  3025. + }
  3026. + catch (Exception e)
  3027. + {
  3028. + e.printStackTrace();
  3029. + }
  3030. + finally
  3031. + {
  3032. + DbUtils.closeQuietly(con, statement);
  3033. + }
  3034. + }
  3035. +
  3036. + private final String joinAllSkillsToString(Collection<Skill> skills)
  3037. + {
  3038. + if (skills.isEmpty())
  3039. + {
  3040. + return "";
  3041. + }
  3042. + String result = "";
  3043. + for (Skill val : skills)
  3044. + {
  3045. + result = result + val.getId() + ",";
  3046. + }
  3047. + return result.substring(0, result.length() - 1);
  3048. + }
  3049. +
  3050. + public static OfflineBuffersTable getInstance()
  3051. + {
  3052. + return SingletonHolder._instance;
  3053. + }
  3054. +
  3055. + private static class SingletonHolder
  3056. + {
  3057. + protected static final OfflineBuffersTable _instance = new OfflineBuffersTable();
  3058. + }
  3059. +}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement