2
0
Эх сурвалжийг харах

BETA: Reworking manufacture system:
* Changing data holder from List to Map with recipe id as key to prevent from duplicated records.
* Reported by: takhs7
* Replaced Recipe class in RequestRecipeShopListSet with L2ManufactureItem.
* Prevented from creating manufacture map when is not needed.

Rumen Nikiforov 12 жил өмнө
parent
commit
60f92de7a4

+ 7 - 10
L2J_Server_BETA/java/com/l2jserver/gameserver/RecipeController.java

@@ -246,18 +246,15 @@ public class RecipeController
 			// check that customer can afford to pay for creation services
 			if (_player != _target)
 			{
-				for (L2ManufactureItem temp : _player.getCreateList())
+				final L2ManufactureItem item = _player.getManufactureItems().get(_recipeList.getId());
+				if (item != null)
 				{
-					if (temp.getRecipeId() == _recipeList.getId()) // find recipe for item we want manufactured
+					_price = item.getCost();
+					if (_target.getAdena() < _price) // check price
 					{
-						_price = temp.getCost();
-						if (_target.getAdena() < _price) // check price
-						{
-							_target.sendPacket(SystemMessageId.YOU_NOT_ENOUGH_ADENA);
-							abort();
-							return;
-						}
-						break;
+						_target.sendPacket(SystemMessageId.YOU_NOT_ENOUGH_ADENA);
+						abort();
+						return;
 					}
 				}
 			}

+ 2 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/OfflineTradersTable.java

@@ -113,7 +113,7 @@ public class OfflineTradersTable
 									continue;
 								}
 								title = pc.getStoreName();
