All pastes #46438 Raw Edit

diff vs latest svn

public text v1 · immutable
#46438 ·published 2006-03-21 04:28 UTC
rendered paste body
Index: C:/workspace/c4/java/net/sf/l2j/status/LoginStatusThread.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/status/LoginStatusThread.java	(revision 1627)
+++ C:/workspace/c4/java/net/sf/l2j/status/LoginStatusThread.java	(working copy)
@@ -19,9 +19,9 @@
 import java.util.Properties;
 import java.util.logging.Logger;
 
+import net.sf.l2j.sql;
 import net.sf.l2j.Base64;
 import net.sf.l2j.Config;
-import net.sf.l2j.L2DatabaseFactory;
 import net.sf.l2j.loginserver.GameServerTable;
 import net.sf.l2j.loginserver.LoginController;
 import net.sf.l2j.loginserver.LoginServer;
@@ -202,10 +202,9 @@
 	{
 		if(!LoginController.getInstance().isGM(login))
 			return false;
-		java.sql.Connection con = null;
+		java.sql.Connection con = sql.Open();
 		try
 		{
-			con = L2DatabaseFactory.getInstance().getConnection();
 			PreparedStatement statement = con.prepareStatement("SELECT password FROM accounts WHERE login=?");
 			statement.setString(1, login);
 			ResultSet rset = statement.executeQuery();
@@ -217,14 +216,16 @@
 				return true;
 			}
 			statement.close();
+			sql.Commit(con);
 		}
-		catch(SQLException sqle)
+		catch(SQLException e)
 		{
-			sqle.printStackTrace();
+			sql.Rollback(con,e);
+			e.printStackTrace();
 		}
 		finally
 		{
-			try { con.close(); } catch (Exception e) {}
+			sql.Close(con);
 		}
 		return false;
 	}
Index: C:/workspace/c4/java/net/sf/l2j/Config.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/Config.java	(revision 1645)
+++ C:/workspace/c4/java/net/sf/l2j/Config.java	(working copy)
@@ -62,6 +62,7 @@
     public static String DATABASE_LOGIN;
     public static String DATABASE_PASSWORD;
     public static int DATABASE_MAX_CONNECTIONS;
+    public static int SQL_LOG_EXEC_TIME_MAX;       
     
     public static int   MAXIMUM_ONLINE_USERS;
     
@@ -234,7 +235,7 @@
     public static int   PLAYER_RATE_DROP_ITEM;
     public static int   PLAYER_RATE_DROP_EQUIP;    
     public static int   PLAYER_RATE_DROP_EQUIP_WEAPON;    
-    
+
 	/** Pet Rates (Multipliers) */ 	
 	public static float         PET_XP_RATE; 
  	public static int           PET_FOOD_RATE;
@@ -322,7 +323,7 @@
     public static final String  HEXID_FILE					= "./config/hexid.txt";
     public static final String  COMMAND_PRIVILEGES_FILE     = "./config/command-privileges.properties";
     public static final String  AI_FILE     				= "./config/ai.properties";
-	    
+    
     public static boolean CHECK_KNOWN;
     
     public static int     GAME_SERVER_LOGIN_PORT;
@@ -577,7 +578,7 @@
 	            PLAYER_RATE_DROP_ITEM           = Integer.parseInt(serverSettings.getProperty("PlayerRateDropItem", "70"));
 	            PLAYER_RATE_DROP_EQUIP          = Integer.parseInt(serverSettings.getProperty("PlayerRateDropEquip", "25"));
 	            PLAYER_RATE_DROP_EQUIP_WEAPON   = Integer.parseInt(serverSettings.getProperty("PlayerRateDropEquipWeapon", "5"));
-	            
+                
 	            PET_XP_RATE     = Float.parseFloat(serverSettings.getProperty("PetXpRate", "1."));
 	            PET_FOOD_RATE   = Integer.parseInt(serverSettings.getProperty("PetFoodRate", "1")); 
                 
@@ -660,6 +661,7 @@
 	            DATABASE_LOGIN              = serverSettings.getProperty("Login", "root");
 	            DATABASE_PASSWORD           = serverSettings.getProperty("Password", "");
 	            DATABASE_MAX_CONNECTIONS    = Integer.parseInt(serverSettings.getProperty("MaximumDbConnections", "10"));
+	            SQL_LOG_EXEC_TIME_MAX       = Integer.parseInt(serverSettings.getProperty("SqlLogExecTimeMax", "1000"));  	            
 	            
 	            COUNT_PACKETS          = Boolean.valueOf(serverSettings.getProperty("CountPacket", "false"));  
 	            DUMP_PACKET_COUNTS     = Boolean.valueOf(serverSettings.getProperty("DumpPacketCounts", "false"));
@@ -834,6 +836,7 @@
                 GM_NAME_COLOUR = Integer.decode("0x" + otherSettings.getProperty("GMNameColour", "00FF00"));
                 GM_STARTUP_INVISIBLE = Boolean.parseBoolean(otherSettings.getProperty("GMStartupInvisible", "True"));
                 GM_STARTUP_SILENCE = Boolean.parseBoolean(otherSettings.getProperty("GMStartupSilence", "True"));
+                
 	        }
 	        catch (Exception e)
 	        {
@@ -879,7 +882,7 @@
 	            ALT_GAME_CANCEL_CAST    = altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("cast") || altSettings.getProperty("AltGameCancelByHit", "Cast").equalsIgnoreCase("all");
 	            ALT_GAME_SHIELD_BLOCKS  = Boolean.parseBoolean(altSettings.getProperty("AltShieldBlocks", "false"));
 	            ALT_GAME_DELEVEL        = Boolean.parseBoolean(altSettings.getProperty("Delevel", "true"));
-            	    ALT_GAME_MAGICFAILURES  = Boolean.parseBoolean(altSettings.getProperty("MagicFailures", "false"));
+            	ALT_GAME_MAGICFAILURES  = Boolean.parseBoolean(altSettings.getProperty("MagicFailures", "false"));
 	            ALT_GAME_MOB_ATTACK_AI  = Boolean.parseBoolean(altSettings.getProperty("AltGameMobAttackAI", "false"));
 	            ALT_GAME_SKILL_FORMULAS = altSettings.getProperty("AltGameSkillFormulas", "none");
 	            ALT_GAME_EXPONENT_XP    = Float.parseFloat(altSettings.getProperty("AltGameExponentXp", "0."));
@@ -1056,6 +1059,7 @@
 	            DATABASE_LOGIN              = serverSettings.getProperty("Login", "root");
 	            DATABASE_PASSWORD           = serverSettings.getProperty("Password", "");
 	            DATABASE_MAX_CONNECTIONS    = Integer.parseInt(serverSettings.getProperty("MaximumDbConnections", "10"));
+	            SQL_LOG_EXEC_TIME_MAX       = Integer.parseInt(serverSettings.getProperty("SqlLogExecTimeMax","1000"));
 	            
 	            SHOW_LICENCE = Boolean.parseBoolean(serverSettings.getProperty("ShowLicence", "true"));
 	            IP_UPDATE_TIME				= Integer.parseInt(serverSettings.getProperty("IpUpdateTime","15"));
Index: C:/workspace/c4/java/net/sf/l2j/loginserver/GameServerTable.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/loginserver/GameServerTable.java	(revision 1629)
+++ C:/workspace/c4/java/net/sf/l2j/loginserver/GameServerTable.java	(working copy)
@@ -48,8 +48,8 @@
 import javolution.xml.pull.XmlPullParserException;
 import javolution.xml.pull.XmlPullParserImpl;
 
+import net.sf.l2j.sql;
 import net.sf.l2j.Config;
-import net.sf.l2j.L2DatabaseFactory;
 import net.sf.l2j.loginserver.gameserverpackets.ServerStatus;
 import net.sf.l2j.loginserver.serverpackets.ServerList;
 
@@ -136,14 +136,13 @@
 		_gameServerList = new FastList<GameServer>();
 		serverNames =  new FastMap<Integer, String>();
 		loadServerNames();
-		java.sql.Connection con = null;
+		java.sql.Connection con = sql.Open();
 		PreparedStatement statement = null;
 		int id = 0;
 		int number = 0;
 		int previousID = 0;
 		try
 		{
-			con = L2DatabaseFactory.getInstance().getConnection();
 			statement = con.prepareStatement("SELECT * FROM gameservers");
 			ResultSet rset = statement.executeQuery();
 			while(rset.next())
@@ -168,8 +167,8 @@
 		}
 		finally
 		{
-			try { con.close();} catch (Exception e2) {}
-        	try { statement.close();} catch (Exception e2) {}
+			try { statement.close();} catch (Exception e2) {}
+			sql.Close(con);
 		}
 		if (Config.DEBUG)
 		{
@@ -349,11 +348,10 @@
 	
 	public void createServer(GameServer gs)
 	{
-		java.sql.Connection con = null;
+		java.sql.Connection con = sql.Open();
 		PreparedStatement statement = null;
         try
         {
-            con = L2DatabaseFactory.getInstance().getConnection();
             statement = con.prepareStatement(
                     "INSERT INTO gameservers " +
                     "(hexid,server_id,host)" +
@@ -370,14 +368,16 @@
             }
 			statement.executeUpdate();
             statement.close();
+            sql.Commit(con);
         }
         catch(SQLException e)
         {
+        	sql.Rollback(con,e);
         	_log.warning("SQL error while saving gameserver :"+e);
         }
         finally
         {
-        	try { con.close();} catch (Exception e) {}
+        	sql.Close(con);
         	try { statement.close();} catch (Exception e) {}
         }
 	}
@@ -404,24 +404,25 @@
 	
 	public void deleteServer(int id)
 	{
-		java.sql.Connection con = null;
+		java.sql.Connection con = sql.Open();
 		PreparedStatement statement = null;
         try
         {
-            con = L2DatabaseFactory.getInstance().getConnection();
             statement = con.prepareStatement(
                     "DELETE FROM gameservers WHERE gameservers.server_id=?");
             statement.setInt(1, id);
 			statement.executeUpdate();
             statement.close();
+            sql.Commit(con);
         }
         catch(SQLException e)
         {
+        	sql.Rollback(con,e);
         	_log.warning("SQL error while deleting gameserver :"+e);
         }
         finally
         {
-        	try { con.close();} catch (Exception e) {}
+        	sql.Close(con);
         	try { statement.close();} catch (Exception e) {}
         }
 	}
@@ -534,11 +535,10 @@
 	 */
 	public void createServer(GameServerThread thread)
 	{
-		java.sql.Connection con = null;
+		java.sql.Connection con = sql.Open();
 		PreparedStatement statement = null;
         try
         {
-            con = L2DatabaseFactory.getInstance().getConnection();
             statement = con.prepareStatement(
                     "INSERT INTO gameservers " +
                     "(hexid,server_id,host)" +
@@ -548,14 +548,16 @@
             statement.setString(3, thread.getGameExternalHost());
 			statement.executeUpdate();
             statement.close();
+            sql.Commit(con);
         }
         catch(SQLException e)
         {
+        	sql.Rollback(con,e);
         	_log.warning("SQL error while saving gameserver :"+e);
         }
         finally
         {
-        	try { con.close();} catch (Exception e) {}
+        	sql.Close(con);
         	try { statement.close();} catch (Exception e) {}
         }
 	}
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/clientpackets/RequestSetAllyCrest.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/clientpackets/RequestSetAllyCrest.java	(revision 1644)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/clientpackets/RequestSetAllyCrest.java	(working copy)
@@ -24,13 +24,13 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import net.sf.l2j.L2DatabaseFactory;
 import net.sf.l2j.gameserver.ClanTable;
 import net.sf.l2j.gameserver.ClientThread;
 import net.sf.l2j.gameserver.cache.CrestCache;
 import net.sf.l2j.gameserver.idfactory.BitSetIDFactory;
 import net.sf.l2j.gameserver.model.L2Clan;
 import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.sql;
 
 /**
  * This class ...
@@ -80,24 +80,25 @@
                 crestCache.removeAllyCrest(leaderclan.getAllyCrestId());
             }
             
-            java.sql.Connection con = null;
+            java.sql.Connection con = sql.Open();
             
             try
             {
-                con = L2DatabaseFactory.getInstance().getConnection();
                 PreparedStatement statement = con.prepareStatement("UPDATE clan_data SET ally_crest_id = ? WHERE ally_id = ?");
                 statement.setInt(1, newId);
                 statement.setInt(2, leaderclan.getAllyId());
                 statement.executeUpdate();
                 statement.close();
+                sql.Commit(con);
             }
             catch (SQLException e)
             {
+            	sql.Rollback(con,e);
                 _log.warning("could not update the ally crest id:"+e.getMessage());
             }
             finally
             {
-                try { con.close(); } catch (Exception e) {}
+                sql.Close(con);
             }
             
             
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/clientpackets/RequestExSetPledgeCrestLarge.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/clientpackets/RequestExSetPledgeCrestLarge.java	(revision 1644)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/clientpackets/RequestExSetPledgeCrestLarge.java	(working copy)
@@ -24,7 +24,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import net.sf.l2j.L2DatabaseFactory;
+import net.sf.l2j.sql;
 import net.sf.l2j.gameserver.ClientThread;
 import net.sf.l2j.gameserver.cache.CrestCache;
 import net.sf.l2j.gameserver.idfactory.BitSetIDFactory;
@@ -95,24 +95,25 @@
                 crestCache.removePledgeCrestLarge(clan.getCrestLargeId());
             }
             
-            java.sql.Connection con = null;
+            java.sql.Connection con = sql.Open();
             
             try
             {
-                con = L2DatabaseFactory.getInstance().getConnection();
                 PreparedStatement statement = con.prepareStatement("UPDATE clan_data SET crest_large_id = ? WHERE clan_id = ?");
                 statement.setInt(1, newId);
                 statement.setInt(2, clan.getClanId());
                 statement.executeUpdate();
                 statement.close();
+                sql.Commit(con);
             }
             catch (SQLException e)
             {
+            	sql.Rollback(con,e);
                 _log.warning("could not update the large crest id:"+e.getMessage());
             }
             finally
             {
-                try { con.close(); } catch (Exception e) {}
+                sql.Close(con);
             }
             
             clan.setCrestLargeId(newId);
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/clientpackets/EnterWorld.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/clientpackets/EnterWorld.java	(revision 1644)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/clientpackets/EnterWorld.java	(working copy)
@@ -22,11 +22,12 @@
 import java.nio.ByteBuffer;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
+import java.sql.SQLException;
 import java.util.logging.Logger;
 
 import net.sf.l2j.Base64;
 import net.sf.l2j.Config;
-import net.sf.l2j.L2DatabaseFactory;
+import net.sf.l2j.sql;
 import net.sf.l2j.gameserver.Announcements;
 import net.sf.l2j.gameserver.ClientThread;
 import net.sf.l2j.gameserver.LoginServerThread;
@@ -223,9 +224,8 @@
 	 */
 	private void notifyFriends(L2PcInstance cha)
 	{
-		java.sql.Connection con = null;
+		java.sql.Connection con = sql.Open();
 		try {
-		    con = L2DatabaseFactory.getInstance().getConnection();
 		    PreparedStatement statement;
 		    statement = con.prepareStatement("SELECT char_id,friend_name from character_friends where char_id=? or friend_name=?");
 		    statement.setInt(1, cha.getObjectId());
@@ -251,10 +251,12 @@
                 if (friend != null) //friend logged in.
                     friend.sendPacket(sm);
 		    }
-        } catch (Exception e) {
+            sql.Commit(con);
+        } catch (SQLException e) {
+        	sql.Rollback(con,e);
             _log.warning("could not restore friend data:"+e);
         } finally {
-            try {con.close();} catch (Exception e){}
+            sql.Close(con);
         }
         cha.updateEffectIcons();
 	}
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/clientpackets/RequestSetPledgeCrest.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/clientpackets/RequestSetPledgeCrest.java	(revision 1644)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/clientpackets/RequestSetPledgeCrest.java	(working copy)
@@ -23,8 +23,7 @@
 import java.sql.SQLException;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-
-import net.sf.l2j.L2DatabaseFactory;
+import net.sf.l2j.sql;
 import net.sf.l2j.gameserver.ClientThread;
 import net.sf.l2j.gameserver.cache.CrestCache;
 import net.sf.l2j.gameserver.idfactory.BitSetIDFactory;
@@ -83,24 +82,25 @@
                 return;
             }
 
-            java.sql.Connection con = null;
+            java.sql.Connection con = sql.Open();
             
             try
             {
-                con = L2DatabaseFactory.getInstance().getConnection();
                 PreparedStatement statement = con.prepareStatement("UPDATE clan_data SET crest_id = ? WHERE clan_id = ?");
                 statement.setInt(1, newId);
                 statement.setInt(2, clan.getClanId());
                 statement.executeUpdate();
                 statement.close();
+                sql.Commit(con);
             }
             catch (SQLException e)
             {
+            	sql.Rollback(con,e);
                 _log.warning("could not update the crest id:"+e.getMessage());
             }
             finally
             {
-                try { con.close(); } catch (Exception e) {}
+                sql.Close(con);
             }
             
             clan.setCrestId(newId);
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/clientpackets/ValidatePosition.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/clientpackets/ValidatePosition.java	(revision 1644)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/clientpackets/ValidatePosition.java	(working copy)
@@ -166,7 +166,15 @@
                 }
             }
             
