Save offline traders in real time.

This commit is contained in:
mobius 2015-01-02 12:18:31 +00:00
parent 13dc95d50b
commit 0a69033fa0
8 changed files with 143 additions and 4 deletions

View File

@ -308,6 +308,11 @@ OfflineMaxDays = 10
#Default: True
OfflineDisconnectFinished = True
#Store offline trader transactions in realtime.
#Uses more datatabase resources, but helps if server shuts down unexpectedly.
StoreOfflineTradeInRealtime = True
# ---------------------------------------------------------------------------
# Mana Drugs/Potions
# ---------------------------------------------------------------------------

View File

@ -767,6 +767,7 @@ public final class Config
public static boolean OFFLINE_SET_NAME_COLOR;
public static int OFFLINE_NAME_COLOR;
public static boolean OFFLINE_FAME;
public static boolean STORE_OFFLINE_TRADE_IN_REALTIME;
public static boolean L2JMOD_ENABLE_MANA_POTIONS_SUPPORT;
public static boolean L2JMOD_DISPLAY_SERVER_TIME;
public static boolean WELCOME_MESSAGE_ENABLED;
@ -2478,6 +2479,7 @@ public final class Config
RESTORE_OFFLINERS = CustomSettings.getBoolean("RestoreOffliners", false);
OFFLINE_MAX_DAYS = CustomSettings.getInt("OfflineMaxDays", 10);
OFFLINE_DISCONNECT_FINISHED = CustomSettings.getBoolean("OfflineDisconnectFinished", true);
STORE_OFFLINE_TRADE_IN_REALTIME = CustomSettings.getBoolean("StoreOfflineTradeInRealtime", true);
L2JMOD_ENABLE_MANA_POTIONS_SUPPORT = CustomSettings.getBoolean("EnableManaPotionSupport", false);

View File

