diff --git a/src/main/java/com/eu/habbo/habbohotel/bots/Bot.java b/src/main/java/com/eu/habbo/habbohotel/bots/Bot.java index 26360efd..738e7883 100644 --- a/src/main/java/com/eu/habbo/habbohotel/bots/Bot.java +++ b/src/main/java/com/eu/habbo/habbohotel/bots/Bot.java @@ -54,9 +54,7 @@ public class Bot extends Avatar implements Runnable { private final int bubbleId; private final String type; private int effect; - private transient boolean canWalk; private boolean sqlUpdateNeeded; - private boolean xyzUpdateNeeded; private transient int followingHabboId; protected final RoomBot roomUnit; public static final String NO_CHAT_SET = "${bot.skill.chatter.configuration.text.placeholder}"; @@ -82,13 +80,14 @@ public class Bot extends Avatar implements Runnable { this.chatLines = new ArrayList<>(Arrays.asList(set.getString("chat_lines").split("\r"))); this.type = set.getString("type"); this.effect = set.getInt("effect"); - this.canWalk = set.getString("freeroam").equals("1"); this.chatTimeOut = Emulator.getIntUnixTimestamp() + this.chatDelay; this.sqlUpdateNeeded = false; this.bubbleId = set.getInt("bubble_id"); this.roomUnit = new RoomBot(); this.roomUnit.setUnit(this); + + this.roomUnit.setCanWalk(set.getString("freeroam").equals("1")); } public static void initialise() {} @@ -97,8 +96,8 @@ public class Bot extends Avatar implements Runnable { @Override public void run() { - if (this.sqlUpdateNeeded) { - try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE bots SET name = ?, motto = ?, figure = ?, gender = ?, owner_id = ?, room_id = ?, rot = ?, dance = ?, freeroam = ?, chat_lines = ?, chat_auto = ?, chat_random = ?, chat_delay = ?, effect = ?, bubble_id = ? WHERE id = ?")) { + if (this.sqlUpdateNeeded) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE bots SET name = ?, motto = ?, figure = ?, gender = ?, owner_id = ?, room_id = ?, rot = ?, dance = ?, freeroam = ?, chat_lines = ?, chat_auto = ?, chat_random = ?, chat_delay = ?, effect = ?, bubble_id = ?, x = ?, y = ?, z = ? WHERE id = ?")) { statement.setString(1, this.name); statement.setString(2, this.motto); statement.setString(3, this.figure); @@ -107,7 +106,7 @@ public class Bot extends Avatar implements Runnable { statement.setInt(6, this.roomUnit.getRoom() == null ? 0 : this.roomUnit.getRoom().getRoomInfo().getId()); statement.setInt(7, this.roomUnit.getBodyRotation().getValue()); statement.setInt(8, this.roomUnit.getDanceType().getType()); - statement.setString(9, this.canWalk ? "1" : "0"); + statement.setString(9, this.roomUnit.isCanWalk() ? "1" : "0"); StringBuilder text = new StringBuilder(); for (String s : this.chatLines) { text.append(s).append("\r"); @@ -118,7 +117,10 @@ public class Bot extends Avatar implements Runnable { statement.setInt(13, this.chatDelay); statement.setInt(14, this.effect); statement.setInt(15, this.bubbleId); - statement.setInt(16, this.id); + statement.setInt(16, this.roomUnit.getSpawnTile() == null ? 0 : this.roomUnit.getSpawnTile().getX()); + statement.setInt(17, this.roomUnit.getSpawnTile() == null ? 0 : this.roomUnit.getSpawnTile().getY()); + statement.setDouble(18, this.roomUnit.getSpawnHeight()); + statement.setInt(19, this.id); statement.execute(); this.sqlUpdateNeeded = false; } catch (SQLException e) { @@ -213,13 +215,19 @@ public class Bot extends Avatar implements Runnable { public void setOwnerId(int ownerId) { this.ownerId = ownerId; this.sqlUpdateNeeded = true; - this.roomUnit.getRoom().sendComposer(new RoomUsersComposer(this).compose()); + + if(this.roomUnit.getRoom() != null) { + this.roomUnit.getRoom().sendComposer(new RoomUsersComposer(this).compose()); + } } public void setOwnerName(String ownerName) { this.ownerName = ownerName; this.sqlUpdateNeeded = true; - this.roomUnit.getRoom().sendComposer(new RoomUsersComposer(this).compose()); + + if(this.roomUnit.getRoom() != null) { + this.roomUnit.getRoom().sendComposer(new RoomUsersComposer(this).compose()); + } } public void setChatAuto(boolean chatAuto) { @@ -253,10 +261,8 @@ public class Bot extends Avatar implements Runnable { this.effect = effect; this.sqlUpdateNeeded = true; - if (this.roomUnit != null) { - if (this.roomUnit.getRoom() != null) { - this.roomUnit.giveEffect(this.effect, duration); - } + if (this.roomUnit.getRoom() != null) { + this.roomUnit.giveEffect(this.effect, duration); } } @@ -274,14 +280,6 @@ public class Bot extends Avatar implements Runnable { } } - public boolean canWalk() { - return this.canWalk; - } - - public void setCanWalk(boolean canWalk) { - this.canWalk = canWalk; - } - public void incrementLastChatIndex() { this.lastChatIndex++; } @@ -297,8 +295,8 @@ public class Bot extends Avatar implements Runnable { message.appendString(this.motto); message.appendString(this.figure); message.appendInt(this.roomUnit.getVirtualId()); - message.appendInt(this.roomUnit.getCurrentPosition().getX()); - message.appendInt(this.roomUnit.getCurrentPosition().getY()); + message.appendInt(this.roomUnit.getCurrentPosition() == null ? 0 : this.roomUnit.getCurrentPosition().getX()); + message.appendInt(this.roomUnit.getCurrentPosition() == null ? 0 : this.roomUnit.getCurrentPosition().getY()); message.appendString(String.valueOf(this.roomUnit.getCurrentZ())); message.appendInt(this.roomUnit.getBodyRotation().getValue()); message.appendInt(4); diff --git a/src/main/java/com/eu/habbo/habbohotel/bots/BotManager.java b/src/main/java/com/eu/habbo/habbohotel/bots/BotManager.java index a06492db..f14b26f6 100644 --- a/src/main/java/com/eu/habbo/habbohotel/bots/BotManager.java +++ b/src/main/java/com/eu/habbo/habbohotel/bots/BotManager.java @@ -61,7 +61,7 @@ public class BotManager { public Bot createBot(THashMap data, String type) { Bot bot = null; - try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO bots (user_id, room_id, name, motto, figure, gender, type) VALUES (0, 0, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO bots (owner_id, room_id, name, motto, figure, gender, type) VALUES (0, 0, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { statement.setString(1, data.get("name")); statement.setString(2, data.get("motto")); statement.setString(3, data.get("figure")); @@ -70,7 +70,7 @@ public class BotManager { statement.execute(); try (ResultSet set = statement.getGeneratedKeys()) { if (set.next()) { - try (PreparedStatement stmt = connection.prepareStatement("SELECT users.username AS owner_name, bots.* FROM bots LEFT JOIN users ON bots.user_id = users.id WHERE bots.id = ? LIMIT 1")) { + try (PreparedStatement stmt = connection.prepareStatement("SELECT users.username AS owner_name, bots.* FROM bots LEFT JOIN users ON bots.owner_id = users.id WHERE bots.id = ? LIMIT 1")) { stmt.setInt(1, set.getInt(1)); try (ResultSet resultSet = stmt.executeQuery()) { if (resultSet.next()) { diff --git a/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java b/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java index 6885f3c1..b932d6a5 100644 --- a/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java +++ b/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java @@ -900,8 +900,12 @@ public class CatalogManager { Bot bot = Emulator.getGameEnvironment().getBotManager().createBot(data, type); if (bot != null) { + //TODO @Deprecated bot.setOwnerId(habbo.getClient().getHabbo().getHabboInfo().getId()); bot.setOwnerName(habbo.getClient().getHabbo().getHabboInfo().getUsername()); + + bot.setOwnerInfo(habbo.getHabboInfo()); + bot.setSqlUpdateNeeded(true); Emulator.getThreading().run(bot); habbo.getClient().getHabbo().getInventory().getBotsComponent().addBot(bot); diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomLayout.java b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomLayout.java index f7ccff0a..85cd6f1a 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomLayout.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomLayout.java @@ -1,8 +1,8 @@ package com.eu.habbo.habbohotel.rooms; import com.eu.habbo.Emulator; -import com.eu.habbo.habbohotel.bots.Bot; import com.eu.habbo.habbohotel.rooms.entities.units.RoomUnit; +import com.eu.habbo.habbohotel.rooms.entities.units.types.RoomBot; import gnu.trove.set.hash.THashSet; import lombok.Getter; import lombok.Setter; @@ -560,27 +560,33 @@ public class RoomLayout { return availableTiles; } - public RoomTile getRandomWalkableTilesAround(RoomUnit roomUnit, RoomTile tile, Room room, int radius) { - if(!this.tileExists(tile.getX(), tile.getY())) { - tile = this.getTile(roomUnit.getCurrentPosition().getX(), roomUnit.getCurrentPosition().getY()); - Bot bot = room.getRoomUnitManager().getRoomBotById(roomUnit.getVirtualId()); - bot.setSqlUpdateNeeded(true); + public RoomTile getRandomWalkableTilesAround(RoomBot roomBot, RoomTile tile, int radius) { + if(tile == null || !this.tileExists(tile.getX(), tile.getY()) || tile.getState().equals(RoomTileState.INVALID)) { + roomBot.setCanWalk(false); + return null; } List newTiles = new ArrayList<>(); int minX = Math.max(0, tile.getX() - radius); int minY = Math.max(0, tile.getY() - radius); - int maxX = Math.min(room.getLayout().getMapSizeX(), tile.getX() + radius); - int maxY = Math.min(room.getLayout().getMapSizeY(), tile.getY() + radius); + int maxX = Math.min(this.room.getLayout().getMapSizeX(), tile.getX() + radius); + int maxY = Math.min(this.room.getLayout().getMapSizeY(), tile.getY() + radius); for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { - RoomTile tile2 = room.getLayout().getTile((short) x, (short) y); - if (tile2 != null && tile.getState() != RoomTileState.BLOCKED && tile.getState() != RoomTileState.INVALID) + RoomTile tile2 = this.room.getLayout().getTile((short) x, (short) y); + if (tile2 != null && tile2.getState() != RoomTileState.BLOCKED && tile2.getState() != RoomTileState.INVALID) { newTiles.add(tile2); + } } } + + if(newTiles.isEmpty()) { + log.debug("No Random tiles found."); + return null; + } + Collections.shuffle(newTiles); return newTiles.get(0); } diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitManager.java b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitManager.java index 589fa924..d3c2d7c0 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitManager.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitManager.java @@ -77,21 +77,24 @@ public class RoomUnitManager { try (ResultSet set = statement.executeQuery()) { while (set.next()) { Bot bot = Emulator.getGameEnvironment().getBotManager().loadBot(set); - //TODO IMPROVE THIS + if (bot != null) { bot.getRoomUnit().setRoom(this.room); RoomTile spawnTile = this.room.getLayout().getTile((short) set.getInt("x"), (short) set.getInt("y")); if(spawnTile == null) { - bot.getRoomUnit().setCurrentPosition(this.room.getLayout().getDoorTile()); - bot.getRoomUnit().setCurrentZ(this.room.getLayout().getDoorTile().getStackHeight()); - bot.getRoomUnit().setRotation(RoomRotation.fromValue(this.room.getLayout().getDoorDirection())); + bot.getRoomUnit().setCanWalk(false); } else { + if(spawnTile.getState().equals(RoomTileState.INVALID)) { + bot.getRoomUnit().setCanWalk(false); + } bot.getRoomUnit().setCurrentPosition(spawnTile); bot.getRoomUnit().setCurrentZ(set.getDouble("z")); bot.getRoomUnit().setRotation(RoomRotation.values()[set.getInt("rot")]); + bot.getRoomUnit().setSpawnTile(spawnTile); + bot.getRoomUnit().setSpawnHeight(spawnTile.getState().equals(RoomTileState.INVALID) ? 0 : spawnTile.getStackHeight()); } bot.getRoomUnit().setDanceType(DanceType.values()[set.getInt("dance")]); @@ -300,9 +303,10 @@ public class RoomUnitManager { roomBot.setRoom(this.room); roomBot.setCurrentPosition(spawnTile); - roomBot.setCurrentZ(spawnTile.getZ()); + roomBot.setCurrentZ(spawnTile.getStackHeight()); roomBot.setRotation(RoomRotation.SOUTH); - roomBot.setCanWalk(this.room.isAllowBotsWalk()); + roomBot.setSpawnTile(spawnTile); + roomBot.setSpawnHeight(spawnTile.getState().equals(RoomTileState.INVALID) ? 0 : spawnTile.getStackHeight()); bot.setSqlUpdateNeeded(true); Emulator.getThreading().run(bot); diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/entities/units/types/RoomAvatar.java b/src/main/java/com/eu/habbo/habbohotel/rooms/entities/units/types/RoomAvatar.java index 0e978c4b..5b19e1db 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/entities/units/types/RoomAvatar.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/entities/units/types/RoomAvatar.java @@ -58,6 +58,10 @@ public abstract class RoomAvatar extends RoomUnit { @Override public boolean walkTo(RoomTile goalLocation) { + if(goalLocation == null) { + return false; + } + if (this.hasStatus(RoomUnitStatus.LAY)) { if (this.room.getLayout().getTilesInFront(this.getCurrentPosition(), this.getBodyRotation().getValue(), 2).contains(goalLocation)) return false; diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/entities/units/types/RoomBot.java b/src/main/java/com/eu/habbo/habbohotel/rooms/entities/units/types/RoomBot.java index b522a776..9368064c 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/entities/units/types/RoomBot.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/entities/units/types/RoomBot.java @@ -4,6 +4,7 @@ import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.bots.Bot; import com.eu.habbo.habbohotel.rooms.RoomChatMessage; import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.rooms.RoomTile; import com.eu.habbo.habbohotel.rooms.RoomUserAction; import com.eu.habbo.habbohotel.rooms.entities.units.RoomUnitType; import com.eu.habbo.habbohotel.wired.WiredHandler; @@ -24,16 +25,19 @@ import lombok.extern.slf4j.Slf4j; public class RoomBot extends RoomAvatar { private Bot unit; + private RoomTile spawnTile; + private double spawnHeight; + public RoomBot() { super(); } @Override public void cycle() { - if(this.room.isAllowBotsWalk() && this.unit.canWalk()) { + if (this.room.isAllowBotsWalk() && this.isCanWalk()) { if (!this.isWalking()) { if (this.getWalkTimeOut() < Emulator.getIntUnixTimestamp() && this.unit.getFollowingHabboId() == 0) { - this.walkTo(Emulator.getConfig().getBoolean("hotel.bot.limit.walking.distance", true) ? this.getRoom().getLayout().getRandomWalkableTilesAround(this, this.currentPosition, this.getRoom(), Emulator.getConfig().getInt("hotel.bot.limit.walking.distance.radius", 5)) : this.getRoom().getRandomWalkableTile()); + this.walkTo(Emulator.getConfig().getBoolean("hotel.bot.limit.walking.distance", true) ? this.getRoom().getLayout().getRandomWalkableTilesAround(this, this.currentPosition, Emulator.getConfig().getInt("hotel.bot.limit.walking.distance.radius", 5)) : this.getRoom().getRandomWalkableTile()); int timeOut = Emulator.getRandom().nextInt(20) * 2; this.setWalkTimeOut((timeOut < 10 ? 5 : timeOut) + Emulator.getIntUnixTimestamp()); } diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/CommandBotEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/CommandBotEvent.java index 657a96ad..08befe11 100644 --- a/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/CommandBotEvent.java +++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/CommandBotEvent.java @@ -8,7 +8,6 @@ import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.users.DanceType; import com.eu.habbo.messages.incoming.MessageHandler; import com.eu.habbo.messages.outgoing.generic.alerts.BotErrorComposer; -import com.eu.habbo.messages.outgoing.rooms.users.DanceMessageComposer; import com.eu.habbo.messages.outgoing.rooms.users.RoomUsersComposer; import com.eu.habbo.messages.outgoing.rooms.users.UserNameChangedMessageComposer; import com.eu.habbo.plugin.events.bots.BotSavedChatEvent; @@ -50,7 +49,6 @@ public class CommandBotEvent extends MessageHandler { bot.setFigure(lookEvent.getNewLook()); bot.setGender(lookEvent.getGender()); bot.setEffect(lookEvent.getEffect(), -1); - bot.setSqlUpdateNeeded(true); } case 2 -> { String messageString = this.packet.readString(); @@ -107,12 +105,11 @@ public class CommandBotEvent extends MessageHandler { bot.setSqlUpdateNeeded(true); } case 3 -> { - bot.setCanWalk(!bot.canWalk()); + bot.getRoomUnit().setCanWalk(!bot.getRoomUnit().isCanWalk()); bot.setSqlUpdateNeeded(true); } case 4 -> { - bot.getRoomUnit().setDanceType(DanceType.values()[(bot.getRoomUnit().getDanceType().getType() + 1) % DanceType.values().length]); - room.sendComposer(new DanceMessageComposer(bot.getRoomUnit()).compose()); + bot.getRoomUnit().setDance(DanceType.values()[(bot.getRoomUnit().getDanceType().getType() + 1) % DanceType.values().length]); bot.setSqlUpdateNeeded(true); } case 5 -> { @@ -142,7 +139,6 @@ public class CommandBotEvent extends MessageHandler { String motto = this.packet.readString(); if (motto.length() > Emulator.getConfig().getInt("motto.max_length", 38)) break; bot.setMotto(motto); - bot.setSqlUpdateNeeded(true); room.sendComposer(new RoomUsersComposer(bot).compose()); } }