+            try
+            {
             activeChar.getKnownList().updateKnownObjects();
+            } catch (Exception e) 
+            {
+            	_log.warning("clientpackets.ValidatePosition - updateKnownObjects exception: "+e);
+            	e.printStackTrace();
+            }
+            
 //          // check for objects that are now out of range
 //          activeChar.updateKnownCounter += 1;
 //          if (activeChar.updateKnownCounter >3)
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/model/ItemContainer.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/model/ItemContainer.java	(revision 1645)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/model/ItemContainer.java	(working copy)
@@ -155,7 +155,7 @@
 			// Updates database
 			item.updateDatabase();
 		}
-		// If item hasn't be found in inventory, create new one
+		// If item hasn't been found in inventory, create new one
 		else
 			for(int i = 0; i < count; i++)
 			{
@@ -330,8 +330,14 @@
 			item.setCount(process, item.getCount() - count, actor, reference);
 			item.setLastChange(L2ItemInstance.MODIFIED);
 		}
-		// Directly drop entire item
-		else return destroyItem(process, item, actor, reference);
+		else 
+		{
+			if (item.getCount() < count) {
+				_log.warning("ItemContainer.destroyItemByItemId error: requested to destroy more items than available");
+				_log.warning("Proceeding with destroying what we have available");
+			}
+			return destroyItem(process, item, actor, reference);
+		}
 
 		item.updateDatabase();
 		refreshWeight();
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/model/L2ItemInstance.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/model/L2ItemInstance.java	(revision 1645)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/model/L2ItemInstance.java	(working copy)
@@ -589,7 +589,7 @@
      */
 	public void updateDatabase()
 	{
-		if(isWear()) //avoid saving weared items
+		if(isWear()) //avoid saving worn items
 		{
 			return;
 		}
@@ -714,6 +714,7 @@
 		try
 		{
 			con = L2DatabaseFactory.getInstance().getConnection();
+			con.setAutoCommit(false);
 			PreparedStatement statement = con.prepareStatement(
 					"INSERT INTO items (owner_id,item_id,count,loc,loc_data,enchant_level,price_sell,price_buy,object_id,custom_type1,custom_type2) " +
 					"VALUES (?,?,?,?,?,?,?,?,?,?,?)");
@@ -730,12 +731,14 @@
 			statement.setInt(11, _type2);
 			
 			statement.executeUpdate();
+			statement.close();
+            con.commit();			
 			_existsInDb = true;
 			_storedInDb = true;
-            statement.close();
         } catch (Exception e) {
 			_log.log(Level.SEVERE, "Could not insert item "+getObjectId()+" into DB: Reason: " +
                     "Duplicate itemId" );
+			try {con.rollback();} catch (Exception e2) { _log.warning("rollback failed");};
 		} finally {
 			try { con.close(); } catch (Exception e) {}
 		}
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/model/actor/instance/L2MerchantInstance.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/model/actor/instance/L2MerchantInstance.java	(revision 1645)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/model/actor/instance/L2MerchantInstance.java	(working copy)
@@ -33,8 +33,8 @@
 
 import javolution.util.FastList;
 
+import net.sf.l2j.sql;
 import net.sf.l2j.Config;
-import net.sf.l2j.L2DatabaseFactory;
 import net.sf.l2j.gameserver.ClientScheduler;
 import net.sf.l2j.gameserver.ClientThread;
 import net.sf.l2j.gameserver.ItemTable;
@@ -733,10 +733,10 @@
 
 	private static synchronized boolean addBidder(int merchant_id, int player_id, BidderDbType bt, int bid, String name)
 	{
-		boolean ok;
-		java.sql.Connection con = null;
+		boolean ok=false;
+		java.sql.Connection con = sql.Open();
+		
 		try {
-			con = L2DatabaseFactory.getInstance().getConnection();
 			PreparedStatement statement1 = con.prepareStatement(
 					"INSERT INTO merchant_lease (merchant_id, player_id, bid, type, player_name)" +
 					" VALUES (?,?,?,?,?)");
@@ -747,21 +747,23 @@
 			statement1.setString(5, name);
 			ok = statement1.executeUpdate() > 0;
 			statement1.close();
+			sql.Commit(con);
 		} catch (SQLException e) {
+			sql.Rollback(con,e);
 			_log.log(Level.SEVERE, "", e);
-			return false;
+			ok=false;
 		} finally {
-			try { con.close(); } catch (Exception e) {}
+			sql.Close(con);
 		}
 		return ok;
 	}
 
 	private static synchronized boolean updateBidder(int merchant_id, int player_id, BidderDbType bt, int bid)
 	{
-		boolean ok;
-		java.sql.Connection con = null;
+		boolean ok=false;
+		java.sql.Connection con = sql.Open();
+		
 		try {
-			con = L2DatabaseFactory.getInstance().getConnection();
 			PreparedStatement statement1 = con.prepareStatement(
 					"UPDATE merchant_lease SET bid=?" +
 					" WHERE merchant_id = ? AND player_id = ? AND type = ?");
@@ -771,20 +773,23 @@
 			statement1.setInt(4, bt.ordinal());
 			ok = statement1.executeUpdate() > 0;
 			statement1.close();
+			sql.Commit(con);
 		} catch (SQLException e) {
+			sql.Rollback(con,e);
 			_log.log(Level.SEVERE, "", e);
-			return false;
+			ok=false;
 		} finally {
-			try { con.close(); } catch (Exception e) {}
+			sql.Close(con);
 		}
 		return ok;
 	}
 
 	private static synchronized boolean removeBidder(int merchant_id, int player_id, BidderDbType bt)
 	{
-		java.sql.Connection con = null;
+		boolean ok=false;
+		java.sql.Connection con = sql.Open();
+		
 		try {
-			con = L2DatabaseFactory.getInstance().getConnection();
 			PreparedStatement statement1 = con.prepareStatement(
 					"DELETE FROM merchant_lease" +
 					" WHERE merchant_id = ? AND player_id = ? AND type = ?");
@@ -793,21 +798,23 @@
 			statement1.setInt(3, bt.ordinal());
 			statement1.executeUpdate();
 			statement1.close();
+			sql.Commit(con);
+			ok=true;
 		} catch (SQLException e) {
+			sql.Rollback(con,e);
 			_log.log(Level.SEVERE, "", e);
-			return false;
 		} finally {
-			try { con.close(); } catch (Exception e) {}
+			sql.Close(con);
 		}
-		return true;
+		return ok;
 	}
 
 	private static synchronized boolean returnItems(int merchant_id, int player_id)
 	{
-		boolean ok;
-		java.sql.Connection con = null;
+		boolean ok=false;
+		java.sql.Connection con = sql.Open();
+		
 		try {
-			con = L2DatabaseFactory.getInstance().getConnection();
 			PreparedStatement statement1 = con.prepareStatement(
 					"UPDATE items" +
 					" SET loc='WAREHOUSE', loc_data=0 " +
@@ -816,21 +823,21 @@
 			statement1.setInt(2, player_id);
 			ok = statement1.executeUpdate() > 0;
 			statement1.close();
+			sql.Commit(con);
 		} catch (SQLException e) {
+			sql.Rollback(con,e);
 			_log.log(Level.SEVERE, "", e);
-			return false;
+			ok=false;
 		} finally {
-			try { con.close(); } catch (Exception e) {}
+			sql.Close(con);
 		}
 		return ok;
 	}
 
 	private static void loadBidders()
 	{
-		java.sql.Connection con = null;
+		java.sql.Connection con = sql.Open();
 		try {
-			con = L2DatabaseFactory.getInstance().getConnection();
-
 			PreparedStatement statement;
 			ResultSet rset;
 
@@ -853,21 +860,21 @@
 			}
 			rset.close();
 			statement.close();
-
+			sql.Commit(con);
 		} catch (SQLException e) {
+			sql.Rollback(con,e);
 			_log.log(Level.SEVERE, "", e);
 		} finally {
-			try { con.close(); } catch (Exception e) {}
+			sql.Close(con);
 		}
 
 	}
 
 	private void loadMerchant()
 	{
-		java.sql.Connection con = null;
+		java.sql.Connection con = sql.Open();
+		
 		try {
-			con = L2DatabaseFactory.getInstance().getConnection();
-
 			PreparedStatement statement = con.prepareStatement("SELECT merchant_id, player_id, bid, type, player_name FROM merchant_lease WHERE merchant_id = ?");
 			statement.setInt(1, getTemplate().npcId);
 			ResultSet rset = statement.executeQuery();
@@ -891,20 +898,20 @@
 			}
 			rset.close();
 			statement.close();
+			sql.Commit(con);
 		} catch (SQLException e) {
+			sql.Rollback(con,e);
 			_log.log(Level.SEVERE, "", e);
 		} finally {
-			try { con.close(); } catch (Exception e) {}
+			sql.Close(con);
 		}
 	}
 
 	private synchronized void loadItems(int player_id)
 	{
 		leaseList = new FastList<L2ItemInstance>();
-		java.sql.Connection con = null;
+		java.sql.Connection con = sql.Open();
 		try {
-			con = L2DatabaseFactory.getInstance().getConnection();
-
 			PreparedStatement statement;
 			ResultSet rset;
 
@@ -926,10 +933,12 @@
 			}
 			rset.close();
 			statement.close();
+			sql.Commit(con);
 		} catch (SQLException e) {
+			sql.Rollback(con,e);
 			_log.log(Level.SEVERE, "", e);
 		} finally {
-			try { con.close(); } catch (Exception e) {}
+			sql.Close(con);
 		}
 	}
 }
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java	(revision 1645)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/model/actor/instance/L2PcInstance.java	(working copy)
@@ -1911,17 +1911,17 @@
 		    sm.addNumber(count);
 		    sendPacket(sm);
 		}
