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,116 +289,179 @@ 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;
} }
try (Connection con = DatabaseFactory.getConnection(); if (!trader.isKicked() //
PreparedStatement stm1 = con.prepareStatement(CLEAR_OFFLINE_TABLE_ITEMS_PLAYER); && !Olympiad.getInstance().isRegistered(trader) //
PreparedStatement stm2 = con.prepareStatement(CLEAR_OFFLINE_TABLE_PLAYER); && !trader.isInOlympiadMode() //
PreparedStatement stm3 = con.prepareStatement(SAVE_ITEMS); && ((trader.isInStoreMode() && Config.OFFLINE_TRADE_ENABLE) //
PreparedStatement stm4 = con.prepareStatement(SAVE_OFFLINE_STATUS)) || (trader.isCrafting() && Config.OFFLINE_CRAFT_ENABLE)))
{ {
stm1.setInt(1, trader.getObjectId()); if (!Config.OFFLINE_MODE_IN_PEACE_ZONE || (Config.OFFLINE_MODE_IN_PEACE_ZONE && trader.isInsideZone(ZoneId.PEACE)))
stm1.execute();
stm2.setInt(1, trader.getObjectId());
stm2.execute();
con.setAutoCommit(false); // avoid halfway done
boolean save = true;
try
{ {
String title = null; try (Connection con = DatabaseFactory.getConnection();
switch (trader.getPrivateStoreType()) PreparedStatement stm1 = con.prepareStatement(CLEAR_OFFLINE_TABLE_ITEMS_PLAYER);
PreparedStatement stm2 = con.prepareStatement(CLEAR_OFFLINE_TABLE_PLAYER);
PreparedStatement stm3 = con.prepareStatement(SAVE_ITEMS);
PreparedStatement stm4 = con.prepareStatement(SAVE_OFFLINE_STATUS))
{ {
case Player.STORE_PRIVATE_BUY: trader.setOnlineStatus(false);
trader.leaveParty();
trader.store();
if (Config.OFFLINE_MODE_SET_INVULNERABLE)
{ {
if (!Config.OFFLINE_TRADE_ENABLE) trader.setInvul(true);
{
break;
}
title = trader.getBuyList().getTitle();
for (TradeItem i : trader.getBuyList().getItems())
{
stm3.setInt(1, trader.getObjectId());
stm3.setInt(2, i.getItem().getItemId());
stm3.setLong(3, i.getCount());
stm3.setLong(4, i.getPrice());
stm3.setLong(5, i.getEnchant());
stm3.executeUpdate();
stm3.clearParameters();
}
break;
} }
case Player.STORE_PRIVATE_SELL:
case Player.STORE_PRIVATE_PACKAGE_SELL: if (Config.OFFLINE_SET_NAME_COLOR)
{ {
if (!Config.OFFLINE_TRADE_ENABLE) trader._originalNameColorOffline = trader.getAppearance().getNameColor();
{ trader.getAppearance().setNameColor(Config.OFFLINE_NAME_COLOR);
break; trader.broadcastUserInfo();
}
title = trader.getSellList().getTitle();
trader.getSellList().updateItems();
for (TradeItem i : trader.getSellList().getItems())
{
stm3.setInt(1, trader.getObjectId());
stm3.setInt(2, i.getObjectId());
stm3.setLong(3, i.getCount());
stm3.setLong(4, i.getPrice());
stm3.setLong(5, i.getEnchant());
stm3.executeUpdate();
stm3.clearParameters();
}
break;
} }
case Player.STORE_PRIVATE_MANUFACTURE:
stm1.setInt(1, trader.getObjectId());
stm1.execute();
stm2.setInt(1, trader.getObjectId());
stm2.execute();
con.setAutoCommit(false); // avoid halfway done
boolean save = true;
try
{ {
if (!Config.OFFLINE_CRAFT_ENABLE) String title = null;
switch (trader.getPrivateStoreType())
{ {
break; case Player.STORE_PRIVATE_BUY:
{
if (!Config.OFFLINE_TRADE_ENABLE || (trader.getBuyList().getItems().size() < 1))
{
save = false;
}
title = trader.getBuyList().getTitle();
for (TradeItem i : trader.getBuyList().getItems())
{
stm3.setInt(1, trader.getObjectId());
stm3.setInt(2, i.getItem().getItemId());
stm3.setLong(3, i.getCount());
stm3.setLong(4, i.getPrice());
stm3.setLong(5, i.getEnchant());
stm3.executeUpdate();
stm3.clearParameters();
}
break;
}
case Player.STORE_PRIVATE_SELL:
case Player.STORE_PRIVATE_PACKAGE_SELL:
{
if (!Config.OFFLINE_TRADE_ENABLE || (trader.getSellList().getItems().size() < 1))
{
save = false;
}
title = trader.getSellList().getTitle();
trader.getSellList().updateItems();
for (TradeItem i : trader.getSellList().getItems())
{
stm3.setInt(1, trader.getObjectId());
stm3.setInt(2, i.getObjectId());
stm3.setLong(3, i.getCount());
stm3.setLong(4, i.getPrice());
stm3.setLong(5, i.getEnchant());
stm3.executeUpdate();
stm3.clearParameters();
}
break;
}
case Player.STORE_PRIVATE_MANUFACTURE:
{
if (!Config.OFFLINE_CRAFT_ENABLE || (trader.getCreateList().getList().size() < 1))
{
save = false;
}
title = trader.getCreateList().getStoreName();
for (ManufactureItem i : trader.getCreateList().getList())
{
stm3.setInt(1, trader.getObjectId());
stm3.setInt(2, i.getRecipeId());
stm3.setLong(3, 0);
stm3.setLong(4, i.getCost());
stm3.setLong(5, 0);
stm3.executeUpdate();
stm3.clearParameters();
}
break;
}
default:
{
LOGGER.info(getClass().getSimpleName() + ": Error while saving offline trader: " + trader.getObjectId() + ", store type: " + trader.getPrivateStoreType());
save = false;
}
} }
title = trader.getCreateList().getStoreName();
for (ManufactureItem i : trader.getCreateList().getList()) if (save)
{ {
stm3.setInt(1, trader.getObjectId()); if (trader.getOfflineStartTime() == 0)
stm3.setInt(2, i.getRecipeId()); {
stm3.setLong(3, 0); trader.setOfflineStartTime(System.currentTimeMillis());
stm3.setLong(4, i.getCost()); }
stm3.setLong(5, 0);
stm3.executeUpdate(); stm4.setInt(1, trader.getObjectId()); // Char Id
stm3.clearParameters(); stm4.setLong(2, trader.getOfflineStartTime());
stm4.setInt(3, trader.getPrivateStoreType()); // store type
stm4.setString(4, title);
stm4.executeUpdate();
stm4.clearParameters();
con.commit();
LOGGER.info("Player: (" + trader.getName() + ") trade offline enable");
World.OFFLINE_TRADE_COUNT++;
return true;
} }
break;
return false;
} }
default: catch (Exception e)
{ {
// LOGGER.info(getClass().getSimpleName() + ": Error while saving offline trader: " + pc.getObjectId() + ", store type: "+pc.getPrivateStoreType()); LOGGER.warning(getClass().getSimpleName() + ": Error while saving offline trader: " + trader.getObjectId() + " " + e);
save = false;
} }
} }
catch (Exception e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while saving offline trader: " + trader.getObjectId() + " " + e);
return false;
}
if (save) return false;
{ }
stm4.setInt(1, trader.getObjectId()); // Char Id }
stm4.setLong(2, trader.getOfflineStartTime());
stm4.setInt(3, trader.getPrivateStoreType()); // store type return false;
stm4.setString(4, title); }
stm4.executeUpdate();
stm4.clearParameters(); public void removeStoreOffliner(Player player)
con.commit(); {
} 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) catch (Exception e)
{ {
LOGGER.warning(getClass().getSimpleName() + ": Error while saving offline trader: " + trader.getObjectId() + " " + e); LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while cleanning offline trader: " + player.getName() + " " + e);
} }
} }
catch (Exception e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while saving offline trader: " + trader.getObjectId() + " " + 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;
}
} }
// prevent closing again if (!offlineshop)
player.deleteMe(); {
player.store(true); // prevent closing again
player.setClient(null); player.deleteMe();
player.store(true);
}
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,50 +580,28 @@ 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);
}
if (!offlineshop)
{
// notify the world about our disconnect
player.deleteMe();
}
else
{
// store operation
try
{ {
player.setOnlineStatus(false);
player.leaveParty();
player.store(); 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)
{
player.setOfflineStartTime(System.currentTimeMillis());
}
OfflineTraderTable.getInstance().storeOffliner(player);
World.OFFLINE_TRADE_COUNT++;
return;
} }
} catch (Exception e2)
{
// notify the world about our disconnect }
player.deleteMe();
// store operation
try
{
player.store();
}
catch (Exception e2)
{
} }
} }

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,116 +289,179 @@ 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;
} }
try (Connection con = DatabaseFactory.getConnection(); if (!trader.isKicked() //
PreparedStatement stm1 = con.prepareStatement(CLEAR_OFFLINE_TABLE_ITEMS_PLAYER); && !Olympiad.getInstance().isRegistered(trader) //
PreparedStatement stm2 = con.prepareStatement(CLEAR_OFFLINE_TABLE_PLAYER); && !trader.isInOlympiadMode() //
PreparedStatement stm3 = con.prepareStatement(SAVE_ITEMS); && ((trader.isInStoreMode() && Config.OFFLINE_TRADE_ENABLE) //
PreparedStatement stm4 = con.prepareStatement(SAVE_OFFLINE_STATUS)) || (trader.isCrafting() && Config.OFFLINE_CRAFT_ENABLE)))
{ {
stm1.setInt(1, trader.getObjectId()); if (!Config.OFFLINE_MODE_IN_PEACE_ZONE || (Config.OFFLINE_MODE_IN_PEACE_ZONE && trader.isInsideZone(ZoneId.PEACE)))
stm1.execute();
stm2.setInt(1, trader.getObjectId());
stm2.execute();
con.setAutoCommit(false); // avoid halfway done
boolean save = true;
try
{ {
String title = null; try (Connection con = DatabaseFactory.getConnection();
switch (trader.getPrivateStoreType()) PreparedStatement stm1 = con.prepareStatement(CLEAR_OFFLINE_TABLE_ITEMS_PLAYER);
PreparedStatement stm2 = con.prepareStatement(CLEAR_OFFLINE_TABLE_PLAYER);
PreparedStatement stm3 = con.prepareStatement(SAVE_ITEMS);
PreparedStatement stm4 = con.prepareStatement(SAVE_OFFLINE_STATUS))
{ {
case Player.STORE_PRIVATE_BUY: trader.setOnlineStatus(false);
trader.leaveParty();
trader.store();
if (Config.OFFLINE_MODE_SET_INVULNERABLE)
{ {
if (!Config.OFFLINE_TRADE_ENABLE) trader.setInvul(true);
{
break;
}
title = trader.getBuyList().getTitle();
for (TradeItem i : trader.getBuyList().getItems())
{
stm3.setInt(1, trader.getObjectId());
stm3.setInt(2, i.getItem().getItemId());
stm3.setLong(3, i.getCount());
stm3.setLong(4, i.getPrice());
stm3.setLong(5, i.getEnchant());
stm3.executeUpdate();
stm3.clearParameters();
}
break;
} }
case Player.STORE_PRIVATE_SELL:
case Player.STORE_PRIVATE_PACKAGE_SELL: if (Config.OFFLINE_SET_NAME_COLOR)
{ {
if (!Config.OFFLINE_TRADE_ENABLE) trader._originalNameColorOffline = trader.getAppearance().getNameColor();
{ trader.getAppearance().setNameColor(Config.OFFLINE_NAME_COLOR);
break; trader.broadcastUserInfo();
}
title = trader.getSellList().getTitle();
trader.getSellList().updateItems();
for (TradeItem i : trader.getSellList().getItems())
{
stm3.setInt(1, trader.getObjectId());
stm3.setInt(2, i.getObjectId());
stm3.setLong(3, i.getCount());
stm3.setLong(4, i.getPrice());
stm3.setLong(5, i.getEnchant());
stm3.executeUpdate();
stm3.clearParameters();
}
break;
} }
case Player.STORE_PRIVATE_MANUFACTURE:
stm1.setInt(1, trader.getObjectId());
stm1.execute();
stm2.setInt(1, trader.getObjectId());
stm2.execute();
con.setAutoCommit(false); // avoid halfway done
boolean save = true;
try
{ {
if (!Config.OFFLINE_CRAFT_ENABLE) String title = null;
switch (trader.getPrivateStoreType())
{ {
break; case Player.STORE_PRIVATE_BUY:
{
if (!Config.OFFLINE_TRADE_ENABLE || (trader.getBuyList().getItems().size() < 1))
{
save = false;
}
title = trader.getBuyList().getTitle();
for (TradeItem i : trader.getBuyList().getItems())
{
stm3.setInt(1, trader.getObjectId());
stm3.setInt(2, i.getItem().getItemId());
stm3.setLong(3, i.getCount());
stm3.setLong(4, i.getPrice());
stm3.setLong(5, i.getEnchant());
stm3.executeUpdate();
stm3.clearParameters();
}
break;
}
case Player.STORE_PRIVATE_SELL:
case Player.STORE_PRIVATE_PACKAGE_SELL:
{
if (!Config.OFFLINE_TRADE_ENABLE || (trader.getSellList().getItems().size() < 1))
{
save = false;
}
title = trader.getSellList().getTitle();
trader.getSellList().updateItems();
for (TradeItem i : trader.getSellList().getItems())
{
stm3.setInt(1, trader.getObjectId());
stm3.setInt(2, i.getObjectId());
stm3.setLong(3, i.getCount());
stm3.setLong(4, i.getPrice());
stm3.setLong(5, i.getEnchant());
stm3.executeUpdate();
stm3.clearParameters();
}
break;
}
case Player.STORE_PRIVATE_MANUFACTURE:
{
if (!Config.OFFLINE_CRAFT_ENABLE || (trader.getCreateList().getList().size() < 1))
{
save = false;
}
title = trader.getCreateList().getStoreName();
for (ManufactureItem i : trader.getCreateList().getList())
{
stm3.setInt(1, trader.getObjectId());
stm3.setInt(2, i.getRecipeId());
stm3.setLong(3, 0);
stm3.setLong(4, i.getCost());
stm3.setLong(5, 0);
stm3.executeUpdate();
stm3.clearParameters();
}
break;
}
default:
{
LOGGER.info(getClass().getSimpleName() + ": Error while saving offline trader: " + trader.getObjectId() + ", store type: " + trader.getPrivateStoreType());
save = false;
}
} }
title = trader.getCreateList().getStoreName();
for (ManufactureItem i : trader.getCreateList().getList()) if (save)
{ {
stm3.setInt(1, trader.getObjectId()); if (trader.getOfflineStartTime() == 0)
stm3.setInt(2, i.getRecipeId()); {
stm3.setLong(3, 0); trader.setOfflineStartTime(System.currentTimeMillis());
stm3.setLong(4, i.getCost()); }
stm3.setLong(5, 0);
stm3.executeUpdate(); stm4.setInt(1, trader.getObjectId()); // Char Id
stm3.clearParameters(); stm4.setLong(2, trader.getOfflineStartTime());
stm4.setInt(3, trader.getPrivateStoreType()); // store type
stm4.setString(4, title);
stm4.executeUpdate();
stm4.clearParameters();
con.commit();
LOGGER.info("Player: (" + trader.getName() + ") trade offline enable");
World.OFFLINE_TRADE_COUNT++;
return true;
} }
break;
return false;
} }
default: catch (Exception e)
{ {
// LOGGER.info(getClass().getSimpleName() + ": Error while saving offline trader: " + pc.getObjectId() + ", store type: "+pc.getPrivateStoreType()); LOGGER.warning(getClass().getSimpleName() + ": Error while saving offline trader: " + trader.getObjectId() + " " + e);
save = false;
} }
} }
catch (Exception e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while saving offline trader: " + trader.getObjectId() + " " + e);
return false;
}
if (save) return false;
{ }
stm4.setInt(1, trader.getObjectId()); // Char Id }
stm4.setLong(2, trader.getOfflineStartTime());
stm4.setInt(3, trader.getPrivateStoreType()); // store type return false;
stm4.setString(4, title); }
stm4.executeUpdate();
stm4.clearParameters(); public void removeStoreOffliner(Player player)
con.commit(); {
} 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) catch (Exception e)
{ {
LOGGER.warning(getClass().getSimpleName() + ": Error while saving offline trader: " + trader.getObjectId() + " " + e); LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while cleanning offline trader: " + player.getName() + " " + e);
} }
} }
catch (Exception e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while saving offline trader: " + trader.getObjectId() + " " + 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;
}
} }
// prevent closing again if (!offlineshop)
player.deleteMe(); {
player.store(true); // prevent closing again
player.setClient(null); player.deleteMe();
player.store(true);
}
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,50 +588,28 @@ 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);
}
if (!offlineshop)
{
// notify the world about our disconnect
player.deleteMe();
}
else
{
// store operation
try
{ {
player.setOnlineStatus(false);
player.leaveParty();
player.store(); 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)
{
player.setOfflineStartTime(System.currentTimeMillis());
}
OfflineTraderTable.getInstance().storeOffliner(player);
World.OFFLINE_TRADE_COUNT++;
return;
} }
} catch (Exception e2)
{
// notify the world about our disconnect }
player.deleteMe();
// store operation
try
{
player.store();
}
catch (Exception e2)
{
} }
} }