AbstractMessagePacket.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. /*
  2. * Copyright (C) 2004-2015 L2J Server
  3. *
  4. * This file is part of L2J Server.
  5. *
  6. * L2J Server is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * L2J Server is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package com.l2jserver.gameserver.network.serverpackets;
  20. import java.io.PrintStream;
  21. import java.util.Arrays;
  22. import java.util.logging.Level;
  23. import com.l2jserver.Config;
  24. import com.l2jserver.gameserver.data.xml.impl.DoorData;
  25. import com.l2jserver.gameserver.data.xml.impl.NpcData;
  26. import com.l2jserver.gameserver.datatables.ItemTable;
  27. import com.l2jserver.gameserver.datatables.SkillData;
  28. import com.l2jserver.gameserver.instancemanager.CastleManager;
  29. import com.l2jserver.gameserver.instancemanager.InstanceManager;
  30. import com.l2jserver.gameserver.instancemanager.ZoneManager;
  31. import com.l2jserver.gameserver.model.Elementals;
  32. import com.l2jserver.gameserver.model.actor.L2Character;
  33. import com.l2jserver.gameserver.model.actor.L2Npc;
  34. import com.l2jserver.gameserver.model.actor.L2Summon;
  35. import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
  36. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  37. import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
  38. import com.l2jserver.gameserver.model.entity.Castle;
  39. import com.l2jserver.gameserver.model.items.L2Item;
  40. import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
  41. import com.l2jserver.gameserver.model.skills.Skill;
  42. import com.l2jserver.gameserver.model.zone.L2ZoneType;
  43. import com.l2jserver.gameserver.network.SystemMessageId;
  44. import com.l2jserver.gameserver.network.SystemMessageId.SMLocalisation;
  45. /**
  46. * @author UnAfraid
  47. * @param <T>
  48. */
  49. @SuppressWarnings("unchecked")
  50. public abstract class AbstractMessagePacket<T extends AbstractMessagePacket<?>> extends L2GameServerPacket
  51. {
  52. private static final SMParam[] EMPTY_PARAM_ARRAY = new SMParam[0];
  53. private static final class SMParam
  54. {
  55. private final byte _type;
  56. private final Object _value;
  57. public SMParam(final byte type, final Object value)
  58. {
  59. _type = type;
  60. _value = value;
  61. }
  62. public final byte getType()
  63. {
  64. return _type;
  65. }
  66. public final Object getValue()
  67. {
  68. return _value;
  69. }
  70. public final String getStringValue()
  71. {
  72. return (String) _value;
  73. }
  74. public final int getIntValue()
  75. {
  76. return ((Integer) _value).intValue();
  77. }
  78. public final long getLongValue()
  79. {
  80. return ((Long) _value).longValue();
  81. }
  82. public final int[] getIntArrayValue()
  83. {
  84. return (int[]) _value;
  85. }
  86. }
  87. // TODO: UnAfraid: Check/Implement id's: 14,15.
  88. // 15 exists in goddess of destruction but also may works in h5 needs to be verified!
  89. // private static final byte TYPE_CLASS_ID = 15;
  90. // id 14 unknown
  91. private static final byte TYPE_SYSTEM_STRING = 13;
  92. private static final byte TYPE_PLAYER_NAME = 12;
  93. private static final byte TYPE_DOOR_NAME = 11;
  94. private static final byte TYPE_INSTANCE_NAME = 10;
  95. private static final byte TYPE_ELEMENT_NAME = 9;
  96. // id 8 - same as 3
  97. private static final byte TYPE_ZONE_NAME = 7;
  98. private static final byte TYPE_LONG_NUMBER = 6;
  99. private static final byte TYPE_CASTLE_NAME = 5;
  100. private static final byte TYPE_SKILL_NAME = 4;
  101. private static final byte TYPE_ITEM_NAME = 3;
  102. private static final byte TYPE_NPC_NAME = 2;
  103. private static final byte TYPE_INT_NUMBER = 1;
  104. private static final byte TYPE_TEXT = 0;
  105. private SMParam[] _params;
  106. private final SystemMessageId _smId;
  107. private int _paramIndex;
  108. public AbstractMessagePacket(SystemMessageId smId)
  109. {
  110. if (smId == null)
  111. {
  112. throw new NullPointerException("SystemMessageId cannot be null!");
  113. }
  114. _smId = smId;
  115. _params = smId.getParamCount() > 0 ? new SMParam[smId.getParamCount()] : EMPTY_PARAM_ARRAY;
  116. }
  117. public final int getId()
  118. {
  119. return _smId.getId();
  120. }
  121. public final SystemMessageId getSystemMessageId()
  122. {
  123. return _smId;
  124. }
  125. private final void append(SMParam param)
  126. {
  127. if (_paramIndex >= _params.length)
  128. {
  129. _params = Arrays.copyOf(_params, _paramIndex + 1);
  130. _smId.setParamCount(_paramIndex + 1);
  131. _log.log(Level.INFO, "Wrong parameter count '" + (_paramIndex + 1) + "' for SystemMessageId: " + _smId);
  132. }
  133. _params[_paramIndex++] = param;
  134. }
  135. public final T addString(final String text)
  136. {
  137. append(new SMParam(TYPE_TEXT, text));
  138. return (T) this;
  139. }
  140. /**
  141. * Appends a Castle name parameter type, the name will be read from CastleName-e.dat.<br>
  142. * <ul>
  143. * <li>1-9 Castle names</li>
  144. * <li>21 Fortress of Resistance</li>
  145. * <li>22-33 Clan Hall names</li>
  146. * <li>34 Devastated Castle</li>
  147. * <li>35 Bandit Stronghold</li>
  148. * <li>36-61 Clan Hall names</li>
  149. * <li>62 Rainbow Springs</li>
  150. * <li>63 Wild Beast Reserve</li>
  151. * <li>64 Fortress of the Dead</li>
  152. * <li>81-89 Territory names</li>
  153. * <li>90-100 null</li>
  154. * <li>101-121 Fortress names</li>
  155. * </ul>
  156. * @param number the conquerable entity
  157. * @return the system message with the proper parameter
  158. */
  159. public final T addCastleId(final int number)
  160. {
  161. append(new SMParam(TYPE_CASTLE_NAME, number));
  162. return (T) this;
  163. }
  164. public final T addInt(final int number)
  165. {
  166. append(new SMParam(TYPE_INT_NUMBER, number));
  167. return (T) this;
  168. }
  169. public final T addLong(final long number)
  170. {
  171. append(new SMParam(TYPE_LONG_NUMBER, number));
  172. return (T) this;
  173. }
  174. public final T addCharName(final L2Character cha)
  175. {
  176. if (cha.isNpc())
  177. {
  178. final L2Npc npc = (L2Npc) cha;
  179. if (npc.getTemplate().isUsingServerSideName())
  180. {
  181. return addString(npc.getTemplate().getName());
  182. }
  183. return addNpcName(npc);
  184. }
  185. else if (cha.isPlayer())
  186. {
  187. return addPcName(cha.getActingPlayer());
  188. }
  189. else if (cha.isSummon())
  190. {
  191. final L2Summon summon = (L2Summon) cha;
  192. if (summon.getTemplate().isUsingServerSideName())
  193. {
  194. return addString(summon.getTemplate().getName());
  195. }
  196. return addNpcName(summon);
  197. }
  198. else if (cha.isDoor())
  199. {
  200. final L2DoorInstance door = (L2DoorInstance) cha;
  201. return addDoorName(door.getId());
  202. }
  203. return addString(cha.getName());
  204. }
  205. public final T addPcName(final L2PcInstance pc)
  206. {
  207. append(new SMParam(TYPE_PLAYER_NAME, pc.getAppearance().getVisibleName()));
  208. return (T) this;
  209. }
  210. /**
  211. * ID from doorData.xml
  212. * @param doorId
  213. * @return
  214. */
  215. public final T addDoorName(int doorId)
  216. {
  217. append(new SMParam(TYPE_DOOR_NAME, doorId));
  218. return (T) this;
  219. }
  220. public final T addNpcName(L2Npc npc)
  221. {
  222. return addNpcName(npc.getTemplate());
  223. }
  224. public final T addNpcName(final L2Summon npc)
  225. {
  226. return addNpcName(npc.getId());
  227. }
  228. public final T addNpcName(final L2NpcTemplate template)
  229. {
  230. if (template.isUsingServerSideName())
  231. {
  232. return addString(template.getName());
  233. }
  234. return addNpcName(template.getId());
  235. }
  236. public final T addNpcName(final int id)
  237. {
  238. append(new SMParam(TYPE_NPC_NAME, 1000000 + id));
  239. return (T) this;
  240. }
  241. public T addItemName(final L2ItemInstance item)
  242. {
  243. return addItemName(item.getId());
  244. }
  245. public T addItemName(final L2Item item)
  246. {
  247. return addItemName(item.getId());
  248. }
  249. public final T addItemName(final int id)
  250. {
  251. final L2Item item = ItemTable.getInstance().getTemplate(id);
  252. if (item.getDisplayId() != id)
  253. {
  254. return addString(item.getName());
  255. }
  256. append(new SMParam(TYPE_ITEM_NAME, id));
  257. return (T) this;
  258. }
  259. public final T addZoneName(final int x, final int y, final int z)
  260. {
  261. append(new SMParam(TYPE_ZONE_NAME, new int[]
  262. {
  263. x,
  264. y,
  265. z
  266. }));
  267. return (T) this;
  268. }
  269. public final T addSkillName(final Skill skill)
  270. {
  271. if (skill.getId() != skill.getDisplayId())
  272. {
  273. return addString(skill.getName());
  274. }
  275. return addSkillName(skill.getId(), skill.getLevel());
  276. }
  277. public final T addSkillName(final int id)
  278. {
  279. return addSkillName(id, 1);
  280. }
  281. public final T addSkillName(final int id, final int lvl)
  282. {
  283. append(new SMParam(TYPE_SKILL_NAME, new int[]
  284. {
  285. id,
  286. lvl
  287. }));
  288. return (T) this;
  289. }
  290. /**
  291. * Elemental name - 0(Fire) ...
  292. * @param type
  293. * @return
  294. */
  295. public final T addElemental(final int type)
  296. {
  297. append(new SMParam(TYPE_ELEMENT_NAME, type));
  298. return (T) this;
  299. }
  300. /**
  301. * ID from sysstring-e.dat
  302. * @param type
  303. * @return
  304. */
  305. public final T addSystemString(final int type)
  306. {
  307. append(new SMParam(TYPE_SYSTEM_STRING, type));
  308. return (T) this;
  309. }
  310. /**
  311. * Instance name from instantzonedata-e.dat
  312. * @param type id of instance
  313. * @return
  314. */
  315. public final T addInstanceName(final int type)
  316. {
  317. append(new SMParam(TYPE_INSTANCE_NAME, type));
  318. return (T) this;
  319. }
  320. protected final void writeMe()
  321. {
  322. writeD(getId());
  323. writeD(_params.length);
  324. SMParam param;
  325. for (int i = 0; i < _paramIndex; i++)
  326. {
  327. param = _params[i];
  328. writeD(param.getType());
  329. switch (param.getType())
  330. {
  331. case TYPE_TEXT:
  332. case TYPE_PLAYER_NAME:
  333. {
  334. writeS(param.getStringValue());
  335. break;
  336. }
  337. case TYPE_LONG_NUMBER:
  338. {
  339. writeQ(param.getLongValue());
  340. break;
  341. }
  342. case TYPE_ITEM_NAME:
  343. case TYPE_CASTLE_NAME:
  344. case TYPE_INT_NUMBER:
  345. case TYPE_NPC_NAME:
  346. case TYPE_ELEMENT_NAME:
  347. case TYPE_SYSTEM_STRING:
  348. case TYPE_INSTANCE_NAME:
  349. case TYPE_DOOR_NAME:
  350. {
  351. writeD(param.getIntValue());
  352. break;
  353. }
  354. case TYPE_SKILL_NAME:
  355. {
  356. final int[] array = param.getIntArrayValue();
  357. writeD(array[0]); // SkillId
  358. writeD(array[1]); // SkillLevel
  359. break;
  360. }
  361. case TYPE_ZONE_NAME:
  362. {
  363. final int[] array = param.getIntArrayValue();
  364. writeD(array[0]); // x
  365. writeD(array[1]); // y
  366. writeD(array[2]); // z
  367. break;
  368. }
  369. }
  370. }
  371. }
  372. public final void printMe(PrintStream out)
  373. {
  374. out.println(0x62);
  375. out.println(getId());
  376. out.println(_params.length);
  377. for (SMParam param : _params)
  378. {
  379. switch (param.getType())
  380. {
  381. case TYPE_TEXT:
  382. case TYPE_PLAYER_NAME:
  383. {
  384. out.println(param.getStringValue());
  385. break;
  386. }
  387. case TYPE_LONG_NUMBER:
  388. {
  389. out.println(param.getLongValue());
  390. break;
  391. }
  392. case TYPE_ITEM_NAME:
  393. case TYPE_CASTLE_NAME:
  394. case TYPE_INT_NUMBER:
  395. case TYPE_NPC_NAME:
  396. case TYPE_ELEMENT_NAME:
  397. case TYPE_SYSTEM_STRING:
  398. case TYPE_INSTANCE_NAME:
  399. case TYPE_DOOR_NAME:
  400. {
  401. out.println(param.getIntValue());
  402. break;
  403. }
  404. case TYPE_SKILL_NAME:
  405. {
  406. final int[] array = param.getIntArrayValue();
  407. out.println(array[0]); // SkillId
  408. out.println(array[1]); // SkillLevel
  409. break;
  410. }
  411. case TYPE_ZONE_NAME:
  412. {
  413. final int[] array = param.getIntArrayValue();
  414. out.println(array[0]); // x
  415. out.println(array[1]); // y
  416. out.println(array[2]); // z
  417. break;
  418. }
  419. }
  420. }
  421. }
  422. public final T getLocalizedMessage(final String lang)
  423. {
  424. if (!Config.L2JMOD_MULTILANG_SM_ENABLE || (getSystemMessageId() == SystemMessageId.S1))
  425. {
  426. return (T) this;
  427. }
  428. final SMLocalisation sml = getSystemMessageId().getLocalisation(lang);
  429. if (sml == null)
  430. {
  431. return (T) this;
  432. }
  433. final Object[] params = new Object[_paramIndex];
  434. SMParam param;
  435. for (int i = 0; i < _paramIndex; i++)
  436. {
  437. param = _params[i];
  438. switch (param.getType())
  439. {
  440. case TYPE_TEXT:
  441. case TYPE_PLAYER_NAME:
  442. {
  443. params[i] = param.getValue();
  444. break;
  445. }
  446. case TYPE_LONG_NUMBER:
  447. {
  448. params[i] = param.getValue();
  449. break;
  450. }
  451. case TYPE_ITEM_NAME:
  452. {
  453. final L2Item item = ItemTable.getInstance().getTemplate(param.getIntValue());
  454. params[i] = item == null ? "Unknown" : item.getName();
  455. break;
  456. }
  457. case TYPE_CASTLE_NAME:
  458. {
  459. final Castle castle = CastleManager.getInstance().getCastleById(param.getIntValue());
  460. params[i] = castle == null ? "Unknown" : castle.getName();
  461. break;
  462. }
  463. case TYPE_INT_NUMBER:
  464. {
  465. params[i] = param.getValue();
  466. break;
  467. }
  468. case TYPE_NPC_NAME:
  469. {
  470. final L2NpcTemplate template = NpcData.getInstance().getTemplate(param.getIntValue());
  471. params[i] = template == null ? "Unknown" : template.getName();
  472. break;
  473. }
  474. case TYPE_ELEMENT_NAME:
  475. {
  476. params[i] = Elementals.getElementName((byte) param.getIntValue());
  477. break;
  478. }
  479. case TYPE_SYSTEM_STRING:
  480. {
  481. params[i] = "SYS-S-" + param.getIntValue(); // writeD(param.getIntValue());
  482. break;
  483. }
  484. case TYPE_INSTANCE_NAME:
  485. {
  486. final String instanceName = InstanceManager.getInstance().getInstanceIdName(param.getIntValue());
  487. params[i] = instanceName == null ? "Unknown" : instanceName;
  488. break;
  489. }
  490. case TYPE_DOOR_NAME:
  491. {
  492. final L2DoorInstance door = DoorData.getInstance().getDoor(param.getIntValue());
  493. params[i] = door == null ? "Unknown" : door.getName();
  494. break;
  495. }
  496. case TYPE_SKILL_NAME:
  497. {
  498. final int[] array = param.getIntArrayValue();
  499. final Skill skill = SkillData.getInstance().getSkill(array[0], array[1]);
  500. params[i] = skill == null ? "Unknown" : skill.getName();
  501. break;
  502. }
  503. case TYPE_ZONE_NAME:
  504. {
  505. final int[] array = param.getIntArrayValue();
  506. final L2ZoneType zone = ZoneManager.getInstance().getZone(array[0], array[1], array[2], L2ZoneType.class);
  507. params[i] = zone == null ? "Unknown ZONE-N-" + Arrays.toString(array) : zone.getName();
  508. break;
  509. }
  510. }
  511. i++;
  512. }
  513. addString(sml.getLocalisation(params));
  514. return (T) this;
  515. }
  516. }