- 
-	if(count>0)
-	{
-		_inventory.addAdena(process, count, this, reference);
 		
-		// Send update packet
-		InventoryUpdate iu = new InventoryUpdate();
-		iu.addItem(_inventory.getAdenaInstance());
-		sendPacket(iu);
-	}
+		if(count>0)
+		{
+			_inventory.addAdena(process, count, this, reference);
 
+			// Send update packet
+		    InventoryUpdate iu = new InventoryUpdate();
+		    iu.addItem(_inventory.getAdenaInstance());
+		    sendPacket(iu);
+		}
+
 	}
 
 	/**
@@ -1957,98 +1957,98 @@
 				sendPacket(sm);
 			}
 		}
- 
+		
 		return true;
 	}
 
-	/**
-	 * Adds item to inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
+    /**
+     * Adds item to inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
 	 * @param process : String Identifier of process triggering this action
-	 * @param item : L2ItemInstance to be added
+     * @param item : L2ItemInstance to be added
 	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
 	 * @param sendMessage : boolean Specifies whether to send message to Client about this action
-	 */
-	public void addItem(String process, L2ItemInstance item, L2Object reference, boolean sendMessage)
-	{
+     */
+    public void addItem(String process, L2ItemInstance item, L2Object reference, boolean sendMessage)
+    {
 		if(item.getCount()>0)
 		{
-			// Sends message to client if requested
-			if (sendMessage)
+	    	// Sends message to client if requested
+	    	if (sendMessage)
 			{
-				if (item.getCount() > 1) 
-				{
-					SystemMessage sm = new SystemMessage(SystemMessage.YOU_PICKED_UP_S1_S2);
-					sm.addItemName(item.getItemId());
-					sm.addNumber(item.getCount());
-					sendPacket(sm);
-				}
-				else
-				{
-					SystemMessage sm = new SystemMessage(SystemMessage.YOU_PICKED_UP_S1);
-					sm.addItemName(item.getItemId());
-					sendPacket(sm);
-				}
+	            if (item.getCount() > 1) 
+	    	    {
+	            	SystemMessage sm = new SystemMessage(SystemMessage.YOU_PICKED_UP_S1_S2);
+	            	sm.addItemName(item.getItemId());
+	            	sm.addNumber(item.getCount());
+	    		    sendPacket(sm);
+	    	    }
+	    	    else
+	    	    {
+	    	    	SystemMessage sm = new SystemMessage(SystemMessage.YOU_PICKED_UP_S1);
+	    	    	sm.addItemName(item.getItemId());
+	    		    sendPacket(sm);
+	    	    }
 			}
-			
-			// Add the item to inventory
-			L2ItemInstance newitem = _inventory.addItem(process, item, this, reference);
-			
-			// Send inventory update packet
+
+	    	// Add the item to inventory
+	    	L2ItemInstance newitem = _inventory.addItem(process, item, this, reference);
+
+	    	// Send inventory update packet
 			InventoryUpdate playerIU = new InventoryUpdate();
-			playerIU.addItem(newitem);
-			sendPacket(playerIU);
-			
-			// Update current load as well
-			StatusUpdate su = new StatusUpdate(getObjectId());
-			su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
-			sendPacket(su);
+	    	playerIU.addItem(newitem);
+	    	sendPacket(playerIU);
+
+	    	// Update current load as well
+	    	StatusUpdate su = new StatusUpdate(getObjectId());
+		    su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
+		    sendPacket(su);
 		}
-	}
+    }
 
-	/**
-	 * Adds item to Inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
+    /**
+     * Adds item to Inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
 	 * @param process : String Identifier of process triggering this action
-	 * @param itemId : int Item Identifier of the item to be added
-	 * @param count : int Quantity of items to be added
+     * @param itemId : int Item Identifier of the item to be added
+     * @param count : int Quantity of items to be added
 	 * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
 	 * @param sendMessage : boolean Specifies whether to send message to Client about this action
-	 */
-	public void addItem(String process, int itemId, int count, L2Object reference, boolean sendMessage)
-	{
+     */
+    public void addItem(String process, int itemId, int count, L2Object reference, boolean sendMessage)
+    {
 		if(count>0) 
 		{
-			// Sends message to client if requested
-			if (sendMessage)
+	    	// Sends message to client if requested
+		    if (sendMessage)
 			{
-				if (count > 1) 
-				{
-					SystemMessage sm = new SystemMessage(SystemMessage.YOU_PICKED_UP_S1_S2);
-					sm.addItemName(itemId);
-					sm.addNumber(count);
-					sendPacket(sm);
-				}
-				else
-				{
-					SystemMessage sm = new SystemMessage(SystemMessage.YOU_PICKED_UP_S1);
-					sm.addItemName(itemId);
-					sendPacket(sm);
-				}
+	            if (count > 1) 
+	    	    {
+	            	SystemMessage sm = new SystemMessage(SystemMessage.YOU_PICKED_UP_S1_S2);
+	            	sm.addItemName(itemId);
+	            	sm.addNumber(count);
+	    		    sendPacket(sm);
+	    	    }
+	    	    else
+	    	    {
+	    	    	SystemMessage sm = new SystemMessage(SystemMessage.YOU_PICKED_UP_S1);
+	    	    	sm.addItemName(itemId);
+	    		    sendPacket(sm);
+	    	    }
 			}
-			
-			// Add the item to inventory
-			L2ItemInstance item = _inventory.addItem(process, itemId, count, this, reference);
-			
-			// Send inventory update packet
+
+		    // Add the item to inventory
+	    	L2ItemInstance item = _inventory.addItem(process, itemId, count, this, reference);
+
+	    	// Send inventory update packet
 			InventoryUpdate playerIU = new InventoryUpdate();
-			playerIU.addItem(item);
-			sendPacket(playerIU);
-			
-			// Update current load as well
-			StatusUpdate su = new StatusUpdate(getObjectId());
-			su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
-			sendPacket(su);
+	    	playerIU.addItem(item);
+	    	sendPacket(playerIU);
+
+	    	// Update current load as well
+	    	StatusUpdate su = new StatusUpdate(getObjectId());
+		    su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
+		    sendPacket(su);
 		}
-	}
+    }
 
 	/**
 	 * Destroy item from inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
@@ -2180,20 +2180,20 @@
 		for (L2ItemInstance item : getInventory().getItems())
 		{
 			if (item.isWear())
-			{
-//				if (item.isEquipped()) getInventory().unEquipItemInSlotAndRecord(item.getEquipSlot());
-				if (_inventory.destroyItem(process, item, this, reference) == null)
 				{
-					_log.warning("Player " + getName() + " can't destroy weared item: " + item.getName() + "[ " + item.getObjectId() + " ]");
-					continue;
+//					if (item.isEquipped()) getInventory().unEquipItemInSlotAndRecord(item.getEquipSlot());
+					if (_inventory.destroyItem(process, item, this, reference) == null)
+						{
+						_log.warning("Player " + getName() + " can't destroy weared item: " + item.getName() + "[ " + item.getObjectId() + " ]");
+						continue;
+						}
+
+					// Send Unequip packet
+					SystemMessage sm = new SystemMessage(0x1a1);
+		            sm.addItemName(item.getItemId());
+		            sendPacket(sm);
+//					playerIU.addRemovedItem(item);
 				}
-				
-				// Send Unequip packet
-				SystemMessage sm = new SystemMessage(0x1a1);
-				sm.addItemName(item.getItemId());
-				sendPacket(sm);
-//				playerIU.addRemovedItem(item);
-			}
 		}
 
     	// Send inventory update packet
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/model/actor/knownlist/ObjectKnownList.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/model/actor/knownlist/ObjectKnownList.java	(revision 1645)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/model/actor/knownlist/ObjectKnownList.java	(working copy)
@@ -3,6 +3,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Set;
+import java.util.logging.Logger;
 
 
 import net.sf.l2j.gameserver.model.L2Character;
@@ -17,7 +18,8 @@
 
 public class ObjectKnownList
 {
-    // =========================================================
+	private static Logger _log = Logger.getLogger(ObjectKnownList.class.getName());
+	// =========================================================
     // Data Field
     private L2Object[] _ActiveObject;          // Use array as a dirty trick to keep object as byref instead of byval
     private Set<L2Object> _KnownObjects;
@@ -71,8 +73,21 @@
         // Only bother updating knownobjects for L2Character; don't for L2Object
         if (getActiveObject() instanceof L2Character)
         {
-            findCloseObjects();
+        	try {
+        		findCloseObjects();	
+        	} catch (Exception e)
+        	{
+        		_log.warning("exception in call to findCloseObjects() "+e);
+        		e.printStackTrace();
+        	}
+        	try
+        	{
             forgetObjects();
+        	} catch (Exception e)
+        	{
+        		_log.warning("exception in call to forgetObjects() "+e);
+        		e.printStackTrace();
+        	}
         }
     }
 
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/model/L2Skill.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/model/L2Skill.java	(revision 1645)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/model/L2Skill.java	(working copy)
@@ -373,7 +373,6 @@
 	else
 		_ispotion = false;
 
-
         _displayId    = set.getInteger("displayId", _id);
         _name         = set.getString("name");
         _operateType  = set.getEnum("operateType", SkillOpType.class);
@@ -461,6 +460,12 @@
         return _ispotion;
     }
 
+    public final boolean isCraftingSkillType()
+    {
+    	if (getSkillType() == SkillType.DWARVEN_CRAFT || getSkillType() == SkillType.COMMON_CRAFT) return true;    	
+		return false;
+    }
+    
     public final int getArmorsAllowed()
     {
         return _armorsAllowed;
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/cache/CrestCache.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/cache/CrestCache.java	(revision 1627)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/cache/CrestCache.java	(working copy)
@@ -15,8 +15,8 @@
 import java.util.logging.Logger;
 
 import javolution.util.FastMap;
+import net.sf.l2j.sql;
 import net.sf.l2j.Config;
-import net.sf.l2j.L2DatabaseFactory;
 import net.sf.l2j.gameserver.ClanTable;
 import net.sf.l2j.gameserver.idfactory.BitSetIDFactory;
 import net.sf.l2j.gameserver.model.L2Clan;
@@ -135,24 +135,25 @@
                 file.renameTo(new File(Config.DATAPACK_ROOT, "data/crests/Crest_"+newId+".bmp"));
                 _log.info("Renamed Clan crest to new format: Crest_"+newId+".bmp");
                 
-                java.sql.Connection con = null;
+                java.sql.Connection con = sql.Open();
                 
                 try
                 {
-                    con = L2DatabaseFactory.getInstance().getConnection();
                     PreparedStatement statement = con.prepareStatement("UPDATE clan_data SET crest_id = ? WHERE clan_id = ?");
                     statement.setInt(1, newId);
                     statement.setInt(2, clan.getClanId());
                     statement.executeUpdate();
                     statement.close();
+                    con.commit();
                 }
                 catch (SQLException e)
                 {
+                	sql.Rollback(con,e);
                     _log.warning("could not update the crest id:"+e.getMessage());
                 }
                 finally
                 {
-                    try { con.close(); } catch (Exception e) {}
+                    sql.Close(con);
                 }
                 
                 clan.setCrestId(newId);
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/cache/HtmCache.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/cache/HtmCache.java	(revision 1627)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/cache/HtmCache.java	(working copy)
@@ -114,6 +114,8 @@
                 byte[] raw = new byte[bytes];
                 bis.read(raw);
                 content = new String(raw, "UTF-8");
+
+                content.replaceAll("\r\n","\n");
                 
                 String relpath = Util.getRelativePath(Config.DATAPACK_ROOT,file); 
                 int hashcode = relpath.hashCode();
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/ClanTable.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/ClanTable.java	(revision 1627)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/ClanTable.java	(working copy)
@@ -20,12 +20,13 @@
 
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
+import java.sql.SQLException;
 import java.util.Map;
 import java.util.logging.Logger;
 
 import javolution.util.FastMap;
+import net.sf.l2j.sql;
 import net.sf.l2j.Config;
-import net.sf.l2j.L2DatabaseFactory;
 import net.sf.l2j.gameserver.idfactory.IdFactory;
 import net.sf.l2j.gameserver.model.L2Clan;
 import net.sf.l2j.gameserver.model.L2ClanMember;
@@ -85,10 +86,9 @@
     public L2Clan getClanIfExists(int clanId)
     {
         String clanName = null;
-        java.sql.Connection con = null;
+        java.sql.Connection con = sql.Open();
         try
         {
-            con = L2DatabaseFactory.getInstance().getConnection();
             PreparedStatement statement = con.prepareStatement("SELECT clan_name FROM clan_data WHERE clan_id=?");
             statement.setInt(1, clanId);
             ResultSet result = statement.executeQuery();
@@ -100,12 +100,14 @@
             
             result.close();
             statement.close();
+            sql.Commit(con);
         }
-        catch (Exception e) {
+        catch (SQLException e) {
+        	sql.Rollback(con,e);
             _log.warning("data error on clan item: " + e);
             e.printStackTrace();
         } finally {
-            try { con.close(); } catch (Exception e) {}
+            sql.Close(con);
         }
         
         L2Clan clan = null;
@@ -120,11 +122,10 @@
 	
     public L2Clan getClanByName(String clanName)
     {
-        java.sql.Connection con = null;
+        java.sql.Connection con = sql.Open();
         L2Clan clan = null;
 		try
 		{
-            con = L2DatabaseFactory.getInstance().getConnection();
             PreparedStatement statement = con.prepareStatement("SELECT clan_id FROM clan_data WHERE clan_name LIKE ?");
             statement.setString(1, clanName);
             ResultSet result = statement.executeQuery();
@@ -135,11 +136,13 @@
             }
             result.close();
 			statement.close();
+			sql.Commit(con);
 		}
-		catch (Exception e) {
+		catch (SQLException e) {
+			sql.Rollback(con,e);
 			_log.warning("data error on clan item: " + e);
 		} finally {
-			try { con.close(); } catch (Exception e) {}
+			sql.Close(con);
 		}
         return clan;
     }
@@ -150,27 +153,28 @@
 	 */
 	public L2Clan createClan(L2PcInstance player, String clanName)
 	{
-        java.sql.Connection con = null;
+        java.sql.Connection con = sql.Open();
         boolean clanExists = true;
         L2Clan clan = null;
         
         try//store the new clan in db
         {
-            con = L2DatabaseFactory.getInstance().getConnection();
             PreparedStatement statement = con.prepareStatement("SELECT clan_id FROM clan_data WHERE clan_name=?");
             statement.setString(1, clanName);
             ResultSet result = statement.executeQuery();
             clanExists = result.next(); 
             result.close();
             statement.close();
+            sql.Commit(con);
         }
-        catch (Exception e)
+        catch (SQLException e)
         {
+        	sql.Rollback(con,e);
             _log.warning("error while saving new clan to db "+e);
         }
         finally
         {
-            try { con.close(); } catch (Exception e) {}
+            sql.Close(con);
         }
 
         if (!clanExists)
@@ -191,25 +195,26 @@
 	}
 	public boolean isAllyExists(String allyName)
 	{
-        java.sql.Connection con = null;
+        java.sql.Connection con = sql.Open();
         boolean allyExists = true;
         try//store the new clan in db
         {
-            con = L2DatabaseFactory.getInstance().getConnection();
             PreparedStatement statement = con.prepareStatement("SELECT ally_id FROM clan_data WHERE ally_name=?");
             statement.setString(1, allyName);
             ResultSet result = statement.executeQuery();
             allyExists = result.next(); 
             result.close();
             statement.close();
+            sql.Commit(con);
         }
-        catch (Exception e)
+        catch (SQLException e)
         {
+            sql.Rollback(con,e);
             _log.warning("error while saving new clan to db "+e);
         }
         finally
         {
-            try { con.close(); } catch (Exception e) {}
+            sql.Close(con);
         }
 	    return allyExists;
 	}