-								for (L2ManufactureItem i : pc.getCreateList())
+								for (L2ManufactureItem i : pc.getManufactureItems().values())
 								{
 									stm_items.setInt(1, pc.getObjectId());
 									stm_items.setInt(2, i.getRecipeId());
@@ -217,7 +217,7 @@ public class OfflineTradersTable
 								case L2PcInstance.STORE_PRIVATE_MANUFACTURE:
 									while (items.next())
 									{
-										player.getCreateList().add(new L2ManufactureItem(items.getInt(2), items.getLong(4)));
+										player.getManufactureItems().put(items.getInt(2), new L2ManufactureItem(items.getInt(2), items.getLong(4)));
 									}
 									player.setStoreName(rs.getString("title"));
 									break;

+ 40 - 40
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java

@@ -27,8 +27,10 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -628,7 +630,7 @@ public final class L2PcInstance extends L2Playable
 	
 	private TradeList _activeTradeList;
 	private ItemContainer _activeWarehouse;
-	private List<L2ManufactureItem> _createList;
+	private volatile Map<Integer, L2ManufactureItem> _manufactureItems;
 	private String _storeName = "";
 	private TradeList _sellList;
 	private TradeList _buyList;
@@ -1401,18 +1403,7 @@ public final class L2PcInstance extends L2Playable
 	 */
 	public boolean hasRecipeList(int recipeId)
 	{
-		if (_dwarvenRecipeBook.containsKey(recipeId))
-		{
-			return true;
-		}
-		else if (_commonRecipeBook.containsKey(recipeId))
-		{
-			return true;
-		}
-		else
-		{
-			return false;
-		}
+		return _dwarvenRecipeBook.containsKey(recipeId) || _commonRecipeBook.containsKey(recipeId);
 	}
 	
 	/**
@@ -6503,23 +6494,28 @@ public final class L2PcInstance extends L2Playable
 		onTradeCancel(this);
 	}
 	
+	public boolean hasManufactureShop()
+	{
+		return (_manufactureItems != null) && !_manufactureItems.isEmpty();
+	}
+	
 	/**
-	 * Get the create list of this player.
-	 * @return the the create list
+	 * Get the manufacture items map of this player.
+	 * @return the the manufacture items map
 	 */
-	public List<L2ManufactureItem> getCreateList()
+	public Map<Integer, L2ManufactureItem> getManufactureItems()
 	{
-		if (_createList == null)
+		if (_manufactureItems == null)
 		{
 			synchronized (this)
 			{
-				if (_createList == null)
+				if (_manufactureItems == null)
 				{
-					_createList = new CopyOnWriteArrayList<>();
+					_manufactureItems = Collections.synchronizedMap(new LinkedHashMap<Integer, L2ManufactureItem>());
 				}
 			}
 		}
-		return _createList;
+		return _manufactureItems;
 	}
 	
 	/**
@@ -14428,49 +14424,53 @@ public final class L2PcInstance extends L2Playable
 	
 	private void storeRecipeShopList()
 	{
-		if ((_createList != null) && !_createList.isEmpty())
+		if (hasManufactureShop())
 		{
-			try (Connection con = L2DatabaseFactory.getInstance().getConnection();
-				PreparedStatement delete = con.prepareStatement("DELETE FROM character_recipeshoplist WHERE charId=? ");
-				PreparedStatement insert = con.prepareStatement("INSERT INTO character_recipeshoplist (charId, Recipeid, Price, Pos) VALUES (?, ?, ?, ?)"))
+			try (Connection con = L2DatabaseFactory.getInstance().getConnection())
 			{
-				delete.setInt(1, getObjectId());
-				delete.execute();
-				int _position = 1;
-				for (L2ManufactureItem item : _createList)
+				try (PreparedStatement st = con.prepareStatement("DELETE FROM character_recipeshoplist WHERE charId=?"))
 				{
-					insert.setInt(1, getObjectId());
-					insert.setInt(2, item.getRecipeId());
-					insert.setLong(3, item.getCost());
-					insert.setInt(4, _position);
-					insert.addBatch();
-					_position++;
+					st.setInt(1, getObjectId());
+					st.execute();
+				}
+				
+				try (PreparedStatement st = con.prepareStatement("INSERT INTO character_recipeshoplist (charId, recipeId, price, index) VALUES (?, ?, ?, ?)"))
+				{
+					int i = 1;
+					for (L2ManufactureItem item : _manufactureItems.values())
+					{
+						st.setInt(1, getObjectId());
+						st.setInt(2, item.getRecipeId());
+						st.setLong(3, item.getCost());
+						st.setInt(4, i++);
+						st.addBatch();
+					}
+					st.executeBatch();
 				}
-				insert.executeBatch();
 			}
 			catch (Exception e)
 			{
-				_log.log(Level.SEVERE, "Could not store recipe shop for playerID " + getObjectId() + ": ", e);
+				_log.log(Level.SEVERE, "Could not store recipe shop for playerId " + getObjectId() + ": ", e);
 			}
 		}
 	}
 	
 	private void restoreRecipeShopList()
 	{
-		if (_createList != null)
+		if (_manufactureItems != null)
 		{
-			_createList.clear();
+			_manufactureItems.clear();
 		}
 		
 		try (Connection con = L2DatabaseFactory.getInstance().getConnection();
-			PreparedStatement statement = con.prepareStatement("SELECT Recipeid,Price FROM character_recipeshoplist WHERE charId=? ORDER BY Pos ASC"))
+			PreparedStatement statement = con.prepareStatement("SELECT * FROM character_recipeshoplist WHERE charId=? ORDER BY index"))
 		{
 			statement.setInt(1, getObjectId());
 			try (ResultSet rset = statement.executeQuery())
 			{
 				while (rset.next())
 				{
-					getCreateList().add(new L2ManufactureItem(rset.getInt("Recipeid"), rset.getLong("Price")));
+					getManufactureItems().put(rset.getInt("recipeId"), new L2ManufactureItem(rset.getInt("recipeId"), rset.getLong("price")));
 				}
 			}
 		}

+ 11 - 38
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestRecipeShopListSet.java

@@ -33,6 +33,7 @@ import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
 import com.l2jserver.gameserver.network.serverpackets.RecipeShopMsg;
 import com.l2jserver.gameserver.taskmanager.AttackStanceTaskManager;
+import com.l2jserver.gameserver.util.Broadcast;
 import com.l2jserver.gameserver.util.Util;
 
 /**
@@ -44,7 +45,7 @@ public final class RequestRecipeShopListSet extends L2GameClientPacket
 	
 	private static final int BATCH_LENGTH = 12;
 	
-	private Recipe[] _items = null;
+	private L2ManufactureItem[] _items = null;
 	
 	@Override
 	protected void readImpl()
@@ -55,7 +56,7 @@ public final class RequestRecipeShopListSet extends L2GameClientPacket
 			return;
 		}
 		
-		_items = new Recipe[count];
+		_items = new L2ManufactureItem[count];
 		for (int i = 0; i < count; i++)
 		{
 			int id = readD();
@@ -65,7 +66,7 @@ public final class RequestRecipeShopListSet extends L2GameClientPacket
 				_items = null;
 				return;
 			}
-			_items[i] = new Recipe(id, cost);
+			_items[i] = new L2ManufactureItem(id, cost);
 		}
 	}
 	
@@ -101,57 +102,29 @@ public final class RequestRecipeShopListSet extends L2GameClientPacket
 		
 		List<L2RecipeList> dwarfRecipes = Arrays.asList(player.getDwarvenRecipeBook());
 		List<L2RecipeList> commonRecipes = Arrays.asList(player.getCommonRecipeBook());
-		final RecipeData rd = RecipeData.getInstance();
-		for (Recipe i : _items)
+		for (L2ManufactureItem i : _items)
 		{
-			L2RecipeList list = rd.getRecipeList(i.getRecipeId());
+			final L2RecipeList list = RecipeData.getInstance().getRecipeList(i.getRecipeId());
 			if (!dwarfRecipes.contains(list) && !commonRecipes.contains(list))
 			{
 				Util.handleIllegalPlayerAction(player, "Warning!! Player " + player.getName() + " of account " + player.getAccountName() + " tried to set recipe which he dont have.", Config.DEFAULT_PUNISH);
 				return;
 			}
 			
-			if (!i.addToList(player.getCreateList()))
+			if (i.getCost() > MAX_ADENA)
 			{
 				Util.handleIllegalPlayerAction(player, "Warning!! Character " + player.getName() + " of account " + player.getAccountName() + " tried to set price more than " + MAX_ADENA + " adena in Private Manufacture.", Config.DEFAULT_PUNISH);
 				return;
 			}
+			
+			player.getManufactureItems().put(i.getRecipeId(), i);
 		}
 		
-		player.setStoreName(player.getCreateList().isEmpty() ? "" : player.getStoreName());
+		player.setStoreName(!player.hasManufactureShop() ? "" : player.getStoreName());
 		player.setPrivateStoreType(L2PcInstance.STORE_PRIVATE_MANUFACTURE);
 		player.sitDown();
 		player.broadcastUserInfo();
-		player.sendPacket(new RecipeShopMsg(player));
-		player.broadcastPacket(new RecipeShopMsg(player));
-	}
-	
-	private static class Recipe
-	{
-		private final int _recipeId;
-		private final long _cost;
-		
-		public Recipe(int id, long c)
-		{
-			_recipeId = id;
-			_cost = c;
-		}
-		
-		public boolean addToList(List<L2ManufactureItem> list)
-		{
-			if (_cost > MAX_ADENA)
-			{
-				return false;
-			}
-			
-			list.add(new L2ManufactureItem(_recipeId, _cost));
-			return true;
-		}
-		
-		public int getRecipeId()
-		{
-			return _recipeId;
-		}
+		Broadcast.toSelfAndKnownPlayers(player, new RecipeShopMsg(player));
 	}
 	
 	@Override

+ 4 - 11
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestRecipeShopManagePrev.java

@@ -39,25 +39,18 @@ public final class RequestRecipeShopManagePrev extends L2GameClientPacket
 	@Override
 	protected void runImpl()
 	{
-		L2PcInstance player = getClient().getActiveChar();
-		if ((player == null) || (player.getTarget() == null))
+		final L2PcInstance player = getActiveChar();
+		if ((player == null))
 		{
 			return;
 		}
-		
-		// Player shouldn't be able to set stores if he/she is alike dead (dead or fake death)
-		if (player.isAlikeDead())
+		else if (player.isAlikeDead() || (player.getTarget() == null) || !player.getTarget().isPlayer())
 		{
 			sendPacket(ActionFailed.STATIC_PACKET);
 			return;
 		}
 		
-		if (!(player.getTarget() instanceof L2PcInstance))
-		{
-			return;
-		}
-		L2PcInstance target = (L2PcInstance) player.getTarget();
-		player.sendPacket(new RecipeShopSellList(player, target));
+		player.sendPacket(new RecipeShopSellList(player, player.getTarget().getActingPlayer()));
 	}
 	
 	@Override

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestRecipeShopMessageSet.java

@@ -55,7 +55,7 @@ public class RequestRecipeShopMessageSet extends L2GameClientPacket
 			return;
 		}
 		
-		if (!player.getCreateList().isEmpty())
+		if (player.hasManufactureShop())
 		{
 			player.setStoreName(_name);
 		}

+ 23 - 8
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/RecipeShopManageList.java

@@ -18,6 +18,8 @@
  */
 package com.l2jserver.gameserver.network.serverpackets;
 
+import java.util.Iterator;
+
 import com.l2jserver.gameserver.model.L2ManufactureItem;
 import com.l2jserver.gameserver.model.L2RecipeList;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
@@ -42,11 +44,17 @@ public class RecipeShopManageList extends L2GameServerPacket
 			_recipes = _seller.getCommonRecipeBook();
 		}
 		
