diff --git a/Server/src/main/content/global/handlers/npc/DecantListener.kt b/Server/src/main/content/global/handlers/npc/DecantListener.kt index b9c741c4f..57bdc858a 100644 --- a/Server/src/main/content/global/handlers/npc/DecantListener.kt +++ b/Server/src/main/content/global/handlers/npc/DecantListener.kt @@ -24,7 +24,7 @@ class DecantListener : InteractionListener { val potcounts = HashMap() val results: List for (i in 0..27) { - val pot = (Consumables.getConsumableById(p.inventory.getId(i)) ?: continue) as Potion + val pot = (Consumables.getConsumableById(p.inventory.getId(i)) ?: continue) as? Potion ?: continue if (pot != null) { val dosage = p.inventory[i].name.replace("[^\\d.]".toRegex(), "").toInt() if (potcounts[pot] != null) { diff --git a/Server/src/main/content/global/skill/thieving/PickableDoorHandler.java b/Server/src/main/content/global/skill/thieving/PickableDoorHandler.java index 315984644..4b892914a 100644 --- a/Server/src/main/content/global/skill/thieving/PickableDoorHandler.java +++ b/Server/src/main/content/global/skill/thieving/PickableDoorHandler.java @@ -19,6 +19,8 @@ import core.tools.RandomFunction; import java.util.ArrayList; import java.util.List; +import static core.api.ContentAPIKt.sendMessage; + /** * Represents a pickable door. * @author Vexia @@ -66,6 +68,10 @@ public class PickableDoorHandler extends OptionHandler { return true; } if (option.equals("pick-lock")) { + if (door == null) { + sendMessage(player, "This door cannot be unlocked."); + return true; + } door.pickLock(player, (Scenery) node); return true; } diff --git a/Server/src/main/content/minigame/pestcontrol/PCPortalNPC.java b/Server/src/main/content/minigame/pestcontrol/PCPortalNPC.java index c19cf1887..64dfbcb60 100644 --- a/Server/src/main/content/minigame/pestcontrol/PCPortalNPC.java +++ b/Server/src/main/content/minigame/pestcontrol/PCPortalNPC.java @@ -294,9 +294,8 @@ public final class PCPortalNPC extends AbstractNPC { } } session.sendString("0", 13 + getPortalIndex()); - updateLifepoints = false; session.getSquire().getSkills().heal(50); - session.getSquire().onImpact(this, null); + ((PCSquireNPC) session.getSquire()).FlagInterfaceUpdate(); } } diff --git a/Server/src/main/content/minigame/pestcontrol/PCSquireNPC.java b/Server/src/main/content/minigame/pestcontrol/PCSquireNPC.java index 1f156b761..14a4eb1a1 100644 --- a/Server/src/main/content/minigame/pestcontrol/PCSquireNPC.java +++ b/Server/src/main/content/minigame/pestcontrol/PCSquireNPC.java @@ -84,10 +84,14 @@ public final class PCSquireNPC extends AbstractNPC { @Override public void onImpact(final Entity entity, BattleState state) { - updateLifepoints = true; + FlagInterfaceUpdate(); super.onImpact(entity, state); } + public void FlagInterfaceUpdate() { + updateLifepoints = true; + } + @Override public int[] getIds() { return new int[] { 3782, 3785 }; diff --git a/Server/src/main/content/minigame/pyramidplunder/PlunderUtils.kt b/Server/src/main/content/minigame/pyramidplunder/PlunderUtils.kt index 2d99034b2..579abe8b8 100644 --- a/Server/src/main/content/minigame/pyramidplunder/PlunderUtils.kt +++ b/Server/src/main/content/minigame/pyramidplunder/PlunderUtils.kt @@ -240,7 +240,7 @@ object PlunderUtils { fun getDoorXp(player: Player, lockpick: Boolean) : Double { - val room = getRoom(player)!!.room + val room = getRoom(player)?.room ?: return 0.0 var reward = when(room) { 1 -> 60.0 diff --git a/Server/src/main/content/region/misthalin/draynor/handlers/DBRCutscenePlugin.java b/Server/src/main/content/region/misthalin/draynor/handlers/DBRCutscenePlugin.java index 6c68b2a23..78c30fa3e 100644 --- a/Server/src/main/content/region/misthalin/draynor/handlers/DBRCutscenePlugin.java +++ b/Server/src/main/content/region/misthalin/draynor/handlers/DBRCutscenePlugin.java @@ -408,7 +408,7 @@ public final class DBRCutscenePlugin extends CutscenePlugin { getWiseOldMan().graphics(TELEKENTIC_GRAPHIC); getWiseOldMan().getSkills().setStaticLevel(Skills.MAGIC, 99); getWiseOldMan().getSkills().setLevel(Skills.MAGIC, 99); - SpellBookManager.SpellBook.MODERN.getSpell(65535).cast(getWiseOldMan(), GroundItemManager.get(PARTY_HAT.getId(), base.transform(20, 44, 0), player)); + SpellBookManager.SpellBook.MODERN.getSpell(19).cast(getWiseOldMan(), GroundItemManager.get(PARTY_HAT.getId(), base.transform(20, 44, 0), player)); } /** diff --git a/Server/src/main/core/game/interaction/MovementPulse.java b/Server/src/main/core/game/interaction/MovementPulse.java index 9f819f091..9b30b48d2 100644 --- a/Server/src/main/core/game/interaction/MovementPulse.java +++ b/Server/src/main/core/game/interaction/MovementPulse.java @@ -194,6 +194,8 @@ public abstract class MovementPulse extends Pulse { Location ml = mover.getLocation(); // Allow being within 1 square of moving entities to interact with them. int radius = destination instanceof Entity && ((Entity)destination).getWalkingQueue().hasPath() ? 1 : 0; + if (interactLocation == null) + return false; if (Math.max(Math.abs(ml.getX() - interactLocation.getX()), Math.abs(ml.getY() - interactLocation.getY())) <= radius) { try { if (near || pulse()) { diff --git a/Server/src/main/core/game/node/entity/impl/WalkingQueue.java b/Server/src/main/core/game/node/entity/impl/WalkingQueue.java index 5b81e2aef..449b37841 100644 --- a/Server/src/main/core/game/node/entity/impl/WalkingQueue.java +++ b/Server/src/main/core/game/node/entity/impl/WalkingQueue.java @@ -8,6 +8,7 @@ import core.game.world.map.Direction; import core.game.world.map.Location; import core.game.world.map.Point; import core.game.world.map.RegionManager; +import core.tools.SystemLogger; import java.util.Deque; import java.util.LinkedList; @@ -374,7 +375,7 @@ public final class WalkingQueue { Location loc = entity.getLocation(); if (loc == null) { - throw new IllegalStateException( + SystemLogger.logErr(this.getClass(), "The entity location provided was null." + "Are you sure anything down the stack trace isn't providing an NPC with a null location?" ); diff --git a/Server/src/main/core/game/system/command/sets/DevelopmentCommandSet.kt b/Server/src/main/core/game/system/command/sets/DevelopmentCommandSet.kt index 4194f45b7..563748a1c 100644 --- a/Server/src/main/core/game/system/command/sets/DevelopmentCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/DevelopmentCommandSet.kt @@ -1,7 +1,7 @@ package core.game.system.command.sets import content.global.activity.jobs.JobManager -import core.api.removeAttribute +import content.global.skill.slayer.Master import core.api.sendMessage import core.cache.Cache import core.cache.def.impl.DataMap @@ -179,5 +179,23 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) { define("testpacket") { player, _ -> PacketWriteQueue.write(ResetInterface(), PlayerContext(player)) } + + define("npcsearch", Privilege.STANDARD, "npcsearch name", "Searches for NPCs that match the name either in main or children.") {player, strings -> + val name = strings.slice(1 until strings.size).joinToString(" ").lowercase() + for (id in 0 until 9000) { + val def = NPCDefinition.forId(id) + if (def.name.isNotBlank() && (def.name.lowercase().contains(name) || name.contains(def.name.lowercase()))) { + notify(player, "$id - ${def.name}") + } + else { + for ((childId,index) in def.childNPCIds?.withIndex() ?: continue) { + val childDef = NPCDefinition.forId(childId) + if (childDef.name.lowercase().contains(name) || name.contains(childDef.name.lowercase())) { + notify(player, "$childId child($id) index $index - ${childDef.name}") + } + } + } + } + } } } \ No newline at end of file diff --git a/Server/src/main/core/net/IoEventHandler.java b/Server/src/main/core/net/IoEventHandler.java index f6d63d869..047569771 100644 --- a/Server/src/main/core/net/IoEventHandler.java +++ b/Server/src/main/core/net/IoEventHandler.java @@ -68,7 +68,7 @@ public class IoEventHandler { return; } } catch (IOException e) { - if (e.getMessage().contains("reset by peer")) { + if (e.getMessage().contains("reset by peer") && session != null) { session.disconnect(); if (session.getPlayer() != null) session.getPlayer().clear(true); diff --git a/Server/src/main/core/net/event/LoginReadEvent.kt b/Server/src/main/core/net/event/LoginReadEvent.kt index b80501b12..fb713b1db 100644 --- a/Server/src/main/core/net/event/LoginReadEvent.kt +++ b/Server/src/main/core/net/event/LoginReadEvent.kt @@ -15,23 +15,28 @@ import java.nio.ByteBuffer */ class LoginReadEvent(session: IoSession?, buffer: ByteBuffer?) : IoReadEvent(session, buffer) { override fun read(session: IoSession, buffer: ByteBuffer) { - val (response, info) = Login.decodeFromBuffer(buffer) - if(response != AuthResponse.Success || info == null) { - session.write(response) - return - } - val (authResponse, accountInfo) = GameWorld.authenticator.checkLogin(info.username, info.password) + try { + val (response, info) = Login.decodeFromBuffer(buffer) + if (response != AuthResponse.Success || info == null) { + session.write(response) + return + } + val (authResponse, accountInfo) = GameWorld.authenticator.checkLogin(info.username, info.password) - if(authResponse != AuthResponse.Success || accountInfo == null) { - session.write(authResponse) - return + if (authResponse != AuthResponse.Success || accountInfo == null) { + session.write(authResponse) + return + } + val details = PlayerDetails(info.username) + details.accountInfo = accountInfo + details.communication.parse(accountInfo) + session.clientInfo = ClientInfo(info.displayMode, info.windowMode, info.screenWidth, info.screenHeight) + session.isaacPair = info.isaacPair + session.associatedUsername = info.username + Login.proceedWith(session, details, info.opcode) + } catch (e: Exception) { + e.printStackTrace() + session.write(AuthResponse.UnexpectedError) } - val details = PlayerDetails(info.username) - details.accountInfo = accountInfo - details.communication.parse(accountInfo) - session.clientInfo = ClientInfo(info.displayMode, info.windowMode, info.screenWidth, info.screenHeight) - session.isaacPair = info.isaacPair - session.associatedUsername = info.username - Login.proceedWith(session, details, info.opcode) } } \ No newline at end of file