diff --git a/src/main/java/emu/nebula/GameConstants.java b/src/main/java/emu/nebula/GameConstants.java index c66a008..5352116 100644 --- a/src/main/java/emu/nebula/GameConstants.java +++ b/src/main/java/emu/nebula/GameConstants.java @@ -32,6 +32,7 @@ public class GameConstants { public static final String PROTO_BASE_TYPE_URL = "type.googleapis.com/proto."; public static final int INTRO_GUIDE_ID = 1; + public static final int DEFAULT_HONOR_ID = 111001; public static final int GOLD_ITEM_ID = 1; public static final int GEM_ITEM_ID = 2; diff --git a/src/main/java/emu/nebula/data/resources/HonorDef.java b/src/main/java/emu/nebula/data/resources/HonorDef.java index ed84922..39faa80 100644 --- a/src/main/java/emu/nebula/data/resources/HonorDef.java +++ b/src/main/java/emu/nebula/data/resources/HonorDef.java @@ -1,6 +1,7 @@ package emu.nebula.data.resources; import emu.nebula.data.BaseDef; +import emu.nebula.data.GameData; import emu.nebula.data.ResourceType; import lombok.Getter; @@ -9,9 +10,27 @@ import lombok.Getter; public class HonorDef extends BaseDef { private int Id; private int Type; + private int[] Params; @Override public int getId() { return Id; } + + public boolean isValid() { + if (this.Type == 2) { + if (this.Params.length < 1) { + return false; + } + + int charId = this.Params[0]; + var charData = GameData.getCharacterDataTable().get(charId); + + if (charData == null || !charData.isAvailable()) { + return false; + } + } + + return true; + } } diff --git a/src/main/java/emu/nebula/game/inventory/Inventory.java b/src/main/java/emu/nebula/game/inventory/Inventory.java index d44c149..89d8531 100644 --- a/src/main/java/emu/nebula/game/inventory/Inventory.java +++ b/src/main/java/emu/nebula/game/inventory/Inventory.java @@ -259,6 +259,10 @@ public class Inventory extends PlayerManager implements GameDatabaseObject { return true; } + public boolean hasHonor(int id) { + return id == GameConstants.DEFAULT_HONOR_ID || this.getHonorList().contains(id); + } + // Resources public synchronized int getResourceCount(int id) { diff --git a/src/main/java/emu/nebula/game/player/Player.java b/src/main/java/emu/nebula/game/player/Player.java index 52cdb04..c10714e 100644 --- a/src/main/java/emu/nebula/game/player/Player.java +++ b/src/main/java/emu/nebula/game/player/Player.java @@ -405,8 +405,20 @@ public class Player implements GameDatabaseObject { // Verify that we have the honor titles for (int id : honorIds) { - if (id != 0 && !getInventory().getHonorList().contains(id)) { - System.out.println(id); + // Empty honor title + if (id == 0) { + continue; + } + + // Make sure we own the honor title + if (!getInventory().hasHonor(id)) { + return false; + } + + // Make sure honor exists and won't crash the client + var honor = GameData.getHonorDataTable().get(id); + + if (honor == null || !honor.isValid()) { return false; } } @@ -788,6 +800,9 @@ public class Player implements GameDatabaseObject { // See if we need to reset dailies this.checkResetDailies(); + // Fix any broken honor ids + this.checkBrokenHonor(); + // Update last login time this.lastLogin = System.currentTimeMillis(); Nebula.getGameDatabase().update(this, this.getUid(), "lastLogin", this.getLastLogin()); @@ -815,6 +830,35 @@ public class Player implements GameDatabaseObject { } } + /** + * Checks the player's honor ids to make sure they don't crash the client + */ + private void checkBrokenHonor() { + boolean changed = false; + + for (int i = 0; i < this.honor.length; i++) { + int honorId = this.honor[i]; + + if (honorId == 0) { + continue; + } + + // Get honor data + var honor = GameData.getHonorDataTable().get(honorId); + + // Check if honor is valid + if (honor == null || !honor.isValid()) { + this.honor[i] = 0; + changed = true; + } + } + + // Update in database + if (changed) { + Nebula.getGameDatabase().update(this, this.getUid(), "honor", this.getHonor()); + } + } + // Proto public PlayerInfo toProto() {