@@ -221,10 +226,9 @@
         //clan2.setEnemyClan(clan1);
         clan1.broadcastClanStatus();
         //clan2.broadcastClanStatus();
-     	java.sql.Connection con = null;
+     	java.sql.Connection con = sql.Open();
         try
         {
-            con = L2DatabaseFactory.getInstance().getConnection();
             PreparedStatement statement;
             statement = con.prepareStatement("INSERT INTO clan_wars (clan1, clan2, wantspeace1, wantspeace2) VALUES(?,?,?,?)");
 			statement.setInt(1, clanId1);
@@ -232,15 +236,17 @@
 			statement.setInt(3, 0);
 			statement.setInt(4, 0);
 			statement.execute();
-			statement.close();            
+			statement.close();    
+			sql.Commit(con);
         }
-        catch (Exception e)
+        catch (SQLException e)
         {
+        	sql.Rollback(con,e);
             _log.warning("could not store clans wars data:"+e);
         } 
         finally 
         {
-            try { con.close(); } catch (Exception e) {}
+            sql.Close(con);
         }
         //SystemMessage msg = new SystemMessage(SystemMessage.WAR_WITH_THE_S1_CLAN_HAS_BEGUN);
 	//
@@ -274,27 +280,30 @@
         //    if(player.getPlayerInstance()!=null)
 	//			player.getPlayerInstance().setWantsPeace(0);
         //}
-     	java.sql.Connection con = null;
+     	java.sql.Connection con = sql.Open();
         try
         {
-            con = L2DatabaseFactory.getInstance().getConnection();
             PreparedStatement statement;
             statement = con.prepareStatement("DELETE FROM clan_wars WHERE clan1=? AND clan2=?");
             statement.setInt(1,clanId1);
             statement.setInt(2,clanId2);
             statement.execute();
+            
             //statement = con.prepareStatement("DELETE FROM clan_wars WHERE clan1=? AND clan2=?");
             //statement.setInt(1,clanId2);
             //statement.setInt(2,clanId1);
             //statement.execute();
+
+            sql.Commit(con);
         }
-        catch (Exception e)
+        catch (SQLException e)
         {
+        	sql.Rollback(con,e);
             _log.warning("could not restore clans wars data:"+e);
         } 
         finally 
         {
-            try { con.close(); } catch (Exception e) {}
+            sql.Close(con);
         }
         //SystemMessage msg = new SystemMessage(SystemMessage.WAR_WITH_THE_S1_CLAN_HAS_ENDED);
         SystemMessage msg = new SystemMessage(1567);
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/handler/itemhandlers/AdvQuestItems.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/handler/itemhandlers/AdvQuestItems.java	(revision 1645)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/handler/itemhandlers/AdvQuestItems.java	(working copy)
@@ -84,7 +84,7 @@
             break;
         }
 
-        activeChar.getInventory().destroyItem("Extract", item, activeChar, null);
+        activeChar.getInventory().destroyItem("Extract",item.getObjectId(),1,activeChar,null);
 	    activeChar.getInventory().addItem("Extract", itemToCreateId, 1, activeChar, item);
 
         SystemMessage sm = new SystemMessage(SystemMessage.EARNED_S2_S1_s); 
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminBanChat.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminBanChat.java	(revision 1644)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminBanChat.java	(working copy)
@@ -21,9 +21,9 @@
 import java.sql.PreparedStatement;
 import java.util.StringTokenizer;
 import java.util.logging.Logger;
-
+import java.sql.SQLException;
 import net.sf.l2j.Config;
-import net.sf.l2j.L2DatabaseFactory;
+import net.sf.l2j.sql;
 import net.sf.l2j.gameserver.handler.IAdminCommandHandler;
 import net.sf.l2j.gameserver.model.GMAudit;
 import net.sf.l2j.gameserver.model.L2Object;
@@ -114,17 +114,16 @@
     
     private void setCharacterAccessLevel(String user, L2PcInstance player, int banLevel)
     {
-        java.sql.Connection con = null;
+        java.sql.Connection con = sql.Open();
         try
         {           
-            con = L2DatabaseFactory.getInstance().getConnection();
-            
             String stmt = "UPDATE characters SET characters.accesslevel = ? WHERE characters.char_name=?";
             PreparedStatement statement = con.prepareStatement(stmt);
             statement.setInt(1, banLevel);
             statement.setString(2, user);
             statement.executeUpdate();
             statement.close();
+            sql.Commit(con);
             
             L2PcInstance userInstance = L2World.getInstance().getPlayer(user);
             if (userInstance != null)
@@ -134,14 +133,14 @@
             sm.addString("Character Access Level for "+user+" set to "+banLevel+".");
             player.sendPacket(sm);
         }
-        catch (Exception e)
+        catch (SQLException e)
         {
-            //System.out.println("Error in sql");
+            sql.Rollback(con,e);
             _log.warning("Could not set accessLevl:"+e);
         } 
         finally 
         {
-            try { con.close(); } catch (Exception e) {}
+            sql.Close(con);
         }
     }
 }
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/serverpackets/RecipeItemMakeInfo.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/serverpackets/RecipeItemMakeInfo.java	(revision 1643)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/serverpackets/RecipeItemMakeInfo.java	(working copy)
@@ -31,14 +31,23 @@
 {
 	private static final String _S__D7_RECIPEITEMMAKEINFO = "[S] D7 RecipeItemMakeInfo";
 	private int _id;
-	private L2PcInstance _player;
+	private L2PcInstance _player;
+	private boolean _success;
 	
-	public RecipeItemMakeInfo(int id, L2PcInstance player)
+	public RecipeItemMakeInfo(int id, L2PcInstance player, boolean success)
 	{
 		_id = id;
-		_player = player;
+		_player = player;
+		_success = success;
 	}	
 	
+	public RecipeItemMakeInfo(int id,L2PcInstance player)
+	{
+		_id = id;
+		_player = player;
+		_success = true;
+	}
+	
 	final void runImpl()
 	{
 		// no long-running tasks
@@ -49,8 +58,10 @@
 		writeC(0xD7);
 		
 		writeD(_id);
+			writeD(0);	// unknown
     		writeD((int)_player.getCurrentMp());
     		writeD((int)_player.getMaxMp());
+    		writeD(_success ? 1 : 0);	// item creation success/failed 		
 	}
 
 	/* (non-Javadoc)
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/idfactory/CompactionIDFactory.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/idfactory/CompactionIDFactory.java	(revision 1627)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/idfactory/CompactionIDFactory.java	(working copy)
@@ -33,8 +33,8 @@
 import java.sql.SQLException;
 import java.util.logging.Logger;
 
+import net.sf.l2j.sql;
 import net.sf.l2j.Config;
-import net.sf.l2j.L2DatabaseFactory;
 
 /**
  * This class ...
@@ -54,14 +54,13 @@
         _curOID = FIRST_OID;
         _freeSize = 0;
         
-        java.sql.Connection con = null;
+        java.sql.Connection con = sql.Open();
         try
         {
-            con = L2DatabaseFactory.getInstance().getConnection();
-            //con.createStatement().execute("drop table if exists tmp_obj_id");
-            
             int[] tmp_obj_ids = extractUsedObjectIDTable();
             
+            if(Config.ASSERT) assert(tmp_obj_ids!=null);
+            
             int N = tmp_obj_ids.length;
             for (int idx = 0; idx < N; idx++)
             {
@@ -78,7 +77,7 @@
         }
         finally
         {
-            try { con.close(); } catch (Exception e) {}
+            sql.Close(con);
         }
     }
     
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/idfactory/IdFactory.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/idfactory/IdFactory.java	(revision 1627)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/idfactory/IdFactory.java	(working copy)
@@ -23,8 +23,8 @@
 import java.sql.Statement;
 import java.util.logging.Logger;
 
+import net.sf.l2j.sql;
 import net.sf.l2j.Config;
-import net.sf.l2j.L2DatabaseFactory;
 
 /**
  * This class ...
@@ -111,26 +111,22 @@
      */
     private void setAllCharacterOffline()
     {
-        java.sql.Connection con2 = null;
+        java.sql.Connection con2 = sql.Open();
         try
         {
-            con2 = L2DatabaseFactory.getInstance().getConnection();
             Statement s2 = con2.createStatement();
             s2.executeUpdate("update characters set online=0");
+            sql.Commit(con2);
+            
             _log.info("Updated characters online status.");
         }
         catch (SQLException e)
         {
+        	sql.Rollback(con2,e);
         }
         finally
         {
-            try
-            {
-                con2.close();
-            }
-            catch (Exception e)
-            {
-            }
+            sql.Close(con2);
         }
     }
     
@@ -139,12 +135,11 @@
      */
     private void cleanUpDB()
     {
-        java.sql.Connection conn = null;
+        java.sql.Connection con = sql.Open();
         try
         {
             int cleanCount = 0;
-            conn = L2DatabaseFactory.getInstance().getConnection();
-            Statement stmt = conn.createStatement();
+            Statement stmt = con.createStatement();
 
             cleanCount += stmt.executeUpdate("DELETE FROM clan_data WHERE clan_data.leader_id NOT IN (SELECT obj_Id FROM characters);");
             cleanCount += stmt.executeUpdate("DELETE FROM character_skills WHERE character_skills.char_obj_id NOT IN (SELECT obj_Id FROM characters);");
@@ -156,22 +151,19 @@
             cleanCount += stmt.executeUpdate("DELETE FROM pets WHERE pets.item_obj_id NOT IN (SELECT object_id FROM items);");
             stmt.executeUpdate("UPDATE characters SET clanid=0 WHERE characters.clanid NOT IN (SELECT clan_id FROM clan_data);");
             cleanCount += stmt.executeUpdate("DELETE FROM siege_clans WHERE siege_clans.clan_id NOT IN (SELECT clan_id FROM clan_data);");
-            
             stmt.close();
+
+            sql.Commit(con);
             _log.info("Cleaned " + cleanCount + " elements from database.");
         }
         catch (SQLException e)
         {
+        	sql.Rollback(con,e);
+        	_log.info("Error while cleaning old data from database.");
         }
         finally
         {
-            try
-            {
-                conn.close();
-            }
-            catch (Exception e)
-            {
-            }
+            sql.Close(con);
         }
     }
 
@@ -180,57 +172,72 @@
      * @return
      * @throws SQLException
      */
-    protected int[] extractUsedObjectIDTable() throws SQLException
-    {
-        java.sql.Connection con = null;
-        try
-        {
-            con = L2DatabaseFactory.getInstance().getConnection();
-            
-            //create a temporary table
-            Statement s = con.createStatement();
-            try
-            {
-                s.executeUpdate("drop table temporaryObjectTable");
-            }
-            catch (SQLException e)
-            {
-            }
-            
-            s.executeUpdate("create table temporaryObjectTable" + " (object_id int NOT NULL PRIMARY KEY)");
-            
-            s.executeUpdate("insert into temporaryObjectTable (object_id)" + " select obj_id from characters");
-            s.executeUpdate("insert into temporaryObjectTable (object_id)" + " select object_id from items");
-            s.executeUpdate("insert into temporaryObjectTable (object_id)" + " select clan_id from clan_data");
-//            s.executeUpdate("insert into temporaryObjectTable (object_id)" + " select crest_id from clan_data where crest_id > 0");
-            
-            ResultSet result = s.executeQuery("select count(object_id) from temporaryObjectTable");
-            
-            result.next();
-            int size = result.getInt(1);
-            int[] tmp_obj_ids = new int[size];
-            // System.out.println("tmp table size: " + tmp_obj_ids.length);
-            result.close();
-            
-            result = s.executeQuery("select object_id from temporaryObjectTable ORDER BY object_id");
-            
-            int idx = 0;
-            while (result.next())
-            {
-                tmp_obj_ids[idx++] = result.getInt(1);
-            }
-            
-            result.close();
-            s.close();
-            
-            return tmp_obj_ids;
-        }
-        finally
-        {
-            try { con.close(); } catch (Exception e) {}
-        }
-    }
+    protected int[] extractUsedObjectIDTable()
+	{
+		int[] tmp_obj_ids = null;
+		java.sql.Connection con = sql.Open();
+		Statement s = null;
+		
+		// attempt to remove table if it exists - safely
+		// yes, I know temporary tables don't support transactions, but in that case
+		// commit will be silently ignored so no harm done
+		try
+		{
+			s=con.createStatement();
+			s.executeUpdate("drop table temporaryObjectTable");
+			sql.Commit(con);
+		}
+		catch (SQLException e)
+		{
+			sql.Rollback(con, e);
+		}
 
+		try
+		{
+			s.executeUpdate("create table temporaryObjectTable"
+				+ " (object_id int NOT NULL PRIMARY KEY)");
+
+			s.executeUpdate("insert into temporaryObjectTable (object_id)"
+				+ " select obj_id from characters");
+			s.executeUpdate("insert into temporaryObjectTable (object_id)"
+				+ " select object_id from items");
+			s.executeUpdate("insert into temporaryObjectTable (object_id)"
+				+ " select clan_id from clan_data");
+			//            s.executeUpdate("insert into temporaryObjectTable (object_id)" + " select crest_id from clan_data where crest_id > 0");
+
+			sql.Commit(con);
+			ResultSet result = s.executeQuery("select count(object_id) from temporaryObjectTable");
+
+			result.next();
+			int size = result.getInt(1);
+			tmp_obj_ids = new int[size];
+			// System.out.println("tmp table size: " + tmp_obj_ids.length);
+			result.close();
+
+			result = s.executeQuery("select object_id from temporaryObjectTable ORDER BY object_id");
+
+			int idx = 0;
+			while (result.next())
+			{
+				tmp_obj_ids[idx++] = result.getInt(1);
+			}
+
+			result.close();
+			s.close();
+			sql.Commit(con);
+		}
+		catch (SQLException e)
+		{
+			sql.Rollback(con, e);
+		}
+		
+		finally
+		{
+			sql.Close(con);
+		}
+		return tmp_obj_ids;
+	}
+
 	public boolean isInitialized() {
 		return initialized;
 	}
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/idfactory/StackIDFactory.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/idfactory/StackIDFactory.java	(revision 1627)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/idfactory/StackIDFactory.java	(working copy)
@@ -25,7 +25,7 @@
 import java.util.logging.Logger;
 
 import net.sf.l2j.Config;
-import net.sf.l2j.L2DatabaseFactory;
+import net.sf.l2j.sql;
 
 /**
  * This class ...
@@ -47,10 +47,9 @@
         _curOID = FIRST_OID;
         _tempOID = FIRST_OID;
 
-        java.sql.Connection con = null;
+        java.sql.Connection con = sql.Open();
         try
         {
-            con = L2DatabaseFactory.getInstance().getConnection();
             //con.createStatement().execute("drop table if exists tmp_obj_id");
             
             int[] tmp_obj_ids = extractUsedObjectIDTable();
@@ -77,7 +76,7 @@
         }
         finally
         {
-            try { con.close(); } catch (Exception e) {}
+            sql.Close(con);
         }
 	}
     
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/ItemTable.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/ItemTable.java	(revision 1627)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/ItemTable.java	(working copy)
@@ -29,7 +29,7 @@
 
 import javolution.util.FastMap;
 import net.sf.l2j.Config;
-import net.sf.l2j.L2DatabaseFactory;
+import net.sf.l2j.sql;
 import net.sf.l2j.gameserver.idfactory.IdFactory;
 import net.sf.l2j.gameserver.model.L2ItemInstance;
 import net.sf.l2j.gameserver.model.L2Object;
@@ -193,10 +193,9 @@
         _armors     = new FastMap<Integer, L2Armor>();
         _weapons    = new FastMap<Integer, L2Weapon>();
 	
-		java.sql.Connection con = null;
+		java.sql.Connection con = sql.Open(false);
 		try
 		{
-			con = L2DatabaseFactory.getInstance().getConnection();
             for (String selectQuery : SQL_ITEM_SELECTS)
             {
                 PreparedStatement statement = con.prepareStatement(selectQuery);
@@ -227,7 +226,7 @@
         {
             _log.log(Level.WARNING, "data error on item: ", e);
         }
-        finally { try { con.close(); } catch (Exception e) {} }
+        finally { sql.Close(con); }
 
         for (L2Armor armor : SkillsEngine.getInstance().loadArmors(armorData))
 		{
@@ -700,7 +699,7 @@
 					|| item.getItemId() == 3500 || item.getItemId() == 3501 || item.getItemId() == 3502 // hatchlings
 					|| item.getItemId() == 4422 || item.getItemId() == 4423 || item.getItemId() == 4424) // striders
 			{
-				java.sql.Connection con = null;
+				java.sql.Connection con = sql.Open();
 				try
 				{
 /*					con = L2DatabaseFactory.getInstance().getConnection();
@@ -721,19 +720,20 @@
 					}
 */
 					// Delete the pet in db
-					con = L2DatabaseFactory.getInstance().getConnection();
 					PreparedStatement statement = con.prepareStatement("DELETE FROM pets WHERE item_obj_id=?");
 					statement.setInt(1, item.getObjectId());
 					statement.execute();
 					statement.close();
+					sql.Commit(con);
 				}