@ -201,7 +201,7 @@ public class Shutdown extends Thread
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)
{
OfflineTradersTable.getInstance().storeOffliners();
_log.info("Offline Traders Table: Offline shops stored(" + tc.getEstimatedTimeAndRestartCounter() + "ms).");

View File

@ -45,7 +45,9 @@ public class OfflineTradersTable
private static final String SAVE_OFFLINE_STATUS = "INSERT INTO character_offline_trade (`charId`,`time`,`type`,`title`) VALUES (?,?,?,?)";
private static final String SAVE_ITEMS = "INSERT INTO character_offline_trade_items (`charId`,`item`,`count`,`price`) VALUES (?,?,?,?)";
private static final String CLEAR_OFFLINE_TABLE = "DELETE FROM character_offline_trade";
private static final String CLEAR_OFFLINE_TABLE_PLAYER = "DELETE FROM character_offline_trade WHERE `charId`=?";
private static final String CLEAR_OFFLINE_TABLE_ITEMS = "DELETE FROM character_offline_trade_items";
private static final String CLEAR_OFFLINE_TABLE_ITEMS_PLAYER = "DELETE FROM character_offline_trade_items WHERE `charId`=?";
private static final String LOAD_OFFLINE_STATUS = "SELECT * FROM character_offline_trade";
private static final String LOAD_OFFLINE_ITEMS = "SELECT * FROM character_offline_trade_items WHERE charId = ?";
@ -253,10 +255,13 @@ public class OfflineTradersTable
LOGGER.info(getClass().getSimpleName() + ": Loaded: " + nTraders + " offline trader(s)");
try (Statement stm1 = con.createStatement())
if (!Config.STORE_OFFLINE_TRADE_IN_REALTIME)
{
stm1.execute(CLEAR_OFFLINE_TABLE);
stm1.execute(CLEAR_OFFLINE_TABLE_ITEMS);
try (Statement stm1 = con.createStatement())
{
stm1.execute(CLEAR_OFFLINE_TABLE);
stm1.execute(CLEAR_OFFLINE_TABLE_ITEMS);
}
}
}
catch (Exception e)
@ -265,6 +270,106 @@ public class OfflineTradersTable
}
}
public static synchronized void onTransaction(L2PcInstance trader, boolean finished, boolean firstCall)
{
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
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))
{
String title = null;
stm1.setInt(1, trader.getObjectId()); // Char Id
stm1.execute();
stm1.close();
// Trade is done - clear info
if (finished)
{
stm2.setInt(1, trader.getObjectId()); // Char Id
stm2.execute();
stm2.close();
}
else
{
try
{
if ((trader.getClient() == null) || trader.getClient().isDetached())
{
switch (trader.getPrivateStoreType())
{
case BUY:
if (firstCall)
{
title = trader.getBuyList().getTitle();
}
for (TradeItem i : trader.getBuyList().getItems())
{
stm3.setInt(1, trader.getObjectId());
stm3.setInt(2, i.getItem().getId());
stm3.setLong(3, i.getCount());
stm3.setLong(4, i.getPrice());
stm3.executeUpdate();
stm3.clearParameters();
}
break;
case SELL:
case PACKAGE_SELL:
if (firstCall)
{
title = trader.getSellList().getTitle();
}
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.executeUpdate();
stm3.clearParameters();
}
break;
case MANUFACTURE:
if (firstCall)
{
title = trader.getStoreName();
}
for (L2ManufactureItem i : trader.getManufactureItems().values())
{
stm3.setInt(1, trader.getObjectId());
stm3.setInt(2, i.getRecipeId());
stm3.setLong(3, 0);
stm3.setLong(4, i.getCost());
stm3.executeUpdate();
stm3.clearParameters();
}
}
stm3.close();
if (firstCall)
{
stm4.setInt(1, trader.getObjectId()); // Char Id
stm4.setLong(2, trader.getOfflineStartTime());
stm4.setInt(3, trader.getPrivateStoreType().getId()); // store type
stm4.setString(4, title);
stm4.executeUpdate();
stm4.clearParameters();
stm4.close();
}
}
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, "OfflineTradersTable[storeTradeItems()]: Error while saving offline trader: " + trader.getObjectId() + " " + e, e);
}
}
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, "OfflineTradersTable[storeTradeItems()]: Error while saving offline traders: " + e, e);
}
}
/**
* Gets the single instance of OfflineTradersTable.
* @return single instance of OfflineTradersTable

View File

@ -44,6 +44,7 @@ import com.l2jserver.gameserver.LoginServerThread.SessionKey;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.CharNameTable;
import com.l2jserver.gameserver.datatables.ClanTable;
import com.l2jserver.gameserver.datatables.OfflineTradersTable;
import com.l2jserver.gameserver.datatables.SecondaryAuthData;
import com.l2jserver.gameserver.instancemanager.AntiFeedManager;
import com.l2jserver.gameserver.model.CharSelectInfoPackage;
@ -804,6 +805,12 @@ public final class L2GameClient extends MMOClient<MMOConnection<L2GameClient>> i
getActiveChar().setOfflineStartTime(System.currentTimeMillis());
}
// Store trade on exit, if realtime saving is enabled.
if (Config.STORE_OFFLINE_TRADE_IN_REALTIME)
{
OfflineTradersTable.onTransaction(getActiveChar(), false, true);
}
final LogRecord record = new LogRecord(Level.INFO, "Entering offline mode");
record.setParameters(new Object[]
{

View File

@ -24,6 +24,7 @@ import com.l2jserver.gameserver.cache.HtmCache;
import com.l2jserver.gameserver.datatables.AdminTable;
import com.l2jserver.gameserver.datatables.AnnouncementsTable;
import com.l2jserver.gameserver.datatables.BeautyShopData;
import com.l2jserver.gameserver.datatables.OfflineTradersTable;
import com.l2jserver.gameserver.datatables.SkillTreesData;
import com.l2jserver.gameserver.enums.Race;
import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
@ -575,6 +576,11 @@ public class EnterWorld extends L2GameClientPacket
activeChar.sendPacket(ExNotifyPremiumItem.STATIC_PACKET);
}
if ((Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE) && Config.STORE_OFFLINE_TRADE_IN_REALTIME)
{
OfflineTradersTable.onTransaction(activeChar, true, false);
}
activeChar.broadcastUserInfo();
if (BeautyShopData.getInstance().hasBeautyData(activeChar.getRace(), activeChar.getAppearance().getSexType()))

View File

@ -22,6 +22,7 @@ import static com.l2jserver.gameserver.model.actor.L2Npc.INTERACTION_DISTANCE;
import javolution.util.FastSet;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.OfflineTradersTable;
import com.l2jserver.gameserver.enums.PrivateStoreType;
import com.l2jserver.gameserver.model.ItemRequest;
import com.l2jserver.gameserver.model.L2Object;
@ -153,6 +154,12 @@ public final class RequestPrivateStoreBuy extends L2GameClientPacket
return;
}
// Update offline trade record, if realtime saving is enabled
if (Config.OFFLINE_TRADE_ENABLE && Config.STORE_OFFLINE_TRADE_IN_REALTIME && ((storePlayer.getClient() == null) || storePlayer.getClient().isDetached()))
{
OfflineTradersTable.onTransaction(storePlayer, storeList.getItemCount() == 0, false);
}
if (storeList.getItemCount() == 0)
{
storePlayer.setPrivateStoreType(PrivateStoreType.NONE);

View File

@ -21,6 +21,7 @@ package com.l2jserver.gameserver.network.clientpackets;
import static com.l2jserver.gameserver.model.actor.L2Npc.INTERACTION_DISTANCE;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.OfflineTradersTable;
import com.l2jserver.gameserver.enums.PrivateStoreType;
import com.l2jserver.gameserver.model.ItemRequest;
import com.l2jserver.gameserver.model.L2World;
@ -138,6 +139,12 @@ public final class RequestPrivateStoreSell extends L2GameClientPacket
return;
}
// Update offline trade record, if realtime saving is enabled
if (Config.OFFLINE_TRADE_ENABLE && Config.STORE_OFFLINE_TRADE_IN_REALTIME && ((storePlayer.getClient() == null) || storePlayer.getClient().isDetached()))
{
OfflineTradersTable.onTransaction(storePlayer, storeList.getItemCount() == 0, false);
}
if (storeList.getItemCount() == 0)
{
storePlayer.setPrivateStoreType(PrivateStoreType.NONE);