Bladeren bron

Fixing concurrency issues in Grand Boss Manager

Reported by: @momo61
Zoey76 9 jaren geleden
bovenliggende
commit
71a587f398

+ 24 - 93
L2J_Server/java/com/l2jserver/gameserver/instancemanager/GrandBossManager.java

@@ -30,7 +30,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -65,9 +64,9 @@ public final class GrandBossManager implements IStorable
 	
 	protected static Map<Integer, StatsSet> _storedInfo = new HashMap<>();
 	
-	private final Map<Integer, Integer> _bossStatus = new HashMap<>();
+	private final Map<Integer, Integer> _bossStatus = new ConcurrentHashMap<>();
 	
-	private final List<L2BossZone> _zones = new CopyOnWriteArrayList<>();
+	private final Map<Integer, L2BossZone> _zones = new ConcurrentHashMap<>();
 	
 	protected GrandBossManager()
 	{
@@ -124,21 +123,10 @@ public final class GrandBossManager implements IStorable
 	 */
 	public void initZones()
 	{
-		Map<Integer, List<Integer>> zones = new HashMap<>();
-		
-		if (_zones == null)
-		{
-			_log.warning(getClass().getSimpleName() + ": Could not read Grand Boss zone data");
-			return;
-		}
-		
-		for (L2BossZone zone : _zones)
+		final Map<Integer, List<Integer>> zones = new HashMap<>();
+		for (Integer zoneId : _zones.keySet())
 		{
-			if (zone == null)
-			{
-				continue;
-			}
-			zones.put(zone.getId(), new ArrayList<>());
+			zones.put(zoneId, new ArrayList<>());
 		}
 		
 		try (Connection con = L2DatabaseFactory.getInstance().getConnection();
@@ -148,8 +136,8 @@ public final class GrandBossManager implements IStorable
 			while (rs.next())
 			{
 				int id = rs.getInt("player_id");
-				int zone_id = rs.getInt("zone");
-				zones.get(zone_id).add(id);
+				int zoneId = rs.getInt("zone");
+				zones.get(zoneId).add(id);
 			}
 			_log.info(getClass().getSimpleName() + ": Initialized " + _zones.size() + " Grand Boss Zones");
 		}
@@ -162,13 +150,9 @@ public final class GrandBossManager implements IStorable
 			_log.log(Level.WARNING, "Error while initializing GrandBoss zones: " + e.getMessage(), e);
 		}
 		
-		for (L2BossZone zone : _zones)
+		for (Entry<Integer, L2BossZone> e : _zones.entrySet())
 		{
-			if (zone == null)
-			{
-				continue;
-			}
-			zone.setAllowedPlayers(zones.get(zone.getId()));
+			e.getValue().setAllowedPlayers(zones.get(e.getKey()));
 		}
 		
 		zones.clear();
@@ -176,86 +160,38 @@ public final class GrandBossManager implements IStorable
 	
 	public void addZone(L2BossZone zone)
 	{
-		if (_zones != null)
-		{
-			_zones.add(zone);
-		}
+		_zones.put(zone.getId(), zone);
 	}
 	
-	public final L2BossZone getZone(int zoneId)
+	public L2BossZone getZone(int zoneId)
 	{
-		if (_zones != null)
-		{
-			for (L2BossZone temp : _zones)
-			{
-				if (temp.getId() == zoneId)
-				{
-					return temp;
-				}
-			}
-		}
-		return null;
+		return _zones.get(zoneId);
 	}
 	
-	public final L2BossZone getZone(L2Character character)
+	public L2BossZone getZone(L2Character character)
 	{
-		if (_zones != null)
-		{
-			for (L2BossZone temp : _zones)
-			{
-				if (temp.isCharacterInZone(character))
-				{
-					return temp;
-				}
-			}
-		}
-		return null;
+		return _zones.values().stream().filter(z -> z.isCharacterInZone(character)).findFirst().orElse(null);
 	}
 	
-	public final L2BossZone getZone(Location loc)
+	public L2BossZone getZone(Location loc)
 	{
 		return getZone(loc.getX(), loc.getY(), loc.getZ());
 	}
 	
-	public final L2BossZone getZone(int x, int y, int z)
+	public L2BossZone getZone(int x, int y, int z)
 	{
-		if (_zones != null)
-		{
-			for (L2BossZone temp : _zones)
-			{
-				if (temp.isInsideZone(x, y, z))
-				{
-					return temp;
-				}
-			}
-		}
-		return null;
+		return _zones.values().stream().filter(zone -> zone.isInsideZone(x, y, z)).findFirst().orElse(null);
 	}
 	
 	public boolean checkIfInZone(String zoneType, L2Object obj)
 	{
-		L2BossZone temp = getZone(obj.getX(), obj.getY(), obj.getZ());
-		if (temp == null)
-		{
-			return false;
-		}
-		
-		return temp.getName().equalsIgnoreCase(zoneType);
+		final L2BossZone temp = getZone(obj.getX(), obj.getY(), obj.getZ());
+		return (temp != null) && temp.getName().equalsIgnoreCase(zoneType);
 	}
 	
 	public boolean checkIfInZone(L2PcInstance player)
 	{
-		if (player == null)
-		{
-			return false;
-		}
-		L2BossZone temp = getZone(player.getX(), player.getY(), player.getZ());
-		if (temp == null)
-		{
-			return false;
-		}
-		
-		return true;
+		return (player != null) && (getZone(player.getX(), player.getY(), player.getZ()) != null);
 	}
 	
 	public int getBossStatus(int bossId)
@@ -308,14 +244,9 @@ public final class GrandBossManager implements IStorable
 			
 			try (PreparedStatement insert = con.prepareStatement(INSERT_GRAND_BOSS_LIST))
 			{
-				for (L2BossZone zone : _zones)
+				for (Entry<Integer, L2BossZone> e : _zones.entrySet())
 				{
-					if (zone == null)
-					{
-						continue;
-					}
-					Integer id = zone.getId();
-					List<Integer> list = zone.getAllowedPlayers();
+					List<Integer> list = e.getValue().getAllowedPlayers();
 					if ((list == null) || list.isEmpty())
 					{
 						continue;
@@ -323,7 +254,7 @@ public final class GrandBossManager implements IStorable
 					for (Integer player : list)
 					{
 						insert.setInt(1, player);
-						insert.setInt(2, id);
+						insert.setInt(2, e.getKey());
 						insert.executeUpdate();
 						insert.clearParameters();
 					}
@@ -436,7 +367,7 @@ public final class GrandBossManager implements IStorable
 		_zones.clear();
 	}
 	
-	public List<L2BossZone> getZones()
+	public Map<Integer, L2BossZone> getZones()
 	{
 		return _zones;
 	}

+ 3 - 4
L2J_Server/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java

@@ -13646,9 +13646,9 @@ public final class L2PcInstance extends L2Playable
 	{
 		try
 		{
-			for (L2BossZone _zone : GrandBossManager.getInstance().getZones())
+			for (L2BossZone zone : GrandBossManager.getInstance().getZones().values())
 			{
-				_zone.removePlayer(this);
+				zone.removePlayer(this);
 			}
 		}
 		catch (Exception e)
@@ -13662,10 +13662,9 @@ public final class L2PcInstance extends L2Playable
 	 */
 	public void checkPlayerSkills()
 	{
-		L2SkillLearn learn;
 		for (Entry<Integer, Skill> e : getSkills().entrySet())
 		{
-			learn = SkillTreesData.getInstance().getClassSkill(e.getKey(), e.getValue().getLevel() % 100, getClassId());
+			final L2SkillLearn learn = SkillTreesData.getInstance().getClassSkill(e.getKey(), e.getValue().getLevel() % 100, getClassId());
 			if (learn != null)
 			{
 				int lvlDiff = e.getKey() == CommonSkill.EXPERTISE.getId() ? 0 : 9;