-				catch (Exception e)
+				catch (SQLException e)
 				{
+					sql.Rollback(con,e);
 					_log.log(Level.WARNING, "could not restore pet objectid:", e);
 				}
 				finally
 				{
-					try { con.close(); } catch (Exception e) {}
+					sql.Close(con);
 				}
 			}
 		}
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/RecipeController.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/RecipeController.java	(revision 1627)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/RecipeController.java	(working copy)
@@ -57,61 +57,74 @@
 public class RecipeController
 {
 	protected static Logger _log = Logger.getLogger(RecipeController.class.getName());
-	
+
 	private static RecipeController _instance;
 	private Map<Integer, L2RecipeList> _lists;
-	protected static Map<L2PcInstance, RecipeItemMaker> activeMakers = Collections.synchronizedMap(new WeakHashMap<L2PcInstance,RecipeItemMaker>());
-    protected static final Random _rnd = new Random();
-	
-	public static RecipeController getInstance()	{return _instance == null? _instance = new RecipeController() : _instance;}
-	
+	protected static Map<L2PcInstance, RecipeItemMaker> activeMakers = Collections.synchronizedMap(new WeakHashMap<L2PcInstance, RecipeItemMaker>());
+	protected static final Random _rnd = new Random();
+
+	public static RecipeController getInstance()
+	{
+		return _instance == null ? _instance = new RecipeController() : _instance;
+	}
+
 	public RecipeController()
 	{
 		_lists = new FastMap<Integer, L2RecipeList>();
 		String line = null;
 		LineNumberReader lnr = null;
-		
+
 		try
 		{
 			File recipesData = new File(Config.DATAPACK_ROOT, "data/recipes.csv");
-			lnr = new LineNumberReader(new BufferedReader( new FileReader(recipesData)));
-			
-			while ((line=lnr.readLine()) != null)
+			lnr = new LineNumberReader(new BufferedReader(new FileReader(recipesData)));
+
+			while ((line = lnr.readLine()) != null)
 			{
 				if (line.trim().length() == 0 || line.startsWith("#"))
 				{
 					continue;
 				}
-				
+
 				parseList(line);
-				
+
 			}
-			_log.config("RecipeController: Loaded "+_lists.size()+" Recipes.");
+			_log.config("RecipeController: Loaded " + _lists.size() + " Recipes.");
 		}
 		catch (Exception e)
 		{
 			if (lnr != null)
 			{
-				_log.log(Level.WARNING, "error while creating recipe controller in linenr: "+lnr.getLineNumber(), e);
+				_log.log(Level.WARNING, "error while creating recipe controller in linenr: "
+					+ lnr.getLineNumber(), e);
 			}
 			else
 			{
 				_log.warning("No recipes were found in data folder");
 			}
 		}
-        finally
-        {
-            try { lnr.close(); } catch (Exception e) { }
-        }
+		finally
+		{
+			try
+			{
+				lnr.close();
+			}
+			catch (Exception e)
+			{
+			}
+		}
 	}
+
 	public int getRecipesCount()
 	{
 		return _lists.size();
 	}
+
 	public L2RecipeList getRecipeList(int listId)
 	{
 		return _lists.get(listId);
 	}
+
 	public L2RecipeList getRecipeByItemId(int itemId)
 	{
 		for (int i = 0; i < _lists.size(); i++)
@@ -124,120 +137,112 @@
 		}
 		return null;
 	}
+
 	public synchronized void requestBookOpen(L2PcInstance player, boolean isDwarvenCraft)
