LaRoja

aCis398_Offline_Shop_by_LaRoja

May 19th, 2021 (edited)
5,238
1
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 21.65 KB | None | 1 0
  1. diff --git a/aCis_datapack/sql/character_offline_trade.sql b/aCis_datapack/sql/character_offline_trade.sql
  2. new file mode 100644
  3. index 0000000..a69f895
  4. --- /dev/null
  5. +++ b/aCis_datapack/sql/character_offline_trade.sql
  6. @@ -0,0 +1,7 @@
  7. +CREATE TABLE IF NOT EXISTS `character_offline_trade`  (
  8. +  `charId` int(10) NOT NULL,
  9. +  `time` bigint(13) NOT NULL DEFAULT 0,
  10. +  `type` tinyint(4) NOT NULL DEFAULT 0,
  11. +  `title` varchar(50) NULL DEFAULT NULL,
  12. +  PRIMARY KEY (`charId`)
  13. +);
  14. \ No newline at end of file
  15. diff --git a/aCis_datapack/sql/character_offline_trade_items.sql b/aCis_datapack/sql/character_offline_trade_items.sql
  16. new file mode 100644
  17. index 0000000..e69de29
  18. --- /dev/null
  19. +++ b/aCis_datapack/sql/character_offline_trade_items.sql
  20. @@ -0,0 +1,7 @@
  21. +CREATE TABLE IF NOT EXISTS `character_offline_trade_items`  (
  22. +  `charId` int(10) NOT NULL,
  23. +  `item` int(10) NOT NULL DEFAULT 0,
  24. +  `count` bigint(20) NOT NULL DEFAULT 0,
  25. +  `price` bigint(20) NOT NULL DEFAULT 0,
  26. +  `enchant` bigint(20) NULL DEFAULT NULL
  27. +);
  28. diff --git a/aCis_gameserver/config/offline.properties b/aCis_gameserver/config/offline.properties
  29. new file mode 100644
  30. index 0000000..0fe0a89
  31. --- /dev/null
  32. +++ b/aCis_gameserver/config/offline.properties
  33. @@ -0,0 +1,38 @@
  34. +# =================================================================
  35. +#                           Offline
  36. +# =================================================================
  37. +
  38. +# Enable or disable offline trade feature.
  39. +# Enable -> true, Disable -> false
  40. +OfflineTradeEnable = True
  41. +
  42. +# Enable or disable offline craft feature.
  43. +# Enable -> true, Disable -> false
  44. +OfflineCraftEnable = True
  45. +
  46. +# If set to True, players will be allowed to be offline only in peace zones.
  47. +# Default: False
  48. +OfflineInPeaceZone = True
  49. +
  50. +# If set to True, players offline will be invulnerable.
  51. +# Default: False
  52. +OfflineNoDamage = False
  53. +
  54. +# Restore offline traders/crafters after restart/shutdown.
  55. +# Default: False
  56. +OfflineRestore = True
  57. +
  58. +# Require OfflineRestore = true
  59. +# If a player is offline for more than the set value, won't be restored on server start.
  60. +# 0 = Offline will be always restored
  61. +OfflineMaxDays = 30
  62. +
  63. +# Disconnect offline player after he sold/bought all items in his list.
  64. +OfflineDisconnect = True
  65. +
  66. +# Offline Effect - Choose one of the following effects:
  67. +# none, stun, sleep, muted, root -> (none = No effect)
  68. +OfflineEffect = root
  69. +
  70. +# Offline Name Color (set 0 to Disable)
  71. +OfflineNameColor = 808080
  72. diff --git a/aCis_gameserver/java/net/sf/l2j/Config.java b/aCis_gameserver/java/net/sf/l2j/Config.java
  73. index dcbc2f0..10dab9c 100644
  74. --- a/aCis_gameserver/java/net/sf/l2j/Config.java
  75. +++ b/aCis_gameserver/java/net/sf/l2j/Config.java
  76. @@ -35,6 +35,7 @@
  77.     public static final String PLAYERS_FILE = "./config/players.properties";
  78.     public static final String SERVER_FILE = "./config/server.properties";
  79.     public static final String SIEGE_FILE = "./config/siege.properties";
  80. +   public static final String OFFLINE_FILE = "./config/offline.properties";
  81.    
  82.     // --------------------------------------------------
  83.     // Clans settings
  84. @@ -450,6 +451,20 @@
  85.     public static int CH_MAX_ATTACKERS_NUMBER;
  86.    
  87.     // --------------------------------------------------
  88. +   // Offline
  89. +   // --------------------------------------------------
  90. +  
  91. +   public static boolean OFFLINE_TRADE_ENABLE;
  92. +   public static boolean OFFLINE_CRAFT_ENABLE;
  93. +   public static boolean OFFLINE_IN_PEACE_ZONE;
  94. +   public static boolean OFFLINE_NO_DAMAGE;
  95. +   public static boolean OFFLINE_DISCONNECT;
  96. +   public static boolean OFFLINE_RESTORE;
  97. +   public static int OFFLINE_MAX_DAYS;
  98. +   public static int OFFLINE_NAME_COLOR;
  99. +   public static String OFFLINE_EFFECT;
  100. +  
  101. +   // --------------------------------------------------
  102.     // Server
  103.     // --------------------------------------------------
  104.    
  105. @@ -1097,6 +1112,25 @@
  106.     }
  107.    
  108.     /**
  109. +    * Loads offline settings.
  110. +    */
  111. +   private static final void loadOffline()
  112. +   {
  113. +       final ExProperties offline = initProperties(Config.OFFLINE_FILE);
  114. +      
  115. +       OFFLINE_TRADE_ENABLE = offline.getProperty("OfflineTradeEnable", false);
  116. +       OFFLINE_CRAFT_ENABLE = offline.getProperty("OfflineCraftEnable", false);
  117. +       OFFLINE_IN_PEACE_ZONE = offline.getProperty("OfflineInPeaceZone", false);
  118. +       OFFLINE_NO_DAMAGE = offline.getProperty("OfflineNoDamage", false);
  119. +       OFFLINE_EFFECT = offline.getProperty("OfflineEffect", "none");
  120. +       OFFLINE_RESTORE = offline.getProperty("OfflineRestore", false);
  121. +       OFFLINE_MAX_DAYS = offline.getProperty("OfflineMaxDays", 10);
  122. +       OFFLINE_DISCONNECT = offline.getProperty("OfflineDisconnect", true);
  123. +       OFFLINE_NAME_COLOR = Integer.decode("0x" + offline.getProperty("OfflineNameColor", 808080));
  124. +
  125. +   }
  126. +  
  127. +   /**
  128.      * Loads gameserver settings.<br>
  129.      * IP addresses, database, rates, feature enabled/disabled, misc.
  130.      */
  131. @@ -1293,6 +1327,9 @@
  132.         // siege settings
  133.         loadSieges();
  134.        
  135. +       // offline settings
  136. +       loadOffline();
  137. +      
  138.         // server settings
  139.         loadServer();
  140.     }
  141. diff --git a/aCis_gameserver/java/net/sf/l2j/gameserver/GameServer.java b/aCis_gameserver/java/net/sf/l2j/gameserver/GameServer.java
  142. index 052fd0b..c19e082 100644
  143. --- a/aCis_gameserver/java/net/sf/l2j/gameserver/GameServer.java
  144. +++ b/aCis_gameserver/java/net/sf/l2j/gameserver/GameServer.java
  145. @@ -45,6 +45,7 @@
  146. import net.sf.l2j.gameserver.data.sql.AutoSpawnTable;
  147. import net.sf.l2j.gameserver.data.sql.BookmarkTable;
  148. import net.sf.l2j.gameserver.data.sql.ClanTable;
  149. +import net.sf.l2j.gameserver.data.sql.OfflineTable;
  150. import net.sf.l2j.gameserver.data.sql.PlayerInfoTable;
  151. import net.sf.l2j.gameserver.data.sql.ServerMemoTable;
  152. import net.sf.l2j.gameserver.data.sql.SpawnTable;
  153. @@ -259,6 +260,10 @@
  154.         DerbyTrackManager.getInstance();
  155.         LotteryManager.getInstance();
  156.        
  157. +       StringUtil.printSection("Offline");
  158. +       if (Config.OFFLINE_RESTORE && (Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE))
  159. +           OfflineTable.getInstance().restore();
  160. +      
  161.         if (Config.ALLOW_WEDDING)
  162.             CoupleManager.getInstance();
  163.        
  164. diff --git a/aCis_gameserver/java/net/sf/l2j/gameserver/LoginServerThread.java b/aCis_gameserver/java/net/sf/l2j/gameserver/LoginServerThread.java
  165. index 141b2c7..8f96418 100644
  166. --- a/aCis_gameserver/java/net/sf/l2j/gameserver/LoginServerThread.java
  167. +++ b/aCis_gameserver/java/net/sf/l2j/gameserver/LoginServerThread.java
  168. @@ -295,6 +295,10 @@
  169.     public void addClient(String account, GameClient client)
  170.     {
  171.         final GameClient existingClient = _clients.putIfAbsent(account, client);
  172. +      
  173. +       if (client.isDetached())
  174. +           return;
  175. +      
  176.         if (existingClient == null)
  177.         {
  178.             try
  179. diff --git a/aCis_gameserver/java/net/sf/l2j/gameserver/Shutdown.java b/aCis_gameserver/java/net/sf/l2j/gameserver/Shutdown.java
  180. index 275ae88..11ba89c 100644
  181. --- a/aCis_gameserver/java/net/sf/l2j/gameserver/Shutdown.java
  182. +++ b/aCis_gameserver/java/net/sf/l2j/gameserver/Shutdown.java
  183. @@ -18,6 +18,7 @@
  184. import net.sf.l2j.gameserver.data.manager.RaidBossManager;
  185. import net.sf.l2j.gameserver.data.manager.SevenSignsManager;
  186. import net.sf.l2j.gameserver.data.manager.ZoneManager;
  187. +import net.sf.l2j.gameserver.data.sql.OfflineTable;
  188. import net.sf.l2j.gameserver.model.World;
  189. import net.sf.l2j.gameserver.model.actor.Player;
  190. import net.sf.l2j.gameserver.model.olympiad.Olympiad;
  191. @@ -78,6 +79,10 @@
  192.         {
  193.             StringUtil.printSection("Under " + MODE_TEXT[_shutdownMode] + " process");
  194.            
  195. +           // store offline
  196. +           if (Config.OFFLINE_RESTORE && (Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE))
  197. +               OfflineTable.getInstance().store();
  198. +          
  199.             // disconnect players
  200.             try
  201.             {
  202. diff --git a/aCis_gameserver/java/net/sf/l2j/gameserver/data/sql/OfflineTable.java b/aCis_gameserver/java/net/sf/l2j/gameserver/data/sql/OfflineTable.java
  203. new file mode 100644
  204. index 0000000..41ec827
  205. --- /dev/null
  206. +++ b/aCis_gameserver/java/net/sf/l2j/gameserver/data/sql/OfflineTable.java
  207. @@ -0,0 +1,301 @@
  208. +package net.sf.l2j.gameserver.data.sql;
  209. +
  210. +import java.sql.Connection;
  211. +import java.sql.PreparedStatement;
  212. +import java.sql.ResultSet;
  213. +import java.sql.Statement;
  214. +import java.util.Arrays;
  215. +import java.util.Calendar;
  216. +import java.util.List;
  217. +
  218. +import net.sf.l2j.commons.logging.CLogger;
  219. +import net.sf.l2j.commons.pool.ConnectionPool;
  220. +
  221. +import net.sf.l2j.Config;
  222. +import net.sf.l2j.gameserver.enums.ZoneId;
  223. +import net.sf.l2j.gameserver.enums.actors.OperateType;
  224. +import net.sf.l2j.gameserver.enums.skills.AbnormalEffect;
  225. +import net.sf.l2j.gameserver.model.World;
  226. +import net.sf.l2j.gameserver.model.actor.Player;
  227. +import net.sf.l2j.gameserver.model.craft.ManufactureItem;
  228. +import net.sf.l2j.gameserver.model.trade.TradeItem;
  229. +import net.sf.l2j.gameserver.network.GameClient;
  230. +
  231. +public class OfflineTable
  232. +{
  233. +   private static final CLogger LOGGER = new CLogger(OfflineTable.class.getName());
  234. +  
  235. +   private static final String SAVE_OFFLINE_STATUS = "INSERT INTO character_offline_trade (`charId`,`time`,`type`,`title`) VALUES (?,?,?,?)";
  236. +   private static final String SAVE_ITEMS = "INSERT INTO character_offline_trade_items (`charId`,`item`,`count`,`price`,`enchant`) VALUES (?,?,?,?,?)";
  237. +   private static final String CLEAR_OFFLINE_TABLE = "DELETE FROM character_offline_trade";
  238. +   private static final String CLEAR_OFFLINE_TABLE_ITEMS = "DELETE FROM character_offline_trade_items";
  239. +   private static final String LOAD_OFFLINE_STATUS = "SELECT * FROM character_offline_trade";
  240. +   private static final String LOAD_OFFLINE_ITEMS = "SELECT * FROM character_offline_trade_items WHERE charId = ?";
  241. +  
  242. +   private static final String EFFECT = Config.OFFLINE_EFFECT;
  243. +   private static final int NAME_COLOR = Config.OFFLINE_NAME_COLOR;
  244. +  
  245. +   private static final List<String> ALLOWED_EFFECTS = Arrays.asList("sleep", "muted", "root", "stun");
  246. +  
  247. +   public void store()
  248. +   {
  249. +       if (!Config.OFFLINE_RESTORE || (!Config.OFFLINE_TRADE_ENABLE && !Config.OFFLINE_CRAFT_ENABLE))
  250. +           return;
  251. +      
  252. +       try (Connection con = ConnectionPool.getConnection();
  253. +           PreparedStatement offline = con.prepareStatement(SAVE_OFFLINE_STATUS);
  254. +           PreparedStatement item = con.prepareStatement(SAVE_ITEMS))
  255. +       {
  256. +           try (Statement stm = con.createStatement())
  257. +           {
  258. +               stm.execute(CLEAR_OFFLINE_TABLE);
  259. +               stm.execute(CLEAR_OFFLINE_TABLE_ITEMS);
  260. +           }
  261. +           for (Player player : World.getInstance().getPlayers())
  262. +           {
  263. +               try
  264. +               {
  265. +                   if (player.getOperateType() != OperateType.NONE && (player.getClient() == null || player.getClient().isDetached()))
  266. +                   {
  267. +                       offline.setInt(1, player.getObjectId());
  268. +                       offline.setLong(2, player.getOfflineStartTime());
  269. +                       offline.setInt(3, player.getOperateType().getId());
  270. +                       switch (player.getOperateType())
  271. +                       {
  272. +                           case BUY:
  273. +                               if (!Config.OFFLINE_TRADE_ENABLE)
  274. +                                   continue;
  275. +                              
  276. +                               offline.setString(4, player.getBuyList().getTitle());
  277. +                               for (TradeItem i : player.getBuyList())
  278. +                               {
  279. +                                   item.setInt(1, player.getObjectId());
  280. +                                   item.setInt(2, i.getItem().getItemId());
  281. +                                   item.setLong(3, i.getCount());
  282. +                                   item.setLong(4, i.getPrice());
  283. +                                   item.setLong(5, i.getEnchant());
  284. +                                   item.addBatch();
  285. +                               }
  286. +                               break;
  287. +                           case SELL:
  288. +                           case PACKAGE_SELL:
  289. +                               if (!Config.OFFLINE_TRADE_ENABLE)
  290. +                                   continue;
  291. +                              
  292. +                               offline.setString(4, player.getSellList().getTitle());
  293. +                               player.getSellList().updateItems();
  294. +                               for (TradeItem i : player.getSellList())
  295. +                               {
  296. +                                   item.setInt(1, player.getObjectId());
  297. +                                   item.setInt(2, i.getObjectId());
  298. +                                   item.setLong(3, i.getCount());
  299. +                                   item.setLong(4, i.getPrice());
  300. +                                   item.setLong(5, i.getEnchant());
  301. +                                   item.addBatch();
  302. +                               }
  303. +                               break;
  304. +                           case MANUFACTURE:
  305. +                               if (!Config.OFFLINE_CRAFT_ENABLE)
  306. +                                   continue;
  307. +                              
  308. +                               offline.setString(4, player.getManufactureList().getStoreName());
  309. +                               for (final ManufactureItem i : player.getManufactureList())
  310. +                               {
  311. +                                   item.setInt(1, player.getObjectId());
  312. +                                   item.setInt(2, i.getId());
  313. +                                   item.setLong(3, 0L);
  314. +                                   item.setLong(4, i.getValue());
  315. +                                   item.setLong(5, 0L);
  316. +                                   item.addBatch();
  317. +                               }
  318. +                               break;
  319. +                       }
  320. +                       item.executeBatch();
  321. +                       offline.execute();
  322. +                   }
  323. +               }
  324. +               catch (Exception e)
  325. +               {
  326. +                   LOGGER.warn("Error while saving offline: " + player.getObjectId() + " " + e, e);
  327. +               }
  328. +           }
  329. +          
  330. +           LOGGER.info("Offline stored.");
  331. +       }
  332. +       catch (Exception e)
  333. +       {
  334. +           LOGGER.warn("Error while saving offline: " + e, e);
  335. +       }
  336. +   }
  337. +  
  338. +   public void restore()
  339. +   {
  340. +      
  341. +       if (!Config.OFFLINE_RESTORE || (!Config.OFFLINE_TRADE_ENABLE && !Config.OFFLINE_CRAFT_ENABLE))
  342. +           return;
  343. +      
  344. +       LOGGER.info("Loading offline...");
  345. +      
  346. +       int count = 0;
  347. +      
  348. +       try (Connection con = ConnectionPool.getConnection();
  349. +           Statement stm = con.createStatement();
  350. +           ResultSet rs = stm.executeQuery(LOAD_OFFLINE_STATUS))
  351. +       {
  352. +          
  353. +           while (rs.next())
  354. +           {
  355. +               final long time = rs.getLong("time");
  356. +               if (Config.OFFLINE_MAX_DAYS > 0 && isExpired(time))
  357. +                   continue;
  358. +              
  359. +               final OperateType type = getType(rs.getInt("type"));
  360. +               if (type == null || type == OperateType.NONE)
  361. +                   continue;
  362. +              
  363. +               final Player player = Player.restore(rs.getInt("charId"));
  364. +               if (player == null)
  365. +                   continue;
  366. +              
  367. +               final GameClient client = new GameClient(null);
  368. +               client.spawnOffline(player);
  369. +               player.setOfflineStartTime(time);
  370. +               player.sitDown();
  371. +              
  372. +               final String title = rs.getString("title");
  373. +              
  374. +               try (PreparedStatement ps = con.prepareStatement(LOAD_OFFLINE_ITEMS))
  375. +               {
  376. +                   ps.setInt(1, player.getObjectId());
  377. +                   try (ResultSet item = ps.executeQuery())
  378. +                   {
  379. +                       switch (type)
  380. +                       {
  381. +                           case BUY:
  382. +                               while (item.next())
  383. +                               {
  384. +                                   if (player.getBuyList().addItemByItemId(item.getInt(2), item.getInt(3), item.getInt(4), item.getInt(5)) == null)
  385. +                                       throw new NullPointerException("NPE at BUY of offline" + player.getName() + "(" + player.getObjectId() + ") " + item.getInt(2) + " " + item.getInt(3) + " " + item.getInt(4));
  386. +                               }
  387. +                              
  388. +                               player.getBuyList().setTitle(title);
  389. +                               break;
  390. +                           case SELL:
  391. +                           case PACKAGE_SELL:
  392. +                               while (item.next())
  393. +                                   if (player.getSellList().addItem(item.getInt(2), item.getInt(3), item.getInt(4)) == null)
  394. +                                       throw new NullPointerException("NPE at SELL of offline " + player.getObjectId() + " " + item.getInt(2) + " " + item.getInt(3) + " " + item.getInt(4));
  395. +                                  
  396. +                               player.getSellList().setTitle(title);
  397. +                               player.getSellList().setPackaged(type == OperateType.PACKAGE_SELL);
  398. +                               break;
  399. +                           case MANUFACTURE:
  400. +                               while (item.next())
  401. +                                   player.getManufactureList().add(new ManufactureItem(item.getInt(2), item.getInt(4)));
  402. +                              
  403. +                               player.getManufactureList().setStoreName(title);
  404. +                               break;
  405. +                       }
  406. +                   }
  407. +                  
  408. +                   applyEffect(player);
  409. +                   player.setOperateType(type);
  410. +                   player.restoreEffects();
  411. +                   player.broadcastUserInfo();
  412. +                   player.broadcastTitleInfo();
  413. +                  
  414. +                   count++;
  415. +               }
  416. +               catch (Exception e)
  417. +               {
  418. +                  
  419. +                   LOGGER.warn("Error loading offline {}({}).", e, player.getName(), player.getObjectId());
  420. +                   player.logout(true);
  421. +               }
  422. +           }
  423. +          
  424. +           LOGGER.info("Loaded " + count + " offline.");
  425. +          
  426. +           try (Statement stm2 = con.createStatement())
  427. +           {
  428. +               stm2.execute(CLEAR_OFFLINE_TABLE);
  429. +               stm2.execute(CLEAR_OFFLINE_TABLE_ITEMS);
  430. +           }
  431. +       }
  432. +       catch (Exception e)
  433. +       {
  434. +           LOGGER.warn("Error while loading offline: ", e);
  435. +       }
  436. +   }
  437. +  
  438. +   protected OperateType getType(int id)
  439. +   {
  440. +       for (final OperateType type : OperateType.values())
  441. +           if (type.getId() == id)
  442. +               return type;
  443. +          
  444. +       LOGGER.warn("Wrong OperateType id '{}' not found.", id);
  445. +       return null;
  446. +   }
  447. +  
  448. +   protected boolean isExpired(long time)
  449. +   {
  450. +       final Calendar cal = Calendar.getInstance();
  451. +       cal.setTimeInMillis(time);
  452. +       cal.add(Calendar.DAY_OF_YEAR, Config.OFFLINE_MAX_DAYS);
  453. +       return (cal.getTimeInMillis() <= System.currentTimeMillis());
  454. +   }
  455. +  
  456. +   public boolean canBeOffline(Player player)
  457. +   {
  458. +       if (player.isInOlympiadMode() || player.isFestivalParticipant() || player.isInJail() || player.getBoat() != null)
  459. +           return false;
  460. +      
  461. +       if (Config.OFFLINE_IN_PEACE_ZONE && !player.isInsideZone(ZoneId.PEACE))
  462. +           return false;
  463. +      
  464. +       switch (player.getOperateType())
  465. +       {
  466. +           case SELL:
  467. +           case PACKAGE_SELL:
  468. +           case BUY:
  469. +               return Config.OFFLINE_TRADE_ENABLE;
  470. +           case MANUFACTURE:
  471. +               return Config.OFFLINE_CRAFT_ENABLE;
  472. +       }
  473. +      
  474. +       return false;
  475. +   }
  476. +  
  477. +   public void applyEffect(Player player)
  478. +   {
  479. +       if (EFFECT != null)
  480. +       {
  481. +           if (EFFECT.equalsIgnoreCase("none"))
  482. +               return;
  483. +          
  484. +           if (!ALLOWED_EFFECTS.contains(EFFECT))
  485. +               return;
  486. +          
  487. +           player.startAbnormalEffect(AbnormalEffect.getByName(EFFECT.toLowerCase()).getMask());
  488. +       }
  489. +      
  490. +       if (NAME_COLOR > 0)
  491. +       {
  492. +           player.getAppearance().setNameColor(NAME_COLOR);
  493. +           player.broadcastUserInfo();
  494. +       }
  495. +      
  496. +   }
  497. +  
  498. +   public static OfflineTable getInstance()
  499. +   {
  500. +       return SingletonHolder._instance;
  501. +   }
  502. +  
  503. +   private static class SingletonHolder
  504. +   {
  505. +       protected static final OfflineTable _instance = new OfflineTable();
  506. +   }
  507. +  
  508. +}
  509. \ No newline at end of file
  510. diff --git a/aCis_gameserver/java/net/sf/l2j/gameserver/model/actor/Player.java b/aCis_gameserver/java/net/sf/l2j/gameserver/model/actor/Player.java
  511. index 66ee319..a41d429 100644
  512. --- a/aCis_gameserver/java/net/sf/l2j/gameserver/model/actor/Player.java
  513. +++ b/aCis_gameserver/java/net/sf/l2j/gameserver/model/actor/Player.java
  514. @@ -464,6 +464,8 @@
  515.    
  516.     private Door _requestedGate;
  517.    
  518. +   private long _offlineStartTime;
  519. +  
  520.     /**
  521.      * Constructor of Player (use Creature constructor).
  522.      * <ul>
  523. @@ -3278,6 +3280,9 @@
  524.     public void setOperateType(OperateType type)
  525.     {
  526.         _operateType = type;
  527. +      
  528. +       if (Config.OFFLINE_DISCONNECT && type == OperateType.NONE && (getClient() == null || getClient().isDetached()))
  529. +           deleteMe();
  530.     }
  531.    
  532.     /**
  533. @@ -7380,4 +7385,14 @@
  534.        
  535.         return gms;
  536.     }
  537. +  
  538. +   public long getOfflineStartTime()
  539. +   {
  540. +       return _offlineStartTime;
  541. +   }
  542. +  
  543. +   public void setOfflineStartTime(long time)
  544. +   {
  545. +       _offlineStartTime = time;
  546. +   }
  547. }
  548. \ No newline at end of file
  549. diff --git a/aCis_gameserver/java/net/sf/l2j/gameserver/model/trade/TradeList.java b/aCis_gameserver/java/net/sf/l2j/gameserver/model/trade/TradeList.java
  550. index 019aa39..5542c6f 100644
  551. --- a/aCis_gameserver/java/net/sf/l2j/gameserver/model/trade/TradeList.java
  552. +++ b/aCis_gameserver/java/net/sf/l2j/gameserver/model/trade/TradeList.java
  553. @@ -190,6 +190,9 @@
  554.         if (!item.isStackable() && count > 1)
  555.             return null;
  556.        
  557. +       if (count == 0)
  558. +           return null;
  559. +      
  560.         if ((Integer.MAX_VALUE / count) < price)
  561.             return null;
  562. diff --git a/aCis_gameserver/java/net/sf/l2j/gameserver/network/GameClient.java b/aCis_gameserver/java/net/sf/l2j/gameserver/network/GameClient.java
  563. index 72499d0..83c8f8f 100644
  564. --- a/aCis_gameserver/java/net/sf/l2j/gameserver/network/GameClient.java
  565. +++ b/aCis_gameserver/java/net/sf/l2j/gameserver/network/GameClient.java
  566. @@ -20,11 +20,15 @@
  567. import net.sf.l2j.Config;
  568. import net.sf.l2j.gameserver.LoginServerThread;
  569. import net.sf.l2j.gameserver.data.sql.ClanTable;
  570. +import net.sf.l2j.gameserver.data.sql.OfflineTable;
  571. import net.sf.l2j.gameserver.data.sql.PlayerInfoTable;
  572. import net.sf.l2j.gameserver.enums.FloodProtector;
  573. +import net.sf.l2j.gameserver.enums.MessageType;
  574. import net.sf.l2j.gameserver.model.CharSelectSlot;
  575. import net.sf.l2j.gameserver.model.World;
  576. import net.sf.l2j.gameserver.model.actor.Player;
  577. +import net.sf.l2j.gameserver.model.actor.Summon;
  578. +import net.sf.l2j.gameserver.model.olympiad.OlympiadManager;
  579. import net.sf.l2j.gameserver.model.pledge.Clan;
  580. import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
  581. import net.sf.l2j.gameserver.network.serverpackets.L2GameServerPacket;
  582. @@ -206,10 +210,33 @@
  583.             ThreadPool.execute(() ->
  584.             {
  585.                 boolean fast = true;
  586. -               if (getPlayer() != null && !isDetached())
  587. +               final Player player = getPlayer();
  588. +              
  589. +               if (player != null && !isDetached())
  590.                 {
  591.                     setDetached(true);
  592. -                   fast = !getPlayer().isInCombat() && !getPlayer().isLocked();
  593. +                   if (OfflineTable.getInstance().canBeOffline(player))
  594. +                   {
  595. +                       if (player.getParty() != null)
  596. +                           player.getParty().removePartyMember(player, MessageType.EXPELLED);
  597. +                      
  598. +                       OlympiadManager.getInstance().unRegisterNoble(player);
  599. +                      
  600. +                       final Summon summon = player.getSummon();
  601. +                       if (summon!= null)
  602. +                       {
  603. +                           summon.doRevive();
  604. +                           summon.unSummon(player);
  605. +                       }
  606. +                      
  607. +                       OfflineTable.getInstance().applyEffect(player);
  608. +                      
  609. +                       if (player.getOfflineStartTime() == 0)
  610. +                           player.setOfflineStartTime(System.currentTimeMillis());
  611. +                      
  612. +                       return;
  613. +                   }
  614. +                   fast = !player.isInCombat() && !player.isLocked();
  615.                 }
  616.                 cleanMe(fast);
  617.             });
  618. @@ -581,6 +608,9 @@
  619.    
  620.     public void close(L2GameServerPacket gsp)
  621.     {
  622. +       if (getConnection() == null)
  623. +           return;
  624. +      
  625.         getConnection().close(gsp);
  626.     }
  627.    
  628. @@ -773,4 +803,24 @@
  629.             return true;
  630.         }
  631.     }
  632. +  
  633. +   public void spawnOffline(Player player)
  634. +   {
  635. +       player.isRunning();
  636. +       player.sitDown();
  637. +       player.setOnlineStatus(true, false);
  638. +      
  639. +       World.getInstance().addPlayer(player);
  640. +      
  641. +       setDetached(true);
  642. +       player.setClient(this);
  643. +       setPlayer(player);
  644. +       setAccountName(player.getAccountName());
  645. +       player.setOnlineStatus(true, true);
  646. +       setState(GameClientState.IN_GAME);
  647. +       player.spawnMe();
  648. +      
  649. +       LoginServerThread.getInstance().addClient(player.getAccountName(), this);
  650. +   }
  651. +  
  652. }
Comments
Add Comment
Please, Sign In to add comment