-		for (L2ManufactureItem item : _seller.getCreateList())
+		if (_seller.hasManufactureShop())
 		{
-			if ((item.isDwarven() != _isDwarven) || !seller.hasRecipeList(item.getRecipeId()))
+			final Iterator<L2ManufactureItem> it = _seller.getManufactureItems().values().iterator();
+			L2ManufactureItem item;
+			while (it.hasNext())
 			{
-				_seller.getCreateList().remove(item);
+				item = it.next();
+				if ((item.isDwarven() != _isDwarven) || !seller.hasRecipeList(item.getRecipeId()))
+				{
+					it.remove();
+				}
 			}
 		}
 	}
@@ -54,7 +62,7 @@ public class RecipeShopManageList extends L2GameServerPacket
 	@Override
 	protected final void writeImpl()
 	{
-		writeC(0xde);
+		writeC(0xDE);
 		writeD(_seller.getObjectId());
 		writeD((int) _seller.getAdena());
 		writeD(_isDwarven ? 0x00 : 0x01);
@@ -75,12 +83,19 @@ public class RecipeShopManageList extends L2GameServerPacket
 			}
 		}
 		
-		writeD(_seller.getCreateList().size());
-		for (L2ManufactureItem item : _seller.getCreateList())
+		if (!_seller.hasManufactureShop())
 		{
-			writeD(item.getRecipeId());
 			writeD(0x00);
-			writeQ(item.getCost());
+		}
+		else
+		{
+			writeD(_seller.getManufactureItems().size());
+			for (L2ManufactureItem item : _seller.getManufactureItems().values())
+			{
+				writeD(item.getRecipeId());
+				writeD(0x00);
+				writeQ(item.getCost());
+			}
 		}
 	}
 }