-	{						
-		if (!Config.ALT_GAME_CREATION){
-			RecipeBookItemList response = new RecipeBookItemList(isDwarvenCraft,player.getMaxMp()); 
-	 		response.addRecipes(isDwarvenCraft ? player.getDwarvenRecipeBook() : player.getCommonRecipeBook()); 
+	{
+		RecipeItemMaker maker = null;
+		if (Config.ALT_GAME_CREATION) maker = activeMakers.get(player);
+
+		if (maker == null)
+		{
+			RecipeBookItemList response = new RecipeBookItemList(isDwarvenCraft, player.getMaxMp());
+			response.addRecipes(isDwarvenCraft	? player.getDwarvenRecipeBook()
+												: player.getCommonRecipeBook());
 			player.sendPacket(response);
 			return;
 		}
-		
-        RecipeItemMaker maker = activeMakers.get(player);
-        
-        if (maker == null) {
-        	RecipeBookItemList response = new RecipeBookItemList(isDwarvenCraft,player.getMaxMp()); 
-        	response.addRecipes(isDwarvenCraft ? player.getDwarvenRecipeBook() : player.getCommonRecipeBook());
-        	player.sendPacket(response);
-        	return;
-        }
-        
-        SystemMessage sm = new SystemMessage(SystemMessage.CANT_ALTER_RECIPEBOOK_WHILE_CRAFTING);
-        player.sendPacket(sm);
-        return;
+
+		SystemMessage sm = new SystemMessage(SystemMessage.CANT_ALTER_RECIPEBOOK_WHILE_CRAFTING);
+		player.sendPacket(sm);
+		return;
 	}
+
 	public synchronized void requestMakeItemAbort(L2PcInstance player)
 	{
 		activeMakers.remove(player);
 	}
-	public synchronized void requestManufactureItem(L2PcInstance manufacturer, int recipeListId, L2PcInstance player)
+
+	public synchronized void requestManufactureItem(L2PcInstance manufacturer, int recipeListId,
+													L2PcInstance player)
 	{
-		L2RecipeList recipeList = getRecipeList(recipeListId-1);
-		
-		SystemMessage sm = new SystemMessage(614);
-		
+		L2RecipeList recipeList = getValidRecipeList(player, recipeListId);
+
+		if (recipeList == null) return;
 		manufacturer.isInCraftMode(true);
-		if ((recipeList == null) || (recipeList.getRecipes().length == 0) || (!manufacturer.hasRecipeList(recipeListId)))
+
+		if (!Config.ALT_GAME_CREATION)
 		{
-			sm = new SystemMessage(614); 
-			sm.addString("No recipe for: " + recipeListId);
-			player.sendPacket(sm);
-        		manufacturer.isInCraftMode(false);
-			return;
+			new RecipeItemMaker(manufacturer, recipeList, player);
 		}
-		if (!Config.ALT_GAME_CREATION) {
-			new RecipeItemMaker(manufacturer, recipeList, player);
-		} else {
+		else
+		{
 			RecipeItemMaker maker = activeMakers.get(manufacturer);
 			if (maker != null)
 			{
-				sm = new SystemMessage(614); 
-				sm.addString("Manufacturer are busy creating.");
-				sm.addItemName(recipeList.getItemId());
-				player.sendPacket(sm);
-            			manufacturer.isInCraftMode(false);
+				player.sendMessage("Manufacturer is busy creating.");
+				manufacturer.isInCraftMode(false);
 				return;
 			}
 			maker = new RecipeItemMaker(manufacturer, recipeList, player);
-			if (maker.isValid)
-				activeMakers.put(manufacturer, maker);
+			if (maker.isValid) activeMakers.put(manufacturer, maker);
 		}
 	}
+
 	public synchronized void requestMakeItem(L2PcInstance player, int recipeListId)
 	{
-		L2RecipeList recipeList = getRecipeList(recipeListId-1);
-        
-   		player.isInCraftMode(true);
-		if ((recipeList == null) || (recipeList.getRecipes().length == 0))
+		L2RecipeList recipeList = getValidRecipeList(player, recipeListId);
+
+		if (recipeList == null) return;
+
+		player.isInCraftMode(true);
+
+		if (!Config.ALT_GAME_CREATION)
 		{
-			player.sendMessage("No recipe for: " + recipeListId);
-            player.isInCraftMode(false);
-			return;
+			new RecipeItemMaker(player, recipeList, player);
 		}
-		if (!Config.ALT_GAME_CREATION) {
-			new RecipeItemMaker(player, recipeList, player);
-		} else {
+		else
+		{
 			RecipeItemMaker maker = activeMakers.get(player);
 			if (maker != null)
 			{
-				SystemMessage sm = new SystemMessage(614); 
+				SystemMessage sm = new SystemMessage(614);
 				sm.addString("You are busy creating ");
 				sm.addItemName(recipeList.getItemId());
 				player.sendPacket(sm);
-                player.isInCraftMode(false);
+				player.isInCraftMode(false);
 				return;
 			}
 			maker = new RecipeItemMaker(player, recipeList, player);
-			if (maker.isValid)
-				activeMakers.put(player, maker);
+			if (maker.isValid) activeMakers.put(player, maker);
 		}
 	}
+
 	private void parseList(String line)
 	{
-		try 
+		try
 		{
-			StringTokenizer st = new StringTokenizer(line,";");
+			StringTokenizer st = new StringTokenizer(line, ";");
 			List<L2RecipeInstance> recipePartList = new FastList<L2RecipeInstance>();
-		
+
 			//we use common/dwarf for easy reading of the recipes.csv file 
-			String recipeTypeString = st.nextToken(); 
-	 	
+			String recipeTypeString = st.nextToken();
+
 			//now we parse the string into a boolean 
-			boolean isDwarvenRecipe; 
-	 	
-			if (recipeTypeString.equalsIgnoreCase("dwarven")) 		isDwarvenRecipe = true; 
-			else if (recipeTypeString.equalsIgnoreCase("common"))	isDwarvenRecipe = false; 
-			else 
-			{	//prints a helpfull message 
-				_log.warning("Error parsing recipes.csv, unknow recipe type "+recipeTypeString); 
+			boolean isDwarvenRecipe;
+
+			if (recipeTypeString.equalsIgnoreCase("dwarven")) isDwarvenRecipe = true;
+			else if (recipeTypeString.equalsIgnoreCase("common")) isDwarvenRecipe = false;
+			else
+			{ //prints a helpfull message 
+				_log.warning("Error parsing recipes.csv, unknow recipe type " + recipeTypeString);
 				return;
 			}
-		
+
 			String recipeName = st.nextToken();
 			int id = Integer.parseInt(st.nextToken());
 			int recipeId = Integer.parseInt(st.nextToken());
 			int level = Integer.parseInt(st.nextToken());
-		
+
 			//material
 			StringTokenizer st2 = new StringTokenizer(st.nextToken(), "[],");
 			while (st2.hasMoreTokens())
@@ -248,28 +253,31 @@
 				L2RecipeInstance rp = new L2RecipeInstance(rpItemId, quantity);
 				recipePartList.add(rp);
 			}
-		
+
 			int itemId = Integer.parseInt(st.nextToken());
 			int count = Integer.parseInt(st.nextToken());
-		
+
 			//npc fee
-			/*String notdoneyet = */ st.nextToken();
-		
+			/*String notdoneyet = */st.nextToken();
+
 			int mpCost = Integer.parseInt(st.nextToken());
 			int successRate = Integer.parseInt(st.nextToken());
-		
-			L2RecipeList recipeList = new L2RecipeList(id,level,recipeId,recipeName,successRate,mpCost,itemId,count,isDwarvenRecipe);
+
+			L2RecipeList recipeList = new L2RecipeList(id, level, recipeId, recipeName, successRate,
+														mpCost, itemId, count, isDwarvenRecipe);
 			for (L2RecipeInstance recipePart : recipePartList)
 			{
 				recipeList.addRecipe(recipePart);
 			}
 			_lists.put(new Integer(_lists.size()), recipeList);
-		} catch (Exception e) {
+		}
+		catch (Exception e)
+		{
 			_log.severe("Exception in RecipeController.parseList() - " + e);
-		};
+		}
+		;
 	}
 
-	
 	public class RecipeItemMaker implements Runnable
 	{
 		public boolean isValid;
@@ -280,103 +288,32 @@
 		final L2RecipeList recipeList;
 		final L2PcInstance target;
 		int timeReady;
+		int delay;
+		int gameTicks;
 		int totalItems;
 		int usedItems;
-
+		int skillLevel;
+		
 		public RecipeItemMaker(L2PcInstance player, L2RecipeList recipeList, L2PcInstance target)
 		{
 			this.player = player;
 			this.target = target;
 			this.recipeList = recipeList;
 			this.items = new FastList<L2ItemInstance>();
+			this.isValid = false;
 
-			int skillLevel = recipeList.isDwarvenRecipe()	? player.getSkillLevel(L2Skill.SKILL_CREATE_DWARVEN)
-															: player.getSkillLevel(L2Skill.SKILL_CREATE_COMMON);
+			skillLevel = recipeList.isDwarvenRecipe()	? player.getSkillLevel(L2Skill.SKILL_CREATE_DWARVEN)
+														: player.getSkillLevel(L2Skill.SKILL_CREATE_COMMON);
 
-			if (skillLevel <= 0)
-			{
-				player.sendPacket(new ActionFailed());
-				player.isInCraftMode(false);
-				return;
-			}
+			if (!validateSkillLevel()) return;
+			if (!validateRecipeList()) return;
+			if (!validateCustomerCanAfford(target,player)) return; 
+			if (!validateMaterials()) return;
+			if (!validateMp()) return;
 
-			if ((recipeList == null) || (recipeList.getRecipes().length == 0))
-			{
-				player.sendMessage("No such recipe");
-				player.isInCraftMode(false);
-				return;
-			}
-
-			if (target != player) // target using manufacture services of player 
-			{
-				for (L2ManufactureItem temp : player.getCreateList().getList())
-					if (temp.getRecipeId() == recipeList.getId()) // find recipe for item we want manufactured
-					{
-						price = temp.getCost();
-						if (target.getAdena() < price) // check price
-						{
-							target.sendPacket(new SystemMessage(SystemMessage.YOU_NOT_ENOUGH_ADENA));
-							player.isInCraftMode(false);
-							return;
-						}
-						break;
-					}
-			}
-
-			if (recipeList.getLevel() > skillLevel)
-			{
-				player.sendMessage("Need skill level " + recipeList.getLevel());
-				player.isInCraftMode(false);
-				return;
-			}
-
-			L2RecipeInstance[] recipes = recipeList.getRecipes();
-
-			Inventory inv = target.getInventory();
-
-			for (L2RecipeInstance recipe : recipes)
-			{
-				if (recipe.getQuantity() != 0)
-				{
-					L2ItemInstance invItem = inv.getItemByItemId(recipe.getItemId());
-					if ((invItem == null)
-						|| ((recipeList.isConsumable()	? (int) (recipe.getQuantity() * Config.RATE_CONSUMABLE_COST)
-														: recipe.getQuantity()) > invItem.getCount()))
-					{
-						target.sendMessage("You dont have the right elements for making this item"
-							+ ((recipeList.isConsumable() && Config.RATE_CONSUMABLE_COST != 1)	? ".\nDue to server rates you need "
-																									+ Config.RATE_CONSUMABLE_COST
-																									+ "x more material than listed in recipe"
-																								: ""));
-						player.isInCraftMode(false);
-						return;
-					}
-				}
-			}
-
-			if (!Config.ALT_GAME_CREATION && !validateMp()) return;
-
-			for (L2RecipeInstance recipe : recipes)
-			{
-				if (recipe.getQuantity() != 0)
-				{
-					L2ItemInstance invItem = inv.getItemByItemId(recipe.getItemId());
-					invItem = inv.dropItem(
-											"Manufacture",
-											invItem.getObjectId(),
-											recipeList.isConsumable()	? (int) (recipe.getQuantity() * Config.RATE_CONSUMABLE_COST)
-																		: recipe.getQuantity(), target,
-											player);
-					items.add(invItem);
-					materialsRefPrice += invItem.getReferencePrice() * invItem.getCount();
-					totalItems += invItem.getCount();
-				}
-			}
-
 			isValid = true;
-			timeReady = GameTimeController.TICKS_PER_SECOND + GameTimeController.getGameTicks();
-			if(Config.ALT_GAME_CREATION) ClientScheduler.getInstance().scheduleLow(this, 1100); 
-			else run(); // :)  this also helps remove craft lag
+			updateTime();
+			run();
 		}
 
 		private void finishCrafting()
@@ -385,9 +322,6 @@
 
 			if (Rnd.get(100) < recipeList.getSuccessRate())
 			{
-				int itemId = recipeList.getItemId();
-				int itemCount = recipeList.getCount();
-
 				if (target != player)
 				{
 					if (price > 0)
@@ -395,62 +329,89 @@
 						target.reduceAdena("Manufacture", price, player, false);
 						player.addAdena("Manufacture", price, target, false);
 					}
-
-					StatusUpdate su2 = new StatusUpdate(target.getObjectId());
-					su2.addAttribute(StatusUpdate.CUR_LOAD, target.getCurrentLoad());
-					target.sendPacket(su2);
+					updateCurLoad();
 				}
 
-				L2ItemInstance createdItem = target.getInventory().addItem("Manufacture", itemId, itemCount,
-																			target, player);
-				SystemMessage sm = new SystemMessage(SystemMessage.EARNED_ITEM);
-				sm.addItemName(itemId);
-				sm.addNumber(itemCount);
-				target.sendPacket(sm);
-
-				if (Config.ALT_GAME_CREATION)
-				{
-					int skillLevel;
-					skillLevel = player.getSkillLevel(recipeList.isDwarvenRecipe() ? L2Skill.SKILL_CREATE_DWARVEN : L2Skill.SKILL_CREATE_COMMON);
-					int receipeLevel = recipeList.getLevel();
-					int exp = createdItem.getReferencePrice() * itemCount;
-					// one variation
-					exp -= materialsRefPrice;
-					if (exp < 0) exp = 0;
-					// another variation
-					// exp /= receipeLevel
-					for (int i = skillLevel; i > receipeLevel; i--)
-						exp /= 4;
-					int sp = exp / 10;
-					player.addExpAndSp((int) player.calcStat(Stats.EXPSP_RATE, exp * Config.RATE_XP, null,
-																null),
-										(int) player.calcStat(Stats.EXPSP_RATE, sp * Config.RATE_SP, null,
-																null));
-					if(Config.DEBUG) 
-						_log.warning("Rewarded "+ player.calcStat(Stats.EXPSP_RATE, exp * Config.RATE_XP, null,null) + 
-					    " XP   "+(int) player.calcStat(Stats.EXPSP_RATE, sp * Config.RATE_SP, null,null) + " SP  to " + player.getName() );
-				}
+				RewardPlayer();
+				updateMakeInfo(true); // success
 			}
 			else
 			{
 				player.sendMessage("Item(s) failed to create");
+				updateMakeInfo(false);
 			}
-			activeMakers.remove(player);  // cause of this, we can't move RecipeItemMaker class out of RecipeController class
-										  // would be nice to rewrite crafting again some day, but for now I am happy with "fix craft lag"
-			
+			activeMakers.remove(player);
 			player.isInCraftMode(false);
 
-			StatusUpdate su = new StatusUpdate(player.getObjectId());
-			su.addAttribute(StatusUpdate.CUR_LOAD, player.getCurrentLoad());
-			su.addAttribute(StatusUpdate.CUR_MP, (int) player.getCurrentMp());
-			player.sendPacket(su);
+			target.sendPacket(new ItemList(target, false));
+		}
 
-			target.sendPacket(new ItemList(target, false));
-			if (target == player) target.sendPacket(new RecipeItemMakeInfo(recipeList.getId(), target));
+		public void run()
+		{
+			player.isInCraftMode(true);
+			gameTicks = GameTimeController.getGameTicks();
+			if (!validateCraftingEnabled() || !validateMp()) return;
+
+			updateTime();
+
+			if (Config.ALT_GAME_CREATION && !items.isEmpty())
+			{
+				player.reduceCurrentMp(recipeList.getMpCost()); // use some mp
+				grabSomeItems(); // grab (equip) some more items with a nice msg to player
+
+				MagicSkillUser msk = new MagicSkillUser(
+														player,
+														recipeList.isDwarvenRecipe() ? L2Skill.SKILL_CREATE_DWARVEN
+																					: L2Skill.SKILL_CREATE_COMMON,
+														skillLevel, delay, 0);
+
+				player.broadcastPacket(msk);
+
+				player.sendPacket(new SetupGauge(0, delay));
+
+				ClientScheduler.getInstance().scheduleLow(this, 100 + delay);
+			}
+			else finishCrafting();
+
+			// update load and mana bar of craft window
+			updateMakeInfo(true);
+			updateCurMp();
+			updateCurLoad();
+		}
+
+		private void updateTime()
+		{
+			// divided by RATE_CONSUMABLES_COST to remove craft time increase on higher consumable rates (more mats consumed -> more time)
+			timeReady = gameTicks
+				+ (int) (Config.ALT_GAME_CREATION_SPEED
+					* player.getMReuseRate(player.getKnownSkill(172))
+					* GameTimeController.TICKS_PER_SECOND / Config.RATE_CONSUMABLE_COST);
+
+			delay = (timeReady - gameTicks) * GameTimeController.MILLIS_IN_TICK;
+		}
+
+		private void updateMakeInfo(boolean success)
+		{
+			if (target == player) target.sendPacket(new RecipeItemMakeInfo(recipeList.getId(), target, success));
 			else target.sendPacket(new RecipeShopItemInfo(player.getObjectId(), recipeList.getId()));
+		}
 
+		private void updateCurLoad()
+		{
+			StatusUpdate su = new StatusUpdate(target.getObjectId());
+			su.addAttribute(StatusUpdate.CUR_LOAD, target.getCurrentLoad());
+			target.sendPacket(su);
 		}
 
+		private void updateCurMp()
+		{
+
+			StatusUpdate su = new StatusUpdate(target.getObjectId());
+			su.addAttribute(StatusUpdate.CUR_MP, (int) target.getCurrentMp());
+			target.sendPacket(su);
+			;
+		}
+
 		private void grabSomeItems()
 		{
 			int numItems = player.getSkillLevel(172);
@@ -467,7 +428,7 @@
 				numItems -= count;
 				usedItems += count;
 
-				SystemMessage sm = new SystemMessage(368);
+				SystemMessage sm = new SystemMessage(368); // you equipped ...
 				sm.addNumber(count);
 				sm.addItemName(item.getItemId());
 				if (target == null) player.sendPacket(sm);
@@ -475,64 +436,177 @@
 			}
 		}
 
-		public void run()
+		private boolean validateCraftingEnabled()
 		{
-			player.isInCraftMode(true);
-			int gameTicks = GameTimeController.getGameTicks();
-			if (!validateCraftingEnabled() || !validateMp()) return;
+			if (!Config.IS_CRAFTING_ENABLED)
+			{
+				target.sendMessage("Crafting is currently disabled.");
+				player.isInCraftMode(false);
+				activeMakers.remove(player);
+				updateMakeInfo(false);
+				return false;
+			}
+			return true;
+		}
 
-	/*		this is why craft lag happened
-	 
-	 		if (timeReady > gameTicks)
+		private boolean validateCustomerCanAfford(L2PcInstance customer, L2PcInstance manufacturer)
+		{
+			if(customer==manufacturer) return true;
+			for (L2ManufactureItem temp : manufacturer.getCreateList().getList())
+				if (temp.getRecipeId() == recipeList.getId()) // find recipe for item we want manufactured
+				{
+					int price = temp.getCost();
+					if (customer.getAdena() < price) // check price
+					{
+						customer.sendPacket(new SystemMessage(SystemMessage.YOU_NOT_ENOUGH_ADENA));
+						manufacturer.isInCraftMode(false);
+						activeMakers.remove(manufacturer);
+						return false;
+					}
+					break;
+				}
+			return true;
+		}		
+		private boolean validateMp()
+		{
+			if (player.getCurrentMp() < recipeList.getMpCost())
 			{
+				target.sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_MP));
 				player.isInCraftMode(false);
-				return;
+				activeMakers.remove(player);
+				updateMakeInfo(false);
+				return false;
 			}
-	*/
+			return true;
+		}
 
