From a2180c3b89b152cd569d89004add6900402c61be Mon Sep 17 00:00:00 2001 From: Dominic Bridge Date: Fri, 8 Dec 2023 17:25:29 +0000 Subject: [PATCH] room unit bot manager --- .../com/eu/habbo/habbohotel/rooms/Room.java | 398 +----------------- .../habbohotel/rooms/RoomUnitManager.java | 375 +++++++++++++++++ .../habbohotel/rooms/bots/RoomBotManager.java | 46 +- .../units/types/RoomUnitSubManager.java | 6 + 4 files changed, 439 insertions(+), 386 deletions(-) diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java b/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java index 4616cd61..86c79146 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java @@ -92,7 +92,7 @@ public class Room implements Comparable, ISerialize, Runnable { private final RoomWordFilterManager roomWordFilterManager; @Getter private RoomTraxManager roomTraxManager; - private static final String CAUGHT_EXCEPTION = "Caught exception"; + public static final String CAUGHT_EXCEPTION = "Caught exception"; public static final Comparator SORT_SCORE = Comparator.comparingInt(room -> room.roomInfo.getScore()); public static final Comparator SORT_ID = Comparator.comparingInt(room -> room.roomInfo.getId()); public static final Comparator SORT_USERS_COUNT = Comparator @@ -127,6 +127,7 @@ public class Room implements Comparable, ISerialize, Runnable { public volatile boolean preventUnloading = false; public volatile boolean preventUncaching = false; public final ConcurrentHashMap.KeySetView scheduledComposers = ConcurrentHashMap.newKeySet(); + public ConcurrentHashMap.KeySetView scheduledTasks = ConcurrentHashMap.newKeySet(); @Getter private String wordQuiz = ""; @@ -155,9 +156,8 @@ public class Room implements Comparable, ISerialize, Runnable { private volatile boolean loaded; @Getter private volatile boolean preLoaded; - private int roomIdleCycles; + private final int muteTime = Emulator.getConfig().getInt("hotel.flood.mute.time", 30); - private long rollerCycle = System.currentTimeMillis(); @Getter @Setter private volatile int lastTimerReset = Emulator.getIntUnixTimestamp(); @@ -235,7 +235,7 @@ public class Room implements Comparable, ISerialize, Runnable { this.roomUnitManager.load(connection); this.roomWordFilterManager.load(connection); - this.roomIdleCycles = 0; + this.loaded = true; this.roomCycleTask = Emulator.getThreading().getService().scheduleAtFixedRate(this, 500, 500, TimeUnit.MILLISECONDS); @@ -431,7 +431,7 @@ public class Room implements Comparable, ISerialize, Runnable { private void cycle() { this.cycleOdd = !this.cycleOdd; this.cycleTimestamp = System.currentTimeMillis(); - final boolean[] foundRightHolder = {false}; + boolean foundRightHolder = false; boolean loaded; synchronized (this.loadLock) { @@ -452,380 +452,11 @@ public class Room implements Comparable, ISerialize, Runnable { task.cycle(this); } - if (!this.roomUnitManager.getCurrentHabbos().isEmpty()) { - this.roomIdleCycles = 0; - - THashSet updatedUnit = new THashSet<>(); - ArrayList toKick = new ArrayList<>(); - - final long millis = System.currentTimeMillis(); - - for (Habbo habbo : this.roomUnitManager.getCurrentHabbos().values()) { - if (!foundRightHolder[0]) { - foundRightHolder[0] = habbo.getRoomUnit().getRightsLevel() != RoomRightLevels.NONE; - } - - if (habbo.getRoomUnit().getEffectId() > 0 && millis / 1000 > habbo.getRoomUnit().getEffectEndTimestamp()) { - habbo.getRoomUnit().giveEffect(0, -1); - } - - if (habbo.getRoomUnit().isKicked()) { - habbo.getRoomUnit().setKickCount(habbo.getRoomUnit().getKickCount() + 1); - - if (habbo.getRoomUnit().getKickCount() >= 5) { - this.scheduledTasks.add(() -> Emulator.getGameEnvironment().getRoomManager().leaveRoom(habbo, this)); - continue; - } - } - - if (Emulator.getConfig().getBoolean("hotel.rooms.auto.idle")) { - cycleIdle(this, habbo, toKick); - } - - if (Emulator.getConfig().getBoolean("hotel.rooms.deco_hosting") && this.roomInfo.getOwnerInfo().getId() != habbo.getHabboInfo().getId()) { - //Check if the time already have 1 minute (120 / 2 = 60s) - if (habbo.getRoomUnit().getTimeInRoom() >= 120) { - AchievementManager.progressAchievement(this.roomInfo.getOwnerInfo().getId(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("RoomDecoHosting")); - habbo.getRoomUnit().resetTimeInRoom(); - } else { - habbo.getRoomUnit().increaseTimeInRoom(); - } - } - - if (habbo.getHabboStats().isMutedBubbleTracker() && habbo.getHabboStats().allowTalk()) { - habbo.getHabboStats().setMutedBubbleTracker(false); - this.sendComposer(new IgnoreResultMessageComposer(habbo, IgnoreResultMessageComposer.UNIGNORED).compose()); - } - - // Substract 1 from the chatCounter every odd cycle, which is every (500ms * 2). - if (this.cycleOdd && habbo.getHabboStats().getChatCounter().get() > 0) { - habbo.getHabboStats().getChatCounter().decrementAndGet(); - } - - habbo.getRoomUnit().cycle(); - - if(habbo.getRoomUnit().isStatusUpdateNeeded()) { - habbo.getRoomUnit().setStatusUpdateNeeded(false); - updatedUnit.add(habbo.getRoomUnit()); - } - } - - if (!toKick.isEmpty()) { - for (Habbo habbo : toKick) { - Emulator.getGameEnvironment().getRoomManager().leaveRoom(habbo, this); - } - } - - if (!this.roomUnitManager.getRoomBotManager().getCurrentBots().isEmpty()) { - Iterator botIterator = this.roomUnitManager.getRoomBotManager().getCurrentBots().values().iterator(); - - while(botIterator.hasNext()) { - try { - final Bot bot; - try { - bot = botIterator.next(); - } catch (Exception e) { - break; - } - - if (!this.allowBotsWalk && bot.getRoomUnit().isWalking()) { - bot.getRoomUnit().stopWalking(); - updatedUnit.add(bot.getRoomUnit()); - continue; - } - - bot.getRoomUnit().cycle(); - - if(bot.getRoomUnit().isStatusUpdateNeeded()) { - bot.getRoomUnit().setStatusUpdateNeeded(false); - updatedUnit.add(bot.getRoomUnit()); - } - - - } catch (NoSuchElementException e) { - log.error(CAUGHT_EXCEPTION, e); - break; - } - } - } - - if (!this.roomUnitManager.getCurrentPets().isEmpty() && this.allowBotsWalk) { - Iterator petIterator = this.roomUnitManager.getCurrentPets().values().iterator(); - while(petIterator.hasNext()) { - final Pet pet; - try { - pet = petIterator.next(); - } catch (Exception e) { - break; - } - - pet.getRoomUnit().cycle(); - pet.cycle(); - - if(pet.getRoomUnit().isStatusUpdateNeeded()) { - pet.getRoomUnit().setStatusUpdateNeeded(false); - updatedUnit.add(pet.getRoomUnit()); - } - - if (pet.getRoomUnit().isWalking() && pet.getRoomUnit().getPath().size() == 1 && pet.getRoomUnit().hasStatus(RoomUnitStatus.GESTURE)) { - pet.getRoomUnit().removeStatus(RoomUnitStatus.GESTURE); - updatedUnit.add(pet.getRoomUnit()); - } - } - } - - - if (this.roomInfo.getRollerSpeed() != -1 && this.rollerCycle >= this.roomInfo.getRollerSpeed()) { - this.rollerCycle = 0; - - THashSet messages = new THashSet<>(); - - //Find alternative for this. - //Reason is that tile gets updated after every roller. - List rollerFurniIds = new ArrayList<>(); - List rolledUnitIds = new ArrayList<>(); - - - this.roomSpecialTypes.getRollers().forEachValue(roller -> { - - RoomItem newRoller = null; - - RoomTile rollerTile = this.layout.getTile(roller.getCurrentPosition().getX(), roller.getCurrentPosition().getY()); - - if (rollerTile == null) - return true; - - THashSet itemsOnRoller = new THashSet<>(); - - for (RoomItem item : this.roomItemManager.getItemsAt(rollerTile)) { - if (item.getCurrentZ() >= roller.getCurrentZ() + Item.getCurrentHeight(roller)) { - itemsOnRoller.add(item); - } - } - - itemsOnRoller.remove(roller); - - if (!this.roomUnitManager.areRoomUnitsAt(rollerTile) && itemsOnRoller.isEmpty()) - return true; - - RoomTile tileInFront = Room.this.layout.getTileInFront(Room.this.layout.getTile(roller.getCurrentPosition().getX(), roller.getCurrentPosition().getY()), roller.getRotation()); - - if (tileInFront == null) - return true; - - if (!Room.this.layout.tileExists(tileInFront.getX(), tileInFront.getY())) - return true; - - if (tileInFront.getState() == RoomTileState.INVALID) - return true; - - if (!tileInFront.getAllowStack() && !(tileInFront.isWalkable() || tileInFront.getState() == RoomTileState.SIT || tileInFront.getState() == RoomTileState.LAY)) - return true; - - if (this.roomUnitManager.areRoomUnitsAt(tileInFront)) - return true; - - THashSet itemsNewTile = new THashSet<>(); - itemsNewTile.addAll(this.roomItemManager.getItemsAt(tileInFront)); - itemsNewTile.removeAll(itemsOnRoller); - - itemsOnRoller.removeIf(item -> item.getCurrentPosition().getX() != roller.getCurrentPosition().getX() || item.getCurrentPosition().getY() != roller.getCurrentPosition().getY() || rollerFurniIds.contains(item.getId())); - - RoomItem topItem = this.roomItemManager.getTopItemAt(tileInFront.getX(), tileInFront.getY()); - - boolean allowUsers = true; - boolean allowFurniture = true; - boolean stackContainsRoller = false; - - for (RoomItem item : itemsNewTile) { - if (!(item.getBaseItem().allowWalk() || item.getBaseItem().allowSit()) && !(item instanceof InteractionGate && item.getExtraData().equals("1"))) { - allowUsers = false; - } - if (item instanceof InteractionRoller) { - newRoller = item; - stackContainsRoller = true; - - if ((item.getCurrentZ() != roller.getCurrentZ() || (itemsNewTile.size() > 1 && item != topItem)) && !InteractionRoller.NO_RULES) { - allowUsers = false; - allowFurniture = false; - continue; - } - - break; - } else { - allowFurniture = false; - } - } - - if (allowFurniture) { - allowFurniture = tileInFront.getAllowStack(); - } - - double zOffset = 0; - if (newRoller != null) { - if ((!itemsNewTile.isEmpty() && (itemsNewTile.size() > 1)) && !InteractionRoller.NO_RULES) { - return true; - } - } else { - zOffset = -Item.getCurrentHeight(roller) + tileInFront.getStackHeight() - rollerTile.getZ(); - } - - if (allowUsers) { - Event roomUserRolledEvent = null; - - if (Emulator.getPluginManager().isRegistered(UserRolledEvent.class, true)) { - roomUserRolledEvent = new UserRolledEvent(null, null, null); - } - - ArrayList unitsOnTile = new ArrayList<>(this.roomUnitManager.getRoomUnitsAt(rollerTile)); - - for (RoomUnit roomUnit : this.roomUnitManager.getRoomUnitsAt(rollerTile)) { - if (roomUnit instanceof RoomPet) { - Pet pet = this.roomUnitManager.getPetByRoomUnit(roomUnit); - if (pet instanceof RideablePet rideablePet && rideablePet.getRider() != null) { - unitsOnTile.remove(roomUnit); - } - } - } - - THashSet usersRolledThisTile = new THashSet<>(); - - for (RoomUnit roomUnit : unitsOnTile) { - if (rolledUnitIds.contains(roomUnit.getVirtualId())) continue; - - if (usersRolledThisTile.size() >= Room.ROLLERS_MAXIMUM_ROLL_AVATARS) break; - - if (stackContainsRoller && !allowFurniture && !(topItem != null && topItem.isWalkable())) - continue; - - if (roomUnit.hasStatus(RoomUnitStatus.MOVE)) - continue; - - double newZ = roomUnit.getCurrentZ() + zOffset; - - if (roomUserRolledEvent != null && roomUnit.getRoomUnitType() == RoomUnitType.HABBO) { - roomUserRolledEvent = new UserRolledEvent(this.getRoomUnitManager().getHabboByRoomUnit(roomUnit), roller, tileInFront); - Emulator.getPluginManager().fireEvent(roomUserRolledEvent); - - if (roomUserRolledEvent.isCancelled()) - continue; - } - - // horse riding - boolean isRiding = false; - if (roomUnit.getRoomUnitType() == RoomUnitType.HABBO) { - Habbo rollingHabbo = this.getRoomUnitManager().getHabboByRoomUnit(roomUnit); - if (rollingHabbo != null && rollingHabbo.getHabboInfo() != null) { - RideablePet ridingPet = rollingHabbo.getRoomUnit().getRidingPet(); - if (ridingPet != null) { - RoomUnit ridingUnit = ridingPet.getRoomUnit(); - newZ = ridingUnit.getCurrentZ() + zOffset; - rolledUnitIds.add(ridingUnit.getVirtualId()); - updatedUnit.remove(ridingUnit); - messages.add(new RoomUnitOnRollerComposer(ridingUnit, roller, ridingUnit.getCurrentPosition(), ridingUnit.getCurrentZ(), tileInFront, newZ, this)); - isRiding = true; - } - } - } - - usersRolledThisTile.add(roomUnit.getVirtualId()); - rolledUnitIds.add(roomUnit.getVirtualId()); - updatedUnit.remove(roomUnit); - messages.add(new RoomUnitOnRollerComposer(roomUnit, roller, roomUnit.getCurrentPosition(), roomUnit.getCurrentZ() + (isRiding ? 1 : 0), tileInFront, newZ + (isRiding ? 1 : 0), this)); - - if (itemsOnRoller.isEmpty()) { - RoomItem item = this.getRoomItemManager().getTopItemAt(tileInFront.getX(), tileInFront.getY()); - - if (item != null && itemsNewTile.contains(item) && !itemsOnRoller.contains(item)) { - Emulator.getThreading().run(() -> { - if (roomUnit.getTargetPosition() == rollerTile) { - try { - item.onWalkOn(roomUnit, this, new Object[]{rollerTile, tileInFront}); - } catch (Exception e) { - log.error(CAUGHT_EXCEPTION, e); - } - } - }, this.roomInfo.getRollerSpeed() == 0 ? 250 : InteractionRoller.DELAY); - } - } - } - } - - if (!messages.isEmpty()) { - for (MessageComposer message : messages) { - this.sendComposer(message.compose()); - } - messages.clear(); - } - - if (allowFurniture || !stackContainsRoller || InteractionRoller.NO_RULES) { - Event furnitureRolledEvent = null; - - if (Emulator.getPluginManager().isRegistered(FurnitureRolledEvent.class, true)) { - furnitureRolledEvent = new FurnitureRolledEvent(null, null, null); - } - - if (newRoller == null || topItem == newRoller) { - List sortedItems = new ArrayList<>(itemsOnRoller); - sortedItems.sort((o1, o2) -> { - return Double.compare(o2.getCurrentZ(), o1.getCurrentZ()); - }); - - for (RoomItem item : sortedItems) { - if ((item.getCurrentPosition().getX() == roller.getCurrentPosition().getX() && item.getCurrentPosition().getY() == roller.getCurrentPosition().getY() && zOffset <= 0) && (item != roller)) { - if (furnitureRolledEvent != null) { - furnitureRolledEvent = new FurnitureRolledEvent(item, roller, tileInFront); - Emulator.getPluginManager().fireEvent(furnitureRolledEvent); - - if (furnitureRolledEvent.isCancelled()) - continue; - } - - messages.add(new FloorItemOnRollerComposer(item, roller, tileInFront, zOffset, this)); - rollerFurniIds.add(item.getId()); - } - } - } - } - - - if (!messages.isEmpty()) { - for (MessageComposer message : messages) { - this.sendComposer(message.compose()); - } - messages.clear(); - } - - return true; - }); - - - int currentTime = (int) (this.cycleTimestamp / 1000); - for (RoomItem pyramid : this.roomSpecialTypes.getItemsOfType(InteractionPyramid.class)) { - if (pyramid instanceof InteractionPyramid interactionPyramid && interactionPyramid.getNextChange() < currentTime) { - interactionPyramid.change(this); - } - } - } else { - this.rollerCycle++; - } - - if (!updatedUnit.isEmpty()) { - this.sendComposer(new UserUpdateComposer(updatedUnit).compose()); - } - - this.roomTraxManager.cycle(); - } else { - - if (this.roomIdleCycles < 60) - this.roomIdleCycles++; - else - this.dispose(); - } + foundRightHolder = roomUnitManager.cycle(cycleOdd); } synchronized (this.habboQueue) { - if (!this.habboQueue.isEmpty() && !foundRightHolder[0]) { + if (!this.habboQueue.isEmpty() && !foundRightHolder) { this.habboQueue.forEachEntry((a, b) -> { if (b.isOnline()) { if (b.getHabboInfo().getRoomQueueId() == this.roomInfo.getId()) { @@ -1042,7 +673,7 @@ public class Room implements Comparable, ISerialize, Runnable { public void setRollerSpeed(int rollerSpeed) { this.roomInfo.setRollerSpeed(rollerSpeed); - this.rollerCycle = 0; + roomUnitManager.setRollerCycle(0); this.needsUpdate = true; } @@ -1652,7 +1283,7 @@ public class Room implements Comparable, ISerialize, Runnable { } public boolean canSitOrLayAt(RoomTile tile) { - if(tile == null) { + if (tile == null) { return false; } @@ -1667,7 +1298,7 @@ public class Room implements Comparable, ISerialize, Runnable { public boolean canSitAt(int x, int y) { RoomTile tile = this.layout.getTile((short) x, (short) y); - if(tile == null) { + if (tile == null) { return false; } @@ -1753,7 +1384,9 @@ public class Room implements Comparable, ISerialize, Runnable { } for (Habbo habbo : this.roomUnitManager.getCurrentHabbos().values()) { - if (habbo == null) { return ; } + if (habbo == null) { + return; + } if (!habbo.getHabboStats().isIgnoreBots()) habbo.getClient().sendResponse(message); } @@ -1779,7 +1412,7 @@ public class Room implements Comparable, ISerialize, Runnable { } public RoomRightLevels getGuildRightLevel(Habbo habbo) { - if(!this.roomInfo.hasGuild()) { + if (!this.roomInfo.hasGuild()) { return RoomRightLevels.NONE; } @@ -1867,7 +1500,8 @@ public class Room implements Comparable, ISerialize, Runnable { THashSet items = new THashSet<>(); for (RoomItem item : this.roomItemManager.getCurrentItems().values()) { - if (!items.contains(item.getBaseItem()) && item.getOwnerInfo().getId() == userId) items.add(item.getBaseItem()); + if (!items.contains(item.getBaseItem()) && item.getOwnerInfo().getId() == userId) + items.add(item.getBaseItem()); } return items.size(); 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 ba776da7..87f7fe95 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitManager.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitManager.java @@ -1,25 +1,42 @@ package com.eu.habbo.habbohotel.rooms; import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; import com.eu.habbo.habbohotel.bots.Bot; import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionGate; +import com.eu.habbo.habbohotel.items.interactions.InteractionPyramid; +import com.eu.habbo.habbohotel.items.interactions.InteractionRoller; import com.eu.habbo.habbohotel.pets.Pet; import com.eu.habbo.habbohotel.pets.PetManager; +import com.eu.habbo.habbohotel.pets.RideablePet; import com.eu.habbo.habbohotel.rooms.bots.RoomBotManager; +import com.eu.habbo.habbohotel.rooms.constants.RoomRightLevels; import com.eu.habbo.habbohotel.rooms.constants.RoomTileState; import com.eu.habbo.habbohotel.rooms.constants.RoomUnitStatus; import com.eu.habbo.habbohotel.rooms.entities.RoomRotation; import com.eu.habbo.habbohotel.rooms.entities.units.RoomUnit; import com.eu.habbo.habbohotel.rooms.entities.units.RoomUnitType; import com.eu.habbo.habbohotel.rooms.entities.units.types.RoomHabbo; +import com.eu.habbo.habbohotel.rooms.entities.units.types.RoomPet; import com.eu.habbo.habbohotel.rooms.items.entities.RoomItem; import com.eu.habbo.habbohotel.units.Unit; import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; import com.eu.habbo.messages.outgoing.inventory.PetAddedToInventoryComposer; +import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; import com.eu.habbo.messages.outgoing.rooms.pets.RoomPetComposer; +import com.eu.habbo.messages.outgoing.rooms.users.IgnoreResultMessageComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUnitOnRollerComposer; import com.eu.habbo.messages.outgoing.rooms.users.UserRemoveMessageComposer; +import com.eu.habbo.messages.outgoing.rooms.users.UserUpdateComposer; +import com.eu.habbo.plugin.Event; +import com.eu.habbo.plugin.events.furniture.FurnitureRolledEvent; +import com.eu.habbo.plugin.events.users.UserRolledEvent; import gnu.trove.set.hash.THashSet; import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import java.sql.Connection; @@ -32,6 +49,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import static com.eu.habbo.database.DatabaseConstants.CAUGHT_SQL_EXCEPTION; +import static com.eu.habbo.habbohotel.rooms.Room.CAUGHT_EXCEPTION; +import static com.eu.habbo.habbohotel.rooms.utils.cycle.CycleFunctions.cycleIdle; @Slf4j @Getter @@ -44,6 +63,13 @@ public class RoomUnitManager { public final Object roomUnitLock; private final RoomBotManager roomBotManager; + + private int roomIdleCycles; + + @Setter + private long rollerCycle = System.currentTimeMillis(); + + public RoomUnitManager(Room room) { this.room = room; this.currentRoomUnits = new ConcurrentHashMap<>(); @@ -55,6 +81,7 @@ public class RoomUnitManager { } public synchronized void load(Connection connection) { + this.roomIdleCycles = 0; roomBotManager.loadBots(connection); this.loadPets(connection); } @@ -402,4 +429,352 @@ public class RoomUnitManager { public void removeUnit(int virtualId) { this.currentRoomUnits.remove(virtualId); } + + public boolean cycle(boolean cycleOdd){ + boolean foundRightHolder = false; + if (!getCurrentHabbos().isEmpty()) { + this.roomIdleCycles = 0; + + THashSet updatedUnit = new THashSet<>(); + ArrayList toKick = new ArrayList<>(); + + final long millis = System.currentTimeMillis(); + + for (Habbo habbo : getCurrentHabbos().values()) { + if (!foundRightHolder) { + foundRightHolder = habbo.getRoomUnit().getRightsLevel() != RoomRightLevels.NONE; + } + + if (habbo.getRoomUnit().getEffectId() > 0 && millis / 1000 > habbo.getRoomUnit().getEffectEndTimestamp()) { + habbo.getRoomUnit().giveEffect(0, -1); + } + + if (habbo.getRoomUnit().isKicked()) { + habbo.getRoomUnit().setKickCount(habbo.getRoomUnit().getKickCount() + 1); + + if (habbo.getRoomUnit().getKickCount() >= 5) { + room.scheduledTasks.add(() -> Emulator.getGameEnvironment().getRoomManager().leaveRoom(habbo, room)); + continue; + } + } + + if (Emulator.getConfig().getBoolean("hotel.rooms.auto.idle")) { + cycleIdle(room, habbo, toKick); + } + + if (Emulator.getConfig().getBoolean("hotel.rooms.deco_hosting") && room.getRoomInfo().getOwnerInfo().getId() != habbo.getHabboInfo().getId()) { + //Check if the time already have 1 minute (120 / 2 = 60s) + if (habbo.getRoomUnit().getTimeInRoom() >= 120) { + AchievementManager.progressAchievement(room.getRoomInfo().getOwnerInfo().getId(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("RoomDecoHosting")); + habbo.getRoomUnit().resetTimeInRoom(); + } else { + habbo.getRoomUnit().increaseTimeInRoom(); + } + } + + if (habbo.getHabboStats().isMutedBubbleTracker() && habbo.getHabboStats().allowTalk()) { + habbo.getHabboStats().setMutedBubbleTracker(false); + room.sendComposer(new IgnoreResultMessageComposer(habbo, IgnoreResultMessageComposer.UNIGNORED).compose()); + } + + // Substract 1 from the chatCounter every odd cycle, which is every (500ms * 2). + if (cycleOdd && habbo.getHabboStats().getChatCounter().get() > 0) { + habbo.getHabboStats().getChatCounter().decrementAndGet(); + } + + habbo.getRoomUnit().cycle(); + + if(habbo.getRoomUnit().isStatusUpdateNeeded()) { + habbo.getRoomUnit().setStatusUpdateNeeded(false); + updatedUnit.add(habbo.getRoomUnit()); + } + } + + if (!toKick.isEmpty()) { + for (Habbo habbo : toKick) { + Emulator.getGameEnvironment().getRoomManager().leaveRoom(habbo, room); + } + } + + updatedUnit.addAll(roomBotManager.cycle()); + if (!getCurrentPets().isEmpty() && room.isAllowBotsWalk()) { + Iterator petIterator = getCurrentPets().values().iterator(); + while(petIterator.hasNext()) { + final Pet pet; + try { + pet = petIterator.next(); + } catch (Exception e) { + break; + } + + pet.getRoomUnit().cycle(); + pet.cycle(); + + if(pet.getRoomUnit().isStatusUpdateNeeded()) { + pet.getRoomUnit().setStatusUpdateNeeded(false); + updatedUnit.add(pet.getRoomUnit()); + } + + if (pet.getRoomUnit().isWalking() && pet.getRoomUnit().getPath().size() == 1 && pet.getRoomUnit().hasStatus(RoomUnitStatus.GESTURE)) { + pet.getRoomUnit().removeStatus(RoomUnitStatus.GESTURE); + updatedUnit.add(pet.getRoomUnit()); + } + } + } + + + if (room.getRoomInfo().getRollerSpeed() != -1 && this.rollerCycle >= room.getRoomInfo().getRollerSpeed()) { + this.rollerCycle = 0; + + THashSet messages = new THashSet<>(); + + //Find alternative for this. + //Reason is that tile gets updated after every roller. + List rollerFurniIds = new ArrayList<>(); + List rolledUnitIds = new ArrayList<>(); + + + room.getRoomSpecialTypes().getRollers().forEachValue(roller -> { + + RoomItem newRoller = null; + + RoomTile rollerTile = room.getLayout().getTile(roller.getCurrentPosition().getX(), roller.getCurrentPosition().getY()); + + if (rollerTile == null) + return true; + + THashSet itemsOnRoller = new THashSet<>(); + + for (RoomItem item : room.getRoomItemManager().getItemsAt(rollerTile)) { + if (item.getCurrentZ() >= roller.getCurrentZ() + Item.getCurrentHeight(roller)) { + itemsOnRoller.add(item); + } + } + + itemsOnRoller.remove(roller); + + if (!areRoomUnitsAt(rollerTile) && itemsOnRoller.isEmpty()) + return true; + + RoomTile tileInFront = room.getLayout().getTileInFront(room.getLayout().getTile(roller.getCurrentPosition().getX(), roller.getCurrentPosition().getY()), roller.getRotation()); + + if (tileInFront == null) + return true; + + if (!room.getLayout().tileExists(tileInFront.getX(), tileInFront.getY())) + return true; + + if (tileInFront.getState() == RoomTileState.INVALID) + return true; + + if (!tileInFront.getAllowStack() && !(tileInFront.isWalkable() || tileInFront.getState() == RoomTileState.SIT || tileInFront.getState() == RoomTileState.LAY)) + return true; + + if (areRoomUnitsAt(tileInFront)) + return true; + + THashSet itemsNewTile = new THashSet<>(); + itemsNewTile.addAll(room.getRoomItemManager().getItemsAt(tileInFront)); + itemsNewTile.removeAll(itemsOnRoller); + + itemsOnRoller.removeIf(item -> item.getCurrentPosition().getX() != roller.getCurrentPosition().getX() || item.getCurrentPosition().getY() != roller.getCurrentPosition().getY() || rollerFurniIds.contains(item.getId())); + + RoomItem topItem = room.getRoomItemManager().getTopItemAt(tileInFront.getX(), tileInFront.getY()); + + boolean allowUsers = true; + boolean allowFurniture = true; + boolean stackContainsRoller = false; + + for (RoomItem item : itemsNewTile) { + if (!(item.getBaseItem().allowWalk() || item.getBaseItem().allowSit()) && !(item instanceof InteractionGate && item.getExtraData().equals("1"))) { + allowUsers = false; + } + if (item instanceof InteractionRoller) { + newRoller = item; + stackContainsRoller = true; + + if ((item.getCurrentZ() != roller.getCurrentZ() || (itemsNewTile.size() > 1 && item != topItem)) && !InteractionRoller.NO_RULES) { + allowUsers = false; + allowFurniture = false; + continue; + } + + break; + } else { + allowFurniture = false; + } + } + + if (allowFurniture) { + allowFurniture = tileInFront.getAllowStack(); + } + + double zOffset = 0; + if (newRoller != null) { + if ((!itemsNewTile.isEmpty() && (itemsNewTile.size() > 1)) && !InteractionRoller.NO_RULES) { + return true; + } + } else { + zOffset = -Item.getCurrentHeight(roller) + tileInFront.getStackHeight() - rollerTile.getZ(); + } + + if (allowUsers) { + Event roomUserRolledEvent = null; + + if (Emulator.getPluginManager().isRegistered(UserRolledEvent.class, true)) { + roomUserRolledEvent = new UserRolledEvent(null, null, null); + } + + ArrayList unitsOnTile = new ArrayList<>(getRoomUnitsAt(rollerTile)); + + for (RoomUnit roomUnit : getRoomUnitsAt(rollerTile)) { + if (roomUnit instanceof RoomPet) { + Pet pet = getPetByRoomUnit(roomUnit); + if (pet instanceof RideablePet rideablePet && rideablePet.getRider() != null) { + unitsOnTile.remove(roomUnit); + } + } + } + + THashSet usersRolledThisTile = new THashSet<>(); + + for (RoomUnit roomUnit : unitsOnTile) { + if (rolledUnitIds.contains(roomUnit.getVirtualId())) continue; + + if (usersRolledThisTile.size() >= Room.ROLLERS_MAXIMUM_ROLL_AVATARS) break; + + if (stackContainsRoller && !allowFurniture && !(topItem != null && topItem.isWalkable())) + continue; + + if (roomUnit.hasStatus(RoomUnitStatus.MOVE)) + continue; + + double newZ = roomUnit.getCurrentZ() + zOffset; + + if (roomUserRolledEvent != null && roomUnit.getRoomUnitType() == RoomUnitType.HABBO) { + roomUserRolledEvent = new UserRolledEvent(getHabboByRoomUnit(roomUnit), roller, tileInFront); + Emulator.getPluginManager().fireEvent(roomUserRolledEvent); + + if (roomUserRolledEvent.isCancelled()) + continue; + } + + // horse riding + boolean isRiding = false; + if (roomUnit.getRoomUnitType() == RoomUnitType.HABBO) { + Habbo rollingHabbo = getHabboByRoomUnit(roomUnit); + if (rollingHabbo != null && rollingHabbo.getHabboInfo() != null) { + RideablePet ridingPet = rollingHabbo.getRoomUnit().getRidingPet(); + if (ridingPet != null) { + RoomUnit ridingUnit = ridingPet.getRoomUnit(); + newZ = ridingUnit.getCurrentZ() + zOffset; + rolledUnitIds.add(ridingUnit.getVirtualId()); + updatedUnit.remove(ridingUnit); + messages.add(new RoomUnitOnRollerComposer(ridingUnit, roller, ridingUnit.getCurrentPosition(), ridingUnit.getCurrentZ(), tileInFront, newZ, room)); + isRiding = true; + } + } + } + + usersRolledThisTile.add(roomUnit.getVirtualId()); + rolledUnitIds.add(roomUnit.getVirtualId()); + updatedUnit.remove(roomUnit); + messages.add(new RoomUnitOnRollerComposer(roomUnit, roller, roomUnit.getCurrentPosition(), roomUnit.getCurrentZ() + (isRiding ? 1 : 0), tileInFront, newZ + (isRiding ? 1 : 0), room)); + + if (itemsOnRoller.isEmpty()) { + RoomItem item = room.getRoomItemManager().getTopItemAt(tileInFront.getX(), tileInFront.getY()); + + if (item != null && itemsNewTile.contains(item) && !itemsOnRoller.contains(item)) { + Emulator.getThreading().run(() -> { + if (roomUnit.getTargetPosition() == rollerTile) { + try { + item.onWalkOn(roomUnit, room, new Object[]{rollerTile, tileInFront}); + } catch (Exception e) { + log.error(CAUGHT_EXCEPTION, e); + } + } + }, room.getRoomInfo().getRollerSpeed() == 0 ? 250 : InteractionRoller.DELAY); + } + } + } + } + + if (!messages.isEmpty()) { + for (MessageComposer message : messages) { + room.sendComposer(message.compose()); + } + messages.clear(); + } + + if (allowFurniture || !stackContainsRoller || InteractionRoller.NO_RULES) { + Event furnitureRolledEvent = null; + + if (Emulator.getPluginManager().isRegistered(FurnitureRolledEvent.class, true)) { + furnitureRolledEvent = new FurnitureRolledEvent(null, null, null); + } + + if (newRoller == null || topItem == newRoller) { + List sortedItems = new ArrayList<>(itemsOnRoller); + sortedItems.sort((o1, o2) -> { + return Double.compare(o2.getCurrentZ(), o1.getCurrentZ()); + }); + + for (RoomItem item : sortedItems) { + if ((item.getCurrentPosition().getX() == roller.getCurrentPosition().getX() && item.getCurrentPosition().getY() == roller.getCurrentPosition().getY() && zOffset <= 0) && (item != roller)) { + if (furnitureRolledEvent != null) { + furnitureRolledEvent = new FurnitureRolledEvent(item, roller, tileInFront); + Emulator.getPluginManager().fireEvent(furnitureRolledEvent); + + if (furnitureRolledEvent.isCancelled()) + continue; + } + + messages.add(new FloorItemOnRollerComposer(item, roller, tileInFront, zOffset, room)); + rollerFurniIds.add(item.getId()); + } + } + } + } + + + if (!messages.isEmpty()) { + for (MessageComposer message : messages) { + this.sendComposer(message.compose()); + } + messages.clear(); + } + + return true; + }); + + + int currentTime = (int) (room.getCycleTimestamp() / 1000); + for (RoomItem pyramid : room.getRoomSpecialTypes().getItemsOfType(InteractionPyramid.class)) { + if (pyramid instanceof InteractionPyramid interactionPyramid && interactionPyramid.getNextChange() < currentTime) { + interactionPyramid.change(room); + } + } + } else { + this.rollerCycle++; + } + + if (!updatedUnit.isEmpty()) { + this.sendComposer(new UserUpdateComposer(updatedUnit).compose()); + } + + room.getRoomTraxManager().cycle(); + } else { + + if (this.roomIdleCycles < 60) + this.roomIdleCycles++; + else + this.dispose(); + } + + return foundRightHolder; + } + + private void sendComposer(ServerMessage serverMessage) { + room.sendComposer(serverMessage); + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/bots/RoomBotManager.java b/src/main/java/com/eu/habbo/habbohotel/rooms/bots/RoomBotManager.java index 24c99516..63060c8b 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/bots/RoomBotManager.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/bots/RoomBotManager.java @@ -33,14 +33,12 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import static com.eu.habbo.database.DatabaseConstants.CAUGHT_SQL_EXCEPTION; +import static com.eu.habbo.habbohotel.rooms.Room.CAUGHT_EXCEPTION; @Slf4j @@ -285,4 +283,44 @@ public class RoomBotManager extends RoomUnitSubManager { this.currentBots.clear(); } + + @Override + public List cycle() { + List updatedBots = new ArrayList<>(); + if (!getCurrentBots().isEmpty()) { + Iterator botIterator = getCurrentBots().values().iterator(); + + while(botIterator.hasNext()) { + try { + final Bot bot; + try { + bot = botIterator.next(); + } catch (Exception e) { + break; + } + + if (!room.isAllowBotsWalk() && bot.getRoomUnit().isWalking()) { + bot.getRoomUnit().stopWalking(); + updatedBots.add(bot.getRoomUnit()); + continue; + } + + bot.getRoomUnit().cycle(); + + if(bot.getRoomUnit().isStatusUpdateNeeded()) { + bot.getRoomUnit().setStatusUpdateNeeded(false); + updatedBots.add(bot.getRoomUnit()); + } + + + } catch (NoSuchElementException e) { + log.error(CAUGHT_EXCEPTION, e); + break; + } + } + } + + + return updatedBots; + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/entities/units/types/RoomUnitSubManager.java b/src/main/java/com/eu/habbo/habbohotel/rooms/entities/units/types/RoomUnitSubManager.java index ecb63b19..d9d01aeb 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/entities/units/types/RoomUnitSubManager.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/entities/units/types/RoomUnitSubManager.java @@ -1,7 +1,11 @@ package com.eu.habbo.habbohotel.rooms.entities.units.types; +import com.eu.habbo.habbohotel.bots.Bot; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.RoomUnitManager; +import com.eu.habbo.habbohotel.rooms.entities.units.RoomUnit; + +import java.util.List; public abstract class RoomUnitSubManager { @@ -11,4 +15,6 @@ public abstract class RoomUnitSubManager { this.roomUnitManager = roomUnitManager; this.room = roomUnitManager.getRoom(); } + + public abstract List cycle(); }