+ 12 - 9
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/RecipeShopSellList.java

@@ -34,16 +34,19 @@ public class RecipeShopSellList extends L2GameServerPacket
 	@Override
 	protected final void writeImpl()
 	{
-		if (!_manufacturer.getCreateList().isEmpty())
+		writeC(0xDF);
+		writeD(_manufacturer.getObjectId());
+		writeD((int) _manufacturer.getCurrentMp());// Creator's MP
+		writeD(_manufacturer.getMaxMp());// Creator's MP
+		writeQ(_buyer.getAdena());// Buyer Adena
+		if (!_manufacturer.hasManufactureShop())
 		{
-			writeC(0xDF);
-			writeD(_manufacturer.getObjectId());
-			writeD((int) _manufacturer.getCurrentMp());// Creator's MP
-			writeD(_manufacturer.getMaxMp());// Creator's MP
-			writeQ(_buyer.getAdena());// Buyer Adena
-			
-			writeD(_manufacturer.getCreateList().size());
-			for (L2ManufactureItem temp : _manufacturer.getCreateList())
+			writeD(0x00);
+		}
+		else
+		{
+			writeD(_manufacturer.getManufactureItems().size());
+			for (L2ManufactureItem temp : _manufacturer.getManufactureItems().values())
 			{
 				writeD(temp.getRecipeId());
 				writeD(0x00); // unknown