Addition of StoreOfflineTradeInRealtime configuration.

Contributed by L2Hanesfor.
This commit is contained in:
MobiusDevelopment 2023-01-16 17:14:03 +02:00
parent 05405f9d21
commit 5e9a7dbe73
10 changed files with 396 additions and 272 deletions

View File

@ -6,6 +6,10 @@
# Enable -> true, Disable -> false # Enable -> true, Disable -> false
OfflineTradeEnable = True OfflineTradeEnable = True
# Store offline trader transactions in realtime.
# Uses more datatabase resources, but helps if server shuts down unexpectedly.
StoreOfflineTradeInRealtime = True
# Option to enable or disable offline craft feature. # Option to enable or disable offline craft feature.
# Enable -> true, Disable -> false # Enable -> true, Disable -> false
OfflineCraftEnable = True OfflineCraftEnable = True

View File

@ -568,6 +568,7 @@ public class Config
public static int CUSTOM_STARTING_LOC_Z; public static int CUSTOM_STARTING_LOC_Z;
public static boolean OFFLINE_TRADE_ENABLE; public static boolean OFFLINE_TRADE_ENABLE;
public static boolean STORE_OFFLINE_TRADE_IN_REALTIME;
public static boolean OFFLINE_CRAFT_ENABLE; public static boolean OFFLINE_CRAFT_ENABLE;
public static boolean OFFLINE_SET_NAME_COLOR; public static boolean OFFLINE_SET_NAME_COLOR;
public static int OFFLINE_NAME_COLOR; public static int OFFLINE_NAME_COLOR;
@ -1819,6 +1820,7 @@ public class Config
{ {
final PropertiesParser offlineConfig = new PropertiesParser(OFFLINE_CONFIG_FILE); final PropertiesParser offlineConfig = new PropertiesParser(OFFLINE_CONFIG_FILE);
OFFLINE_TRADE_ENABLE = offlineConfig.getBoolean("OfflineTradeEnable", false); OFFLINE_TRADE_ENABLE = offlineConfig.getBoolean("OfflineTradeEnable", false);
STORE_OFFLINE_TRADE_IN_REALTIME = offlineConfig.getBoolean("StoreOfflineTradeInRealtime", true);
OFFLINE_CRAFT_ENABLE = offlineConfig.getBoolean("OfflineCraftEnable", false); OFFLINE_CRAFT_ENABLE = offlineConfig.getBoolean("OfflineCraftEnable", false);
OFFLINE_SET_NAME_COLOR = offlineConfig.getBoolean("OfflineNameColorEnable", false); OFFLINE_SET_NAME_COLOR = offlineConfig.getBoolean("OfflineNameColorEnable", false);
OFFLINE_NAME_COLOR = Integer.decode("0x" + offlineConfig.getString("OfflineNameColor", "ff00ff")); OFFLINE_NAME_COLOR = Integer.decode("0x" + offlineConfig.getString("OfflineNameColor", "ff00ff"));

View File

@ -377,7 +377,7 @@ public class Shutdown extends Thread
try try
{ {
if ((Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE) && Config.RESTORE_OFFLINERS) if ((Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE) && Config.RESTORE_OFFLINERS && !Config.STORE_OFFLINE_TRADE_IN_REALTIME)
{ {
OfflineTraderTable.getInstance().storeOffliners(); OfflineTraderTable.getInstance().storeOffliners();
} }

View File

@ -33,6 +33,8 @@ import org.l2jmobius.gameserver.model.TradeList.TradeItem;
import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.model.olympiad.Olympiad;
import org.l2jmobius.gameserver.model.zone.ZoneId;
import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.GameClient;
public class OfflineTraderTable public class OfflineTraderTable
@ -287,24 +289,49 @@ public class OfflineTraderTable
} }
} }
public void storeOffliner(Player trader) public boolean storeOffliner(Player trader)
{ {
if ((trader.getPrivateStoreType() == Player.STORE_PRIVATE_NONE) || (!trader.isInOfflineMode())) if (trader.getPrivateStoreType() == Player.STORE_PRIVATE_NONE)
{ {
return; return false;
} }
if (!trader.isKicked() //
&& !Olympiad.getInstance().isRegistered(trader) //
&& !trader.isInOlympiadMode() //
&& ((trader.isInStoreMode() && Config.OFFLINE_TRADE_ENABLE) //
|| (trader.isCrafting() && Config.OFFLINE_CRAFT_ENABLE)))
{
if (!Config.OFFLINE_MODE_IN_PEACE_ZONE || (Config.OFFLINE_MODE_IN_PEACE_ZONE && trader.isInsideZone(ZoneId.PEACE)))
{
try (Connection con = DatabaseFactory.getConnection(); try (Connection con = DatabaseFactory.getConnection();
PreparedStatement stm1 = con.prepareStatement(CLEAR_OFFLINE_TABLE_ITEMS_PLAYER); PreparedStatement stm1 = con.prepareStatement(CLEAR_OFFLINE_TABLE_ITEMS_PLAYER);
PreparedStatement stm2 = con.prepareStatement(CLEAR_OFFLINE_TABLE_PLAYER); PreparedStatement stm2 = con.prepareStatement(CLEAR_OFFLINE_TABLE_PLAYER);
PreparedStatement stm3 = con.prepareStatement(SAVE_ITEMS); PreparedStatement stm3 = con.prepareStatement(SAVE_ITEMS);
PreparedStatement stm4 = con.prepareStatement(SAVE_OFFLINE_STATUS)) PreparedStatement stm4 = con.prepareStatement(SAVE_OFFLINE_STATUS))
{ {
trader.setOnlineStatus(false);
trader.leaveParty();
trader.store();
if (Config.OFFLINE_MODE_SET_INVULNERABLE)
{
trader.setInvul(true);
}
if (Config.OFFLINE_SET_NAME_COLOR)
{
trader._originalNameColorOffline = trader.getAppearance().getNameColor();
trader.getAppearance().setNameColor(Config.OFFLINE_NAME_COLOR);
trader.broadcastUserInfo();
}
stm1.setInt(1, trader.getObjectId()); stm1.setInt(1, trader.getObjectId());
stm1.execute(); stm1.execute();
stm2.setInt(1, trader.getObjectId()); stm2.setInt(1, trader.getObjectId());
stm2.execute(); stm2.execute();
con.setAutoCommit(false); // avoid halfway done con.setAutoCommit(false); // avoid halfway done
boolean save = true; boolean save = true;
try try
{ {
@ -313,9 +340,9 @@ public class OfflineTraderTable
{ {
case Player.STORE_PRIVATE_BUY: case Player.STORE_PRIVATE_BUY:
{ {
if (!Config.OFFLINE_TRADE_ENABLE) if (!Config.OFFLINE_TRADE_ENABLE || (trader.getBuyList().getItems().size() < 1))
{ {
break; save = false;
} }
title = trader.getBuyList().getTitle(); title = trader.getBuyList().getTitle();
for (TradeItem i : trader.getBuyList().getItems()) for (TradeItem i : trader.getBuyList().getItems())
@ -333,9 +360,9 @@ public class OfflineTraderTable
case Player.STORE_PRIVATE_SELL: case Player.STORE_PRIVATE_SELL:
case Player.STORE_PRIVATE_PACKAGE_SELL: case Player.STORE_PRIVATE_PACKAGE_SELL:
{ {
if (!Config.OFFLINE_TRADE_ENABLE) if (!Config.OFFLINE_TRADE_ENABLE || (trader.getSellList().getItems().size() < 1))
{ {
break; save = false;
} }
title = trader.getSellList().getTitle(); title = trader.getSellList().getTitle();
trader.getSellList().updateItems(); trader.getSellList().updateItems();
@ -353,9 +380,9 @@ public class OfflineTraderTable
} }
case Player.STORE_PRIVATE_MANUFACTURE: case Player.STORE_PRIVATE_MANUFACTURE:
{ {
if (!Config.OFFLINE_CRAFT_ENABLE) if (!Config.OFFLINE_CRAFT_ENABLE || (trader.getCreateList().getList().size() < 1))
{ {
break; save = false;
} }
title = trader.getCreateList().getStoreName(); title = trader.getCreateList().getStoreName();
for (ManufactureItem i : trader.getCreateList().getList()) for (ManufactureItem i : trader.getCreateList().getList())
@ -372,13 +399,18 @@ public class OfflineTraderTable
} }
default: default:
{ {
// LOGGER.info(getClass().getSimpleName() + ": Error while saving offline trader: " + pc.getObjectId() + ", store type: "+pc.getPrivateStoreType()); LOGGER.info(getClass().getSimpleName() + ": Error while saving offline trader: " + trader.getObjectId() + ", store type: " + trader.getPrivateStoreType());
save = false; save = false;
} }
} }
if (save) if (save)
{ {
if (trader.getOfflineStartTime() == 0)
{
trader.setOfflineStartTime(System.currentTimeMillis());
}
stm4.setInt(1, trader.getObjectId()); // Char Id stm4.setInt(1, trader.getObjectId()); // Char Id
stm4.setLong(2, trader.getOfflineStartTime()); stm4.setLong(2, trader.getOfflineStartTime());
stm4.setInt(3, trader.getPrivateStoreType()); // store type stm4.setInt(3, trader.getPrivateStoreType()); // store type
@ -386,7 +418,13 @@ public class OfflineTraderTable
stm4.executeUpdate(); stm4.executeUpdate();
stm4.clearParameters(); stm4.clearParameters();
con.commit(); con.commit();
LOGGER.info("Player: (" + trader.getName() + ") trade offline enable");
World.OFFLINE_TRADE_COUNT++;
return true;
} }
return false;
} }
catch (Exception e) catch (Exception e)
{ {
@ -396,6 +434,33 @@ public class OfflineTraderTable
catch (Exception e) catch (Exception e)
{ {
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while saving offline trader: " + trader.getObjectId() + " " + e); LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while saving offline trader: " + trader.getObjectId() + " " + e);
return false;
}
return false;
}
}
return false;
}
public void removeStoreOffliner(Player player)
{
if (Config.STORE_OFFLINE_TRADE_IN_REALTIME)
{
try (Connection con = DatabaseFactory.getConnection();
PreparedStatement stm1 = con.prepareStatement(CLEAR_OFFLINE_TABLE_ITEMS_PLAYER);
PreparedStatement stm2 = con.prepareStatement(CLEAR_OFFLINE_TABLE_PLAYER))
{
stm1.setInt(1, player.getObjectId());
stm1.execute();
stm2.setInt(1, player.getObjectId());
stm2.execute();
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while cleanning offline trader: " + player.getName() + " " + e);
}
} }
} }

View File

@ -44,7 +44,6 @@ import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.clan.Clan;
import org.l2jmobius.gameserver.model.olympiad.Olympiad; import org.l2jmobius.gameserver.model.olympiad.Olympiad;
import org.l2jmobius.gameserver.model.zone.ZoneId;
import org.l2jmobius.gameserver.network.serverpackets.ServerPacket; import org.l2jmobius.gameserver.network.serverpackets.ServerPacket;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.util.FloodProtectors; import org.l2jmobius.gameserver.util.FloodProtectors;
@ -456,6 +455,7 @@ public class GameClient extends NetClient
} }
player = Player.load(objectId); player = Player.load(objectId);
OfflineTraderTable.getInstance().removeStoreOffliner(player);
return player; return player;
} }
@ -489,6 +489,7 @@ public class GameClient extends NetClient
{ {
// we are going to manually save the char below thus we can force the cancel // we are going to manually save the char below thus we can force the cancel
boolean offlineshop = false;
final Player player = _player; final Player player = _player;
if (player != null) // this should only happen on connection loss if (player != null) // this should only happen on connection loss
{ {
@ -510,19 +511,30 @@ public class GameClient extends NetClient
player.setClient(null); player.setClient(null);
if ((player.isInStoreMode() && Config.OFFLINE_TRADE_ENABLE) // // Only save trader offline if not realtime function is enable
|| (player.isCrafting() && Config.OFFLINE_CRAFT_ENABLE)) if (Config.STORE_OFFLINE_TRADE_IN_REALTIME)
{ {
if (!Config.OFFLINE_MODE_IN_PEACE_ZONE || (Config.OFFLINE_MODE_IN_PEACE_ZONE && player.isInsideZone(ZoneId.PEACE))) // Try execute offline trade
{ offlineshop = OfflineTraderTable.getInstance().storeOffliner(player);
return;
}
} }
if (!offlineshop)
{
// prevent closing again // prevent closing again
player.deleteMe(); player.deleteMe();
player.store(true); player.store(true);
player.setClient(null); }
else
{
// store operation
try
{
player.store();
}
catch (Exception e2)
{
}
}
} }
setPlayer(null); setPlayer(null);
@ -548,6 +560,7 @@ public class GameClient extends NetClient
{ {
// we are going to manually save the char bellow thus we can force the cancel // we are going to manually save the char bellow thus we can force the cancel
boolean offlineshop = false;
final Player player = _player; final Player player = _player;
if (player != null) // this should only happen on connection loss if (player != null) // this should only happen on connection loss
{ {
@ -567,43 +580,20 @@ public class GameClient extends NetClient
player.decreaseBoxes(); player.decreaseBoxes();
} }
if (!player.isKicked() // // Only save trader offline if not realtime function is enable
&& !Olympiad.getInstance().isRegistered(player) // if (Config.STORE_OFFLINE_TRADE_IN_REALTIME)
&& !player.isInOlympiadMode() //
&& ((player.isInStoreMode() && Config.OFFLINE_TRADE_ENABLE) //
|| (player.isCrafting() && Config.OFFLINE_CRAFT_ENABLE)))
{ {
if (!Config.OFFLINE_MODE_IN_PEACE_ZONE || (Config.OFFLINE_MODE_IN_PEACE_ZONE && player.isInsideZone(ZoneId.PEACE))) // Try execute offline trade
{ offlineshop = OfflineTraderTable.getInstance().storeOffliner(player);
player.setOnlineStatus(false);
player.leaveParty();
player.store();
if (Config.OFFLINE_MODE_SET_INVULNERABLE)
{
player.setInvul(true);
}
if (Config.OFFLINE_SET_NAME_COLOR)
{
player._originalNameColorOffline = player.getAppearance().getNameColor();
player.getAppearance().setNameColor(Config.OFFLINE_NAME_COLOR);
player.broadcastUserInfo();
} }
if (player.getOfflineStartTime() == 0) if (!offlineshop)
{ {
player.setOfflineStartTime(System.currentTimeMillis());
}
OfflineTraderTable.getInstance().storeOffliner(player);
World.OFFLINE_TRADE_COUNT++;
return;
}
}
// notify the world about our disconnect // notify the world about our disconnect
player.deleteMe(); player.deleteMe();
}
else
{
// store operation // store operation
try try
{ {
@ -613,6 +603,7 @@ public class GameClient extends NetClient
{ {
} }
} }
}
setPlayer(null); setPlayer(null);
setDetached(true); setDetached(true);

View File

@ -6,6 +6,10 @@
# Enable -> true, Disable -> false # Enable -> true, Disable -> false
OfflineTradeEnable = True OfflineTradeEnable = True
# Store offline trader transactions in realtime.
# Uses more datatabase resources, but helps if server shuts down unexpectedly.
StoreOfflineTradeInRealtime = True
# Option to enable or disable offline craft feature. # Option to enable or disable offline craft feature.
# Enable -> true, Disable -> false # Enable -> true, Disable -> false
OfflineCraftEnable = True OfflineCraftEnable = True

View File

@ -596,6 +596,7 @@ public class Config
public static int CUSTOM_STARTING_LOC_Z; public static int CUSTOM_STARTING_LOC_Z;
public static boolean OFFLINE_TRADE_ENABLE; public static boolean OFFLINE_TRADE_ENABLE;
public static boolean STORE_OFFLINE_TRADE_IN_REALTIME;
public static boolean OFFLINE_CRAFT_ENABLE; public static boolean OFFLINE_CRAFT_ENABLE;
public static boolean OFFLINE_SET_NAME_COLOR; public static boolean OFFLINE_SET_NAME_COLOR;
public static int OFFLINE_NAME_COLOR; public static int OFFLINE_NAME_COLOR;
@ -1873,6 +1874,7 @@ public class Config
{ {
final PropertiesParser offlineConfig = new PropertiesParser(OFFLINE_CONFIG_FILE); final PropertiesParser offlineConfig = new PropertiesParser(OFFLINE_CONFIG_FILE);
OFFLINE_TRADE_ENABLE = offlineConfig.getBoolean("OfflineTradeEnable", false); OFFLINE_TRADE_ENABLE = offlineConfig.getBoolean("OfflineTradeEnable", false);
STORE_OFFLINE_TRADE_IN_REALTIME = offlineConfig.getBoolean("StoreOfflineTradeInRealtime", true);
OFFLINE_CRAFT_ENABLE = offlineConfig.getBoolean("OfflineCraftEnable", false); OFFLINE_CRAFT_ENABLE = offlineConfig.getBoolean("OfflineCraftEnable", false);
OFFLINE_SET_NAME_COLOR = offlineConfig.getBoolean("OfflineNameColorEnable", false); OFFLINE_SET_NAME_COLOR = offlineConfig.getBoolean("OfflineNameColorEnable", false);
OFFLINE_NAME_COLOR = Integer.decode("0x" + offlineConfig.getString("OfflineNameColor", "ff00ff")); OFFLINE_NAME_COLOR = Integer.decode("0x" + offlineConfig.getString("OfflineNameColor", "ff00ff"));

View File

@ -379,7 +379,7 @@ public class Shutdown extends Thread
try try
{ {
if ((Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE) && Config.RESTORE_OFFLINERS) if ((Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE) && Config.RESTORE_OFFLINERS && !Config.STORE_OFFLINE_TRADE_IN_REALTIME)
{ {
OfflineTraderTable.getInstance().storeOffliners(); OfflineTraderTable.getInstance().storeOffliners();
} }

View File

@ -33,6 +33,8 @@ import org.l2jmobius.gameserver.model.TradeList.TradeItem;
import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.model.olympiad.Olympiad;
import org.l2jmobius.gameserver.model.zone.ZoneId;
import org.l2jmobius.gameserver.network.GameClient; import org.l2jmobius.gameserver.network.GameClient;
public class OfflineTraderTable public class OfflineTraderTable
@ -287,24 +289,49 @@ public class OfflineTraderTable
} }
} }
public void storeOffliner(Player trader) public boolean storeOffliner(Player trader)
{ {
if ((trader.getPrivateStoreType() == Player.STORE_PRIVATE_NONE) || (!trader.isInOfflineMode())) if (trader.getPrivateStoreType() == Player.STORE_PRIVATE_NONE)
{ {
return; return false;
} }
if (!trader.isKicked() //
&& !Olympiad.getInstance().isRegistered(trader) //
&& !trader.isInOlympiadMode() //
&& ((trader.isInStoreMode() && Config.OFFLINE_TRADE_ENABLE) //
|| (trader.isCrafting() && Config.OFFLINE_CRAFT_ENABLE)))
{
if (!Config.OFFLINE_MODE_IN_PEACE_ZONE || (Config.OFFLINE_MODE_IN_PEACE_ZONE && trader.isInsideZone(ZoneId.PEACE)))
{
try (Connection con = DatabaseFactory.getConnection(); try (Connection con = DatabaseFactory.getConnection();
PreparedStatement stm1 = con.prepareStatement(CLEAR_OFFLINE_TABLE_ITEMS_PLAYER); PreparedStatement stm1 = con.prepareStatement(CLEAR_OFFLINE_TABLE_ITEMS_PLAYER);
PreparedStatement stm2 = con.prepareStatement(CLEAR_OFFLINE_TABLE_PLAYER); PreparedStatement stm2 = con.prepareStatement(CLEAR_OFFLINE_TABLE_PLAYER);
PreparedStatement stm3 = con.prepareStatement(SAVE_ITEMS); PreparedStatement stm3 = con.prepareStatement(SAVE_ITEMS);
PreparedStatement stm4 = con.prepareStatement(SAVE_OFFLINE_STATUS)) PreparedStatement stm4 = con.prepareStatement(SAVE_OFFLINE_STATUS))
{ {
trader.setOnlineStatus(false);
trader.leaveParty();
trader.store();
if (Config.OFFLINE_MODE_SET_INVULNERABLE)
{
trader.setInvul(true);
}
if (Config.OFFLINE_SET_NAME_COLOR)
{
trader._originalNameColorOffline = trader.getAppearance().getNameColor();
trader.getAppearance().setNameColor(Config.OFFLINE_NAME_COLOR);
trader.broadcastUserInfo();
}
stm1.setInt(1, trader.getObjectId()); stm1.setInt(1, trader.getObjectId());
stm1.execute(); stm1.execute();
stm2.setInt(1, trader.getObjectId()); stm2.setInt(1, trader.getObjectId());
stm2.execute(); stm2.execute();
con.setAutoCommit(false); // avoid halfway done con.setAutoCommit(false); // avoid halfway done
boolean save = true; boolean save = true;
try try
{ {
@ -313,9 +340,9 @@ public class OfflineTraderTable
{ {
case Player.STORE_PRIVATE_BUY: case Player.STORE_PRIVATE_BUY:
{ {
if (!Config.OFFLINE_TRADE_ENABLE) if (!Config.OFFLINE_TRADE_ENABLE || (trader.getBuyList().getItems().size() < 1))
{ {
break; save = false;
} }
title = trader.getBuyList().getTitle(); title = trader.getBuyList().getTitle();
for (TradeItem i : trader.getBuyList().getItems()) for (TradeItem i : trader.getBuyList().getItems())
@ -333,9 +360,9 @@ public class OfflineTraderTable
case Player.STORE_PRIVATE_SELL: case Player.STORE_PRIVATE_SELL:
case Player.STORE_PRIVATE_PACKAGE_SELL: case Player.STORE_PRIVATE_PACKAGE_SELL:
{ {
if (!Config.OFFLINE_TRADE_ENABLE) if (!Config.OFFLINE_TRADE_ENABLE || (trader.getSellList().getItems().size() < 1))
{ {
break; save = false;
} }
title = trader.getSellList().getTitle(); title = trader.getSellList().getTitle();
trader.getSellList().updateItems(); trader.getSellList().updateItems();
@ -353,9 +380,9 @@ public class OfflineTraderTable
} }
case Player.STORE_PRIVATE_MANUFACTURE: case Player.STORE_PRIVATE_MANUFACTURE:
{ {
if (!Config.OFFLINE_CRAFT_ENABLE) if (!Config.OFFLINE_CRAFT_ENABLE || (trader.getCreateList().getList().size() < 1))
{ {
break; save = false;
} }
title = trader.getCreateList().getStoreName(); title = trader.getCreateList().getStoreName();
for (ManufactureItem i : trader.getCreateList().getList()) for (ManufactureItem i : trader.getCreateList().getList())
@ -372,13 +399,18 @@ public class OfflineTraderTable
} }
default: default:
{ {
// LOGGER.info(getClass().getSimpleName() + ": Error while saving offline trader: " + pc.getObjectId() + ", store type: "+pc.getPrivateStoreType()); LOGGER.info(getClass().getSimpleName() + ": Error while saving offline trader: " + trader.getObjectId() + ", store type: " + trader.getPrivateStoreType());
save = false; save = false;
} }
} }
if (save) if (save)
{ {
if (trader.getOfflineStartTime() == 0)
{
trader.setOfflineStartTime(System.currentTimeMillis());
}
stm4.setInt(1, trader.getObjectId()); // Char Id stm4.setInt(1, trader.getObjectId()); // Char Id
stm4.setLong(2, trader.getOfflineStartTime()); stm4.setLong(2, trader.getOfflineStartTime());
stm4.setInt(3, trader.getPrivateStoreType()); // store type stm4.setInt(3, trader.getPrivateStoreType()); // store type
@ -386,7 +418,13 @@ public class OfflineTraderTable
stm4.executeUpdate(); stm4.executeUpdate();
stm4.clearParameters(); stm4.clearParameters();
con.commit(); con.commit();
LOGGER.info("Player: (" + trader.getName() + ") trade offline enable");
World.OFFLINE_TRADE_COUNT++;
return true;
} }
return false;
} }
catch (Exception e) catch (Exception e)
{ {
@ -396,6 +434,33 @@ public class OfflineTraderTable
catch (Exception e) catch (Exception e)
{ {
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while saving offline trader: " + trader.getObjectId() + " " + e); LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while saving offline trader: " + trader.getObjectId() + " " + e);
return false;
}
return false;
}
}
return false;
}
public void removeStoreOffliner(Player player)
{
if (Config.STORE_OFFLINE_TRADE_IN_REALTIME)
{
try (Connection con = DatabaseFactory.getConnection();
PreparedStatement stm1 = con.prepareStatement(CLEAR_OFFLINE_TABLE_ITEMS_PLAYER);
PreparedStatement stm2 = con.prepareStatement(CLEAR_OFFLINE_TABLE_PLAYER))
{
stm1.setInt(1, player.getObjectId());
stm1.execute();
stm2.setInt(1, player.getObjectId());
stm2.execute();
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while cleanning offline trader: " + player.getName() + " " + e);
}
} }
} }

View File

@ -44,7 +44,6 @@ import org.l2jmobius.gameserver.model.World;
import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.model.clan.Clan; import org.l2jmobius.gameserver.model.clan.Clan;
import org.l2jmobius.gameserver.model.olympiad.Olympiad; import org.l2jmobius.gameserver.model.olympiad.Olympiad;
import org.l2jmobius.gameserver.model.zone.ZoneId;
import org.l2jmobius.gameserver.network.serverpackets.ServerPacket; import org.l2jmobius.gameserver.network.serverpackets.ServerPacket;
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import org.l2jmobius.gameserver.util.FloodProtectors; import org.l2jmobius.gameserver.util.FloodProtectors;
@ -464,6 +463,7 @@ public class GameClient extends NetClient
} }
player = Player.load(objectId); player = Player.load(objectId);
OfflineTraderTable.getInstance().removeStoreOffliner(player);
return player; return player;
} }
@ -497,6 +497,7 @@ public class GameClient extends NetClient
{ {
// we are going to manually save the char below thus we can force the cancel // we are going to manually save the char below thus we can force the cancel
boolean offlineshop = false;
final Player player = _player; final Player player = _player;
if (player != null) // this should only happen on connection loss if (player != null) // this should only happen on connection loss
{ {
@ -518,19 +519,30 @@ public class GameClient extends NetClient
player.setClient(null); player.setClient(null);
if ((player.isInStoreMode() && Config.OFFLINE_TRADE_ENABLE) // // Only save trader offline if not realtime function is enable
|| (player.isCrafting() && Config.OFFLINE_CRAFT_ENABLE)) if (Config.STORE_OFFLINE_TRADE_IN_REALTIME)
{ {
if (!Config.OFFLINE_MODE_IN_PEACE_ZONE || (Config.OFFLINE_MODE_IN_PEACE_ZONE && player.isInsideZone(ZoneId.PEACE))) // Try execute offline trade
{ offlineshop = OfflineTraderTable.getInstance().storeOffliner(player);
return;
}
} }
if (!offlineshop)
{
// prevent closing again // prevent closing again
player.deleteMe(); player.deleteMe();
player.store(true); player.store(true);
player.setClient(null); }
else
{
// store operation
try
{
player.store();
}
catch (Exception e2)
{
}
}
} }
setPlayer(null); setPlayer(null);
@ -556,6 +568,7 @@ public class GameClient extends NetClient
{ {
// we are going to manually save the char bellow thus we can force the cancel // we are going to manually save the char bellow thus we can force the cancel
boolean offlineshop = false;
final Player player = _player; final Player player = _player;
if (player != null) // this should only happen on connection loss if (player != null) // this should only happen on connection loss
{ {
@ -575,43 +588,20 @@ public class GameClient extends NetClient
player.decreaseBoxes(); player.decreaseBoxes();
} }
if (!player.isKicked() // // Only save trader offline if not realtime function is enable
&& !Olympiad.getInstance().isRegistered(player) // if (Config.STORE_OFFLINE_TRADE_IN_REALTIME)
&& !player.isInOlympiadMode() //
&& ((player.isInStoreMode() && Config.OFFLINE_TRADE_ENABLE) //
|| (player.isCrafting() && Config.OFFLINE_CRAFT_ENABLE)))
{ {
if (!Config.OFFLINE_MODE_IN_PEACE_ZONE || (Config.OFFLINE_MODE_IN_PEACE_ZONE && player.isInsideZone(ZoneId.PEACE))) // Try execute offline trade
{ offlineshop = OfflineTraderTable.getInstance().storeOffliner(player);
player.setOnlineStatus(false);
player.leaveParty();
player.store();
if (Config.OFFLINE_MODE_SET_INVULNERABLE)
{
player.setInvul(true);
}
if (Config.OFFLINE_SET_NAME_COLOR)
{
player._originalNameColorOffline = player.getAppearance().getNameColor();
player.getAppearance().setNameColor(Config.OFFLINE_NAME_COLOR);
player.broadcastUserInfo();
} }
if (player.getOfflineStartTime() == 0) if (!offlineshop)
{ {
player.setOfflineStartTime(System.currentTimeMillis());
}
OfflineTraderTable.getInstance().storeOffliner(player);
World.OFFLINE_TRADE_COUNT++;
return;
}
}
// notify the world about our disconnect // notify the world about our disconnect
player.deleteMe(); player.deleteMe();
}
else
{
// store operation // store operation
try try
{ {
@ -621,6 +611,7 @@ public class GameClient extends NetClient
{ {
} }
} }
}
setPlayer(null); setPlayer(null);
setDetached(true); setDetached(true);