SystemMessage.java 14 KB

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