-			// divided by RATE_CONSUMABLES_COST to remove craft time increase on higher consumable rates (more mats consumed -> more time)
-			timeReady = gameTicks
-				+ (int) (Config.ALT_GAME_CREATION_SPEED * player.getMReuseRate(player.getKnownSkill(172)) * GameTimeController.TICKS_PER_SECOND / Config.RATE_CONSUMABLE_COST);
+		private boolean validateMaterials()
+		{
+			L2RecipeInstance[] recipes = recipeList.getRecipes();
 
-			if (Config.ALT_GAME_CREATION && !items.isEmpty()) 
+			Inventory inv = target.getInventory();
+
+			for (L2RecipeInstance recipe : recipes)
 			{
-				if (!validateMp()) return;
+				if (recipe.getQuantity() != 0)
+				{
+					L2ItemInstance invItem = inv.getItemByItemId(recipe.getItemId());
+					if ((invItem == null)
+						|| ((recipeList.isConsumable()	? (int) (recipe.getQuantity() * Config.RATE_CONSUMABLE_COST)
+														: recipe.getQuantity()) > invItem.getCount()))
+					{
+						target.sendMessage("You dont have the right elements for making this item"
+							+ ((recipeList.isConsumable() && Config.RATE_CONSUMABLE_COST != 1)	? ".\nDue to server rates you need "
+																									+ Config.RATE_CONSUMABLE_COST
+																									+ "x more material than listed in recipe"
+																								: ""));
+						player.isInCraftMode(false);
+						activeMakers.remove(player);
+						updateMakeInfo(false);
+						return false;
+					}
+				}
+			}
 
-				player.reduceCurrentMp(recipeList.getMpCost());		// use some mp
-				grabSomeItems();									// grab (equip) some more items with a nice msg to player
+			for (L2RecipeInstance recipe : recipes)
+			{
+				if (recipe.getQuantity() != 0)
+				{
+					L2ItemInstance invItem = inv.getItemByItemId(recipe.getItemId());
+					invItem = inv.dropItem(
+											"Manufacture",
+											invItem.getObjectId(),
+											recipeList.isConsumable()	? (int) (recipe.getQuantity() * Config.RATE_CONSUMABLE_COST)
+																		: recipe.getQuantity(), target,
+											player);
+					items.add(invItem);
+					materialsRefPrice += invItem.getReferencePrice() * invItem.getCount();
+					totalItems += invItem.getCount();
+				}
+			}
 
-				int delay = (timeReady - gameTicks) * GameTimeController.MILLIS_IN_TICK;
-				MagicSkillUser msk = new MagicSkillUser(player, 1050, 1, delay, 0);
-				player.broadcastPacket(msk);
-				SetupGauge sg = new SetupGauge(0, delay);
-				player.sendPacket(sg);
-
-				ClientScheduler.getInstance().scheduleLow(this, 100 + delay);
-			} else finishCrafting();
+			return true;
 		}
 
-		private boolean validateCraftingEnabled()
+		private boolean validateSkillLevel()
 		{
-			if (!Config.IS_CRAFTING_ENABLED)
+			if (recipeList.getLevel() > skillLevel)
 			{
-				target.sendMessage("Crafting is currently disabled.");
+				player.sendMessage("Need skill level " + recipeList.getLevel());
+				player.sendPacket(new ActionFailed());
 				player.isInCraftMode(false);
+				activeMakers.remove(player);
+				updateMakeInfo(false);
 				return false;
 			}
 			return true;
 		}
 
-		private boolean validateMp()
+		private boolean validateRecipeList()
 		{
-			if (player.getCurrentMp() < recipeList.getMpCost())
+			if ((recipeList == null) || (recipeList.getRecipes().length == 0))
 			{
-				target.sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_MP));
+				player.sendMessage("No such recipe");
 				player.isInCraftMode(false);
+				activeMakers.remove(player);
+				updateMakeInfo(false);
 				return false;
 			}
 			return true;
 		}
+
+		private void RewardPlayer()
+		{
+			int itemId = recipeList.getItemId();
+			int itemCount = recipeList.getCount();
+
+			L2ItemInstance createdItem = target.getInventory().addItem("Manufacture", itemId, itemCount,
+																		target, player);
+			SystemMessage sm = new SystemMessage(SystemMessage.EARNED_ITEM);
+			sm.addItemName(itemId);
+			sm.addNumber(itemCount);
+			target.sendPacket(sm);
+
+			if (Config.ALT_GAME_CREATION)
+			{
+				int recipeLevel = recipeList.getLevel();
+				int exp = createdItem.getReferencePrice() * itemCount;
+				// one variation
+				// exp -= materialsRefPrice;
+				
+				if (exp < 0) exp = 0;
+				
+				// another variation
+				exp /= recipeLevel;
+				for (int i = skillLevel; i > recipeLevel; i--) exp /= 4;
+				
+				int sp = exp / 10;
+				player.addExpAndSp((int) player.calcStat(Stats.EXPSP_RATE, exp * Config.RATE_XP, null,
+															null),
+									(int) player.calcStat(Stats.EXPSP_RATE, sp * Config.RATE_SP, null,
+															null));
+
+				sm = new SystemMessage(SystemMessage.YOU_EARNED_S1_EXP_AND_S2_SP);
+				sm.addNumber((int) player.calcStat(Stats.EXPSP_RATE, exp * Config.RATE_XP, null, null));
+				sm.addNumber((int) player.calcStat(Stats.EXPSP_RATE, sp * Config.RATE_SP, null, null));
+				player.sendPacket(sm);
+			}
+		}
 	}
+
+	private L2RecipeList getValidRecipeList(L2PcInstance player, int id)
+	{
+		L2RecipeList recipeList = getRecipeList(id - 1);
+
+		if ((recipeList == null) || (recipeList.getRecipes().length == 0))
+		{
+			player.sendMessage("No recipe for: " + id);
+			player.isInCraftMode(false);
+			return null;
+		}
+		return recipeList;
+	};
 	
-	
+
 }
+
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/taskmanager/TaskManager.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/taskmanager/TaskManager.java	(revision 1627)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/taskmanager/TaskManager.java	(working copy)
@@ -22,7 +22,7 @@
 
 import javolution.util.FastList;
 import javolution.util.FastMap;
-import net.sf.l2j.L2DatabaseFactory;
+import net.sf.l2j.sql;
 import net.sf.l2j.gameserver.ClientScheduler;
 import net.sf.l2j.gameserver.taskmanager.tasks.TaskCleanUp;
 import net.sf.l2j.gameserver.taskmanager.tasks.TaskJython;
@@ -78,24 +78,25 @@
             
             _lastActivation = System.currentTimeMillis();
             
-            java.sql.Connection con = null;
+            java.sql.Connection con = sql.Open();
             
             try
             {
-                con = L2DatabaseFactory.getInstance().getConnection();
                 PreparedStatement statement = con.prepareStatement(SQL_STATEMENTS[1]);
                 statement.setLong(1, _lastActivation);
                 statement.setInt(2, _id);
                 statement.executeUpdate();
                 statement.close();
+                sql.Commit(con);
             }
             catch (SQLException e)
             {
+            	sql.Rollback(con,e);
                 _log.warning("cannot updated the Global Task " + _id + ": " + e.getMessage());
             }
             finally
             {
-                try { con.close(); } catch (Exception e) {}
+                sql.Close(con);
             }
             
             if (_type == TYPE_SHEDULED || _type == TYPE_TIME)
