From a9ad0a03e162437a1add8244bd88a958e65fe8e1 Mon Sep 17 00:00:00 2001 From: Dank074 Date: Fri, 9 Oct 2020 16:16:54 -0500 Subject: [PATCH 1/6] added ping/pong timeout handlers --- .../eu/habbo/messages/incoming/Incoming.java | 1 + .../incoming/handshake/SecureLoginEvent.java | 4 +-- .../eu/habbo/messages/outgoing/Outgoing.java | 2 +- ...nectionComposer.java => PingComposer.java} | 4 +-- .../networking/gameserver/GameServer.java | 5 ++++ .../handlers/IdleTimeoutHandler.java | 29 +++++++++++++++++++ 6 files changed, 40 insertions(+), 5 deletions(-) rename src/main/java/com/eu/habbo/messages/outgoing/handshake/{SomeConnectionComposer.java => PingComposer.java} (70%) create mode 100644 src/main/java/com/eu/habbo/networking/gameserver/handlers/IdleTimeoutHandler.java diff --git a/src/main/java/com/eu/habbo/messages/incoming/Incoming.java b/src/main/java/com/eu/habbo/messages/incoming/Incoming.java index 53a76eeb..621a4775 100644 --- a/src/main/java/com/eu/habbo/messages/incoming/Incoming.java +++ b/src/main/java/com/eu/habbo/messages/incoming/Incoming.java @@ -1,6 +1,7 @@ package com.eu.habbo.messages.incoming; public class Incoming { + public static final int PongEvent = 2596; public static final int ChangeNameCheckUsernameEvent = 3950; public static final int ConfirmChangeNameEvent = 2977; public static final int ActivateEffectEvent = 2959; diff --git a/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java b/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java index 89ca6250..bd63c760 100644 --- a/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java +++ b/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java @@ -22,7 +22,7 @@ import com.eu.habbo.messages.outgoing.habboway.nux.NewUserIdentityComposer; import com.eu.habbo.messages.outgoing.handshake.DebugConsoleComposer; import com.eu.habbo.messages.outgoing.handshake.SecureLoginOKComposer; import com.eu.habbo.messages.outgoing.handshake.SessionRightsComposer; -import com.eu.habbo.messages.outgoing.handshake.SomeConnectionComposer; +import com.eu.habbo.messages.outgoing.handshake.PingComposer; import com.eu.habbo.messages.outgoing.inventory.InventoryAchievementsComposer; import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; import com.eu.habbo.messages.outgoing.inventory.UserEffectsListComposer; @@ -124,7 +124,7 @@ public class SecureLoginEvent extends MessageHandler { messages.add(new NewUserIdentityComposer(habbo).compose()); messages.add(new UserPermissionsComposer(this.client.getHabbo()).compose()); messages.add(new SessionRightsComposer().compose()); - messages.add(new SomeConnectionComposer().compose()); + messages.add(new PingComposer().compose()); messages.add(new DebugConsoleComposer(Emulator.debugging).compose()); messages.add(new UserAchievementScoreComposer(this.client.getHabbo()).compose()); messages.add(new IsFirstLoginOfDayComposer(true).compose()); diff --git a/src/main/java/com/eu/habbo/messages/outgoing/Outgoing.java b/src/main/java/com/eu/habbo/messages/outgoing/Outgoing.java index c6e299c0..e627c771 100644 --- a/src/main/java/com/eu/habbo/messages/outgoing/Outgoing.java +++ b/src/main/java/com/eu/habbo/messages/outgoing/Outgoing.java @@ -493,7 +493,7 @@ public class Outgoing { public final static int SimplePollAnswerComposer = 2589; - public final static int SomeConnectionComposer = 3928; + public final static int PingComposer = 3928; public final static int TradingWaitingConfirmComposer = 2720; public final static int BaseJumpJoinQueueComposer = 2260; public final static int ClubCenterDataComposer = 3277; diff --git a/src/main/java/com/eu/habbo/messages/outgoing/handshake/SomeConnectionComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/handshake/PingComposer.java similarity index 70% rename from src/main/java/com/eu/habbo/messages/outgoing/handshake/SomeConnectionComposer.java rename to src/main/java/com/eu/habbo/messages/outgoing/handshake/PingComposer.java index 5a1e6724..a8300686 100644 --- a/src/main/java/com/eu/habbo/messages/outgoing/handshake/SomeConnectionComposer.java +++ b/src/main/java/com/eu/habbo/messages/outgoing/handshake/PingComposer.java @@ -4,10 +4,10 @@ import com.eu.habbo.messages.ServerMessage; import com.eu.habbo.messages.outgoing.MessageComposer; import com.eu.habbo.messages.outgoing.Outgoing; -public class SomeConnectionComposer extends MessageComposer { +public class PingComposer extends MessageComposer { @Override protected ServerMessage composeInternal() { - this.response.init(Outgoing.SomeConnectionComposer); + this.response.init(Outgoing.PingComposer); return this.response; } } \ No newline at end of file diff --git a/src/main/java/com/eu/habbo/networking/gameserver/GameServer.java b/src/main/java/com/eu/habbo/networking/gameserver/GameServer.java index 90514484..3aa20998 100644 --- a/src/main/java/com/eu/habbo/networking/gameserver/GameServer.java +++ b/src/main/java/com/eu/habbo/networking/gameserver/GameServer.java @@ -7,9 +7,11 @@ import com.eu.habbo.networking.Server; import com.eu.habbo.networking.gameserver.decoders.*; import com.eu.habbo.networking.gameserver.encoders.GameServerMessageEncoder; import com.eu.habbo.networking.gameserver.encoders.GameServerMessageLogger; +import com.eu.habbo.networking.gameserver.handlers.IdleTimeoutHandler; import io.netty.channel.ChannelInitializer; import io.netty.channel.socket.SocketChannel; import io.netty.handler.logging.LoggingHandler; +import io.netty.handler.timeout.IdleStateHandler; public class GameServer extends Server { private final PacketManager packetManager; @@ -30,6 +32,9 @@ public class GameServer extends Server { public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast("logger", new LoggingHandler()); + ch.pipeline().addLast("idleStateHandler", new IdleStateHandler(60, 30, 0)); + ch.pipeline().addAfter("idleStateHandler", "idleEventHandler", new IdleTimeoutHandler()); + // Decoders. ch.pipeline().addLast(new GamePolicyDecoder()); ch.pipeline().addLast(new GameByteFrameDecoder()); diff --git a/src/main/java/com/eu/habbo/networking/gameserver/handlers/IdleTimeoutHandler.java b/src/main/java/com/eu/habbo/networking/gameserver/handlers/IdleTimeoutHandler.java new file mode 100644 index 00000000..46bb4c14 --- /dev/null +++ b/src/main/java/com/eu/habbo/networking/gameserver/handlers/IdleTimeoutHandler.java @@ -0,0 +1,29 @@ +package com.eu.habbo.networking.gameserver.handlers; + +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.messages.outgoing.handshake.PingComposer; +import com.eu.habbo.networking.gameserver.GameServerAttributes; +import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; + +public class IdleTimeoutHandler extends ChannelDuplexHandler { + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + if (evt instanceof IdleStateEvent) { + IdleStateEvent e = (IdleStateEvent) evt; + if (e.state() == IdleState.READER_IDLE) { + ctx.close(); + } else if (e.state() == IdleState.WRITER_IDLE) { + GameClient client = ctx.channel().attr(GameServerAttributes.CLIENT).get(); + if (client != null) { + client.sendResponse(new PingComposer()); + } + } + } else { + super.userEventTriggered(ctx, evt); + } + } + +} From e81743117600d128e7daa934fa4bcd4a03acb10a Mon Sep 17 00:00:00 2001 From: Beny Date: Tue, 13 Oct 2020 03:42:30 +0200 Subject: [PATCH 2/6] InteractionMuteArea implemented --- .../interactions/InteractionCustomValues.java | 5 + .../interactions/InteractionMuteArea.java | 114 +++++++++++++++++- .../com/eu/habbo/habbohotel/rooms/Room.java | 9 +- .../rooms/items/AdvertisingSaveEvent.java | 1 + .../com/eu/habbo/plugin/PluginManager.java | 1 + 5 files changed, 125 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCustomValues.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCustomValues.java index d25a3cc8..9ef005bc 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCustomValues.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCustomValues.java @@ -1,5 +1,6 @@ package com.eu.habbo.habbohotel.items.interactions; +import com.eu.habbo.habbohotel.gameclients.GameClient; import com.eu.habbo.habbohotel.items.Item; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.RoomUnit; @@ -78,4 +79,8 @@ public abstract class InteractionCustomValues extends HabboItem { super.serializeExtradata(serverMessage); } + + public void onCustomValuesSaved(Room room, GameClient client) { + + } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMuteArea.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMuteArea.java index fcc9522a..29a7c0ac 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMuteArea.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMuteArea.java @@ -1,8 +1,21 @@ package com.eu.habbo.habbohotel.items.interactions; +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomTileState; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.messages.outgoing.rooms.items.ItemExtraDataComposer; +import com.eu.habbo.messages.outgoing.rooms.items.RemoveFloorItemComposer; +import com.eu.habbo.messages.outgoing.rooms.items.RoomFloorItemsComposer; +import gnu.trove.TCollections; +import gnu.trove.map.TIntObjectMap; import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.set.hash.THashSet; import java.awt.*; import java.sql.ResultSet; @@ -25,25 +38,122 @@ public class InteractionMuteArea extends InteractionCustomValues { { this.put("tilesBack", "0"); } + + { + this.put("state", "0"); + } }; + private THashSet tiles; + public InteractionMuteArea(ResultSet set, Item baseItem) throws SQLException { super(set, baseItem, defaultValues); + tiles = new THashSet<>(); } public InteractionMuteArea(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { super(id, userId, item, extradata, limitedStack, limitedSells, defaultValues); + tiles = new THashSet<>(); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + + if((objects.length >= 2 && objects[1] instanceof WiredEffectType) || (client != null && room.hasRights(client.getHabbo()))) { + this.values.put("state", this.values.get("state").equals("0") ? "1" : "0"); + room.sendComposer(new ItemExtraDataComposer(this).compose()); + } + } + + @Override + public void onPlace(Room room) { + super.onPlace(room); + this.regenAffectedTiles(room); + } + + @Override + public void onPickUp(Room room) { + super.onPickUp(room); + this.tiles.clear(); + } + + @Override + public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + super.onMove(room, oldLocation, newLocation); + this.regenAffectedTiles(room); } public boolean inSquare(RoomTile location) { - try { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if(!this.values.get("state").equals("1")) + return false; + + if(room != null && this.tiles.size() == 0) { + regenAffectedTiles(room); + } + + return this.tiles.contains(location); + + /*try { return new Rectangle( - this.getX() - Integer.valueOf(this.values.get("tilesBack")), + this.getX() - Integer.parseInt(this.values.get("tilesBack")), this.getY() + Integer.valueOf(this.values.get("tilesLeft")) - (Integer.valueOf(this.values.get("tilesLeft")) + Integer.valueOf(this.values.get("tilesRight"))), Integer.valueOf(this.values.get("tilesLeft")) + Integer.valueOf(this.values.get("tilesRight")) + 1, Integer.valueOf(this.values.get("tilesFront")) + Integer.valueOf(this.values.get("tilesBack")) + 1).contains(location.x, location.y); } catch (Exception e) { return false; + }*/ + } + + private void regenAffectedTiles(Room room) { + int minX = Math.max(0, this.getX() - Integer.parseInt(this.values.get("tilesBack"))); + int minY = Math.max(0, this.getY() - Integer.parseInt(this.values.get("tilesRight"))); + int maxX = Math.min(room.getLayout().getMapSizeX(), this.getX() + Integer.parseInt(this.values.get("tilesFront"))); + int maxY = Math.min(room.getLayout().getMapSizeY(), this.getY() + Integer.parseInt(this.values.get("tilesLeft"))); + + this.tiles.clear(); + + for(int x = minX; x <= maxX; x++) { + for(int y = minY; y <= maxY; y++) { + RoomTile tile = room.getLayout().getTile((short)x, (short)y); + if(tile != null && tile.state != RoomTileState.INVALID) + this.tiles.add(tile); + } + } + } + + @Override + public void onCustomValuesSaved(Room room, GameClient client) { + super.onCustomValuesSaved(room, client); + + this.regenAffectedTiles(room); + + // show the effect + Item effectItem = Emulator.getGameEnvironment().getItemManager().getItem("mutearea_sign2"); + + if(effectItem != null) { + TIntObjectMap ownerNames = TCollections.synchronizedMap(new TIntObjectHashMap<>(0)); + ownerNames.put(-1, "System"); + THashSet items = new THashSet<>(); + + int id = 0; + for(RoomTile tile : this.tiles) { + id--; + HabboItem item = new InteractionDefault(id, -1, effectItem, "1", 0, 0); + item.setX(tile.x); + item.setY(tile.y); + item.setZ(tile.relativeHeight()); + items.add(item); + } + + client.sendResponse(new RoomFloorItemsComposer(ownerNames, items)); + Emulator.getThreading().run(() -> { + for(HabboItem item : items) { + client.sendResponse(new RemoveFloorItemComposer(item, true)); + } + }, 3000); } } } 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 29945fef..b6b9170e 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java @@ -115,6 +115,7 @@ public class Room implements Comparable, ISerialize, Runnable { public static int IDLE_CYCLES_KICK = 480; public static String PREFIX_FORMAT = "[%prefix%] "; public static int ROLLERS_MAXIMUM_ROLL_AVATARS = 1; + public static boolean MUTEAREA_CAN_WHISPER = false; static { for (int i = 1; i <= 3; i++) { @@ -3083,9 +3084,11 @@ public class Room implements Comparable, ISerialize, Runnable { if (roomChatMessage == null || roomChatMessage.getMessage() == null || roomChatMessage.getMessage().equals("")) return; - for (HabboItem area : this.getRoomSpecialTypes().getItemsOfType(InteractionMuteArea.class)) { - if (((InteractionMuteArea) area).inSquare(habbo.getRoomUnit().getCurrentLocation())) { - return; + if(!habbo.hasPermission(Permission.ACC_NOMUTE) && (!MUTEAREA_CAN_WHISPER || chatType != RoomChatType.WHISPER)) { + for (HabboItem area : this.getRoomSpecialTypes().getItemsOfType(InteractionMuteArea.class)) { + if (((InteractionMuteArea) area).inSquare(habbo.getRoomUnit().getCurrentLocation())) { + return; + } } } diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/AdvertisingSaveEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/AdvertisingSaveEvent.java index 6fb6b0b6..d705f8ff 100644 --- a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/AdvertisingSaveEvent.java +++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/AdvertisingSaveEvent.java @@ -42,6 +42,7 @@ public class AdvertisingSaveEvent extends MessageHandler { item.needsUpdate(true); Emulator.getThreading().run(item); room.updateItem(item); + ((InteractionCustomValues) item).onCustomValuesSaved(room, this.client); } } } diff --git a/src/main/java/com/eu/habbo/plugin/PluginManager.java b/src/main/java/com/eu/habbo/plugin/PluginManager.java index eff47754..a7d60270 100644 --- a/src/main/java/com/eu/habbo/plugin/PluginManager.java +++ b/src/main/java/com/eu/habbo/plugin/PluginManager.java @@ -82,6 +82,7 @@ public class PluginManager { PacketManager.DEBUG_SHOW_PACKETS = Emulator.getConfig().getBoolean("debug.show.packets"); PacketManager.MULTI_THREADED_PACKET_HANDLING = Emulator.getConfig().getBoolean("io.client.multithreaded.handler"); Room.HABBO_CHAT_DELAY = Emulator.getConfig().getBoolean("room.chat.delay", false); + Room.MUTEAREA_CAN_WHISPER = Emulator.getConfig().getBoolean("room.chat.mutearea.allow_whisper", false); RoomChatMessage.SAVE_ROOM_CHATS = Emulator.getConfig().getBoolean("save.room.chats", false); RoomLayout.MAXIMUM_STEP_HEIGHT = Emulator.getConfig().getDouble("pathfinder.step.maximum.height", 1.1); RoomLayout.ALLOW_FALLING = Emulator.getConfig().getBoolean("pathfinder.step.allow.falling", true); From 96ecbfa8c26b81309b57d4718b8cdfbd1bf0f20b Mon Sep 17 00:00:00 2001 From: Beny Date: Wed, 14 Oct 2020 06:26:24 +0200 Subject: [PATCH 3/6] Clothing Validation fixes #842 #841 --- .../ClothingValidationManager.java | 182 ++++++++++-------- .../clothingvalidation/FiguredataPalette.java | 2 +- 2 files changed, 107 insertions(+), 77 deletions(-) diff --git a/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/ClothingValidationManager.java b/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/ClothingValidationManager.java index ff4e2664..4e470658 100644 --- a/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/ClothingValidationManager.java +++ b/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/ClothingValidationManager.java @@ -2,6 +2,7 @@ package com.eu.habbo.habbohotel.users.clothingvalidation; import com.eu.habbo.habbohotel.users.Habbo; import gnu.trove.TIntCollection; +import gnu.trove.map.hash.THashMap; import gnu.trove.set.hash.TIntHashSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -97,87 +98,116 @@ public class ClothingValidationManager { String[] newLookParts = look.split(Pattern.quote(".")); ArrayList lookParts = new ArrayList<>(); + THashMap parts = new THashMap<>(); + + // add mandatory settypes for(String lookpart : newLookParts) { - if(lookpart.contains("-")) { - try { - String[] data = lookpart.split(Pattern.quote("-")); - if (data.length > 1) { - FiguredataSettype settype = FIGUREDATA.settypes.get(data[0]); - if (settype == null) { - throw new Exception("Set type " + data[0] + " does not exist"); - } - - FiguredataPalette palette = FIGUREDATA.palettes.get(settype.paletteId); - if (palette == null) { - throw new Exception("Palette " + settype.paletteId + " does not exist"); - } - - int setId; - FiguredataSettypeSet set; - - setId = Integer.parseInt(data[1]); - set = settype.getSet(setId); - if (set == null) - throw new Exception("Set " + setId + " does not exist in SetType"); - - if ((set.club && !isHC) || !set.selectable || (set.sellable && !ownedClothing.contains(set.id))) { - if(gender.equalsIgnoreCase("M") && !isHC && !settype.mandatoryMale0) - continue; - - if(gender.equalsIgnoreCase("F") && !isHC && !settype.mandatoryFemale0) - continue; - - if(gender.equalsIgnoreCase("M") && isHC && !settype.mandatoryMale1) - continue; - - if(gender.equalsIgnoreCase("F") && isHC && !settype.mandatoryFemale1) - continue; - - set = settype.getFirstNonHCSetForGender(gender); - setId = set.id; - } - - ArrayList dataParts = new ArrayList<>(); - - int color1 = -1; - int color2 = -1; - - if (data.length > 2 && set.colorable) { - color1 = Integer.parseInt(data[2]); - FiguredataPaletteColor color = palette.getColor(color1); - if (color == null || (color.club && !isHC)) { - color1 = palette.getFirstNonHCColor().id; - } - } - - if (data.length > 3 && set.colorable) { - color2 = Integer.parseInt(data[3]); - FiguredataPaletteColor color = palette.getColor(color2); - if (color == null || (color.club && !isHC)) { - color2 = palette.getFirstNonHCColor().id; - } - } - - dataParts.add(settype.type); - dataParts.add("" + setId); - - if (color1 > -1) { - dataParts.add("" + color1); - } - - if (color2 > -1) { - dataParts.add("" + color2); - } - - lookParts.add(String.join("-", dataParts)); - } - } - catch (Exception e) { - //habbo.alert(e.getMessage()); + if (lookpart.contains("-")) { + String[] data = lookpart.split(Pattern.quote("-")); + FiguredataSettype settype = FIGUREDATA.settypes.get(data[0]); + if(settype != null) { + parts.put(data[0], data); } } } + FIGUREDATA.settypes.entrySet().stream().filter(x -> !parts.containsKey(x.getKey())).forEach(x -> + { + FiguredataSettype settype = x.getValue(); + + if(gender.equalsIgnoreCase("M") && !isHC && !settype.mandatoryMale0) + return; + + if(gender.equalsIgnoreCase("F") && !isHC && !settype.mandatoryFemale0) + return; + + if(gender.equalsIgnoreCase("M") && isHC && !settype.mandatoryMale1) + return; + + if(gender.equalsIgnoreCase("F") && isHC && !settype.mandatoryFemale1) + return; + + parts.put(x.getKey(), new String[] { x.getKey() }); + }); + + + parts.forEach((key, data) -> { + try { + if (data.length >= 1) { + FiguredataSettype settype = FIGUREDATA.settypes.get(data[0]); + if (settype == null) { + //throw new Exception("Set type " + data[0] + " does not exist"); + return; + } + + FiguredataPalette palette = FIGUREDATA.palettes.get(settype.paletteId); + if (palette == null) { + throw new Exception("Palette " + settype.paletteId + " does not exist"); + } + + int setId; + FiguredataSettypeSet set; + + setId = Integer.parseInt(data.length >= 2 ? data[1] : "-1"); + set = settype.getSet(setId); + + if (set == null || (set.club && !isHC) || !set.selectable || (set.sellable && !ownedClothing.contains(set.id)) || (!set.gender.equalsIgnoreCase("U") && !set.gender.equalsIgnoreCase(gender))) { + if (gender.equalsIgnoreCase("M") && !isHC && !settype.mandatoryMale0) + return; + + if (gender.equalsIgnoreCase("F") && !isHC && !settype.mandatoryFemale0) + return; + + if (gender.equalsIgnoreCase("M") && isHC && !settype.mandatoryMale1) + return; + + if (gender.equalsIgnoreCase("F") && isHC && !settype.mandatoryFemale1) + return; + + set = settype.getFirstNonHCSetForGender(gender); + setId = set.id; + } + + ArrayList dataParts = new ArrayList<>(); + + int color1 = -1; + int color2 = -1; + + if (set.colorable) { + color1 = data.length >= 3 ? Integer.parseInt(data[2]) : -1; + FiguredataPaletteColor color = palette.getColor(color1); + if (color == null || (color.club && !isHC)) { + color1 = palette.getFirstNonHCColor().id; + } + } + + if (data.length >= 4 && set.colorable) { + color2 = Integer.parseInt(data[3]); + FiguredataPaletteColor color = palette.getColor(color2); + if (color == null || (color.club && !isHC)) { + color2 = palette.getFirstNonHCColor().id; + } + } + + dataParts.add(settype.type); + dataParts.add("" + setId); + + if (color1 > -1) { + dataParts.add("" + color1); + } + + if (color2 > -1) { + dataParts.add("" + color2); + } + + lookParts.add(String.join("-", dataParts)); + } + } catch (Exception e) { + //habbo.alert(e.getMessage()); + LOGGER.error("Error in clothing validation", e); + } + }); + return String.join(".", lookParts); } diff --git a/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataPalette.java b/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataPalette.java index 841fd5d4..4a1c48d5 100644 --- a/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataPalette.java +++ b/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataPalette.java @@ -20,7 +20,7 @@ public class FiguredataPalette { } public FiguredataPaletteColor getFirstNonHCColor() { - for(FiguredataPaletteColor color : this.colors.descendingMap().values()) { + for(FiguredataPaletteColor color : this.colors.values()) { if(!color.club && color.selectable) return color; } From 9e7abc9d4191854822f6fb090c98c13d90c6eea4 Mon Sep 17 00:00:00 2001 From: Beny Date: Wed, 14 Oct 2020 23:29:57 +0200 Subject: [PATCH 4/6] Bots can now be set a bubble. Closes #390 --- sqlupdates/2_4_0 to 2_5_0-RC-1.sql | 4 ++++ .../com/eu/habbo/habbohotel/bots/Bot.java | 19 ++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/sqlupdates/2_4_0 to 2_5_0-RC-1.sql b/sqlupdates/2_4_0 to 2_5_0-RC-1.sql index 5003f7fa..4fb7bc47 100644 --- a/sqlupdates/2_4_0 to 2_5_0-RC-1.sql +++ b/sqlupdates/2_4_0 to 2_5_0-RC-1.sql @@ -101,3 +101,7 @@ INSERT INTO `emulator_texts` (`key`, `value`) VALUES ('subscriptions.hc.payday.m -- OPTIONAL HC MIGRATION -- INSERT INTO users_subscriptions SELECT NULL, user_id, 'HABBO_CLUB' as `subscription_type`, UNIX_TIMESTAMP() AS `timestamp_start`, (club_expire_timestamp - UNIX_TIMESTAMP()) AS `duration`, 1 AS `active` FROM users_settings WHERE club_expire_timestamp > UNIX_TIMESTAMP(); + +ALTER TABLE `bots` +ADD COLUMN `bubble_id` int(3) NULL DEFAULT 31 AFTER `effect`; + 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 8cedc5ff..611d54cf 100644 --- a/src/main/java/com/eu/habbo/habbohotel/bots/Bot.java +++ b/src/main/java/com/eu/habbo/habbohotel/bots/Bot.java @@ -44,6 +44,7 @@ public class Bot implements Runnable { private int chatTimeOut; private int chatTimestamp; private short lastChatIndex; + private int bubble; private String type; @@ -73,6 +74,7 @@ public class Bot implements Runnable { this.chatLines = new ArrayList<>(); this.type = "generic_bot"; this.room = null; + this.bubble = RoomChatMessageBubbles.BOT_RENTABLE.getType(); } public Bot(ResultSet set) throws SQLException { @@ -94,6 +96,7 @@ public class Bot implements Runnable { this.roomUnit = null; this.chatTimeOut = Emulator.getIntUnixTimestamp() + this.chatDelay; this.needsUpdate = false; + this.bubble = set.getInt("bubble_id"); } public Bot(Bot bot) { @@ -110,6 +113,7 @@ public class Bot implements Runnable { this.chatLines = new ArrayList<>(Arrays.asList("Default Message :D")); this.type = bot.getType(); this.effect = bot.getEffect(); + this.bubble = bot.getBubbleId(); this.needsUpdate = false; } @@ -133,7 +137,7 @@ public class Bot implements Runnable { @Override public void run() { if (this.needsUpdate) { - try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE bots SET name = ?, motto = ?, figure = ?, gender = ?, user_id = ?, room_id = ?, x = ?, y = ?, z = ?, rot = ?, dance = ?, freeroam = ?, chat_lines = ?, chat_auto = ?, chat_random = ?, chat_delay = ?, effect = ? WHERE id = ?")) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE bots SET name = ?, motto = ?, figure = ?, gender = ?, user_id = ?, room_id = ?, x = ?, y = ?, z = ?, rot = ?, dance = ?, freeroam = ?, chat_lines = ?, chat_auto = ?, chat_random = ?, chat_delay = ?, effect = ?, bubble = ? WHERE id = ?")) { statement.setString(1, this.name); statement.setString(2, this.motto); statement.setString(3, this.figure); @@ -155,7 +159,8 @@ public class Bot implements Runnable { statement.setString(15, this.chatRandom ? "1" : "0"); statement.setInt(16, this.chatDelay); statement.setInt(17, this.effect); - statement.setInt(18, this.id); + statement.setInt(18, this.bubble); + statement.setInt(19, this.id); statement.execute(); this.needsUpdate = false; } catch (SQLException e) { @@ -208,7 +213,7 @@ public class Bot implements Runnable { return; this.chatTimestamp = Emulator.getIntUnixTimestamp(); - this.room.botChat(new RoomUserTalkComposer(new RoomChatMessage(event.message, this.roomUnit, RoomChatMessageBubbles.BOT_RENTABLE)).compose()); + this.room.botChat(new RoomUserTalkComposer(new RoomChatMessage(event.message, this.roomUnit, RoomChatMessageBubbles.getBubble(this.getBubbleId()))).compose()); if (message.equals("o/") || message.equals("_o/")) { this.room.sendComposer(new RoomUserActionComposer(this.roomUnit, RoomUserAction.WAVE).compose()); @@ -223,7 +228,7 @@ public class Bot implements Runnable { return; this.chatTimestamp = Emulator.getIntUnixTimestamp(); - this.room.botChat(new RoomUserShoutComposer(new RoomChatMessage(event.message, this.roomUnit, RoomChatMessageBubbles.BOT_RENTABLE)).compose()); + this.room.botChat(new RoomUserShoutComposer(new RoomChatMessage(event.message, this.roomUnit, RoomChatMessageBubbles.getBubble(this.getBubbleId()))).compose()); if (message.equals("o/") || message.equals("_o/")) { this.room.sendComposer(new RoomUserActionComposer(this.roomUnit, RoomUserAction.WAVE).compose()); @@ -238,7 +243,7 @@ public class Bot implements Runnable { return; this.chatTimestamp = Emulator.getIntUnixTimestamp(); - event.target.getClient().sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(event.message, this.roomUnit, RoomChatMessageBubbles.BOT_RENTABLE))); + event.target.getClient().sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(event.message, this.roomUnit, RoomChatMessageBubbles.getBubble(this.getBubbleId())))); } } @@ -270,6 +275,10 @@ public class Bot implements Runnable { return this.name; } + public int getBubbleId() { + return bubble; + } + public void setName(String name) { this.name = name; this.needsUpdate = true; From afec2d2d0d25cb3619b5738384e676dd37a6e53c Mon Sep 17 00:00:00 2001 From: Beny Date: Wed, 14 Oct 2020 23:43:11 +0200 Subject: [PATCH 5/6] Fix unable to buy group with large days of HC left. Closes #845 --- .../eu/habbo/messages/incoming/guilds/RequestGuildBuyEvent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildBuyEvent.java b/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildBuyEvent.java index 4913c027..574987fa 100644 --- a/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildBuyEvent.java +++ b/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildBuyEvent.java @@ -27,7 +27,7 @@ public class RequestGuildBuyEvent extends MessageHandler { if(name.length() > 29 || description.length() > 254) return; - if (Emulator.getConfig().getBoolean("catalog.guild.hc_required", true) && this.client.getHabbo().getHabboStats().getClubExpireTimestamp() < Emulator.getIntUnixTimestamp()) { + if (Emulator.getConfig().getBoolean("catalog.guild.hc_required", true) && !this.client.getHabbo().getHabboStats().hasActiveClub()) { this.client.sendResponse(new GuildEditFailComposer(GuildEditFailComposer.HC_REQUIRED)); return; } From b7b81e8af978a9794ff4ed1b74b77d4a7cd20eee Mon Sep 17 00:00:00 2001 From: Beny Date: Thu, 15 Oct 2020 00:27:53 +0200 Subject: [PATCH 6/6] Typo --- src/main/java/com/eu/habbo/habbohotel/bots/Bot.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 611d54cf..674f5019 100644 --- a/src/main/java/com/eu/habbo/habbohotel/bots/Bot.java +++ b/src/main/java/com/eu/habbo/habbohotel/bots/Bot.java @@ -137,7 +137,7 @@ public class Bot implements Runnable { @Override public void run() { if (this.needsUpdate) { - try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE bots SET name = ?, motto = ?, figure = ?, gender = ?, user_id = ?, room_id = ?, x = ?, y = ?, z = ?, rot = ?, dance = ?, freeroam = ?, chat_lines = ?, chat_auto = ?, chat_random = ?, chat_delay = ?, effect = ?, bubble = ? WHERE id = ?")) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE bots SET name = ?, motto = ?, figure = ?, gender = ?, user_id = ?, room_id = ?, x = ?, y = ?, z = ?, rot = ?, dance = ?, freeroam = ?, chat_lines = ?, chat_auto = ?, chat_random = ?, chat_delay = ?, effect = ?, bubble_id = ? WHERE id = ?")) { statement.setString(1, this.name); statement.setString(2, this.motto); statement.setString(3, this.figure);