ChristianMacedo

Offline Shop V2 aCis 398+

Aug 13th, 2022
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.39 KB | None | 0 0
  1. ### Eclipse Workspace Patch 1.0
  2. #P aCis_gameserver
  3. diff --git config/players.properties
  4. +++ config/players.properties
  5. @@ -255,7 +255,46 @@
  6. #=============================================================
  7.  
  8. # Maximum number of buffs. Remember that Divine Inspiration will give 4 additional buff slots on top of the number specified. Default: 20
  9. MaxBuffsAmount = 20
  10.  
  11. # Store buffs/debuffs on user logout. Default: True
  12. StoreSkillCooltime = True
  13.  
  14. +# =================================================================
  15. +# Offline trade/craft
  16. +# =================================================================
  17. +
  18. +# Option to enable or disable offline trade feature.
  19. +# Enable -> true, Disable -> false
  20. +OfflineTradeEnable = True
  21. +
  22. +# Option to enable or disable offline craft feature.
  23. +# Enable -> true, Disable -> false
  24. +OfflineCraftEnable = True
  25. +
  26. +# If set to True, off-line shops will be possible only in peace zones.
  27. +# Default: False
  28. +OfflineModeInPeaceZone = True
  29. +
  30. +# If set to True, players in off-line shop mode will not take any damage, thus they cannot be killed.
  31. +# Default: False
  32. +OfflineModeNoDamage = False
  33. +
  34. +# Restore offline traders/crafters after restart/shutdown.
  35. +# Default: False
  36. +RestoreOffliners = True
  37. +
  38. +# Do not restore offline characters, after OfflineMaxDays days spent from first restore.
  39. +# Require server restart to disconnect expired shops.
  40. +# 0 = disabled (always restore).
  41. +# Default: 7
  42. +OfflineMaxDays = 7
  43. +
  44. +# Disconnect shop after finished selling, buying.
  45. +# Default: True
  46. +OfflineDisconnectFinished = True
  47. +
  48. +#Offline Effect Sleep
  49. +OfflineSetSleepEffect = True
  50. +
  51. +
  52. diff --git java/net/sf/l2j/Config.java
  53. +++ java/net/sf/l2j/Config.java
  54. @@ -341,12 +341,23 @@
  55. public static int MAX_PVTSTORE_SLOTS_DWARF;
  56. public static int MAX_PVTSTORE_SLOTS_OTHER;
  57. public static boolean DEEPBLUE_DROP_RULES;
  58. public static boolean ALLOW_DELEVEL;
  59. public static int DEATH_PENALTY_CHANCE;
  60.  
  61. + /** Offline Shop */
  62. + public static boolean OFFLINE_TRADE_ENABLE;
  63. + public static boolean OFFLINE_CRAFT_ENABLE;
  64. + public static boolean OFFLINE_MODE_IN_PEACE_ZONE;
  65. + public static boolean OFFLINE_MODE_NO_DAMAGE;
  66. + public static boolean RESTORE_OFFLINERS;
  67. + public static int OFFLINE_MAX_DAYS;
  68. + public static boolean OFFLINE_DISCONNECT_FINISHED;
  69. + public static boolean OFFLINE_SET_SLEEP;
  70. +
  71. /** Inventory & WH */
  72. public static int INVENTORY_MAXIMUM_NO_DWARF;
  73. public static int INVENTORY_MAXIMUM_DWARF;
  74. public static int INVENTORY_MAXIMUM_PET;
  75. public static int MAX_ITEM_IN_PACKET;
  76. public static double WEIGHT_LIMIT;
  77. @@ -970,12 +981,21 @@
  78. MAX_PVTSTORE_SLOTS_DWARF = players.getProperty("MaxPvtStoreSlotsDwarf", 5);
  79. MAX_PVTSTORE_SLOTS_OTHER = players.getProperty("MaxPvtStoreSlotsOther", 4);
  80. DEEPBLUE_DROP_RULES = players.getProperty("UseDeepBlueDropRules", true);
  81. ALLOW_DELEVEL = players.getProperty("AllowDelevel", true);
  82. DEATH_PENALTY_CHANCE = players.getProperty("DeathPenaltyChance", 20);
  83.  
  84. + OFFLINE_TRADE_ENABLE = players.getProperty("OfflineTradeEnable", false);
  85. + OFFLINE_CRAFT_ENABLE = players.getProperty("OfflineCraftEnable", false);
  86. + OFFLINE_MODE_IN_PEACE_ZONE = players.getProperty("OfflineModeInPeaceZone", false);
  87. + OFFLINE_MODE_NO_DAMAGE = players.getProperty("OfflineModeNoDamage", false);
  88. + OFFLINE_SET_SLEEP = players.getProperty("OfflineSetSleepEffect", false);
  89. + RESTORE_OFFLINERS = players.getProperty("RestoreOffliners", false);
  90. + OFFLINE_MAX_DAYS = players.getProperty("OfflineMaxDays", 10);
  91. + OFFLINE_DISCONNECT_FINISHED = players.getProperty("OfflineDisconnectFinished", true);
  92.  
  93. INVENTORY_MAXIMUM_NO_DWARF = players.getProperty("MaximumSlotsForNoDwarf", 80);
  94. INVENTORY_MAXIMUM_DWARF = players.getProperty("MaximumSlotsForDwarf", 100);
  95. INVENTORY_MAXIMUM_PET = players.getProperty("MaximumSlotsForPet", 12);
  96. MAX_ITEM_IN_PACKET = Math.max(INVENTORY_MAXIMUM_NO_DWARF, INVENTORY_MAXIMUM_DWARF);
  97. WEIGHT_LIMIT = players.getProperty("WeightLimit", 1.);
  98. WAREHOUSE_SLOTS_NO_DWARF = players.getProperty("MaximumWarehouseSlotsForNoDwarf", 100);
  99. diff --git java/net/sf/l2j/gameserver/GameServer.java
  100. +++ java/net/sf/l2j/gameserver/GameServer.java
  101. @@ -70,12 +70,13 @@
  102. import net.sf.l2j.gameserver.data.xml.SoulCrystalData;
  103. import net.sf.l2j.gameserver.data.xml.SpellbookData;
  104. import net.sf.l2j.gameserver.data.xml.StaticObjectData;
  105. import net.sf.l2j.gameserver.data.xml.SummonItemData;
  106. import net.sf.l2j.gameserver.data.xml.TeleportData;
  107. import net.sf.l2j.gameserver.data.xml.WalkerRouteData;
  108. +import net.sf.l2j.gameserver.enums.actors.OfflineStoresData;
  109. import net.sf.l2j.gameserver.geoengine.GeoEngine;
  110. import net.sf.l2j.gameserver.handler.AdminCommandHandler;
  111. import net.sf.l2j.gameserver.handler.ChatHandler;
  112. import net.sf.l2j.gameserver.handler.ItemHandler;
  113. import net.sf.l2j.gameserver.handler.SkillHandler;
  114. import net.sf.l2j.gameserver.handler.TargetHandler;
  115. @@ -235,12 +236,23 @@
  116. TeleportData.getInstance();
  117.  
  118. StringUtil.printSection("Olympiads & Heroes");
  119. OlympiadGameManager.getInstance();
  120. Olympiad.getInstance();
  121. HeroManager.getInstance();
  122.  
  123. + StringUtil.printSection("OfflineShop Started");
  124. + if ((Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE) && Config.RESTORE_OFFLINERS)
  125. + {
  126. + OfflineStoresData.getInstance().restoreOfflineTraders();
  127. + }
  128. + else
  129. + {
  130. + LOGGER.info("Offline Shop is disabled.");
  131. + }
  132.  
  133. StringUtil.printSection("Four Sepulchers");
  134. FourSepulchersManager.getInstance();
  135.  
  136. StringUtil.printSection("Quests & Scripts");
  137. ScriptData.getInstance();
  138. diff --git java/net/sf/l2j/gameserver/LoginServerThread.java
  139. +++ java/net/sf/l2j/gameserver/LoginServerThread.java
  140. @@ -292,12 +292,14 @@
  141. }
  142. }
  143.  
  144. public void addClient(String account, GameClient client)
  145. {
  146. final GameClient existingClient = _clients.putIfAbsent(account, client);
  147. + if (client.isDetached())
  148. + return;
  149. if (existingClient == null)
  150. {
  151. try
  152. {
  153. sendPacket(new PlayerAuthRequest(client.getAccountName(), client.getSessionId()));
  154. }
  155. diff --git java/net/sf/l2j/gameserver/Shutdown.java
  156. +++ java/net/sf/l2j/gameserver/Shutdown.java
  157. @@ -15,12 +15,13 @@
  158. import net.sf.l2j.gameserver.data.manager.GrandBossManager;
  159. import net.sf.l2j.gameserver.data.manager.HeroManager;
  160. import net.sf.l2j.gameserver.data.manager.PetitionManager;
  161. import net.sf.l2j.gameserver.data.manager.RaidBossManager;
  162. import net.sf.l2j.gameserver.data.manager.SevenSignsManager;
  163. import net.sf.l2j.gameserver.data.manager.ZoneManager;
  164. +import net.sf.l2j.gameserver.enums.actors.OfflineStoresData;
  165. import net.sf.l2j.gameserver.model.World;
  166. import net.sf.l2j.gameserver.model.actor.Player;
  167. import net.sf.l2j.gameserver.model.olympiad.Olympiad;
  168. import net.sf.l2j.gameserver.network.GameClient;
  169. import net.sf.l2j.gameserver.network.SystemMessageId;
  170. import net.sf.l2j.gameserver.network.gameserverpackets.ServerStatus;
  171. @@ -74,13 +75,24 @@
  172. @Override
  173. public void run()
  174. {
  175. if (this == SingletonHolder.INSTANCE)
  176. {
  177. StringUtil.printSection("Under " + MODE_TEXT[_shutdownMode] + " process");
  178.  
  179. + try
  180. + {
  181. + if ((Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE) && Config.RESTORE_OFFLINERS)
  182. + {
  183. + OfflineStoresData.getInstance().storeOffliners();
  184. + LOGGER.info("Offline Traders Table: Offline shops stored.");
  185. + }
  186. + }
  187. + catch (Throwable t)
  188. + {
  189. +
  190. + }
  191. // disconnect players
  192. try
  193. {
  194. disconnectAllPlayers();
  195. LOGGER.info("All players have been disconnected.");
  196. }
  197. diff --git java/net/sf/l2j/gameserver/enums/actors/OfflineStoresData.java
  198. +++ java/net/sf/l2j/gameserver/enums/actors/OfflineStoresData.java
  199. @@ -0,0 +1,274 @@
  200. +package net.sf.l2j.gameserver.enums.actors;
  201. +
  202. +import java.sql.Connection;
  203. +import java.sql.PreparedStatement;
  204. +import java.sql.ResultSet;
  205. +import java.sql.Statement;
  206. +import java.util.Calendar;
  207. +import java.util.logging.Level;
  208. +import java.util.logging.Logger;
  209. +
  210. +import net.sf.l2j.commons.pool.ConnectionPool;
  211. +
  212. +import net.sf.l2j.Config;
  213. +import net.sf.l2j.gameserver.LoginServerThread;
  214. +import net.sf.l2j.gameserver.enums.ZoneId;
  215. +import net.sf.l2j.gameserver.model.World;
  216. +import net.sf.l2j.gameserver.model.actor.Player;
  217. +import net.sf.l2j.gameserver.model.craft.ManufactureItem;
  218. +import net.sf.l2j.gameserver.model.craft.ManufactureList;
  219. +import net.sf.l2j.gameserver.model.trade.TradeItem;
  220. +import net.sf.l2j.gameserver.network.GameClient;
  221. +import net.sf.l2j.gameserver.network.GameClient.GameClientState;
  222. +
  223. +public class OfflineStoresData
  224. +{
  225. + private static final Logger LOGGER = Logger.getLogger(OfflineStoresData.class.getName());
  226. +
  227. + // SQL DEFINITIONS
  228. + private static final String SAVE_OFFLINE_STATUS = "INSERT INTO character_offline_trade (`charId`,`time`,`type`,`title`) VALUES (?,?,?,?)";
  229. + private static final String SAVE_ITEMS = "INSERT INTO character_offline_trade_items (`charId`,`item`,`count`,`price`,`enchant`) VALUES (?,?,?,?,?)";
  230. + private static final String CLEAR_OFFLINE_TABLE = "DELETE FROM character_offline_trade";
  231. + private static final String CLEAR_OFFLINE_TABLE_ITEMS = "DELETE FROM character_offline_trade_items";
  232. + private static final String LOAD_OFFLINE_STATUS = "SELECT * FROM character_offline_trade";
  233. + private static final String LOAD_OFFLINE_ITEMS = "SELECT * FROM character_offline_trade_items WHERE charId = ?";
  234. +
  235. + public void storeOffliners()
  236. + {
  237. + try (Connection con = ConnectionPool.getConnection(); PreparedStatement save_offline_status = con.prepareStatement(SAVE_OFFLINE_STATUS); PreparedStatement save_items = con.prepareStatement(SAVE_ITEMS))
  238. + {
  239. + try (Statement stm = con.createStatement())
  240. + {
  241. + stm.execute(CLEAR_OFFLINE_TABLE);
  242. + stm.execute(CLEAR_OFFLINE_TABLE_ITEMS);
  243. + }
  244. + for (Player pc : World.getInstance().getPlayers())
  245. + {
  246. + try
  247. + {
  248. + if (pc.getOperateType() != OperateType.NONE && (pc.getClient() == null || pc.getClient().isDetached()))
  249. + {
  250. + save_offline_status.setInt(1, pc.getObjectId());
  251. + save_offline_status.setLong(2, pc.getOfflineStartTime());
  252. + save_offline_status.setInt(3, pc.getOperateType().getId());
  253. + switch (pc.getOperateType())
  254. + {
  255. + case BUY:
  256. + if (!Config.OFFLINE_TRADE_ENABLE)
  257. + continue;
  258. +
  259. + save_offline_status.setString(4, pc.getBuyList().getTitle());
  260. + for (TradeItem i : pc.getBuyList())
  261. + {
  262. + save_items.setInt(1, pc.getObjectId());
  263. + save_items.setInt(2, i.getItem().getItemId());
  264. + save_items.setLong(3, i.getCount());
  265. + save_items.setLong(4, i.getPrice());
  266. + save_items.setLong(5, i.getEnchant());
  267. + save_items.addBatch();
  268. + }
  269. + break;
  270. + case SELL:
  271. + case PACKAGE_SELL:
  272. + if (!Config.OFFLINE_TRADE_ENABLE)
  273. + continue;
  274. +
  275. + save_offline_status.setString(4, pc.getSellList().getTitle());
  276. + pc.getSellList().updateItems();
  277. + for (TradeItem i : pc.getSellList())
  278. + {
  279. + save_items.setInt(1, pc.getObjectId());
  280. + save_items.setInt(2, i.getObjectId());
  281. + save_items.setLong(3, i.getCount());
  282. + save_items.setLong(4, i.getPrice());
  283. + save_items.setLong(5, i.getEnchant());
  284. + save_items.addBatch();
  285. + }
  286. + break;
  287. + case MANUFACTURE:
  288. + if (!Config.OFFLINE_CRAFT_ENABLE)
  289. + continue;
  290. +
  291. + save_offline_status.setString(4, pc.getManufactureList().getStoreName());
  292. + for (final ManufactureItem i : pc.getManufactureList())
  293. + {
  294. + save_items.setInt(1, pc.getObjectId());
  295. + save_items.setInt(2, i.getId());
  296. + save_items.setLong(3, 0L);
  297. + save_items.setLong(4, i.getValue());
  298. + save_items.setLong(5, 0L);
  299. + save_items.addBatch();
  300. + }
  301. + break;
  302. + }
  303. + save_items.executeBatch();
  304. + save_offline_status.execute();
  305. + }
  306. + }
  307. + catch (Exception e)
  308. + {
  309. + LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while saving offline trader: " + pc.getObjectId() + " " + e, e);
  310. + }
  311. + }
  312. +
  313. + LOGGER.info(getClass().getSimpleName() + ": Offline traders stored.");
  314. + }
  315. + catch (Exception e)
  316. + {
  317. + LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while saving offline traders: " + e, e);
  318. + }
  319. + }
  320. +
  321. + public void restoreOfflineTraders()
  322. + {
  323. + LOGGER.info(getClass().getSimpleName() + ": Loading offline traders...");
  324. + try (Connection con = ConnectionPool.getConnection(); Statement stm = con.createStatement(); ResultSet rs = stm.executeQuery(LOAD_OFFLINE_STATUS))
  325. + {
  326. + int nTraders = 0;
  327. + while (rs.next())
  328. + {
  329. + final long time = rs.getLong("time");
  330. + if (Config.OFFLINE_MAX_DAYS > 0)
  331. + {
  332. + final Calendar cal = Calendar.getInstance();
  333. + cal.setTimeInMillis(time);
  334. + cal.add(Calendar.DAY_OF_YEAR, Config.OFFLINE_MAX_DAYS);
  335. + if (cal.getTimeInMillis() <= System.currentTimeMillis())
  336. + continue;
  337. + }
  338. +
  339. + OperateType type = null;
  340. + for (OperateType t : OperateType.values())
  341. + {
  342. + if (t.getId() == rs.getInt("type"))
  343. + {
  344. + type = t;
  345. + break;
  346. + }
  347. + }
  348. + if (type == null)
  349. + {
  350. + LOGGER.warning(getClass().getSimpleName() + ": PrivateStoreType with id " + rs.getInt("type") + " could not be found.");
  351. + continue;
  352. + }
  353. + if (type == OperateType.NONE)
  354. + continue;
  355. +
  356. + final Player player = Player.restore(rs.getInt("charId"));
  357. + if (player == null)
  358. + continue;
  359. +
  360. + try (PreparedStatement stm_items = con.prepareStatement(LOAD_OFFLINE_ITEMS))
  361. + {
  362. + player.isRunning();
  363. + player.sitDown();
  364. + player.setOnlineStatus(true, false);
  365. +
  366. + World.getInstance().addPlayer(player);
  367. +
  368. + final GameClient client = new GameClient(null);
  369. + client.setDetached(true);
  370. + player.setClient(client);
  371. + client.setPlayer(player);
  372. + client.setAccountName(player.getAccountNamePlayer());
  373. + player.setOnlineStatus(true, true);
  374. + client.setState(GameClientState.IN_GAME);
  375. + player.setOfflineStartTime(time);
  376. + player.spawnMe();
  377. +
  378. + LoginServerThread.getInstance().addClient(player.getAccountName(), client);
  379. +
  380. + stm_items.setInt(1, player.getObjectId());
  381. + try (ResultSet items = stm_items.executeQuery())
  382. + {
  383. + switch (type)
  384. + {
  385. + case BUY:
  386. + while (items.next())
  387. + {
  388. + player.getBuyList().addItemByItemId(items.getInt(2), items.getInt(3), items.getInt(4), items.getInt(5));
  389. + }
  390. +
  391. + player.getBuyList().setTitle(rs.getString("title"));
  392. + break;
  393. + case SELL:
  394. + case PACKAGE_SELL:
  395. + while (items.next())
  396. + if (player.getSellList().addItem(items.getInt(2), items.getInt(3), items.getInt(4)) == null)
  397. + throw new NullPointerException("NPE at SELL of offlineShop " + player.getObjectId() + " " + items.getInt(2) + " " + items.getInt(3) + " " + items.getInt(4));
  398. +
  399. + player.getSellList().setTitle(rs.getString("title"));
  400. + player.getSellList().setPackaged(type == OperateType.PACKAGE_SELL);
  401. + break;
  402. + case MANUFACTURE:
  403. + while (items.next())
  404. + player.getManufactureList().add(new ManufactureItem(items.getInt(2), items.getInt(4)));
  405. + player.getManufactureList().setStoreName(rs.getString("title"));
  406. + break;
  407. + }
  408. + }
  409. +
  410. + if (Config.OFFLINE_SET_SLEEP)
  411. + player.startAbnormalEffect(0x000080);
  412. +
  413. + player.setOperateType(type);
  414. + player.restoreEffects();
  415. + player.broadcastUserInfo();
  416. +
  417. + nTraders++;
  418. + }
  419. + catch (Exception e)
  420. + {
  421. + LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error loading trader: " + player, e);
  422. +
  423. + player.deleteMe();
  424. + }
  425. + }
  426. +
  427. + LOGGER.info(getClass().getSimpleName() + ": Loaded: " + nTraders + " offline trader(s)");
  428. +
  429. + try (Statement stm1 = con.createStatement())
  430. + {
  431. + stm1.execute(CLEAR_OFFLINE_TABLE);
  432. + stm1.execute(CLEAR_OFFLINE_TABLE_ITEMS);
  433. + }
  434. + }
  435. + catch (Exception e)
  436. + {
  437. + LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while loading offline traders: ", e);
  438. + }
  439. + }
  440. +
  441. + public static boolean offlineMode(Player player)
  442. + {
  443. + if (player.isInOlympiadMode() || player.isFestivalParticipant() || player.isInJail() || player.getBoat() != null)
  444. + return false;
  445. +
  446. + boolean canSetShop = false;
  447. + switch (player.getOperateType())
  448. + {
  449. + case SELL:
  450. + case PACKAGE_SELL:
  451. + case BUY:
  452. + canSetShop = Config.OFFLINE_TRADE_ENABLE;
  453. + break;
  454. + case MANUFACTURE:
  455. + canSetShop = Config.OFFLINE_CRAFT_ENABLE;
  456. + break;
  457. + }
  458. + if (Config.OFFLINE_MODE_IN_PEACE_ZONE && !player.isInsideZone(ZoneId.PEACE))
  459. + canSetShop = false;
  460. +
  461. + return canSetShop;
  462. + }
  463. +
  464. + public static OfflineStoresData getInstance()
  465. + {
  466. + return SingletonHolder._instance;
  467. + }
  468. +
  469. + private static class SingletonHolder
  470. + {
  471. + protected static final OfflineStoresData _instance = new OfflineStoresData();
  472. + }
  473. +}
  474. \ No newline at end of file
  475. diff --git java/net/sf/l2j/gameserver/enums/actors/OperateType.java
  476. +++ java/net/sf/l2j/gameserver/enums/actors/OperateType.java
  477. @@ -15,12 +15,20 @@
  478. private int _id;
  479.  
  480. private OperateType(int id)
  481. {
  482. _id = id;
  483. }
  484. + public static OperateType findById(int id)
  485. + {
  486. + for (OperateType privateStoreType : values())
  487. + {
  488. + if (privateStoreType.getId() == id)
  489. + return privateStoreType;
  490. + }
  491. + return null;
  492. + }
  493. public int getId()
  494. {
  495. return _id;
  496. }
  497. }
  498. \ No newline at end of file
  499. diff --git java/net/sf/l2j/gameserver/model/actor/Player.java
  500. +++ java/net/sf/l2j/gameserver/model/actor/Player.java
  501. @@ -2240,15 +2240,20 @@
  502. {
  503. _client = client;
  504. }
  505.  
  506. public String getAccountName()
  507. {
  508. + if (getClient() == null)
  509. + return getAccountNamePlayer();
  510. return _accountName;
  511. }
  512.  
  513. + public String getAccountNamePlayer()
  514. + {
  515. + return _accountName;
  516. + }
  517. public Map<Integer, String> getAccountChars()
  518. {
  519. return _chars;
  520. }
  521.  
  522. /**
  523. @@ -3275,14 +3280,26 @@
  524. * Set the {@link OperateType} of this {@link Player}.
  525. * @param type : The new {@link OperateType} state to set.
  526. */
  527. public void setOperateType(OperateType type)
  528. {
  529. _operateType = type;
  530. + if (Config.OFFLINE_DISCONNECT_FINISHED && type == OperateType.NONE && (getClient() == null || getClient().isDetached()))
  531. + deleteMe();
  532. }
  533.  
  534. + private long _offlineShopStart;
  535. + public long getOfflineStartTime()
  536. + {
  537. + return _offlineShopStart;
  538. + }
  539. + public void setOfflineStartTime(long time)
  540. + {
  541. + _offlineShopStart = time;
  542. + }
  543. +
  544. /**
  545. * @return True if this {@link Player} is set on any store mode, or false otherwise.
  546. */
  547. public boolean isInStoreMode()
  548. {
  549. return _operateType == OperateType.BUY || _operateType == OperateType.SELL || _operateType == OperateType.PACKAGE_SELL || _operateType == OperateType.MANUFACTURE;
  550. diff --git java/net/sf/l2j/gameserver/network/GameClient.java
  551. +++ java/net/sf/l2j/gameserver/network/GameClient.java
  552. @@ -19,15 +19,18 @@
  553.  
  554. import net.sf.l2j.Config;
  555. import net.sf.l2j.gameserver.LoginServerThread;
  556. import net.sf.l2j.gameserver.data.sql.ClanTable;
  557. import net.sf.l2j.gameserver.data.sql.PlayerInfoTable;
  558. import net.sf.l2j.gameserver.enums.FloodProtector;
  559. +import net.sf.l2j.gameserver.enums.MessageType;
  560. +import net.sf.l2j.gameserver.enums.ZoneId;
  561. import net.sf.l2j.gameserver.model.CharSelectSlot;
  562. import net.sf.l2j.gameserver.model.World;
  563. import net.sf.l2j.gameserver.model.actor.Player;
  564. +import net.sf.l2j.gameserver.model.olympiad.OlympiadManager;
  565. import net.sf.l2j.gameserver.model.pledge.Clan;
  566. import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
  567. import net.sf.l2j.gameserver.network.serverpackets.L2GameServerPacket;
  568. import net.sf.l2j.gameserver.network.serverpackets.ServerClose;
  569.  
  570. /**
  571. @@ -206,22 +209,82 @@
  572. ThreadPool.execute(() ->
  573. {
  574. boolean fast = true;
  575. if (getPlayer() != null && !isDetached())
  576. {
  577. setDetached(true);
  578. + if (offlineMode(getPlayer()))
  579. + {
  580. + if (getPlayer().getParty() != null)
  581. + getPlayer().getParty().removePartyMember(getPlayer(), MessageType.EXPELLED);
  582. + OlympiadManager.getInstance().unRegisterNoble(getPlayer());
  583. +
  584. + // If the Character has Pet, unsummon it
  585. + if (getPlayer().hasPet())
  586. + {
  587. + getPlayer().getSummon().unSummon(getPlayer());
  588. + // Dead pet wasn't unsummoned, broadcast npcinfo changes (pet will be without owner name - means owner offline)
  589. + if (getPlayer().getSummon() != null)
  590. + getPlayer().getSummon().updateAndBroadcastStatus(0);
  591. + }
  592. +
  593. + if (Config.OFFLINE_SET_SLEEP)
  594. + getPlayer().startAbnormalEffect(0x000080);
  595. +
  596. + if (getPlayer().getOfflineStartTime() == 0)
  597. + getPlayer().setOfflineStartTime(System.currentTimeMillis());
  598. +
  599. + return;
  600. + }
  601. fast = !getPlayer().isInCombat() && !getPlayer().isLocked();
  602. }
  603. cleanMe(fast);
  604. });
  605. }
  606. catch (RejectedExecutionException e)
  607. {
  608. }
  609. }
  610.  
  611. + /**
  612. + * @param player
  613. + * @return
  614. + */
  615. + public static boolean offlineMode(Player player)
  616. + {
  617. + if (player.isInOlympiadMode() || player.isFestivalParticipant() || player.isInJail() || player.getBoat() != null)
  618. + return false;
  619. +
  620. + boolean canSetShop = false;
  621. + switch (player.getOperateType())
  622. + {
  623. + case SELL:
  624. + case PACKAGE_SELL:
  625. + case BUY:
  626. + {
  627. + canSetShop = Config.OFFLINE_TRADE_ENABLE;
  628. + break;
  629. + }
  630. + case MANUFACTURE:
  631. + {
  632. + canSetShop = Config.OFFLINE_TRADE_ENABLE;
  633. + break;
  634. + }
  635. + default:
  636. + {
  637. + canSetShop = Config.OFFLINE_CRAFT_ENABLE && player.isCrafting();
  638. + break;
  639. + }
  640. + }
  641. +
  642. + if (Config.OFFLINE_MODE_IN_PEACE_ZONE && !player.isInsideZone(ZoneId.PEACE))
  643. + canSetShop = false;
  644. +
  645. + return canSetShop;
  646. + }
  647. +
  648. @Override
  649. protected void onForcedDisconnection()
  650. {
  651. LOGGER.debug("{} disconnected abnormally.", toString());
  652. }
  653.  
  654. @@ -578,12 +641,14 @@
  655. {
  656. _slots = list;
  657. }
  658.  
  659. public void close(L2GameServerPacket gsp)
  660. {
  661. + if (getConnection() == null)
  662. + return;
  663. getConnection().close(gsp);
  664. }
  665.  
  666. /**
  667. * @param slot : The slot to test.
  668. * @return the objectId of the character associated to that slot, or -1 if not found.
  669.  
Add Comment
Please, Sign In to add comment