@@ -183,11 +184,10 @@
     
     private void startAllTasks()
     {
-        java.sql.Connection con = null;
+        java.sql.Connection con = sql.Open();
         try
         {
             try {
-            con = L2DatabaseFactory.getInstance().getConnection();
             PreparedStatement statement = con.prepareStatement(SQL_STATEMENTS[0]);
             ResultSet rset = statement.executeQuery();
             
@@ -211,7 +211,6 @@
             
             rset.close();
             rset.close();
-            
             } catch (Exception e) {
                 _log.severe("error while loading Global Task table " + e);
                 e.printStackTrace();
@@ -317,11 +316,11 @@
     
     public static boolean addUniqueTask(String task, TaskTypes type, String param1, String param2, String param3, long lastActivation)
     {
-        java.sql.Connection con = null;
+        boolean ok=false;
+    	java.sql.Connection con = sql.Open();
         
         try
         {
-            con = L2DatabaseFactory.getInstance().getConnection();
             PreparedStatement statement = con.prepareStatement(SQL_STATEMENTS[2]);
             statement.setString(1, task);
             ResultSet rset = statement.executeQuery();
@@ -340,19 +339,19 @@
             
             rset.close();
             statement.close();
-            
-            return true;
+            ok=sql.Commit(con);
         }
         catch (SQLException e)
         {
+        	sql.Rollback(con,e);
             _log.warning("cannot add the unique task: " + e.getMessage());
         }
         finally
         {
-            try { con.close(); } catch (Exception e) {}
+            sql.Close(con);
         }
         
-        return false;
+        return ok;
     }
     
     public static boolean addTask(String task, TaskTypes type, String param1, String param2, String param3)
@@ -362,11 +361,11 @@
     
     public static boolean addTask(String task, TaskTypes type, String param1, String param2, String param3, long lastActivation)
     {
-       java.sql.Connection con = null;
+       boolean ok=false;
+       java.sql.Connection con = sql.Open();
         
         try
         {
-            con = L2DatabaseFactory.getInstance().getConnection();
             PreparedStatement statement = con.prepareStatement(SQL_STATEMENTS[3]);
             statement.setString(1, task);
             statement.setString(2, type.toString());
@@ -377,18 +376,19 @@
             statement.execute();
             
             statement.close();
-            return true;
+            ok=sql.Commit(con);
         }
         catch (SQLException e)
         {
+        	sql.Rollback(con,e);
             _log.warning("cannot add the task:  " + e.getMessage());
         }
         finally
         {
-            try { con.close(); } catch (Exception e) {}
+            sql.Close(con);
         }
         
-        return false;
+        return ok;
     }
     
 }
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/CharTemplateTable.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/CharTemplateTable.java	(revision 1627)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/CharTemplateTable.java	(working copy)
@@ -25,10 +25,10 @@
 import java.util.logging.Logger;
 
 import javolution.util.FastMap;
-import net.sf.l2j.L2DatabaseFactory;
 import net.sf.l2j.gameserver.model.base.ClassId;
 import net.sf.l2j.gameserver.templates.L2PcTemplate;
 import net.sf.l2j.gameserver.templates.StatsSet;
+import net.sf.l2j.sql;
 
 /**
  * This class ...
@@ -71,11 +71,10 @@
 	private CharTemplateTable()
 	{
 		_templates = new FastMap<Integer, L2PcTemplate>();
-		java.sql.Connection con = null;
+		java.sql.Connection con = sql.Open(false);
 		
 		try
 		{
-			con = L2DatabaseFactory.getInstance().getConnection();
 			PreparedStatement statement = con.prepareStatement(
 					"SELECT * FROM class_list, char_templates, lvlupgain" +
 					" WHERE class_list.id = char_templates.classId" +
@@ -176,7 +175,7 @@
 		}
 		finally
 		{
-			try { con.close(); } catch (Exception e) {}
+			sql.Close(con);
 		}
 
 		_log.config("CharTemplateTable: Loaded " + _templates.size() + " Character Templates.");
Index: C:/workspace/c4/java/net/sf/l2j/gameserver/CharNameTable.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/gameserver/CharNameTable.java	(revision 1627)
+++ C:/workspace/c4/java/net/sf/l2j/gameserver/CharNameTable.java	(working copy)
@@ -23,9 +23,8 @@
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.logging.Logger;
+import net.sf.l2j.sql;
 
-import net.sf.l2j.L2DatabaseFactory;
-
 /**
  * This class ...
  * 
@@ -49,25 +48,26 @@
 	public boolean doesCharNameExist(String name)
 	{
 		boolean result = true;
-		java.sql.Connection con = null;
+		java.sql.Connection con = sql.Open(false);
 		
 		try
 		{
-			con = L2DatabaseFactory.getInstance().getConnection();
 			PreparedStatement statement = con.prepareStatement("SELECT account_name FROM characters WHERE char_name=?");
 			statement.setString(1, name);
 			ResultSet rset = statement.executeQuery();
 			result = rset.next();
 			rset.close();
 			statement.close();
+			con.commit();
 		}
 		catch (SQLException e)
 		{
+			sql.Rollback(con,e);
 			_log.warning("could not check existing charname:"+e.getMessage());
 		}
 		finally
 		{
-			try { con.close(); } catch (Exception e) {}
+			sql.Close(con);
 		}
 		return result;
 	}
Index: C:/workspace/c4/java/net/sf/l2j/L2DatabaseFactory.java
===================================================================
--- C:/workspace/c4/java/net/sf/l2j/L2DatabaseFactory.java	(revision 1627)
+++ C:/workspace/c4/java/net/sf/l2j/L2DatabaseFactory.java	(working copy)
@@ -44,10 +44,9 @@
     private static L2DatabaseFactory _instance;
     private ProviderType _Provider_Type;
 	private DataSource _source;
-	
     // =========================================================
     // Constructor
-	public L2DatabaseFactory() throws SQLException
+	public L2DatabaseFactory() // throws SQLException
 	{
 		try
 		{
@@ -59,19 +58,51 @@
 
 			PoolConfig config = new PoolConfig();
 			config.setAutoCommitOnClose(true);
-			config.setInitialPoolSize(1);
+			config.setInitialPoolSize(3);   // 3 is the default for c3p0 anyway  
+											// if > MaxPoolSize, it will be ignored - no worry
+											// (as said in c3p0 docs, it's only a suggestion
+											// how many connections to acquire to start with)
+
 			config.setMinPoolSize(1);
 			config.setMaxPoolSize(Config.DATABASE_MAX_CONNECTIONS);
+
+			
+			config.setAcquireRetryAttempts(0); // try to obtain connections indefinitely (0 = never quit)
+			config.setAcquireRetryDelay(500);  // 500 miliseconds wait before try to acquire connection again
+			config.setCheckoutTimeout(0);      // 0 = wait indefinitely for new connection
+											   // if pool is exhausted
+			config.setAcquireIncrement(5); 	   // if pool is exhausted, get 5 more connections at a time
+			// cause there is a "long" delay on acquire connection
+			// so taking more than one connection at once will make connection pooling 
+			// more effective. 
+			
+			// this "connection_test_table" is automatically created if not already there
+			config.setAutomaticTestTable("connection_test_table");  // very very fast test, don't worry
+			config.setTestConnectionOnCheckin(true);				// this will *not* make l2j slower in any way
+			
+			// testing OnCheckin used with IdleConnectionTestPeriod is faster than  testing on checkout
+			
+			config.setIdleConnectionTestPeriod(60); // test idle connection every 60 sec
+			config.setMaxIdleTime(60*60); // 0 = idle connections never expire 
+									  // *THANKS* to connection testing configured above
+									  // but I'd prefer to disconnect all connections 
+									  // not used for more than 1 hour  
+
+			// enables statement caching,  there is a "semi-bug" in c3p0 0.9.0 but in 0.9.0.2 and later it's fixed
 			config.setMaxStatements(100);
-			config.setIdleConnectionTestPeriod(0); // test idle connection every 1 minute
-			config.setMaxIdleTime(0); // remove unused connection after 10 minutes
 
+			config.setBreakAfterAcquireFailure(false);  // never fail if any way possible
+														// setting this to true will make
+														// c3p0 "crash" and refuse to work 
+														// till restart thus making acquire
+														// errors "FATAL" ... we don't want that
+														// it should be possible to recover
+						
 			Class.forName(Config.DATABASE_DRIVER).newInstance();
 
 			if (Config.DEBUG) _log.fine("Database Connection Working");
-
 			DataSource unpooled = DataSources.unpooledDataSource(Config.DATABASE_URL, Config.DATABASE_LOGIN, Config.DATABASE_PASSWORD);
-			_source = DataSources.pooledDataSource( unpooled, config);
+			_source=DataSources.pooledDataSource( unpooled, config);
 			
 			/* Test the connection */
 			_source.getConnection().close();
@@ -83,14 +114,14 @@
 		}
 		catch (SQLException x)
 		{
-			if (Config.DEBUG) _log.fine("Database Connection FAILED");
-			// rethrow the exception
-			throw x;
+			if (Config.DEBUG) _log.warning("Database Connection FAILED");
+			// do not rethrow the exception - no point, it will crash server anyway
+			// throw x;
 		}
 		catch (Exception e)
 		{
-			if (Config.DEBUG) _log.fine("Database Connection FAILED");
-			throw new SQLException("could not init DB connection:"+e);
+			if (Config.DEBUG) _log.warning("Database Connection FAILED - could not init DB connection: "+e);
+		//	throw new SQLException("could not init DB connection:"+e);
 		}
 	}
     
@@ -113,10 +144,10 @@
     {
         try {
             ((PooledDataSource) _source).close();
-        } catch (SQLException e) {_log.log(Level.INFO, "", e);}
+        } catch (SQLException e) {_log.log(Level.WARNING, "", e);}
         try {
             DataSources.destroy(_source);
-        } catch (SQLException e) {_log.log(Level.INFO, "", e);}
+        } catch (SQLException e) {_log.log(Level.WARNING, "", e);}
     }
 
     public final String safetyString(String[] whatToCheck)
@@ -141,7 +172,7 @@
 
     // =========================================================
     // Property - Public
-	public static L2DatabaseFactory getInstance() throws SQLException
+	public static L2DatabaseFactory getInstance() // throws SQLException
 	{
 		if (_instance == null)
 		{
@@ -150,11 +181,31 @@
 		return _instance;
 	}
 	
-	public Connection getConnection() throws SQLException
+	public Connection getConnection(boolean use_transactions) //throws SQLException
 	{
-		return _source.getConnection();
+		Connection con=null;
+		
+		while(con==null)
+		{
+			try
+			{
+				con=_source.getConnection();
+		        con.setAutoCommit(!use_transactions);
+			} catch (SQLException e)
+			{
+				_log.warning("L2DatabaseFactory: getConnection() failed with error "+e+ ", trying again");
+			}
+		};
+		return con;
 	}
 	
+	public Connection getConnection()  // for compatibility and transparent switch to transactions
+									   // old method defaults to no-transactions
+	{
+		Connection con=getConnection(false);
+		return con;
+	}	
+	
 	public int getBusyConnectionCount() throws SQLException
 	{
 	    return ((PooledDataSource) _source).getNumBusyConnectionsDefaultUser();
@@ -162,7 +213,7 @@
 
 	public int getIdleConnectionCount() throws SQLException
 	{
-	    return ((PooledDataSource) _source).getNumIdleConnectionsDefaultUser();
+		return ((PooledDataSource) _source).getNumIdleConnectionsDefaultUser();
 	}
 
     public final ProviderType getProviderType() { return _Provider_Type; }
Index: C:/workspace/c4/dist/hexid.txt
===================================================================
--- C:/workspace/c4/dist/hexid.txt	(revision 0)
+++ C:/workspace/c4/dist/hexid.txt	(revision 0)
@@ -0,0 +1,3 @@
+#the hexID to auth into login
+#Sat Mar 18 17:38:35 CET 2006
+HexID=25f8d31f8e50d118dd72d93b9da888d1
Index: C:/workspace/c4/dist/LoginServer_loop.sh
===================================================================
--- C:/workspace/c4/dist/LoginServer_loop.sh	(revision 1627)
+++ C:/workspace/c4/dist/LoginServer_loop.sh	(working copy)
@@ -5,7 +5,7 @@
 do
 	mv log/java0.log.0 "log/`date +%Y-%m-%d_%H-%M-%S`_java.log"
 	mv log/stdout.log "log/`date +%Y-%m-%d_%H-%M-%S`_stdout.log"
-	nice -n -2 java -Xms512m -Xmx512m -cp javolution.jar:c3p0-0.9.0.jar:mysql-connector-java-3.1.10-bin.jar:sqljdbc.jar:l2jserver.jar net.sf.l2j.loginserver.LoginServer > log/stdout.log 2>&1
+	nice -n -2 java -Xms8m -Xmx32m -Xss128k -Xincgc -server -cp javolution.jar:c3p0-0.9.0.jar:mysql-connector-java-3.1.10-bin.jar:sqljdbc.jar:l2jserver.jar net.sf.l2j.loginserver.LoginServer > log/stdout.log 2>&1
 	err=$?
 #	/etc/init.d/mysql restart
 	sleep 10;
Index: C:/workspace/c4/dist/GameServer_loop.sh
===================================================================
--- C:/workspace/c4/dist/GameServer_loop.sh	(revision 1627)
+++ C:/workspace/c4/dist/GameServer_loop.sh	(working copy)
@@ -5,7 +5,7 @@
 do
 	mv log/java0.log.0 "log/`date +%Y-%m-%d_%H-%M-%S`_java.log"
 	mv log/stdout.log "log/`date +%Y-%m-%d_%H-%M-%S`_stdout.log"
-	nice -n -2 java -Xms512m -Xmx512m -cp bsf.jar:javolution.jar:bsh-2.0.jar:jython.jar:c3p0-0.9.0.jar:mysql-connector-java-3.1.10-bin.jar:sqljdbc.jar:l2jserver.jar net.sf.l2j.gameserver.GameServer > log/stdout.log 2>&1
+	nice -n -2 java -Xms128m -Xmx512m -Xss128k -Xincgc -server -cp bsf.jar:javolution.jar:bsh-2.0.jar:jython.jar:c3p0-0.9.0.jar:mysql-connector-java-3.1.10-bin.jar:sqljdbc.jar:l2jserver.jar net.sf.l2j.gameserver.GameServer > log/stdout.log 2>&1
 	err=$?
 #	/etc/init.d/mysql restart
 	sleep 10;
Index: C:/workspace/c4/dist/startLoginServer.bat
===================================================================
--- C:/workspace/c4/dist/startLoginServer.bat	(revision 1627)
+++ C:/workspace/c4/dist/startLoginServer.bat	(working copy)
@@ -2,7 +2,7 @@
 :start
 echo Starting L2J Login Server.
 echo.
-java -Xmx128m -cp javolution.jar;c3p0-0.9.0.jar;mysql-connector-java-3.1.10-bin.jar;sqljdbc.jar;l2jserver.jar; net.sf.l2j.loginserver.LoginServer
+java -Xms8m -Xmx32m -Xss128k -Xincgc -cp javolution.jar;c3p0-0.9.0.jar;mysql-connector-java-3.1.10-bin.jar;sqljdbc.jar;l2jserver.jar; net.sf.l2j.loginserver.LoginServer
 if ERRORLEVEL 2 goto restart
 if ERRORLEVEL 1 goto error
 goto end
Index: C:/workspace/c4/dist/startGameServer.bat
===================================================================
--- C:/workspace/c4/dist/startGameServer.bat	(revision 1627)
+++ C:/workspace/c4/dist/startGameServer.bat	(working copy)
@@ -2,7 +2,7 @@
 :start
 echo Starting L2J Game Server.
 echo.
-java -Xmx512m -cp bsf.jar;bsh-2.0.jar;javolution.jar;c3p0-0.9.0.jar;mysql-connector-java-3.1.10-bin.jar;sqljdbc.jar;l2jserver.jar;jython.jar net.sf.l2j.gameserver.GameServer
+java -Xms128m -Xmx512m -Xss128k -Xincgc -cp bsf.jar;bsh-2.0.jar;javolution.jar;c3p0-0.9.0.jar;mysql-connector-java-3.1.10-bin.jar;sqljdbc.jar;l2jserver.jar;jython.jar net.sf.l2j.gameserver.GameServer
 if ERRORLEVEL 2 goto restart
 if ERRORLEVEL 1 goto error
 goto end
Index: C:/workspace/c4/dist/startLoginServer.sh
===================================================================
--- C:/workspace/c4/dist/startLoginServer.sh	(revision 1627)
+++ C:/workspace/c4/dist/startLoginServer.sh	(working copy)
@@ -1,6 +1,9 @@
 #!/bin/bash
 
 ./LoginServer_loop.sh &
+echo Attaching to log file, press Ctrl+C to return to shell
+echo
+tail -f log/stdout.log
 
 
 
Index: C:/workspace/c4/dist/startGameServer.sh
===================================================================
--- C:/workspace/c4/dist/startGameServer.sh	(revision 1627)
+++ C:/workspace/c4/dist/startGameServer.sh	(working copy)
@@ -1,6 +1,8 @@
 #!/bin/bash
 
 ./GameServer_loop.sh &
+echo Attaching to log file, press Ctrl+C to return to shell
+echo
+tail -f log/stdout.log
 
 
-