From d2fd433b8bfd4de905dc21272c87fdb5f027205e Mon Sep 17 00:00:00 2001 From: Chris Kearney <chris@kearneymail.com> Date: Wed, 1 Jul 2015 18:19:29 -0700 Subject: [PATCH] itemdecaymanagerfixes, added sentry --- pom.xml | 7 ++ .../creeper/Items/ForageManager.java | 2 + .../com/comandante/creeper/Items/Item.java | 11 ++- .../creeper/Items/ItemDecayManager.java | 97 +++++++++++-------- .../com/comandante/creeper/MyListener.java | 2 + .../creeper/RecentChangesManager.java | 3 +- .../creeper/command/PickUpCommand.java | 12 ++- .../creeper/entity/EntityManager.java | 8 +- .../creeper/managers/GameManager.java | 2 +- .../creeper/managers/SentryManager.java | 35 +++++++ .../java/com/comandante/creeper/npc/Npc.java | 5 +- .../com/comandante/creeper/player/Player.java | 3 + .../creeper/server/CreeperCommandHandler.java | 2 + .../creeper/world/WorldExporter.java | 2 + 14 files changed, 140 insertions(+), 51 deletions(-) create mode 100644 src/main/java/com/comandante/creeper/managers/SentryManager.java diff --git a/pom.xml b/pom.xml index 33b74c9a..311216a1 100644 --- a/pom.xml +++ b/pom.xml @@ -128,6 +128,13 @@ <artifactId>ForecastIOLib</artifactId> <version>1.5.2</version> </dependency> + + <dependency> + <groupId>net.kencochrane.raven</groupId> + <artifactId>raven</artifactId> + <version>4.0</version> + </dependency> + </dependencies> <build> diff --git a/src/main/java/com/comandante/creeper/Items/ForageManager.java b/src/main/java/com/comandante/creeper/Items/ForageManager.java index e845777f..d86ed152 100644 --- a/src/main/java/com/comandante/creeper/Items/ForageManager.java +++ b/src/main/java/com/comandante/creeper/Items/ForageManager.java @@ -1,6 +1,7 @@ package com.comandante.creeper.Items; import com.comandante.creeper.managers.GameManager; +import com.comandante.creeper.managers.SentryManager; import com.comandante.creeper.player.Player; import com.comandante.creeper.server.Color; import com.comandante.creeper.world.Area; @@ -50,6 +51,7 @@ public class ForageManager { } } catch (InterruptedException e) { log.error(e); + SentryManager.logSentry(this.getClass(), e, "problem with forage delay!"); } } } diff --git a/src/main/java/com/comandante/creeper/Items/Item.java b/src/main/java/com/comandante/creeper/Items/Item.java index 96559025..2671babc 100644 --- a/src/main/java/com/comandante/creeper/Items/Item.java +++ b/src/main/java/com/comandante/creeper/Items/Item.java @@ -3,6 +3,8 @@ package com.comandante.creeper.Items; import com.comandante.creeper.player.Equipment; import com.comandante.creeper.spells.Effect; +import com.google.common.collect.Interner; +import com.google.common.collect.Interners; import java.io.Serializable; import java.util.List; @@ -24,6 +26,7 @@ public class Item implements Serializable { private final Rarity rarity; private final int valueInGold; private Set<Effect> effects; + private final Interner<String> interner = Interners.newWeakInterner(); public static final int CORPSE_ID_RESERVED = 100; public static final int EQUIPMENT_ID_RESERVED = 101; @@ -79,11 +82,15 @@ public class Item implements Serializable { } public boolean isWithPlayer() { - return isWithPlayer; + synchronized (interner.intern(itemId)) { + return isWithPlayer; + } } public void setWithPlayer(boolean isWithPlayer) { - this.isWithPlayer = isWithPlayer; + synchronized (interner.intern(itemId)) { + this.isWithPlayer = isWithPlayer; + } } public int getNumberOfUses() { diff --git a/src/main/java/com/comandante/creeper/Items/ItemDecayManager.java b/src/main/java/com/comandante/creeper/Items/ItemDecayManager.java index bf19bdbc..3a6b8139 100644 --- a/src/main/java/com/comandante/creeper/Items/ItemDecayManager.java +++ b/src/main/java/com/comandante/creeper/Items/ItemDecayManager.java @@ -2,6 +2,8 @@ package com.comandante.creeper.Items; import com.comandante.creeper.entity.CreeperEntity; import com.comandante.creeper.entity.EntityManager; +import com.comandante.creeper.managers.SentryManager; +import org.apache.log4j.Logger; import java.util.ArrayList; import java.util.List; @@ -12,17 +14,20 @@ public class ItemDecayManager extends CreeperEntity { private final ConcurrentHashMap<String, DecayProgress> itemDecayTracker = new ConcurrentHashMap<String, DecayProgress>(); private final EntityManager entityManager; + private static final Logger log = Logger.getLogger(ItemDecayManager.class); + private int tickBucket = 0; public ItemDecayManager(EntityManager entityManager) { this.entityManager = entityManager; } public void addItem(Item item) { + item.setWithPlayer(false); itemDecayTracker.put(item.getItemId(), new DecayProgress(item.getItemHalfLifeTicks())); } - public void removeItem(Item item) { - itemDecayTracker.remove(item.getItemId()); + public void removeItem(String itemId) { + itemDecayTracker.remove(itemId); } public ConcurrentHashMap<String, DecayProgress> getItemDecayTracker() { @@ -31,51 +36,63 @@ public class ItemDecayManager extends CreeperEntity { @Override public void run() { - List<String> itemsToRemoveFromDecay = new ArrayList<>(); - List<String> itemsToDestroy = new ArrayList<>(); - ConcurrentHashMap<String, DecayProgress> itemDecayTracker1 = getItemDecayTracker(); - for (Map.Entry<String, DecayProgress> next : itemDecayTracker1.entrySet()) { - DecayProgress decayProgress = next.getValue(); - Item item = entityManager.getItemEntity(next.getKey()); - if (item.isWithPlayer()) { - itemsToRemoveFromDecay.add(item.getItemId()); - continue; + try { + if (tickBucket == 10) { + List<String> itemsToRemoveFromDecay = new ArrayList<>(); + List<String> itemsToDestroy = new ArrayList<>(); + ConcurrentHashMap<String, DecayProgress> itemDecayTracker1 = getItemDecayTracker(); + for (Map.Entry<String, DecayProgress> next : itemDecayTracker1.entrySet()) { + DecayProgress decayProgress = next.getValue(); + Item item = entityManager.getItemEntity(next.getKey()); + if (item == null) { + removeItem(next.getKey()); + continue; + } + if (item.isWithPlayer()) { + itemsToRemoveFromDecay.add(item.getItemId()); + continue; + } + decayProgress.incTick(); + if (decayProgress.getCurrentTicks() >= decayProgress.getNumberOfTicks()) { + itemsToDestroy.add(item.getItemId()); + } + } + for (String itemId : itemsToRemoveFromDecay) { + removeItem(itemId); + } + for (String itemId : itemsToDestroy) { + removeItem(itemId); + entityManager.removeItem(itemId); + } + tickBucket = 0; + } else { + tickBucket = tickBucket + 1; } - decayProgress.incTick(); - if (decayProgress.getCurrentTicks() >= decayProgress.getNumberOfTicks()) { - itemsToDestroy.add(item.getItemId()); - } - } - for (String itemId : itemsToRemoveFromDecay) { - Item itemEntity = entityManager.getItemEntity(itemId); - removeItem(itemEntity); - } - for (String itemId : itemsToDestroy) { - Item itemEntity = entityManager.getItemEntity(itemId); - removeItem(itemEntity); - entityManager.removeItem(itemEntity); + } catch (Exception e) { + log.error("Problem with item decay manager!", e); + SentryManager.logSentry(this.getClass(), e, "Exception caught in item decay manager!"); } } +} - class DecayProgress { - private final int numberOfTicks; - private int currentTicks = 0; - - DecayProgress(int numberOfTicks) { - this.numberOfTicks = numberOfTicks; - } +class DecayProgress { + private final int numberOfTicks; + private int currentTicks = 0; - public void incTick() { - this.currentTicks++; - } + DecayProgress(int numberOfTicks) { + this.numberOfTicks = numberOfTicks; + } - public int getNumberOfTicks() { - return numberOfTicks; - } + public void incTick() { + this.currentTicks++; + } - public int getCurrentTicks() { - return currentTicks; - } + public int getNumberOfTicks() { + return numberOfTicks; } + public int getCurrentTicks() { + return currentTicks; + } } + diff --git a/src/main/java/com/comandante/creeper/MyListener.java b/src/main/java/com/comandante/creeper/MyListener.java index 3235d56c..214efe7d 100644 --- a/src/main/java/com/comandante/creeper/MyListener.java +++ b/src/main/java/com/comandante/creeper/MyListener.java @@ -2,6 +2,7 @@ package com.comandante.creeper; import com.comandante.creeper.bot.commands.BotCommand; import com.comandante.creeper.managers.GameManager; +import com.comandante.creeper.managers.SentryManager; import com.comandante.creeper.player.Player; import com.comandante.creeper.player.PlayerManager; import com.comandante.creeper.world.Room; @@ -67,6 +68,7 @@ public class MyListener extends ListenerAdapter { } } catch (Exception e) { e.printStackTrace(); + SentryManager.logSentry(this.getClass(), e, "IRC Listener Exception!"); } } } diff --git a/src/main/java/com/comandante/creeper/RecentChangesManager.java b/src/main/java/com/comandante/creeper/RecentChangesManager.java index 3d931476..dbcbabaa 100644 --- a/src/main/java/com/comandante/creeper/RecentChangesManager.java +++ b/src/main/java/com/comandante/creeper/RecentChangesManager.java @@ -1,6 +1,7 @@ package com.comandante.creeper; +import com.comandante.creeper.managers.SentryManager; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -40,7 +41,7 @@ public class RecentChangesManager { i++; } } catch (IOException e) { - e.printStackTrace(); + SentryManager.logSentry(RecentChangesManager.class, e, "Recent changes problem!"); } return sb.toString(); } diff --git a/src/main/java/com/comandante/creeper/command/PickUpCommand.java b/src/main/java/com/comandante/creeper/command/PickUpCommand.java index e3eb2625..a60b8bea 100644 --- a/src/main/java/com/comandante/creeper/command/PickUpCommand.java +++ b/src/main/java/com/comandante/creeper/command/PickUpCommand.java @@ -29,11 +29,13 @@ public class PickUpCommand extends Command { String desiredPickUpItem = Joiner.on(" ").join(originalMessageParts); for (String next : itemIds) { Item itemEntity = entityManager.getItemEntity(next); - if (itemEntity.getItemTriggers().contains(desiredPickUpItem)) { - if (gameManager.acquireItemFromRoom(player, next)) { - String playerName = player.getPlayerName(); - gameManager.roomSay(currentRoom.getRoomId(), playerName + " picked up " + itemEntity.getItemName(), playerId); - return; + if (itemEntity != null) { + if (itemEntity.getItemTriggers().contains(desiredPickUpItem)) { + if (gameManager.acquireItemFromRoom(player, next)) { + String playerName = player.getPlayerName(); + gameManager.roomSay(currentRoom.getRoomId(), playerName + " picked up " + itemEntity.getItemName(), playerId); + return; + } } } } diff --git a/src/main/java/com/comandante/creeper/entity/EntityManager.java b/src/main/java/com/comandante/creeper/entity/EntityManager.java index a6df1fda..a635b96f 100644 --- a/src/main/java/com/comandante/creeper/entity/EntityManager.java +++ b/src/main/java/com/comandante/creeper/entity/EntityManager.java @@ -5,6 +5,7 @@ import com.comandante.creeper.Items.Item; import com.comandante.creeper.Items.ItemDecayManager; import com.comandante.creeper.Items.ItemSerializer; import com.comandante.creeper.Main; +import com.comandante.creeper.managers.SentryManager; import com.comandante.creeper.npc.Npc; import com.comandante.creeper.player.Player; import com.comandante.creeper.player.PlayerManager; @@ -86,6 +87,10 @@ public class EntityManager { items.remove(item.getItemId()); } + public void removeItem(String itemId) { + items.remove(itemId); + } + public void saveEffect(Effect effect) { effects.put(effect.getEntityId(), effect); } @@ -150,7 +155,8 @@ public class EntityManager { context.stop(); Thread.sleep(500); } catch (Exception e) { - log.error("Problem with ticker!", e); + log.error("Problem with ticker!", e); + SentryManager.logSentry(this.getClass(), e, "Problem with ticker!"); } } } diff --git a/src/main/java/com/comandante/creeper/managers/GameManager.java b/src/main/java/com/comandante/creeper/managers/GameManager.java index 837f0b75..82af717c 100644 --- a/src/main/java/com/comandante/creeper/managers/GameManager.java +++ b/src/main/java/com/comandante/creeper/managers/GameManager.java @@ -343,9 +343,9 @@ public class GameManager { synchronized (interner.intern(itemId)) { Stats playerStatsWithEquipmentAndLevel = player.getPlayerStatsWithEquipmentAndLevel(); if (player.getInventory().size() < playerStatsWithEquipmentAndLevel.getInventorySize()) { - player.addInventoryId(itemId); Item itemEntity = entityManager.getItemEntity(itemId); itemEntity.setWithPlayer(true); + player.addInventoryId(itemId); entityManager.saveItem(itemEntity); return true; } else { diff --git a/src/main/java/com/comandante/creeper/managers/SentryManager.java b/src/main/java/com/comandante/creeper/managers/SentryManager.java new file mode 100644 index 00000000..1c4a80f4 --- /dev/null +++ b/src/main/java/com/comandante/creeper/managers/SentryManager.java @@ -0,0 +1,35 @@ +package com.comandante.creeper.managers; + +import net.kencochrane.raven.Dsn; +import net.kencochrane.raven.Raven; +import net.kencochrane.raven.RavenFactory; +import net.kencochrane.raven.event.Event; +import net.kencochrane.raven.event.EventBuilder; +import net.kencochrane.raven.event.interfaces.ExceptionInterface; + +public class SentryManager { + + private static Raven raven = RavenFactory.ravenInstance(new Dsn("https://f6888b8b68384ae8a6e5809f8fb08a6d:e2e3dbaaaa8d40639c87d7b16a1539f9@app.getsentry.com/47336")); + + public static void logSentry(Class c, Exception e, String msg) { + EventBuilder eventBuilder = new EventBuilder() + .setMessage(msg) + .setLevel(Event.Level.ERROR) + .setLogger(c.getName()) + .addSentryInterface(new ExceptionInterface(e)); + + raven.runBuilderHelpers(eventBuilder); + raven.sendEvent(eventBuilder.build()); + } + + public static void logSentry(Class c, Throwable e, String msg) { + EventBuilder eventBuilder = new EventBuilder() + .setMessage(msg) + .setLevel(Event.Level.ERROR) + .setLogger(c.getName()) + .addSentryInterface(new ExceptionInterface(e)); + + raven.runBuilderHelpers(eventBuilder); + raven.sendEvent(eventBuilder.build()); + } +} diff --git a/src/main/java/com/comandante/creeper/npc/Npc.java b/src/main/java/com/comandante/creeper/npc/Npc.java index 098f5088..03f0650d 100644 --- a/src/main/java/com/comandante/creeper/npc/Npc.java +++ b/src/main/java/com/comandante/creeper/npc/Npc.java @@ -6,6 +6,7 @@ import com.comandante.creeper.Items.Loot; import com.comandante.creeper.Items.Rarity; import com.comandante.creeper.entity.CreeperEntity; import com.comandante.creeper.managers.GameManager; +import com.comandante.creeper.managers.SentryManager; import com.comandante.creeper.player.CoolDownType; import com.comandante.creeper.player.Player; import com.comandante.creeper.server.Color; @@ -97,6 +98,7 @@ public class Npc extends CreeperEntity { } } catch (Exception e) { e.printStackTrace(); + SentryManager.logSentry(this.getClass(), e, "NPC Ticker Problem!"); } } } @@ -249,7 +251,8 @@ public class Npc extends CreeperEntity { } } } catch (Exception e) { - e.printStackTrace(); + SentryManager.logSentry(this.getClass(), e, "Problem processing NPC Stat Change!"); + } } diff --git a/src/main/java/com/comandante/creeper/player/Player.java b/src/main/java/com/comandante/creeper/player/Player.java index 8a02b0ec..5155d9b4 100755 --- a/src/main/java/com/comandante/creeper/player/Player.java +++ b/src/main/java/com/comandante/creeper/player/Player.java @@ -5,6 +5,7 @@ import com.comandante.creeper.Items.Item; import com.comandante.creeper.Items.ItemType; import com.comandante.creeper.entity.CreeperEntity; import com.comandante.creeper.managers.GameManager; +import com.comandante.creeper.managers.SentryManager; import com.comandante.creeper.npc.Npc; import com.comandante.creeper.npc.NpcStatsChangeBuilder; import com.comandante.creeper.server.Color; @@ -61,6 +62,8 @@ public class Player extends CreeperEntity { } } catch (Exception e) { log.error("Player ticker failed! + " + playerName, e); + SentryManager.logSentry(this.getClass(), e, "Player ticker problem!"); + } } diff --git a/src/main/java/com/comandante/creeper/server/CreeperCommandHandler.java b/src/main/java/com/comandante/creeper/server/CreeperCommandHandler.java index 80e534d4..968074cc 100644 --- a/src/main/java/com/comandante/creeper/server/CreeperCommandHandler.java +++ b/src/main/java/com/comandante/creeper/server/CreeperCommandHandler.java @@ -8,6 +8,7 @@ import com.comandante.creeper.command.Command; import com.comandante.creeper.command.CommandAuditLog; import com.comandante.creeper.command.UnknownCommand; import com.comandante.creeper.managers.GameManager; +import com.comandante.creeper.managers.SentryManager; import com.comandante.creeper.merchant.Merchant; import com.comandante.creeper.merchant.MerchantCommandHandler; import com.comandante.creeper.merchant.bank.commands.BankCommandHandler; @@ -76,6 +77,7 @@ public class CreeperCommandHandler extends SimpleChannelUpstreamHandler { @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) { + SentryManager.logSentry(this.getClass(), e.getCause(), "Exception caught in command handler!"); CreeperSession creeperSession = (CreeperSession) e.getChannel().getAttachment(); log.error("Error in the Command Handler!, last message: \"" + creeperSession.getLastMessage() + "\" - from username:" + creeperSession.getUsername().get(), e.getCause()); gameManager.getPlayerManager().removePlayer(creeperSession.getUsername().get()); diff --git a/src/main/java/com/comandante/creeper/world/WorldExporter.java b/src/main/java/com/comandante/creeper/world/WorldExporter.java index 76b42d8d..ef84ab26 100644 --- a/src/main/java/com/comandante/creeper/world/WorldExporter.java +++ b/src/main/java/com/comandante/creeper/world/WorldExporter.java @@ -1,6 +1,7 @@ package com.comandante.creeper.world; import com.comandante.creeper.entity.EntityManager; +import com.comandante.creeper.managers.SentryManager; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.collect.Iterators; @@ -43,6 +44,7 @@ public class WorldExporter { try { Files.write(worldJson.getBytes(), new File(WORLD_DIR + "world.json")); } catch (IOException e) { + SentryManager.logSentry(this.getClass(), e, "Save world problem!"); e.printStackTrace(); } } -- GitLab