From b017953b911378cf624755bfafba769139ac48c6 Mon Sep 17 00:00:00 2001 From: duckietm Date: Wed, 13 Mar 2024 11:28:48 +0100 Subject: [PATCH] Uploading Emulator --- Emulator/.gitignore | 17 + Emulator/.gitlab-ci.yml | 18 + Emulator/.gitmodules | 3 + Emulator/Dockerfile | 19 + Emulator/Example_Start/Linux/emulator | 2 + Emulator/Example_Start/Windows/emulator.cmd | 1 + Emulator/LICENSE | 165 + Emulator/featurelist.md | 208 + Emulator/pom.xml | 200 + .../src/main/java/com/eu/habbo/Emulator.java | 527 ++ .../java/com/eu/habbo/core/CleanerThread.java | 160 + .../java/com/eu/habbo/core/CommandLog.java | 41 + .../eu/habbo/core/ConfigurationManager.java | 226 + .../com/eu/habbo/core/CreditsScheduler.java | 66 + .../java/com/eu/habbo/core/CryptoConfig.java | 33 + .../com/eu/habbo/core/DatabaseLoggable.java | 12 + .../com/eu/habbo/core/DatabaseLogger.java | 25 + .../java/com/eu/habbo/core/Disposable.java | 7 + .../main/java/com/eu/habbo/core/Easter.java | 25 + .../main/java/com/eu/habbo/core/ErrorLog.java | 63 + .../eu/habbo/core/GotwPointsScheduler.java | 79 + .../main/java/com/eu/habbo/core/Logging.java | 63 + .../com/eu/habbo/core/PixelScheduler.java | 63 + .../com/eu/habbo/core/PointsScheduler.java | 66 + .../eu/habbo/core/RoomUserPetComposer.java | 49 + .../java/com/eu/habbo/core/Scheduler.java | 36 + .../java/com/eu/habbo/core/TextsManager.java | 97 + .../core/consolecommands/ConsoleCommand.java | 62 + .../consolecommands/ConsoleInfoCommand.java | 40 + .../ConsoleReconnectCameraCommand.java | 17 + .../ConsoleShutdownCommand.java | 14 + .../consolecommands/ConsoleTestCommand.java | 22 + .../ShowInteractionsCommand.java | 19 + .../consolecommands/ShowRCONCommands.java | 19 + .../ThankyouArcturusCommand.java | 42 + .../eu/habbo/crypto/HabboDiffieHellman.java | 108 + .../com/eu/habbo/crypto/HabboEncryption.java | 21 + .../java/com/eu/habbo/crypto/HabboRC4.java | 46 + .../com/eu/habbo/crypto/HabboRSACrypto.java | 168 + .../exceptions/HabboCryptoException.java | 17 + .../habbo/crypto/utils/BigIntegerUtils.java | 17 + .../java/com/eu/habbo/database/Database.java | 109 + .../com/eu/habbo/database/DatabasePool.java | 60 + .../eu/habbo/habbohotel/GameEnvironment.java | 212 + .../eu/habbo/habbohotel/LatencyTracker.java | 47 + .../habbohotel/achievements/Achievement.java | 77 + .../achievements/AchievementCategories.java | 39 + .../achievements/AchievementLevel.java | 29 + .../achievements/AchievementManager.java | 394 ++ .../achievements/TalentTrackLevel.java | 64 + .../achievements/TalentTrackType.java | 9 + .../com/eu/habbo/habbohotel/bots/Bot.java | 485 ++ .../eu/habbo/habbohotel/bots/BotManager.java | 242 + .../eu/habbo/habbohotel/bots/ButlerBot.java | 142 + .../eu/habbo/habbohotel/bots/VisitorBot.java | 70 + .../campaign/calendar/CalendarCampaign.java | 64 + .../campaign/calendar/CalendarManager.java | 151 + .../calendar/CalendarRewardClaimed.java | 50 + .../calendar/CalendarRewardObject.java | 132 + .../catalog/CatalogFeaturedPage.java | 58 + .../habbo/habbohotel/catalog/CatalogItem.java | 354 ++ .../catalog/CatalogLimitedConfiguration.java | 106 + .../habbohotel/catalog/CatalogManager.java | 1191 +++++ .../habbo/habbohotel/catalog/CatalogPage.java | 206 + .../catalog/CatalogPageLayouts.java | 47 + .../habbohotel/catalog/CatalogPageType.java | 9 + .../catalog/CatalogPurchaseLogEntry.java | 61 + .../habbo/habbohotel/catalog/ClothItem.java | 26 + .../habbo/habbohotel/catalog/ClubOffer.java | 122 + .../habbo/habbohotel/catalog/TargetOffer.java | 116 + .../eu/habbo/habbohotel/catalog/Voucher.java | 75 + .../catalog/VoucherHistoryEntry.java | 34 + .../catalog/layouts/BadgeDisplayLayout.java | 27 + .../catalog/layouts/BotsLayout.java | 26 + .../layouts/BuildersClubAddonsLayout.java | 27 + .../layouts/BuildersClubFrontPageLayout.java | 27 + .../layouts/BuildersClubLoyaltyLayout.java | 27 + .../catalog/layouts/CatalogRootLayout.java | 44 + .../catalog/layouts/ClubBuyLayout.java | 22 + .../catalog/layouts/ClubGiftsLayout.java | 22 + .../catalog/layouts/ColorGroupingLayout.java | 26 + .../catalog/layouts/Default_3x3Layout.java | 27 + .../layouts/FrontPageFeaturedLayout.java | 75 + .../catalog/layouts/FrontpageLayout.java | 26 + .../catalog/layouts/GuildForumLayout.java | 25 + .../catalog/layouts/GuildFrontpageLayout.java | 25 + .../catalog/layouts/GuildFurnitureLayout.java | 25 + .../catalog/layouts/InfoDucketsLayout.java | 23 + .../catalog/layouts/InfoLoyaltyLayout.java | 23 + .../catalog/layouts/InfoMonkeyLayout.java | 27 + .../catalog/layouts/InfoNikoLayout.java | 27 + .../catalog/layouts/InfoPetsLayout.java | 26 + .../catalog/layouts/InfoRentablesLayout.java | 26 + .../catalog/layouts/LoyaltyVipBuyLayout.java | 26 + .../catalog/layouts/MadMoneyLayout.java | 27 + .../catalog/layouts/MarketplaceLayout.java | 20 + .../catalog/layouts/MarketplaceOwnItems.java | 21 + .../layouts/PetCustomizationLayout.java | 26 + .../catalog/layouts/Pets2Layout.java | 26 + .../catalog/layouts/Pets3Layout.java | 26 + .../catalog/layouts/PetsLayout.java | 26 + .../catalog/layouts/ProductPage1Layout.java | 26 + .../layouts/RecentPurchasesLayout.java | 26 + .../catalog/layouts/RecyclerInfoLayout.java | 26 + .../catalog/layouts/RecyclerLayout.java | 25 + .../catalog/layouts/RecyclerPrizesLayout.java | 26 + .../catalog/layouts/RoomAdsLayout.java | 24 + .../catalog/layouts/RoomBundleLayout.java | 246 + .../catalog/layouts/SingleBundle.java | 27 + .../catalog/layouts/SoldLTDItemsLayout.java | 23 + .../catalog/layouts/SpacesLayout.java | 27 + .../catalog/layouts/TraxLayout.java | 24 + .../catalog/layouts/TrophiesLayout.java | 27 + .../catalog/layouts/VipBuyLayout.java | 26 + .../catalog/marketplace/MarketPlace.java | 400 ++ .../catalog/marketplace/MarketPlaceOffer.java | 168 + .../catalog/marketplace/MarketPlaceState.java | 36 + .../habbohotel/commands/AboutCommand.java | 55 + .../commands/AddYoutubePlaylistCommand.java | 62 + .../habbohotel/commands/AlertCommand.java | 42 + .../commands/AllowTradingCommand.java | 69 + .../habbohotel/commands/ArcturusCommand.java | 25 + .../habbohotel/commands/BadgeCommand.java | 85 + .../habbo/habbohotel/commands/BanCommand.java | 80 + .../commands/BlockAlertCommand.java | 23 + .../habbohotel/commands/BotsCommand.java | 30 + .../habbohotel/commands/CalendarCommand.java | 38 + .../commands/ChangeNameCommand.java | 18 + .../habbohotel/commands/ChatTypeCommand.java | 54 + .../eu/habbo/habbohotel/commands/Command.java | 19 + .../habbohotel/commands/CommandHandler.java | 311 ++ .../habbohotel/commands/CommandsCommand.java | 27 + .../commands/ConnectCameraCommand.java | 15 + .../habbohotel/commands/ControlCommand.java | 53 + .../habbohotel/commands/CoordsCommand.java | 50 + .../habbohotel/commands/CreditsCommand.java | 56 + .../habbohotel/commands/DiagonalCommand.java | 30 + .../commands/DisconnectCommand.java | 42 + .../habbohotel/commands/EjectAllCommand.java | 25 + .../commands/EmptyBotsInventoryCommand.java | 57 + .../commands/EmptyInventoryCommand.java | 56 + .../commands/EmptyPetsInventoryCommand.java | 57 + .../habbohotel/commands/EnableCommand.java | 52 + .../habbohotel/commands/EventCommand.java | 52 + .../habbohotel/commands/FacelessCommand.java | 46 + .../habbohotel/commands/FastwalkCommand.java | 37 + .../commands/FilterWordCommand.java | 49 + .../commands/FreezeBotsCommand.java | 28 + .../habbohotel/commands/FreezeCommand.java | 39 + .../habbohotel/commands/GiftCommand.java | 90 + .../habbohotel/commands/GiveRankCommand.java | 66 + .../habbohotel/commands/HabnamCommand.java | 21 + .../habbohotel/commands/HandItemCommand.java | 27 + .../habbohotel/commands/HappyHourCommand.java | 26 + .../habbohotel/commands/HideWiredCommand.java | 27 + .../commands/HotelAlertCommand.java | 40 + .../commands/HotelAlertLinkCommand.java | 30 + .../habbohotel/commands/IPBanCommand.java | 70 + .../habbohotel/commands/InvisibleCommand.java | 50 + .../habbo/habbohotel/commands/LayCommand.java | 41 + .../commands/MachineBanCommand.java | 61 + .../habbohotel/commands/MassBadgeCommand.java | 57 + .../commands/MassCreditsCommand.java | 42 + .../habbohotel/commands/MassGiftCommand.java | 86 + .../commands/MassPixelsCommand.java | 42 + .../commands/MassPointsCommand.java | 72 + .../habbohotel/commands/MimicCommand.java | 48 + .../habbohotel/commands/MoonwalkCommand.java | 25 + .../habbohotel/commands/MultiCommand.java | 17 + .../habbohotel/commands/MuteBotsCommand.java | 18 + .../habbohotel/commands/MuteCommand.java | 57 + .../habbohotel/commands/MutePetsCommand.java | 18 + .../habbohotel/commands/PetInfoCommand.java | 53 + .../habbohotel/commands/PickallCommand.java | 27 + .../habbohotel/commands/PingCommand.java | 29 + .../habbohotel/commands/PixelCommand.java | 43 + .../habbohotel/commands/PluginsCommand.java | 32 + .../habbohotel/commands/PointsCommand.java | 66 + .../commands/PromoteTargetOfferCommand.java | 73 + .../habbohotel/commands/PullCommand.java | 53 + .../habbohotel/commands/PushCommand.java | 54 + .../habbohotel/commands/RedeemCommand.java | 106 + .../commands/ReloadRoomCommand.java | 35 + .../habbohotel/commands/RoomAlertCommand.java | 38 + .../habbohotel/commands/RoomBadgeCommand.java | 54 + .../commands/RoomBundleCommand.java | 77 + .../commands/RoomCreditsCommand.java | 37 + .../habbohotel/commands/RoomDanceCommand.java | 42 + .../commands/RoomEffectCommand.java | 40 + .../habbohotel/commands/RoomGiftCommand.java | 71 + .../habbohotel/commands/RoomItemCommand.java | 45 + .../habbohotel/commands/RoomKickCommand.java | 35 + .../habbohotel/commands/RoomMuteCommand.java | 24 + .../commands/RoomPixelsCommand.java | 37 + .../commands/RoomPointsCommand.java | 65 + .../habbohotel/commands/SayAllCommand.java | 31 + .../habbo/habbohotel/commands/SayCommand.java | 45 + .../habbohotel/commands/SetMaxCommand.java | 35 + .../habbohotel/commands/SetPollCommand.java | 40 + .../habbohotel/commands/SetSpeedCommand.java | 42 + .../habbohotel/commands/ShoutAllCommand.java | 31 + .../habbohotel/commands/ShoutCommand.java | 47 + .../habbohotel/commands/ShutdownCommand.java | 50 + .../habbo/habbohotel/commands/SitCommand.java | 17 + .../habbohotel/commands/SitDownCommand.java | 27 + .../habbohotel/commands/SoftKickCommand.java | 41 + .../commands/StaffAlertCommand.java | 30 + .../commands/StaffOnlineCommand.java | 68 + .../habbohotel/commands/StalkCommand.java | 55 + .../habbohotel/commands/StandCommand.java | 18 + .../commands/SubscriptionCommand.java | 109 + .../habbohotel/commands/SummonCommand.java | 61 + .../commands/SummonRankCommand.java | 56 + .../habbohotel/commands/SuperPullCommand.java | 45 + .../habbohotel/commands/SuperbanCommand.java | 59 + .../habbohotel/commands/TakeBadgeCommand.java | 68 + .../habbohotel/commands/TeleportCommand.java | 26 + .../habbohotel/commands/TestCommand.java | 46 + .../habbohotel/commands/TransformCommand.java | 69 + .../habbohotel/commands/TrashCommand.java | 16 + .../habbohotel/commands/UnbanCommand.java | 26 + .../commands/UnloadRoomCommand.java | 23 + .../habbohotel/commands/UnmuteCommand.java | 44 + .../commands/UpdateAchievements.java | 18 + .../commands/UpdateBotsCommand.java | 15 + .../commands/UpdateCalendarCommand.java | 21 + .../commands/UpdateCatalogCommand.java | 28 + .../commands/UpdateConfigCommand.java | 20 + .../commands/UpdateGuildPartsCommand.java | 17 + .../commands/UpdateHotelViewCommand.java | 20 + .../commands/UpdateItemsCommand.java | 32 + .../commands/UpdateNavigatorCommand.java | 21 + .../commands/UpdatePermissionsCommand.java | 20 + .../commands/UpdatePetDataCommand.java | 20 + .../commands/UpdatePluginsCommand.java | 20 + .../commands/UpdatePollsCommand.java | 18 + .../commands/UpdateTextsCommand.java | 24 + .../commands/UpdateWordFilterCommand.java | 20 + .../UpdateYoutubePlaylistsCommand.java | 22 + .../habbohotel/commands/UserInfoCommand.java | 108 + .../habbohotel/commands/WordQuizCommand.java | 38 + .../habbohotel/crafting/CraftingAltar.java | 133 + .../habbohotel/crafting/CraftingManager.java | 122 + .../habbohotel/crafting/CraftingRecipe.java | 88 + .../habbohotel/gameclients/GameClient.java | 135 + .../gameclients/GameClientManager.java | 165 + .../com/eu/habbo/habbohotel/games/Game.java | 304 ++ .../eu/habbo/habbohotel/games/GamePlayer.java | 65 + .../eu/habbo/habbohotel/games/GameState.java | 7 + .../eu/habbo/habbohotel/games/GameTeam.java | 120 + .../habbohotel/games/GameTeamColors.java | 39 + .../games/battlebanzai/BattleBanzaiGame.java | 413 ++ .../battlebanzai/BattleBanzaiGamePlayer.java | 11 + .../battlebanzai/BattleBanzaiGameTeam.java | 38 + .../games/football/FootballGame.java | 52 + .../habbohotel/games/freeze/FreezeGame.java | 336 ++ .../games/freeze/FreezeGamePlayer.java | 218 + .../games/freeze/FreezeGameTeam.java | 40 + .../habbohotel/games/tag/BunnyrunGame.java | 37 + .../habbohotel/games/tag/IceTagGame.java | 41 + .../habbohotel/games/tag/RollerskateGame.java | 36 + .../habbo/habbohotel/games/tag/TagGame.java | 199 + .../habbohotel/games/tag/TagGamePlayer.java | 12 + .../habbohotel/games/wired/WiredGame.java | 50 + .../habbohotel/guides/GuardianTicket.java | 261 + .../habbo/habbohotel/guides/GuardianVote.java | 35 + .../habbohotel/guides/GuardianVoteType.java | 22 + .../habbohotel/guides/GuideChatMessage.java | 13 + .../habbo/habbohotel/guides/GuideManager.java | 388 ++ .../guides/GuideRecommendStatus.java | 7 + .../eu/habbo/habbohotel/guides/GuideTour.java | 96 + .../com/eu/habbo/habbohotel/guilds/Guild.java | 276 + .../habbo/habbohotel/guilds/GuildManager.java | 645 +++ .../habbo/habbohotel/guilds/GuildMember.java | 73 + .../guilds/GuildMembershipStatus.java | 17 + .../eu/habbo/habbohotel/guilds/GuildPart.java | 21 + .../habbohotel/guilds/GuildPartType.java | 14 + .../eu/habbo/habbohotel/guilds/GuildRank.java | 23 + .../habbo/habbohotel/guilds/GuildState.java | 23 + .../habbohotel/guilds/SettingsState.java | 32 + .../habbohotel/guilds/forums/ForumThread.java | 468 ++ .../guilds/forums/ForumThreadComment.java | 206 + .../guilds/forums/ForumThreadState.java | 28 + .../habbohotel/guilds/forums/ForumView.java | 34 + .../habbohotel/hotelview/HallOfFame.java | 47 + .../hotelview/HallOfFameWinner.java | 50 + .../hotelview/HotelViewManager.java | 30 + .../habbo/habbohotel/hotelview/NewsList.java | 38 + .../habbohotel/hotelview/NewsWidget.java | 72 + .../habbohotel/items/CrackableReward.java | 77 + .../habbo/habbohotel/items/FurnitureType.java | 39 + .../eu/habbo/habbohotel/items/ICycleable.java | 7 + .../habbohotel/items/IEventTriggers.java | 13 + .../com/eu/habbo/habbohotel/items/Item.java | 263 + .../habbohotel/items/ItemInteraction.java | 24 + .../habbo/habbohotel/items/ItemManager.java | 787 +++ .../habbo/habbohotel/items/NewUserGift.java | 82 + .../habbo/habbohotel/items/PostItColor.java | 55 + .../habbohotel/items/RandomStateParams.java | 41 + .../items/RedeemableSubscriptionType.java | 25 + .../eu/habbo/habbohotel/items/SoundTrack.java | 46 + .../habbohotel/items/YoutubeManager.java | 230 + .../InteractionBackgroundToner.java | 111 + .../interactions/InteractionBadgeDisplay.java | 70 + .../interactions/InteractionBlackHole.java | 46 + .../interactions/InteractionBuildArea.java | 253 + .../items/interactions/InteractionCannon.java | 105 + .../interactions/InteractionClothing.java | 44 + .../interactions/InteractionColorPlate.java | 60 + .../interactions/InteractionColorWheel.java | 78 + .../InteractionCostumeHopper.java | 28 + .../interactions/InteractionCrackable.java | 183 + .../InteractionCrackableMaster.java | 31 + .../interactions/InteractionCustomValues.java | 86 + .../interactions/InteractionDefault.java | 212 + .../items/interactions/InteractionDice.java | 89 + .../interactions/InteractionEffectGate.java | 85 + .../interactions/InteractionEffectGiver.java | 53 + .../interactions/InteractionEffectTile.java | 81 + .../interactions/InteractionEffectToggle.java | 37 + .../InteractionEffectVendingMachine.java | 35 + ...nteractionEffectVendingMachineNoSides.java | 43 + .../InteractionExternalImage.java | 50 + .../items/interactions/InteractionFXBox.java | 67 + .../interactions/InteractionFireworks.java | 138 + .../items/interactions/InteractionGate.java | 87 + .../items/interactions/InteractionGift.java | 139 + .../InteractionGroupEffectTile.java | 21 + .../InteractionGroupPressurePlate.java | 21 + .../interactions/InteractionGuildFurni.java | 85 + .../interactions/InteractionGuildGate.java | 70 + .../interactions/InteractionGymEquipment.java | 158 + .../InteractionHabboClubGate.java | 76 + .../InteractionHabboClubHopper.java | 34 + .../InteractionHabboClubTeleportTile.java | 36 + .../interactions/InteractionHanditem.java | 51 + .../interactions/InteractionHanditemTile.java | 29 + .../items/interactions/InteractionHopper.java | 103 + .../InteractionInformationTerminal.java | 37 + .../interactions/InteractionJukeBox.java | 75 + .../interactions/InteractionLoveLock.java | 122 + .../interactions/InteractionMannequin.java | 120 + .../InteractionMonsterCrackable.java | 69 + .../interactions/InteractionMoodLight.java | 66 + .../interactions/InteractionMultiHeight.java | 163 + .../interactions/InteractionMusicDisc.java | 83 + .../interactions/InteractionMuteArea.java | 158 + .../InteractionNoSidesVendingMachine.java | 36 + .../interactions/InteractionObstacle.java | 143 + .../interactions/InteractionOneWayGate.java | 165 + .../items/interactions/InteractionPostIt.java | 45 + .../items/interactions/InteractionPoster.java | 43 + .../InteractionPressurePlate.java | 112 + .../interactions/InteractionPushable.java | 162 + .../interactions/InteractionPuzzleBox.java | 98 + .../interactions/InteractionPyramid.java | 51 + .../interactions/InteractionRandomState.java | 42 + .../InteractionRedeemableSubscriptionBox.java | 20 + .../InteractionRentableSpace.java | 265 + .../items/interactions/InteractionRoller.java | 87 + .../interactions/InteractionRoomAds.java | 51 + .../interactions/InteractionRoomOMatic.java | 26 + .../InteractionSnowboardSlope.java | 87 + .../interactions/InteractionStackHelper.java | 48 + .../interactions/InteractionStickyPole.java | 16 + .../items/interactions/InteractionSwitch.java | 71 + .../InteractionTalkingFurniture.java | 16 + .../interactions/InteractionTeleport.java | 235 + .../interactions/InteractionTeleportTile.java | 46 + .../items/interactions/InteractionTent.java | 23 + .../InteractionTileEffectProvider.java | 58 + .../items/interactions/InteractionTrap.java | 71 + .../items/interactions/InteractionTrophy.java | 21 + .../InteractionVendingMachine.java | 193 + .../interactions/InteractionVikingCotie.java | 48 + .../interactions/InteractionVoteCounter.java | 106 + .../items/interactions/InteractionWater.java | 298 ++ .../interactions/InteractionWaterItem.java | 94 + .../items/interactions/InteractionWired.java | 132 + .../InteractionWiredCondition.java | 52 + .../interactions/InteractionWiredEffect.java | 62 + .../interactions/InteractionWiredExtra.java | 38 + .../InteractionWiredHighscore.java | 149 + .../interactions/InteractionWiredTrigger.java | 61 + .../interactions/InteractionYoutubeTV.java | 96 + .../games/InteractionGameGate.java | 55 + .../games/InteractionGameScoreboard.java | 34 + .../games/InteractionGameTeamItem.java | 24 + .../games/InteractionGameTimer.java | 349 ++ .../InteractionBattleBanzaiPuck.java | 186 + .../InteractionBattleBanzaiSphere.java | 44 + .../InteractionBattleBanzaiTeleporter.java | 76 + .../InteractionBattleBanzaiTile.java | 121 + .../gates/InteractionBattleBanzaiGate.java | 69 + .../InteractionBattleBanzaiGateBlue.java | 19 + .../InteractionBattleBanzaiGateGreen.java | 19 + .../gates/InteractionBattleBanzaiGateRed.java | 19 + .../InteractionBattleBanzaiGateYellow.java | 19 + .../InteractionBattleBanzaiScoreboard.java | 35 + ...InteractionBattleBanzaiScoreboardBlue.java | 19 + ...nteractionBattleBanzaiScoreboardGreen.java | 19 + .../InteractionBattleBanzaiScoreboardRed.java | 19 + ...teractionBattleBanzaiScoreboardYellow.java | 19 + .../games/football/InteractionFootball.java | 259 + .../football/InteractionFootballGate.java | 148 + .../goals/InteractionFootballGoal.java | 44 + .../goals/InteractionFootballGoalBlue.java | 17 + .../goals/InteractionFootballGoalGreen.java | 17 + .../goals/InteractionFootballGoalRed.java | 17 + .../goals/InteractionFootballGoalYellow.java | 17 + .../InteractionFootballScoreboard.java | 137 + .../InteractionFootballScoreboardBlue.java | 17 + .../InteractionFootballScoreboardGreen.java | 17 + .../InteractionFootballScoreboardRed.java | 17 + .../InteractionFootballScoreboardYellow.java | 17 + .../games/freeze/InteractionFreezeBlock.java | 129 + .../freeze/InteractionFreezeExitTile.java | 50 + .../games/freeze/InteractionFreezeTile.java | 84 + .../freeze/gates/InteractionFreezeGate.java | 67 + .../gates/InteractionFreezeGateBlue.java | 19 + .../gates/InteractionFreezeGateGreen.java | 19 + .../gates/InteractionFreezeGateRed.java | 19 + .../gates/InteractionFreezeGateYellow.java | 19 + .../InteractionFreezeScoreboard.java | 35 + .../InteractionFreezeScoreboardBlue.java | 19 + .../InteractionFreezeScoreboardGreen.java | 19 + .../InteractionFreezeScoreboardRed.java | 19 + .../InteractionFreezeScoreboardYellow.java | 19 + .../games/tag/InteractionTagField.java | 82 + .../games/tag/InteractionTagPole.java | 48 + .../bunnyrun/InteractionBunnyrunField.java | 34 + .../tag/bunnyrun/InteractionBunnyrunPole.java | 17 + .../tag/icetag/InteractionIceTagField.java | 58 + .../tag/icetag/InteractionIceTagPole.java | 17 + .../InteractionRollerskateField.java | 57 + .../interfaces/ConditionalGate.java | 8 + .../pets/InteractionMonsterPlantSeed.java | 85 + .../interactions/pets/InteractionNest.java | 85 + .../pets/InteractionPetBreedingNest.java | 172 + .../pets/InteractionPetDrink.java | 57 + .../interactions/pets/InteractionPetFood.java | 57 + .../interactions/pets/InteractionPetToy.java | 75 + .../totems/InteractionTotemHead.java | 95 + .../totems/InteractionTotemLegs.java | 66 + .../totems/InteractionTotemPlanet.java | 94 + .../items/interactions/totems/TotemColor.java | 24 + .../interactions/totems/TotemPlanetType.java | 22 + .../items/interactions/totems/TotemType.java | 24 + .../interactions/wired/WiredSettings.java | 63 + .../items/interactions/wired/WiredSuper.java | 117 + .../interactions/wired/WiredTriggerReset.java | 5 + .../WiredConditionDateRangeActive.java | 110 + .../WiredConditionFurniHaveFurni.java | 194 + .../WiredConditionFurniHaveHabbo.java | 193 + .../WiredConditionFurniTypeMatch.java | 165 + .../conditions/WiredConditionGroupMember.java | 75 + .../conditions/WiredConditionHabboCount.java | 107 + .../WiredConditionHabboHasEffect.java | 94 + .../WiredConditionHabboHasHandItem.java | 103 + .../WiredConditionHabboWearsBadge.java | 106 + .../WiredConditionLessTimeElapsed.java | 99 + .../WiredConditionMatchStatePosition.java | 242 + .../WiredConditionMoreTimeElapsed.java | 99 + .../WiredConditionNotFurniHaveFurni.java | 201 + .../WiredConditionNotFurniHaveHabbo.java | 192 + .../WiredConditionNotFurniTypeMatch.java | 165 + .../WiredConditionNotHabboCount.java | 106 + .../WiredConditionNotHabboHasEffect.java | 94 + .../WiredConditionNotHabboWearsBadge.java | 107 + .../conditions/WiredConditionNotInGroup.java | 75 + .../conditions/WiredConditionNotInTeam.java | 107 + .../WiredConditionNotMatchStatePosition.java | 32 + .../WiredConditionNotTriggerOnFurni.java | 39 + .../conditions/WiredConditionTeamMember.java | 109 + .../WiredConditionTriggerOnFurni.java | 173 + .../wired/effects/WiredEffectAlert.java | 35 + .../wired/effects/WiredEffectBotClothes.java | 156 + .../effects/WiredEffectBotFollowHabbo.java | 172 + .../effects/WiredEffectBotGiveHandItem.java | 187 + .../wired/effects/WiredEffectBotTalk.java | 208 + .../effects/WiredEffectBotTalkToHabbo.java | 207 + .../wired/effects/WiredEffectBotTeleport.java | 260 + .../effects/WiredEffectBotWalkToFurni.java | 211 + .../WiredEffectChangeFurniDirection.java | 301 ++ .../wired/effects/WiredEffectGiveEffect.java | 36 + .../effects/WiredEffectGiveHandItem.java | 34 + ...redEffectGiveHotelviewBonusRarePoints.java | 151 + .../WiredEffectGiveHotelviewHofPoints.java | 153 + .../wired/effects/WiredEffectGiveRespect.java | 154 + .../wired/effects/WiredEffectGiveReward.java | 247 + .../wired/effects/WiredEffectGiveScore.java | 219 + .../effects/WiredEffectGiveScoreToTeam.java | 171 + .../wired/effects/WiredEffectJoinTeam.java | 171 + .../wired/effects/WiredEffectKickHabbo.java | 180 + .../wired/effects/WiredEffectLeaveTeam.java | 139 + .../wired/effects/WiredEffectMatchFurni.java | 279 + .../effects/WiredEffectMoveFurniAway.java | 228 + .../wired/effects/WiredEffectMoveFurniTo.java | 241 + .../effects/WiredEffectMoveFurniTowards.java | 365 ++ .../effects/WiredEffectMoveRotateFurni.java | 333 ++ .../wired/effects/WiredEffectMuteHabbo.java | 141 + .../wired/effects/WiredEffectResetTimers.java | 131 + .../wired/effects/WiredEffectTeleport.java | 254 + .../wired/effects/WiredEffectToggleFurni.java | 282 + .../effects/WiredEffectToggleRandom.java | 261 + .../effects/WiredEffectTriggerStacks.java | 224 + .../wired/effects/WiredEffectWhisper.java | 173 + .../interactions/wired/extra/WiredBlob.java | 121 + .../wired/extra/WiredExtraRandom.java | 50 + .../wired/extra/WiredExtraUnseen.java | 87 + .../InteractionWiredMatchFurniSettings.java | 11 + .../wired/triggers/WiredTriggerAtSetTime.java | 136 + .../triggers/WiredTriggerAtTimeLong.java | 134 + .../triggers/WiredTriggerBotReachedFurni.java | 187 + .../triggers/WiredTriggerBotReachedHabbo.java | 100 + .../wired/triggers/WiredTriggerCollision.java | 76 + .../WiredTriggerFurniStateToggled.java | 165 + .../wired/triggers/WiredTriggerGameEnds.java | 89 + .../triggers/WiredTriggerGameStarts.java | 89 + .../triggers/WiredTriggerHabboEntersRoom.java | 107 + .../WiredTriggerHabboSaysKeyword.java | 118 + .../WiredTriggerHabboWalkOffFurni.java | 158 + .../WiredTriggerHabboWalkOnFurni.java | 159 + .../wired/triggers/WiredTriggerRepeater.java | 162 + .../triggers/WiredTriggerRepeaterLong.java | 156 + .../triggers/WiredTriggerScoreAchieved.java | 106 + .../wired/triggers/WiredTriggerTeamLoses.java | 22 + .../wired/triggers/WiredTriggerTeamWins.java | 22 + .../habbohotel/messenger/FriendRequest.java | 34 + .../habbo/habbohotel/messenger/Message.java | 59 + .../habbo/habbohotel/messenger/Messenger.java | 412 ++ .../habbohotel/messenger/MessengerBuddy.java | 194 + .../messenger/MessengerCategory.java | 31 + .../habbohotel/modtool/CfhActionType.java | 34 + .../habbo/habbohotel/modtool/CfhCategory.java | 29 + .../eu/habbo/habbohotel/modtool/CfhTopic.java | 22 + .../habbo/habbohotel/modtool/ModToolBan.java | 83 + .../habbohotel/modtool/ModToolBanType.java | 29 + .../habbohotel/modtool/ModToolCategory.java | 27 + .../habbohotel/modtool/ModToolChatLog.java | 30 + .../modtool/ModToolChatRecordDataContext.java | 25 + .../modtool/ModToolChatRecordDataType.java | 17 + .../modtool/ModToolChatlogType.java | 13 + .../habbohotel/modtool/ModToolIssue.java | 111 + .../modtool/ModToolIssueChatlogType.java | 21 + .../habbohotel/modtool/ModToolManager.java | 725 +++ .../habbohotel/modtool/ModToolPreset.java | 22 + .../habbohotel/modtool/ModToolRoomVisit.java | 33 + .../modtool/ModToolSanctionItem.java | 25 + .../modtool/ModToolSanctionLevelItem.java | 15 + .../habbohotel/modtool/ModToolSanctions.java | 173 + .../modtool/ModToolTicketState.java | 26 + .../habbohotel/modtool/ModToolTicketType.java | 29 + .../habbohotel/modtool/ScripterEvent.java | 16 + .../habbohotel/modtool/ScripterManager.java | 17 + .../habbo/habbohotel/modtool/WordFilter.java | 204 + .../habbohotel/modtool/WordFilterWord.java | 28 + .../habbohotel/navigation/DisplayMode.java | 6 + .../habbohotel/navigation/DisplayOrder.java | 6 + .../habbohotel/navigation/EventCategory.java | 43 + .../habbo/habbohotel/navigation/ListMode.java | 23 + .../navigation/NavigatorFavoriteFilter.java | 25 + .../navigation/NavigatorFilter.java | 121 + .../navigation/NavigatorFilterComparator.java | 7 + .../navigation/NavigatorFilterField.java | 17 + .../navigation/NavigatorHotelFilter.java | 65 + .../navigation/NavigatorManager.java | 168 + .../navigation/NavigatorPublicCategory.java | 34 + .../navigation/NavigatorPublicFilter.java | 35 + .../navigation/NavigatorRoomAdsFilter.java | 24 + .../navigation/NavigatorSavedSearch.java | 34 + .../navigation/NavigatorUserFilter.java | 58 + .../habbohotel/navigation/SearchAction.java | 13 + .../navigation/SearchResultList.java | 79 + .../habbohotel/permissions/Permission.java | 52 + .../permissions/PermissionSetting.java | 24 + .../permissions/PermissionsManager.java | 139 + .../eu/habbo/habbohotel/permissions/Rank.java | 139 + .../eu/habbo/habbohotel/pets/GnomePet.java | 89 + .../eu/habbo/habbohotel/pets/HorsePet.java | 66 + .../eu/habbo/habbohotel/pets/IPetLook.java | 5 + .../habbohotel/pets/MonsterplantPet.java | 396 ++ .../com/eu/habbo/habbohotel/pets/Pet.java | 754 +++ .../eu/habbo/habbohotel/pets/PetAction.java | 25 + .../habbohotel/pets/PetBreedingReward.java | 21 + .../eu/habbo/habbohotel/pets/PetCommand.java | 76 + .../com/eu/habbo/habbohotel/pets/PetData.java | 277 + .../eu/habbo/habbohotel/pets/PetGestures.java | 25 + .../eu/habbo/habbohotel/pets/PetManager.java | 520 ++ .../com/eu/habbo/habbohotel/pets/PetRace.java | 29 + .../eu/habbo/habbohotel/pets/PetTasks.java | 62 + .../eu/habbo/habbohotel/pets/PetVocal.java | 9 + .../habbo/habbohotel/pets/PetVocalsType.java | 19 + .../eu/habbo/habbohotel/pets/RideablePet.java | 56 + .../habbohotel/pets/actions/ActionBeg.java | 27 + .../pets/actions/ActionBreatheFire.java | 27 + .../habbohotel/pets/actions/ActionBreed.java | 39 + .../habbohotel/pets/actions/ActionCroak.java | 29 + .../habbohotel/pets/actions/ActionDip.java | 29 + .../habbohotel/pets/actions/ActionDown.java | 28 + .../habbohotel/pets/actions/ActionDrink.java | 28 + .../habbohotel/pets/actions/ActionEat.java | 33 + .../habbohotel/pets/actions/ActionFollow.java | 33 + .../pets/actions/ActionFollowLeft.java | 30 + .../pets/actions/ActionFollowRight.java | 30 + .../habbohotel/pets/actions/ActionFree.java | 19 + .../habbohotel/pets/actions/ActionHere.java | 29 + .../habbohotel/pets/actions/ActionJump.java | 32 + .../pets/actions/ActionMoveForward.java | 23 + .../habbohotel/pets/actions/ActionNest.java | 28 + .../habbohotel/pets/actions/ActionPlay.java | 25 + .../pets/actions/ActionPlayDead.java | 31 + .../pets/actions/ActionPlayFootball.java | 44 + .../habbohotel/pets/actions/ActionRelax.java | 28 + .../habbohotel/pets/actions/ActionSilent.java | 23 + .../habbohotel/pets/actions/ActionSit.java | 30 + .../habbohotel/pets/actions/ActionSpeak.java | 39 + .../habbohotel/pets/actions/ActionStand.java | 30 + .../habbohotel/pets/actions/ActionStay.java | 29 + .../habbohotel/pets/actions/ActionTorch.java | 29 + .../pets/actions/ActionTurnLeft.java | 20 + .../pets/actions/ActionTurnRight.java | 20 + .../habbohotel/pets/actions/ActionWave.java | 30 + .../habbohotel/pets/actions/ActionWings.java | 27 + .../com/eu/habbo/habbohotel/polls/Poll.java | 52 + .../habbo/habbohotel/polls/PollManager.java | 75 + .../habbo/habbohotel/polls/PollQuestion.java | 93 + .../habbohotel/rooms/CustomRoomLayout.java | 46 + .../rooms/FurnitureMovementError.java | 25 + .../com/eu/habbo/habbohotel/rooms/Room.java | 4698 +++++++++++++++++ .../eu/habbo/habbohotel/rooms/RoomBan.java | 55 + .../habbo/habbohotel/rooms/RoomCategory.java | 73 + .../habbohotel/rooms/RoomChatMessage.java | 267 + .../rooms/RoomChatMessageBubbles.java | 94 + .../habbo/habbohotel/rooms/RoomChatType.java | 7 + .../eu/habbo/habbohotel/rooms/RoomLayout.java | 668 +++ .../habbo/habbohotel/rooms/RoomManager.java | 1574 ++++++ .../habbohotel/rooms/RoomMoodlightData.java | 75 + .../habbo/habbohotel/rooms/RoomPromotion.java | 102 + .../habbohotel/rooms/RoomRightLevels.java | 55 + .../habbohotel/rooms/RoomSpecialTypes.java | 762 +++ .../eu/habbo/habbohotel/rooms/RoomState.java | 18 + .../eu/habbo/habbohotel/rooms/RoomTile.java | 216 + .../habbo/habbohotel/rooms/RoomTileState.java | 19 + .../eu/habbo/habbohotel/rooms/RoomTrade.java | 340 ++ .../habbo/habbohotel/rooms/RoomTradeUser.java | 80 + .../eu/habbo/habbohotel/rooms/RoomUnit.java | 809 +++ .../habbohotel/rooms/RoomUnitEffect.java | 226 + .../habbohotel/rooms/RoomUnitStatus.java | 96 + .../habbo/habbohotel/rooms/RoomUnitType.java | 18 + .../habbohotel/rooms/RoomUserAction.java | 32 + .../habbohotel/rooms/RoomUserRotation.java | 63 + .../habbo/habbohotel/rooms/TraxManager.java | 443 ++ .../eu/habbo/habbohotel/users/DanceType.java | 19 + .../com/eu/habbo/habbohotel/users/Habbo.java | 503 ++ .../eu/habbo/habbohotel/users/HabboBadge.java | 92 + .../habbo/habbohotel/users/HabboGender.java | 6 + .../eu/habbo/habbohotel/users/HabboInfo.java | 576 ++ .../habbohotel/users/HabboInventory.java | 164 + .../eu/habbo/habbohotel/users/HabboItem.java | 555 ++ .../habbo/habbohotel/users/HabboManager.java | 313 ++ .../HabboNavigatorPersonalDisplayMode.java | 22 + .../users/HabboNavigatorWindowSettings.java | 121 + .../eu/habbo/habbohotel/users/HabboStats.java | 802 +++ .../eu/habbo/habbohotel/users/SignType.java | 33 + .../users/cache/HabboOfferPurchase.java | 93 + .../ClothingValidationManager.java | 212 + .../users/clothingvalidation/Figuredata.java | 122 + .../clothingvalidation/FiguredataPalette.java | 31 + .../FiguredataPaletteColor.java | 17 + .../clothingvalidation/FiguredataSettype.java | 60 + .../FiguredataSettypeSet.java | 21 + .../users/inventory/BadgesComponent.java | 174 + .../users/inventory/BotsComponent.java | 71 + .../users/inventory/EffectsComponent.java | 222 + .../users/inventory/ItemsComponent.java | 171 + .../users/inventory/PetsComponent.java | 90 + .../users/inventory/WardrobeComponent.java | 172 + .../users/subscriptions/HcPayDayLogEntry.java | 64 + .../users/subscriptions/Subscription.java | 146 + .../subscriptions/SubscriptionHabboClub.java | 429 ++ .../subscriptions/SubscriptionManager.java | 84 + .../subscriptions/SubscriptionScheduler.java | 69 + .../wired/WiredChangeDirectionSetting.java | 15 + .../wired/WiredConditionOperator.java | 6 + .../habbohotel/wired/WiredConditionType.java | 34 + .../habbohotel/wired/WiredEffectType.java | 36 + .../habbohotel/wired/WiredGiveRewardItem.java | 33 + .../habbo/habbohotel/wired/WiredHandler.java | 474 ++ .../wired/WiredMatchFurniSetting.java | 27 + .../habbohotel/wired/WiredTriggerType.java | 30 + .../highscores/WiredHighscoreClearType.java | 14 + .../highscores/WiredHighscoreDataEntry.java | 55 + .../highscores/WiredHighscoreManager.java | 229 + .../wired/highscores/WiredHighscoreRow.java | 32 + .../highscores/WiredHighscoreScoreType.java | 13 + .../com/eu/habbo/messages/ClientMessage.java | 85 + .../java/com/eu/habbo/messages/ICallable.java | 7 + .../com/eu/habbo/messages/ISerialize.java | 5 + .../com/eu/habbo/messages/NoAuthMessage.java | 7 + .../com/eu/habbo/messages/PacketManager.java | 647 +++ .../com/eu/habbo/messages/PacketNames.java | 54 + .../com/eu/habbo/messages/ServerMessage.java | 188 + .../messages/ServerMessageException.java | 20 + .../eu/habbo/messages/incoming/Incoming.java | 408 ++ .../messages/incoming/MessageHandler.java | 16 + .../RequestAchievementConfigurationEvent.java | 11 + .../RequestAchievementsEvent.java | 11 + .../AmbassadorAlertCommandEvent.java | 34 + .../AmbassadorVisitCommandEvent.java | 24 + .../camera/CameraPublishToWebEvent.java | 62 + .../incoming/camera/CameraPurchaseEvent.java | 57 + .../camera/CameraRoomPictureEvent.java | 37 + .../camera/CameraRoomThumbnailEvent.java | 37 + .../RequestCameraConfigurationEvent.java | 12 + .../catalog/CatalogBuyClubDiscountEvent.java | 82 + .../catalog/CatalogBuyItemAsGiftEvent.java | 378 ++ .../incoming/catalog/CatalogBuyItemEvent.java | 234 + .../CatalogRequestClubDiscountEvent.java | 54 + .../catalog/CatalogSearchedItemEvent.java | 36 + .../catalog/CatalogSelectClubGiftEvent.java | 75 + .../incoming/catalog/CheckPetNameEvent.java | 26 + .../catalog/JukeBoxRequestTrackCodeEvent.java | 19 + .../catalog/JukeBoxRequestTrackDataEvent.java | 27 + .../catalog/PurchaseTargetOfferEvent.java | 42 + .../incoming/catalog/RedeemVoucherEvent.java | 26 + .../catalog/RequestCatalogIndexEvent.java | 10 + .../catalog/RequestCatalogModeEvent.java | 21 + .../catalog/RequestCatalogPageEvent.java | 29 + .../catalog/RequestClubDataEvent.java | 13 + .../catalog/RequestClubGiftsEvent.java | 15 + .../catalog/RequestDiscountEvent.java | 11 + .../RequestGiftConfigurationEvent.java | 11 + .../RequestMarketplaceConfigEvent.java | 11 + .../catalog/RequestPetBreedsEvent.java | 13 + .../catalog/TargetOfferStateEvent.java | 17 + .../catalog/marketplace/BuyItemEvent.java | 13 + .../marketplace/RequestCreditsEvent.java | 11 + .../marketplace/RequestItemInfoEvent.java | 14 + .../marketplace/RequestOffersEvent.java | 45 + .../marketplace/RequestOwnItemsEvent.java | 11 + .../marketplace/RequestSellItemEvent.java | 15 + .../catalog/marketplace/SellItemEvent.java | 53 + .../marketplace/TakeBackItemEvent.java | 12 + .../catalog/recycler/OpenRecycleBoxEvent.java | 71 + .../catalog/recycler/RecycleEvent.java | 70 + .../catalog/recycler/ReloadRecyclerEvent.java | 11 + .../recycler/RequestRecyclerLogicEvent.java | 11 + .../crafting/CraftingAddRecipeEvent.java | 24 + .../crafting/CraftingCraftItemEvent.java | 78 + .../crafting/CraftingCraftSecretEvent.java | 95 + .../RequestCraftingRecipesAvailableEvent.java | 64 + .../crafting/RequestCraftingRecipesEvent.java | 23 + .../AdventCalendarForceOpenEvent.java | 14 + .../calendar/AdventCalendarOpenDayEvent.java | 14 + ...oorPlanEditorRequestBlockedTilesEvent.java | 14 + ...oorPlanEditorRequestDoorSettingsEvent.java | 16 + .../FloorPlanEditorSaveEvent.java | 183 + .../friends/AcceptFriendRequestEvent.java | 83 + .../incoming/friends/ChangeRelationEvent.java | 23 + .../friends/DeclineFriendRequestEvent.java | 20 + .../incoming/friends/FindNewFriendsEvent.java | 34 + .../friends/FriendListUpdateEvent.java | 11 + .../friends/FriendPrivateMessageEvent.java | 36 + .../incoming/friends/FriendRequestEvent.java | 90 + .../incoming/friends/InviteFriendsEvent.java | 36 + .../incoming/friends/RemoveFriendEvent.java | 38 + .../friends/RequestFriendRequestsEvent.java | 11 + .../incoming/friends/RequestFriendsEvent.java | 14 + .../friends/RequestInitFriendsEvent.java | 18 + .../incoming/friends/SearchUserEvent.java | 39 + .../incoming/friends/StalkFriendEvent.java | 48 + .../incoming/gamecenter/GameCenterEvent.java | 9 + .../gamecenter/GameCenterJoinGameEvent.java | 24 + .../gamecenter/GameCenterLeaveGameEvent.java | 11 + .../gamecenter/GameCenterLoadGameEvent.java | 13 + .../GameCenterRequestAccountStatusEvent.java | 11 + .../GameCenterRequestGameStatusEvent.java | 11 + .../GameCenterRequestGamesEvent.java | 11 + .../guardians/GuardianAcceptRequestEvent.java | 11 + .../GuardianNoUpdatesWantedEvent.java | 10 + .../incoming/guardians/GuardianVoteEvent.java | 34 + .../guides/GuideCancelHelpRequestEvent.java | 17 + .../guides/GuideCloseHelpRequestEvent.java | 16 + .../guides/GuideHandleHelpRequestEvent.java | 24 + .../incoming/guides/GuideInviteUserEvent.java | 20 + .../guides/GuideRecommendHelperEvent.java | 18 + .../guides/GuideReportHelperEvent.java | 47 + .../guides/GuideUserMessageEvent.java | 23 + .../incoming/guides/GuideUserTypingEvent.java | 23 + .../incoming/guides/GuideVisitUserEvent.java | 17 + .../guides/RequestGuideAssistanceEvent.java | 26 + .../guides/RequestGuideToolEvent.java | 42 + .../GetHabboGuildBadgesMessageEvent.java | 10 + .../guilds/GuildAcceptMembershipEvent.java | 63 + .../guilds/GuildChangeBadgeEvent.java | 66 + .../guilds/GuildChangeColorsEvent.java | 42 + .../guilds/GuildChangeNameDescEvent.java | 44 + .../guilds/GuildChangeSettingsEvent.java | 40 + .../guilds/GuildConfirmRemoveMemberEvent.java | 33 + .../guilds/GuildDeclineMembershipEvent.java | 46 + .../incoming/guilds/GuildDeleteEvent.java | 46 + .../guilds/GuildRemoveAdminEvent.java | 47 + .../guilds/GuildRemoveFavoriteEvent.java | 31 + .../guilds/GuildRemoveMemberEvent.java | 66 + .../incoming/guilds/GuildSetAdminEvent.java | 47 + .../guilds/GuildSetFavoriteEvent.java | 37 + .../incoming/guilds/RequestGuildBuyEvent.java | 115 + .../guilds/RequestGuildBuyRoomsEvent.java | 25 + .../guilds/RequestGuildFurniWidgetEvent.java | 23 + .../guilds/RequestGuildInfoEvent.java | 20 + .../guilds/RequestGuildJoinEvent.java | 39 + .../guilds/RequestGuildManageEvent.java | 15 + .../guilds/RequestGuildMembersEvent.java | 31 + .../guilds/RequestGuildPartsEvent.java | 11 + .../guilds/RequestOwnGuildsEvent.java | 27 + .../guilds/forums/GuildForumDataEvent.java | 24 + .../guilds/forums/GuildForumListEvent.java | 96 + .../GuildForumModerateMessageEvent.java | 77 + .../forums/GuildForumModerateThreadEvent.java | 65 + .../forums/GuildForumPostThreadEvent.java | 99 + .../forums/GuildForumThreadUpdateEvent.java | 69 + .../guilds/forums/GuildForumThreadsEvent.java | 26 + .../GuildForumThreadsMessagesEvent.java | 47 + .../forums/GuildForumUpdateSettingsEvent.java | 46 + .../CompleteDiffieHandshakeEvent.java | 34 + .../handshake/InitDiffieHandshakeEvent.java | 23 + .../handshake/IsFirstLoginOfDayComposer.java | 20 + .../incoming/handshake/MachineIDEvent.java | 21 + .../incoming/handshake/PingEvent.java | 11 + .../handshake/ReleaseVersionEvent.java | 21 + .../incoming/handshake/SecureLoginEvent.java | 238 + .../incoming/handshake/UsernameEvent.java | 112 + .../helper/MySanctionStatusEvent.java | 12 + .../helper/RequestTalentTrackEvent.java | 15 + .../HotelViewClaimBadgeRewardEvent.java | 25 + .../hotelview/HotelViewDataEvent.java | 35 + .../incoming/hotelview/HotelViewEvent.java | 33 + .../HotelViewRequestBadgeRewardEvent.java | 13 + .../HotelViewRequestBonusRareEvent.java | 11 + .../HotelViewRequestLTDAvailabilityEvent.java | 25 + .../HotelViewRequestSecondsUntilEvent.java | 20 + .../hotelview/RequestNewsListEvent.java | 16 + .../RequestInventoryBadgesEvent.java | 11 + .../inventory/RequestInventoryBotsEvent.java | 11 + .../RequestInventoryItemsDelete.java | 63 + .../inventory/RequestInventoryItemsEvent.java | 62 + .../inventory/RequestInventoryPetsEvent.java | 11 + .../incoming/modtool/ModToolAlertEvent.java | 22 + .../ModToolChangeRoomSettingsEvent.java | 26 + .../modtool/ModToolCloseTicketEvent.java | 42 + .../modtool/ModToolIssueChangeTopicEvent.java | 26 + .../ModToolIssueDefaultSanctionEvent.java | 46 + .../incoming/modtool/ModToolKickEvent.java | 11 + .../modtool/ModToolPickTicketEvent.java | 37 + .../modtool/ModToolReleaseTicketEvent.java | 39 + .../ModToolRequestIssueChatlogEvent.java | 76 + .../ModToolRequestRoomChatlogEvent.java | 23 + .../modtool/ModToolRequestRoomInfoEvent.java | 25 + .../ModToolRequestRoomUserChatlogEvent.java | 30 + .../ModToolRequestRoomVisitsEvent.java | 23 + .../ModToolRequestUserChatlogEvent.java | 22 + .../modtool/ModToolRequestUserInfoEvent.java | 18 + .../modtool/ModToolRoomAlertEvent.java | 23 + .../modtool/ModToolSanctionAlertEvent.java | 53 + .../modtool/ModToolSanctionBanEvent.java | 77 + .../modtool/ModToolSanctionMuteEvent.java | 65 + .../ModToolSanctionTradeLockEvent.java | 54 + .../incoming/modtool/ModToolWarnEvent.java | 22 + .../incoming/modtool/ReportBullyEvent.java | 55 + .../incoming/modtool/ReportCommentEvent.java | 43 + .../incoming/modtool/ReportEvent.java | 120 + .../modtool/ReportFriendPrivateChatEvent.java | 54 + .../incoming/modtool/ReportPhotoEvent.java | 57 + .../incoming/modtool/ReportThreadEvent.java | 41 + .../modtool/RequestReportRoomEvent.java | 12 + .../RequestReportUserBullyingEvent.java | 29 + .../modtool/StartSafetyQuizEvent.java | 14 + .../navigator/AddSavedSearchEvent.java | 20 + .../navigator/DeleteSavedSearchEvent.java | 26 + .../NavigatorCategoryListModeEvent.java | 18 + .../NavigatorCollapseCategoryEvent.java | 12 + .../NavigatorUncollapseCategoryEvent.java | 12 + .../navigator/NewNavigatorActionEvent.java | 29 + .../navigator/RequestCanCreateRoomEvent.java | 15 + .../navigator/RequestCreateRoomEvent.java | 61 + .../navigator/RequestDeleteRoomEvent.java | 118 + .../RequestHighestScoreRoomsEvent.java | 12 + .../navigator/RequestMyRoomsEvent.java | 12 + .../RequestNavigatorSettingsEvent.java | 14 + .../RequestNewNavigatorDataEvent.java | 16 + .../RequestNewNavigatorRoomsEvent.java | 170 + .../navigator/RequestPopularRoomsEvent.java | 12 + .../navigator/RequestPromotedRoomsEvent.java | 12 + .../navigator/RequestPublicRoomsEvent.java | 10 + .../navigator/RequestRoomCategoriesEvent.java | 17 + .../incoming/navigator/RequestTagsEvent.java | 12 + .../navigator/SaveWindowSettingsEvent.java | 23 + .../navigator/SearchRoomsByTagEvent.java | 14 + .../incoming/navigator/SearchRoomsEvent.java | 67 + .../navigator/SearchRoomsFriendsNowEvent.java | 12 + .../navigator/SearchRoomsFriendsOwnEvent.java | 12 + .../navigator/SearchRoomsInGroupEvent.java | 12 + .../SearchRoomsMyFavouriteEvent.java | 12 + .../navigator/SearchRoomsVisitedEvent.java | 12 + .../navigator/SearchRoomsWithRightsEvent.java | 12 + .../incoming/polls/AnswerPollEvent.java | 67 + .../incoming/polls/CancelPollEvent.java | 34 + .../incoming/polls/GetPollDataEvent.java | 19 + .../incoming/rooms/HandleDoorbellEvent.java | 34 + .../incoming/rooms/RequestHeightmapEvent.java | 19 + .../incoming/rooms/RequestRoomDataEvent.java | 26 + .../rooms/RequestRoomHeightmapEvent.java | 24 + .../incoming/rooms/RequestRoomLoadEvent.java | 32 + .../rooms/RequestRoomRightsEvent.java | 20 + .../rooms/RequestRoomSettingsEvent.java | 19 + .../rooms/RequestRoomWordFilterEvent.java | 20 + .../incoming/rooms/RoomBackgroundEvent.java | 44 + .../incoming/rooms/RoomFavoriteEvent.java | 29 + .../incoming/rooms/RoomMuteEvent.java | 19 + .../incoming/rooms/RoomPlacePaintEvent.java | 52 + .../rooms/RoomRemoveAllRightsEvent.java | 40 + .../incoming/rooms/RoomRemoveRightsEvent.java | 13 + .../rooms/RoomRequestBannedUsersEvent.java | 25 + .../incoming/rooms/RoomSettingsSaveEvent.java | 134 + .../incoming/rooms/RoomStaffPickEvent.java | 45 + .../incoming/rooms/RoomUnFavoriteEvent.java | 23 + .../incoming/rooms/RoomVoteEvent.java | 11 + .../rooms/RoomWordFilterModifyEvent.java | 37 + .../incoming/rooms/SetHomeRoomEvent.java | 16 + .../incoming/rooms/bots/BotPickupEvent.java | 19 + .../incoming/rooms/bots/BotPlaceEvent.java | 26 + .../rooms/bots/BotSaveSettingsEvent.java | 170 + .../incoming/rooms/bots/BotSettingsEvent.java | 28 + .../rooms/items/AdvertisingSaveEvent.java | 52 + .../incoming/rooms/items/CloseDiceEvent.java | 38 + .../items/FootballGateSaveLookEvent.java | 36 + .../rooms/items/MannequinSaveLookEvent.java | 47 + .../rooms/items/MannequinSaveNameEvent.java | 35 + .../items/MoodLightSaveSettingsEvent.java | 64 + .../rooms/items/MoodLightSettingsEvent.java | 12 + .../rooms/items/MoodLightTurnOnEvent.java | 39 + .../rooms/items/MoveWallItemEvent.java | 40 + .../rooms/items/PostItDeleteEvent.java | 34 + .../rooms/items/PostItPlaceEvent.java | 57 + .../rooms/items/PostItRequestDataEvent.java | 24 + .../rooms/items/PostItSaveDataEvent.java | 60 + .../rooms/items/RedeemClothingEvent.java | 67 + .../incoming/rooms/items/RedeemItemEvent.java | 138 + .../rooms/items/RoomPickupItemEvent.java | 42 + .../rooms/items/RoomPlaceItemEvent.java | 118 + .../rooms/items/RotateMoveItemEvent.java | 42 + .../items/SavePostItStickyPoleEvent.java | 60 + .../items/SetStackHelperHeightEvent.java | 59 + .../rooms/items/ToggleFloorItemEvent.java | 138 + .../rooms/items/ToggleWallItemEvent.java | 40 + .../rooms/items/TriggerColorWheelEvent.java | 24 + .../rooms/items/TriggerDiceEvent.java | 30 + .../rooms/items/TriggerOneWayGateEvent.java | 27 + .../rooms/items/UseRandomStateItemEvent.java | 30 + .../jukebox/JukeBoxAddSoundTrackEvent.java | 27 + .../rooms/items/jukebox/JukeBoxEventOne.java | 16 + .../rooms/items/jukebox/JukeBoxEventTwo.java | 16 + .../jukebox/JukeBoxRemoveSoundTrackEvent.java | 17 + .../jukebox/JukeBoxRequestPlayListEvent.java | 21 + .../lovelock/LoveLockStartConfirmEvent.java | 48 + .../rentablespace/RentSpaceCancelEvent.java | 30 + .../items/rentablespace/RentSpaceEvent.java | 29 + .../youtube/YoutubeRequestPlaylistChange.java | 55 + .../youtube/YoutubeRequestPlaylists.java | 40 + .../youtube/YoutubeRequestStateChange.java | 109 + .../rooms/pets/BreedMonsterplantsEvent.java | 26 + .../rooms/pets/CompostMonsterplantEvent.java | 55 + .../rooms/pets/ConfirmPetBreedingEvent.java | 22 + .../rooms/pets/HorseRemoveSaddleEvent.java | 65 + .../incoming/rooms/pets/MovePetEvent.java | 37 + .../rooms/pets/PetPackageNameEvent.java | 81 + .../incoming/rooms/pets/PetPickupEvent.java | 56 + .../incoming/rooms/pets/PetPlaceEvent.java | 93 + .../incoming/rooms/pets/PetRideEvent.java | 57 + .../rooms/pets/PetRideSettingsEvent.java | 35 + .../incoming/rooms/pets/PetUseItemEvent.java | 149 + .../pets/RequestPetInformationEvent.java | 24 + .../pets/RequestPetTrainingPanelEvent.java | 20 + .../incoming/rooms/pets/ScratchPetEvent.java | 31 + .../rooms/pets/StopBreedingEvent.java | 18 + .../ToggleMonsterplantBreedableEvent.java | 22 + .../promotions/BuyRoomPromotionEvent.java | 72 + .../RequestPromotionRoomsEvent.java | 18 + .../promotions/UpdateRoomPromotionEvent.java | 39 + .../rooms/users/IgnoreRoomUserEvent.java | 31 + .../rooms/users/RequestRoomUserTagsEvent.java | 20 + .../rooms/users/RoomUserActionEvent.java | 56 + .../rooms/users/RoomUserBanEvent.java | 16 + .../rooms/users/RoomUserDanceEvent.java | 47 + .../users/RoomUserDropHandItemEvent.java | 17 + .../users/RoomUserGiveHandItemEvent.java | 30 + .../rooms/users/RoomUserGiveRespectEvent.java | 24 + .../rooms/users/RoomUserGiveRightsEvent.java | 37 + .../rooms/users/RoomUserKickEvent.java | 51 + .../rooms/users/RoomUserLookAtPoint.java | 58 + .../rooms/users/RoomUserMuteEvent.java | 32 + .../users/RoomUserRemoveRightsEvent.java | 25 + .../rooms/users/RoomUserShoutEvent.java | 43 + .../rooms/users/RoomUserSignEvent.java | 37 + .../rooms/users/RoomUserSitEvent.java | 26 + .../rooms/users/RoomUserStartTypingEvent.java | 19 + .../rooms/users/RoomUserStopTypingEvent.java | 19 + .../rooms/users/RoomUserTalkEvent.java | 44 + .../rooms/users/RoomUserWalkEvent.java | 164 + .../rooms/users/RoomUserWhisperEvent.java | 40 + .../rooms/users/UnIgnoreRoomUserEvent.java | 26 + .../rooms/users/UnbanRoomUserEvent.java | 22 + .../incoming/trading/TradeAcceptEvent.java | 22 + .../incoming/trading/TradeCancelEvent.java | 25 + .../trading/TradeCancelOfferItemEvent.java | 21 + .../incoming/trading/TradeCloseEvent.java | 25 + .../incoming/trading/TradeConfirmEvent.java | 18 + .../incoming/trading/TradeOfferItemEvent.java | 25 + .../trading/TradeOfferMultipleItemsEvent.java | 31 + .../incoming/trading/TradeStartEvent.java | 65 + .../incoming/trading/TradeUnAcceptEvent.java | 18 + .../unknown/RequestResolutionEvent.java | 16 + .../incoming/unknown/UnknownEvent1.java | 11 + .../incoming/unknown/UnknownEvent2.java | 9 + .../incoming/users/ActivateEffectEvent.java | 14 + .../incoming/users/ChangeChatBubbleEvent.java | 23 + .../users/ChangeNameCheckUsernameEvent.java | 52 + .../users/ConfirmChangeNameEvent.java | 93 + .../incoming/users/EnableEffectEvent.java | 22 + .../users/PerformanceLogMessageEvent.java | 37 + .../incoming/users/PickNewUserGiftEvent.java | 27 + .../users/RequestClubCenterEvent.java | 12 + .../users/RequestMeMenuSettingsEvent.java | 11 + .../users/RequestProfileFriendsEvent.java | 20 + .../users/RequestUserCitizinShipEvent.java | 11 + .../incoming/users/RequestUserClubEvent.java | 12 + .../users/RequestUserCreditsEvent.java | 13 + .../incoming/users/RequestUserDataEvent.java | 64 + .../users/RequestUserProfileEvent.java | 20 + .../users/RequestUserWardrobeEvent.java | 11 + .../users/RequestWearingBadgesEvent.java | 20 + .../users/SaveBlockCameraFollowEvent.java | 13 + .../users/SaveIgnoreRoomInvitesEvent.java | 13 + .../incoming/users/SaveMottoEvent.java | 30 + .../users/SavePreferOldChatEvent.java | 13 + .../incoming/users/SaveUserVolumesEvent.java | 20 + .../incoming/users/SaveWardrobeEvent.java | 34 + .../incoming/users/UpdateUIFlagsEvent.java | 13 + .../incoming/users/UserActivityEvent.java | 51 + .../messages/incoming/users/UserNuxEvent.java | 46 + .../incoming/users/UserSaveLookEvent.java | 47 + .../incoming/users/UserWearBadgeEvent.java | 44 + .../wired/WiredApplySetConditionsEvent.java | 103 + .../wired/WiredConditionSaveDataEvent.java | 33 + .../wired/WiredEffectSaveDataEvent.java | 39 + .../incoming/wired/WiredSaveException.java | 15 + .../wired/WiredTriggerSaveDataEvent.java | 33 + .../messages/outgoing/MessageComposer.java | 25 + .../eu/habbo/messages/outgoing/Outgoing.java | 557 ++ .../achievements/AchievementListComposer.java | 59 + .../AchievementProgressComposer.java | 59 + .../AchievementUnlockedComposer.java | 38 + .../TalentLevelUpdateComposer.java | 41 + .../talenttrack/TalentTrackComposer.java | 130 + .../CameraCompetitionStatusComposer.java | 23 + .../outgoing/camera/CameraPriceComposer.java | 26 + .../CameraPublishWaitMessageComposer.java | 31 + .../CameraPurchaseSuccesfullComposer.java | 13 + .../CameraRoomThumbnailSavedComposer.java | 13 + .../outgoing/camera/CameraURLComposer.java | 20 + .../catalog/AlertLimitedSoldOutComposer.java | 13 + .../catalog/AlertPurchaseFailedComposer.java | 23 + .../AlertPurchaseUnavailableComposer.java | 23 + .../outgoing/catalog/CatalogModeComposer.java | 20 + .../outgoing/catalog/CatalogPageComposer.java | 71 + .../catalog/CatalogPagesListComposer.java | 77 + .../catalog/CatalogSearchResultComposer.java | 21 + .../catalog/CatalogUpdatedComposer.java | 14 + .../catalog/ClubCenterDataComposer.java | 54 + .../outgoing/catalog/ClubDataComposer.java | 37 + .../outgoing/catalog/ClubGiftsComposer.java | 68 + .../outgoing/catalog/DiscountComposer.java | 30 + .../catalog/GiftConfigurationComposer.java | 45 + .../catalog/GiftReceiverNotFoundComposer.java | 13 + .../catalog/NotEnoughPointsTypeComposer.java | 26 + .../PetBoughtNotificationComposer.java | 24 + .../outgoing/catalog/PetBreedsComposer.java | 34 + .../catalog/PetNameErrorComposer.java | 29 + .../outgoing/catalog/PurchaseOKComposer.java | 43 + .../catalog/RecyclerCompleteComposer.java | 24 + .../catalog/RecyclerLogicComposer.java | 30 + .../catalog/RedeemVoucherErrorComposer.java | 23 + .../catalog/RedeemVoucherOKComposer.java | 15 + .../catalog/ReloadRecyclerComposer.java | 15 + .../catalog/TargetedOfferComposer.java | 26 + .../MarketplaceBuyErrorComposer.java | 34 + .../MarketplaceCancelSaleComposer.java | 24 + .../MarketplaceConfigComposer.java | 21 + .../MarketplaceItemInfoComposer.java | 21 + .../MarketplaceItemPostedComposer.java | 25 + .../MarketplaceOffersComposer.java | 48 + .../MarketplaceOwnItemsComposer.java | 65 + .../MarketplaceSellItemComposer.java | 30 + .../crafting/CraftableProductsComposer.java | 38 + .../crafting/CraftingRecipeComposer.java | 29 + .../CraftingRecipesAvailableComposer.java | 23 + .../crafting/CraftingResultComposer.java | 35 + .../calendar/AdventCalendarDataComposer.java | 64 + .../AdventCalendarProductComposer.java | 49 + .../mysticbox/MysticBoxCloseComposer.java | 13 + .../mysticbox/MysticBoxPrizeComposer.java | 23 + .../mysticbox/MysticBoxStartOpenComposer.java | 13 + .../NewYearResolutionCompletedComposer.java | 21 + .../resolution/NewYearResolutionComposer.java | 32 + .../NewYearResolutionProgressComposer.java | 35 + .../FloorPlanEditorBlockedTilesComposer.java | 31 + .../FloorPlanEditorDoorSettingsComposer.java | 23 + .../friends/FriendChatMessageComposer.java | 53 + .../friends/FriendFindingRoomComposer.java | 23 + .../friends/FriendNotificationComposer.java | 34 + .../friends/FriendRequestComposer.java | 25 + .../friends/FriendRequestErrorComposer.java | 26 + .../outgoing/friends/FriendsComposer.java | 80 + .../friends/LoadFriendRequestsComposer.java | 33 + .../friends/MessengerInitComposer.java | 48 + .../friends/RemoveFriendComposer.java | 33 + .../outgoing/friends/RoomInviteComposer.java | 23 + .../friends/RoomInviteErrorComposer.java | 33 + .../outgoing/friends/StalkErrorComposer.java | 25 + .../friends/UpdateFriendComposer.java | 77 + .../friends/UserSearchResultComposer.java | 80 + .../GameCenterAccountInfoComposer.java | 24 + ...nterAchievementsConfigurationComposer.java | 27 + .../gamecenter/GameCenterGameComposer.java | 26 + .../GameCenterGameListComposer.java | 37 + .../basejump/BaseJumpJoinQueueComposer.java | 20 + .../basejump/BaseJumpLeaveQueueComposer.java | 14 + .../basejump/BaseJumpLoadGameComposer.java | 51 + .../basejump/BaseJumpLoadGameURLComposer.java | 16 + .../basejump/BaseJumpUnloadGameComposer.java | 15 + .../generic/MinimailCountComposer.java | 14 + ...ckMonthlyClubGiftNotificationComposer.java | 20 + .../generic/alerts/BotErrorComposer.java | 26 + .../generic/alerts/BubbleAlertComposer.java | 41 + .../generic/alerts/BubbleAlertKeys.java | 43 + .../alerts/CustomNotificationComposer.java | 26 + .../generic/alerts/GenericAlertComposer.java | 27 + .../alerts/GenericErrorMessagesComposer.java | 28 + .../alerts/HotelClosedAndOpensComposer.java | 23 + .../HotelClosesAndWillOpenAtComposer.java | 26 + ...elWillCloseInMinutesAndBackInComposer.java | 24 + .../HotelWillCloseInMinutesComposer.java | 20 + .../alerts/MessagesForYouComposer.java | 39 + .../generic/alerts/PetErrorComposer.java | 27 + .../StaffAlertAndOpenHabboWayComposer.java | 20 + ...fAlertWIthLinkAndOpenHabboWayComposer.java | 23 + .../alerts/StaffAlertWithLinkComposer.java | 23 + .../generic/alerts/UpdateFailedComposer.java | 20 + .../outgoing/generic/testcomposer.java | 27 + .../GuardianNewReportReceivedComposer.java | 15 + .../GuardianVotingRequestedComposer.java | 50 + .../GuardianVotingResultComposer.java | 37 + .../guardians/GuardianVotingTimeEnded.java | 13 + .../GuardianVotingVotesComposer.java | 35 + .../guides/BullyReportClosedComposer.java | 23 + .../guides/GuideSessionAttachedComposer.java | 28 + .../guides/GuideSessionDetachedComposer.java | 13 + .../guides/GuideSessionEndedComposer.java | 23 + .../guides/GuideSessionErrorComposer.java | 24 + ...uideSessionInvitedToGuideRoomComposer.java | 23 + .../guides/GuideSessionMessageComposer.java | 22 + .../GuideSessionPartnerIsPlayingComposer.java | 20 + .../GuideSessionPartnerIsTypingComposer.java | 20 + .../GuideSessionRequesterRoomComposer.java | 21 + .../guides/GuideSessionStartedComposer.java | 26 + .../outgoing/guides/GuideToolsComposer.java | 24 + .../GuildAcceptMemberErrorComposer.java | 27 + .../outgoing/guilds/GuildBoughtComposer.java | 22 + .../guilds/GuildBuyRoomsComposer.java | 52 + .../GuildConfirmRemoveMemberComposer.java | 23 + .../guilds/GuildEditFailComposer.java | 25 + .../GuildFavoriteRoomUserUpdateComposer.java | 27 + .../guilds/GuildFurniWidgetComposer.java | 33 + .../outgoing/guilds/GuildInfoComposer.java | 56 + .../guilds/GuildJoinErrorComposer.java | 28 + .../outgoing/guilds/GuildListComposer.java | 36 + .../outgoing/guilds/GuildManageComposer.java | 62 + .../guilds/GuildMemberUpdateComposer.java | 29 + .../outgoing/guilds/GuildMembersComposer.java | 62 + .../outgoing/guilds/GuildPartsComposer.java | 47 + .../GuildRefreshMembersListComposer.java | 22 + .../guilds/RemoveGuildFromRoomComposer.java | 20 + .../forums/GuildForumAddCommentComposer.java | 23 + .../forums/GuildForumCommentsComposer.java | 37 + .../guilds/forums/GuildForumDataComposer.java | 162 + .../guilds/forums/GuildForumListComposer.java | 55 + .../GuildForumThreadMessagesComposer.java | 22 + .../forums/GuildForumThreadsComposer.java | 61 + ...uildForumsUnreadMessagesCountComposer.java | 20 + .../forums/PostUpdateMessageComposer.java | 29 + .../forums/ThreadUpdatedMessageComposer.java | 38 + .../habboway/HabboWayQuizComposer1.java | 26 + .../habboway/HabboWayQuizComposer2.java | 26 + .../habboway/nux/NewUserGiftComposer.java | 31 + .../habboway/nux/NewUserIdentityComposer.java | 21 + .../habboway/nux/NuxAlertComposer.java | 20 + .../AvailabilityStatusMessageComposer.java | 27 + .../CompleteDiffieHandshakeComposer.java | 29 + .../handshake/ConnectionErrorComposer.java | 33 + .../EnableNotificationsComposer.java | 20 + .../InitDiffieHandshakeComposer.java | 25 + .../outgoing/handshake/MachineIDComposer.java | 22 + .../outgoing/handshake/PingComposer.java | 13 + .../outgoing/handshake/PongComposer.java | 20 + .../handshake/SecureLoginOKComposer.java | 13 + .../outgoing/hotelview/BonusRareComposer.java | 28 + .../hotelview/HallOfFameComposer.java | 40 + .../HotelViewBadgeButtonConfigComposer.java | 23 + .../HotelViewCatalogPageExpiringComposer.java | 26 + .../HotelViewCommunityGoalComposer.java | 60 + .../outgoing/hotelview/HotelViewComposer.java | 13 + .../HotelViewConcurrentUsersComposer.java | 30 + .../HotelViewCustomTimerComposer.java | 23 + .../hotelview/HotelViewDataComposer.java | 25 + ...HotelViewExpiringCatalogPageCommposer.java | 25 + ...elViewHideCommunityVoteButtonComposer.java | 20 + .../HotelViewNextLTDAvailableComposer.java | 29 + .../HotelViewSecondsUntilComposer.java | 24 + .../outgoing/hotelview/NewsListComposer.java | 30 + .../outgoing/inventory/AddBotComposer.java | 26 + .../inventory/AddHabboItemComposer.java | 97 + .../outgoing/inventory/AddPetComposer.java | 22 + .../inventory/EffectsListAddComposer.java | 25 + .../EffectsListEffectEnableComposer.java | 23 + .../inventory/EffectsListRemoveComposer.java | 21 + .../InventoryAchievementsComposer.java | 38 + .../inventory/InventoryBadgesComposer.java | 44 + .../inventory/InventoryBotsComposer.java | 33 + .../inventory/InventoryItemsComposer.java | 107 + .../inventory/InventoryPetsComposer.java | 40 + .../inventory/InventoryRefreshComposer.java | 13 + .../InventoryUpdateItemComposer.java | 65 + .../outgoing/inventory/RemoveBotComposer.java | 21 + .../inventory/RemoveHabboItemComposer.java | 20 + .../outgoing/inventory/RemovePetComposer.java | 21 + .../inventory/UserEffectsListComposer.java | 51 + .../modtool/BullyReportRequestComposer.java | 44 + .../modtool/BullyReportedMessageComposer.java | 26 + .../modtool/CfhTopicsMessageComposer.java | 38 + .../HelperRequestDisabledComposer.java | 14 + .../outgoing/modtool/ModToolComposer.java | 97 + .../modtool/ModToolIssueChatlogComposer.java | 101 + .../modtool/ModToolIssueHandledComposer.java | 32 + ...ModToolIssueHandlerDimensionsComposer.java | 29 + .../modtool/ModToolIssueInfoComposer.java | 21 + .../ModToolIssueResponseAlertComposer.java | 20 + .../modtool/ModToolIssueUpdateComposer.java | 21 + .../ModToolReportReceivedAlertComposer.java | 27 + .../modtool/ModToolRoomChatlogComposer.java | 46 + .../modtool/ModToolRoomInfoComposer.java | 32 + .../modtool/ModToolSanctionInfoComposer.java | 105 + .../modtool/ModToolUserChatlogComposer.java | 52 + .../modtool/ModToolUserInfoComposer.java | 84 + .../ModToolUserRoomVisitsComposer.java | 39 + .../modtool/ReportRoomFormComposer.java | 29 + .../mysterybox/MysteryBoxKeysComposer.java | 15 + .../navigator/CanCreateEventComposer.java | 15 + .../navigator/CanCreateRoomComposer.java | 25 + ...NewNavigatorCategoryUserCountComposer.java | 29 + ...wNavigatorCollapsedCategoriesComposer.java | 60 + .../NewNavigatorEventCategoriesComposer.java | 26 + .../NewNavigatorLiftedRoomsComposer.java | 14 + .../NewNavigatorMetaDataComposer.java | 23 + .../NewNavigatorSavedSearchesComposer.java | 32 + .../NewNavigatorSearchResultsComposer.java | 37 + .../NewNavigatorSettingsComposer.java | 26 + .../OpenRoomCreationWindowComposer.java | 13 + .../navigator/PrivateRoomsComposer.java | 49 + .../navigator/RoomCategoriesComposer.java | 40 + .../navigator/RoomCreatedComposer.java | 22 + .../outgoing/navigator/TagsComposer.java | 30 + .../outgoing/polls/PollQuestionsComposer.java | 31 + .../outgoing/polls/PollStartComposer.java | 24 + .../infobus/SimplePollAnswerComposer.java | 32 + .../infobus/SimplePollAnswersComposer.java | 27 + .../infobus/SimplePollStartComposer.java | 30 + .../quests/QuestCompletedComposer.java | 62 + .../outgoing/quests/QuestComposer.java | 20 + .../outgoing/quests/QuestExpiredComposer.java | 20 + .../outgoing/quests/QuestionInfoComposer.java | 14 + .../outgoing/quests/QuestsComposer.java | 87 + .../BotForceOpenContextMenuComposer.java | 20 + .../outgoing/rooms/BotSettingsComposer.java | 62 + .../rooms/DoorbellAddUserComposer.java | 20 + .../rooms/FavoriteRoomChangedComposer.java | 23 + .../outgoing/rooms/FloodCounterComposer.java | 20 + .../outgoing/rooms/ForwardToRoomComposer.java | 20 + .../outgoing/rooms/FreezeLivesComposer.java | 22 + .../outgoing/rooms/HideDoorbellComposer.java | 20 + .../rooms/KnockKnockUnknownComposer.java | 21 + .../rooms/RoomAccessDeniedComposer.java | 20 + .../rooms/RoomAddRightsListComposer.java | 27 + .../rooms/RoomBannedUsersComposer.java | 54 + .../rooms/RoomChatSettingsComposer.java | 25 + .../outgoing/rooms/RoomDataComposer.java | 115 + .../rooms/RoomEditSettingsErrorComposer.java | 34 + .../rooms/RoomEnterErrorComposer.java | 38 + .../outgoing/rooms/RoomEntryInfoComposer.java | 22 + .../rooms/RoomFilterWordsComposer.java | 27 + .../RoomFloorThicknessUpdatedComposer.java | 23 + .../outgoing/rooms/RoomHeightMapComposer.java | 23 + .../outgoing/rooms/RoomModelComposer.java | 22 + .../outgoing/rooms/RoomMutedComposer.java | 21 + .../outgoing/rooms/RoomNoRightsComposer.java | 13 + .../outgoing/rooms/RoomOpenComposer.java | 13 + .../outgoing/rooms/RoomOwnerComposer.java | 13 + .../outgoing/rooms/RoomPaintComposer.java | 23 + .../outgoing/rooms/RoomPaneComposer.java | 24 + .../rooms/RoomQueueStatusMessage.java | 22 + .../rooms/RoomRelativeMapComposer.java | 42 + .../rooms/RoomRemoveRightsListComposer.java | 25 + .../outgoing/rooms/RoomRightsComposer.java | 21 + .../rooms/RoomRightsListComposer.java | 34 + .../outgoing/rooms/RoomScoreComposer.java | 23 + .../outgoing/rooms/RoomSettingsComposer.java | 57 + .../rooms/RoomSettingsSavedComposer.java | 21 + .../rooms/RoomSettingsUpdatedComposer.java | 21 + .../outgoing/rooms/RoomThicknessComposer.java | 23 + .../rooms/UpdateStackHeightComposer.java | 82 + .../rooms/items/AddFloorItemComposer.java | 31 + .../rooms/items/AddWallItemComposer.java | 24 + .../items/FloorItemOnRollerComposer.java | 80 + .../rooms/items/FloorItemUpdateComposer.java | 28 + .../rooms/items/ItemExtraDataComposer.java | 22 + .../rooms/items/ItemIntStateComposer.java | 23 + .../rooms/items/ItemStateComposer.java | 28 + .../rooms/items/ItemsDataUpdateComposer.java | 30 + .../rooms/items/MoodLightDataComposer.java | 55 + .../rooms/items/PostItDataComposer.java | 26 + .../items/PostItStickyPoleOpenComposer.java | 22 + .../items/PresentItemOpenedComposer.java | 31 + .../rooms/items/RemoveFloorItemComposer.java | 33 + .../rooms/items/RemoveWallItemComposer.java | 22 + .../rooms/items/RoomFloorItemsComposer.java | 53 + .../rooms/items/RoomWallItemsComposer.java | 54 + .../UpdateStackHeightTileHeightComposer.java | 25 + .../rooms/items/WallItemUpdateComposer.java | 22 + .../items/jukebox/JukeBoxMySongsComposer.java | 31 + .../JukeBoxNowPlayingMessageComposer.java | 38 + .../JukeBoxPlayListAddSongComposer.java | 24 + .../jukebox/JukeBoxPlayListComposer.java | 30 + .../JukeBoxPlayListUpdatedComposer.java | 38 + .../jukebox/JukeBoxPlaylistFullComposer.java | 13 + .../jukebox/JukeBoxTrackCodeComposer.java | 22 + .../jukebox/JukeBoxTrackDataComposer.java | 33 + .../LoveLockFurniFinishedComposer.java | 21 + .../LoveLockFurniFriendConfirmedComposer.java | 21 + .../lovelock/LoveLockFurniStartComposer.java | 22 + .../RentableSpaceInfoComposer.java | 54 + .../RentableSpaceUnknown2Composer.java | 20 + .../RentableSpaceUnknownComposer.java | 20 + .../youtube/YoutubeDisplayListComposer.java | 36 + .../youtube/YoutubeStateChangeComposer.java | 24 + .../items/youtube/YoutubeVideoComposer.java | 31 + .../CantScratchPetNotOldEnoughComposer.java | 23 + .../rooms/pets/PetInformationComposer.java | 70 + .../rooms/pets/PetLevelUpComposer.java | 30 + .../rooms/pets/PetLevelUpdatedComposer.java | 23 + .../rooms/pets/PetPackageComposer.java | 21 + .../PetPackageNameValidationComposer.java | 32 + .../rooms/pets/PetStatusUpdateComposer.java | 28 + .../rooms/pets/PetTrainingPanelComposer.java | 49 + .../outgoing/rooms/pets/RoomPetComposer.java | 62 + .../rooms/pets/RoomPetExperienceComposer.java | 25 + .../pets/RoomPetHorseFigureComposer.java | 51 + .../rooms/pets/RoomPetRespectComposer.java | 33 + .../pets/breeding/PetBreedingCompleted.java | 23 + .../breeding/PetBreedingFailedComposer.java | 23 + .../breeding/PetBreedingResultComposer.java | 112 + .../breeding/PetBreedingStartComposer.java | 27 + .../PetBreedingStartFailedComposer.java | 28 + .../PromoteOwnRoomsListComposer.java | 33 + .../RoomPromotionMessageComposer.java | 53 + .../users/ChangeNameUpdatedComposer.java | 23 + .../rooms/users/RoomUnitIdleComposer.java | 22 + .../rooms/users/RoomUnitOnRollerComposer.java | 124 + .../rooms/users/RoomUserActionComposer.java | 25 + .../rooms/users/RoomUserDanceComposer.java | 22 + .../rooms/users/RoomUserDataComposer.java | 25 + .../rooms/users/RoomUserEffectComposer.java | 30 + .../rooms/users/RoomUserHandItemComposer.java | 22 + .../rooms/users/RoomUserIgnoredComposer.java | 28 + .../users/RoomUserNameChangedComposer.java | 39 + .../RoomUserReceivedHandItemComposer.java | 24 + .../rooms/users/RoomUserRemoveComposer.java | 21 + .../users/RoomUserRemoveRightsComposer.java | 24 + .../rooms/users/RoomUserRespectComposer.java | 22 + .../rooms/users/RoomUserShoutComposer.java | 25 + .../rooms/users/RoomUserStatusComposer.java | 85 + .../rooms/users/RoomUserTagsComposer.java | 26 + .../rooms/users/RoomUserTalkComposer.java | 25 + .../rooms/users/RoomUserTypingComposer.java | 24 + .../rooms/users/RoomUserUnbannedComposer.java | 24 + .../rooms/users/RoomUserWhisperComposer.java | 25 + .../users/RoomUsersAddGuildBadgeComposer.java | 23 + .../rooms/users/RoomUsersComposer.java | 153 + .../users/RoomUsersGuildBadgesComposer.java | 31 + .../trading/OtherTradingDisabledComposer.java | 13 + .../trading/TradeAcceptedComposer.java | 22 + .../trading/TradeCloseWindowComposer.java | 13 + .../outgoing/trading/TradeClosedComposer.java | 26 + .../trading/TradeCompleteComposer.java | 13 + .../outgoing/trading/TradeStartComposer.java | 32 + .../trading/TradeStartFailComposer.java | 34 + .../outgoing/trading/TradeUpdateComposer.java | 46 + .../TradingWaitingConfirmComposer.java | 13 + .../trading/YouTradingDisabledComposer.java | 13 + .../unknown/BuildersClubExpiredComposer.java | 18 + .../unknown/CloseWebPageComposer.java | 14 + .../CompetitionEntrySubmitResultComposer.java | 41 + .../ConvertedForwardToRoomComposer.java | 23 + .../unknown/EpicPopupFrameComposer.java | 21 + .../outgoing/unknown/ErrorLoginComposer.java | 20 + .../unknown/ExtendClubMessageComposer.java | 37 + .../outgoing/unknown/HabboMallComposer.java | 14 + .../unknown/IgnoredUsersComposer.java | 14 + .../unknown/MessengerErrorComposer.java | 26 + .../unknown/MinimailNewMessageComposer.java | 13 + .../outgoing/unknown/ModToolComposerOne.java | 15 + .../unknown/ModToolSanctionDataComposer.java | 55 + .../MostUselessErrorAlertComposer.java | 14 + .../unknown/MysteryPrizeComposer.java | 19 + .../unknown/RemoveRoomEventComposer.java | 14 + .../RentableItemBuyOutPriceComposer.java | 35 + .../outgoing/unknown/RoomAdErrorComposer.java | 23 + .../RoomCategoryUpdateMessageComposer.java | 20 + .../RoomMessagesPostedCountComposer.java | 25 + .../unknown/RoomUnknown3Composer.java | 14 + .../RoomUserQuestionAnsweredComposer.java | 32 + .../unknown/SnowWarsAddUserComposer.java | 22 + .../outgoing/unknown/SnowWarsCompose1.java | 44 + .../SnowWarsFullGameStatusComposer.java | 36 + .../SnowWarsGameStartedErrorComposer.java | 13 + .../unknown/SnowWarsGenericErrorComposer.java | 13 + .../unknown/SnowWarsInitGameArena.java | 13 + .../unknown/SnowWarsJoinErrorComposer.java | 17 + .../unknown/SnowWarsLevelDataComposer.java | 87 + .../unknown/SnowWarsLoadingArenaComposer.java | 21 + .../unknown/SnowWarsLongDataComposer.java | 39 + .../unknown/SnowWarsOnGameEnding.java | 52 + .../unknown/SnowWarsOnStageEnding.java | 13 + .../SnowWarsOnStageRunningComposer.java | 13 + .../unknown/SnowWarsOnStageStartComposer.java | 65 + .../SnowWarsPlayNowWindowComposer.java | 16 + .../unknown/SnowWarsPreviousRoomComposer.java | 13 + .../unknown/SnowWarsQuePositionComposer.java | 13 + .../unknown/SnowWarsQuickJoinComposer.java | 37 + .../unknown/SnowWarsRemoveUserComposer.java | 14 + .../unknown/SnowWarsResetTimerComposer.java | 14 + .../unknown/SnowWarsStartLobbyCounter.java | 14 + .../unknown/SnowWarsUnknownComposer.java | 22 + .../unknown/SnowWarsUserChatComposer.java | 14 + .../SnowWarsUserEnteredArenaComposer.java | 32 + .../SnowWarsUserExitArenaComposer.java | 14 + .../TalentTrackEmailFailedComposer.java | 20 + .../TalentTrackEmailVerifiedComposer.java | 26 + .../unknown/UnknownAdManagerComposer.java | 20 + .../unknown/UnknownAvatarEditorComposer.java | 20 + .../UnknownCatalogPageOfferComposer.java | 24 + .../unknown/UnknownCompetitionComposer.java | 29 + .../outgoing/unknown/UnknownComposer4.java | 14 + .../outgoing/unknown/UnknownComposer8.java | 26 + .../unknown/UnknownFurniModelComposer.java | 24 + .../unknown/UnknownGuild2Composer.java | 20 + .../unknown/UnknownGuildComposer3.java | 20 + .../unknown/UnknownHabboWayQuizComposer.java | 28 + .../unknown/UnknownHelperComposer.java | 14 + .../outgoing/unknown/UnknownHintComposer.java | 20 + .../UnknownMessengerErrorComposer.java | 26 + .../unknown/UnknownPollQuestionComposer.java | 29 + .../unknown/UnknownRoomDesktopComposer.java | 29 + .../unknown/UnknownRoomViewerComposer.java | 26 + .../unknown/UnknownStatusComposer.java | 23 + .../unknown/UnknownTradeComposer.java | 14 + .../unknown/UnkownPetPackageComposer.java | 26 + .../unknown/UserClassificationComposer.java | 28 + .../unknown/VipTutorialsStartComposer.java | 14 + .../unknown/WatchAndEarnRewardComposer.java | 24 + .../outgoing/unknown/WelcomeGiftComposer.java | 32 + .../unknown/WelcomeGiftErrorComposer.java | 25 + .../outgoing/users/AddUserBadgeComposer.java | 22 + .../users/ChangeNameCheckResultComposer.java | 38 + .../users/ClubGiftReceivedComposer.java | 32 + .../users/FavoriteRoomsCountComposer.java | 31 + .../users/MeMenuSettingsComposer.java | 28 + .../outgoing/users/MutedWhisperComposer.java | 20 + .../users/ProfileFriendsComposer.java | 108 + .../users/UpdateUserLookComposer.java | 22 + .../users/UserAchievementScoreComposer.java | 21 + .../outgoing/users/UserBCLimitsComposer.java | 16 + .../outgoing/users/UserBadgesComposer.java | 32 + .../users/UserCitizinShipComposer.java | 22 + .../outgoing/users/UserClothesComposer.java | 45 + .../outgoing/users/UserClubComposer.java | 163 + .../outgoing/users/UserCreditsComposer.java | 21 + .../outgoing/users/UserCurrencyComposer.java | 37 + .../outgoing/users/UserDataComposer.java | 36 + .../outgoing/users/UserHomeRoomComposer.java | 23 + .../outgoing/users/UserPerksComposer.java | 84 + .../users/UserPermissionsComposer.java | 27 + .../outgoing/users/UserPointsComposer.java | 26 + .../outgoing/users/UserProfileComposer.java | 117 + .../outgoing/users/UserWardrobeComposer.java | 27 + .../VerifyMobileNumberComposer.java | 13 + .../VerifyMobilePhoneCodeWindowComposer.java | 23 + .../VerifyMobilePhoneDoneComposer.java | 23 + .../VerifyMobilePhoneWindowComposer.java | 26 + .../wired/WiredConditionDataComposer.java | 25 + .../wired/WiredEffectDataComposer.java | 25 + .../outgoing/wired/WiredOpenComposer.java | 21 + .../wired/WiredRewardAlertComposer.java | 30 + .../outgoing/wired/WiredSavedComposer.java | 13 + .../wired/WiredTriggerDataComposer.java | 25 + .../com/eu/habbo/messages/rcon/AlertUser.java | 31 + .../habbo/messages/rcon/ChangeRoomOwner.java | 35 + .../habbo/messages/rcon/ChangeUsername.java | 70 + .../messages/rcon/CreateModToolTicket.java | 39 + .../habbo/messages/rcon/DisconnectUser.java | 43 + .../habbo/messages/rcon/ExecuteCommand.java | 37 + .../eu/habbo/messages/rcon/ForwardUser.java | 44 + .../eu/habbo/messages/rcon/FriendRequest.java | 57 + .../com/eu/habbo/messages/rcon/GiveBadge.java | 93 + .../eu/habbo/messages/rcon/GiveCredits.java | 40 + .../eu/habbo/messages/rcon/GivePixels.java | 43 + .../eu/habbo/messages/rcon/GivePoints.java | 44 + .../eu/habbo/messages/rcon/GiveRespect.java | 50 + .../habbo/messages/rcon/GiveUserClothing.java | 48 + .../eu/habbo/messages/rcon/HotelAlert.java | 45 + .../eu/habbo/messages/rcon/IgnoreUser.java | 41 + .../habbo/messages/rcon/ImageAlertUser.java | 77 + .../habbo/messages/rcon/ImageHotelAlert.java | 78 + .../messages/rcon/ModifyUserSubscription.java | 105 + .../com/eu/habbo/messages/rcon/MuteUser.java | 45 + .../messages/rcon/ProgressAchievement.java | 41 + .../eu/habbo/messages/rcon/RCONMessage.java | 43 + .../com/eu/habbo/messages/rcon/SendGift.java | 98 + .../habbo/messages/rcon/SendRoomBundle.java | 43 + .../com/eu/habbo/messages/rcon/SetMotto.java | 47 + .../com/eu/habbo/messages/rcon/SetRank.java | 39 + .../eu/habbo/messages/rcon/StaffAlert.java | 20 + .../com/eu/habbo/messages/rcon/StalkUser.java | 57 + .../com/eu/habbo/messages/rcon/TalkUser.java | 52 + .../eu/habbo/messages/rcon/UpdateCatalog.java | 28 + .../eu/habbo/messages/rcon/UpdateUser.java | 143 + .../habbo/messages/rcon/UpdateWordfilter.java | 19 + .../java/com/eu/habbo/networking/Server.java | 91 + .../habbo/networking/camera/CameraClient.java | 89 + .../networking/camera/CameraDecoder.java | 29 + .../networking/camera/CameraHandler.java | 50 + .../camera/CameraIncomingMessage.java | 63 + .../networking/camera/CameraMessage.java | 18 + .../camera/CameraOutgoingMessage.java | 128 + .../camera/CameraPacketHandler.java | 45 + .../messages/CameraOutgoingHeaders.java | 6 + .../CameraAuthenticationTicketEvent.java | 21 + .../incoming/CameraLoginStatusEvent.java | 53 + .../incoming/CameraResultURLEvent.java | 56 + .../CameraRoomThumbnailGeneratedEvent.java | 25 + .../incoming/CameraUpdateNotification.java | 35 + .../outgoing/CameraLoginComposer.java | 19 + .../outgoing/CameraRenderImageComposer.java | 36 + .../networking/gameserver/GameServer.java | 64 + .../gameserver/GameServerAttributes.java | 13 + .../gameserver/decoders/GameByteDecoder.java | 19 + .../decoders/GameByteDecryption.java | 29 + .../decoders/GameByteFrameDecoder.java | 41 + .../decoders/GameClientMessageLogger.java | 30 + .../decoders/GameMessageHandler.java | 104 + .../decoders/GameMessageRateLimit.java | 44 + .../decoders/GamePolicyDecoder.java | 39 + .../encoders/GameByteEncryption.java | 30 + .../encoders/GameServerMessageEncoder.java | 29 + .../encoders/GameServerMessageLogger.java | 30 + .../handlers/IdleTimeoutHandler.java | 148 + .../networking/rconserver/RCONServer.java | 110 + .../rconserver/RCONServerHandler.java | 57 + .../websockets/NetworkChannelInitializer.java | 74 + .../websockets/codec/WebSocketCodec.java | 22 + .../handlers/CustomHTTPHandler.java | 64 + .../websockets/ssl/SSLCertificateLoader.java | 24 + .../networking/websockets/utils/Utils.java | 22 + .../main/java/com/eu/habbo/plugin/Event.java | 13 + .../com/eu/habbo/plugin/EventHandler.java | 18 + .../com/eu/habbo/plugin/EventListener.java | 4 + .../com/eu/habbo/plugin/EventPriority.java | 26 + .../java/com/eu/habbo/plugin/HabboPlugin.java | 27 + .../plugin/HabboPluginConfiguration.java | 7 + .../com/eu/habbo/plugin/PluginManager.java | 429 ++ .../plugin/events/bots/BotChatEvent.java | 15 + .../eu/habbo/plugin/events/bots/BotEvent.java | 14 + .../plugin/events/bots/BotPickUpEvent.java | 16 + .../plugin/events/bots/BotPlacedEvent.java | 20 + .../plugin/events/bots/BotSavedChatEvent.java | 29 + .../plugin/events/bots/BotSavedLookEvent.java | 24 + .../plugin/events/bots/BotSavedNameEvent.java | 15 + .../events/bots/BotServerItemEvent.java | 19 + .../plugin/events/bots/BotShoutEvent.java | 10 + .../plugin/events/bots/BotTalkEvent.java | 10 + .../plugin/events/bots/BotWhisperEvent.java | 16 + .../emulator/EmulatorConfigUpdatedEvent.java | 4 + .../plugin/events/emulator/EmulatorEvent.java | 6 + .../EmulatorLoadCatalogManagerEvent.java | 7 + .../EmulatorLoadItemsManagerEvent.java | 7 + .../events/emulator/EmulatorLoadedEvent.java | 9 + .../emulator/EmulatorStartShutdownEvent.java | 7 + .../events/emulator/EmulatorStoppedEvent.java | 7 + .../emulator/SSOAuthenticationEvent.java | 11 + .../furniture/FurnitureBuildheightEvent.java | 30 + .../furniture/FurnitureDiceRolledEvent.java | 16 + .../events/furniture/FurnitureEvent.java | 14 + .../events/furniture/FurnitureMovedEvent.java | 29 + .../furniture/FurniturePickedUpEvent.java | 11 + .../furniture/FurniturePlacedEvent.java | 26 + .../furniture/FurnitureRedeemedEvent.java | 22 + .../furniture/FurnitureRolledEvent.java | 20 + .../furniture/FurnitureRoomTonerEvent.java | 19 + .../furniture/FurnitureRotatedEvent.java | 16 + .../furniture/FurnitureStackHeightEvent.java | 37 + .../furniture/FurnitureToggleEvent.java | 14 + .../events/furniture/FurnitureUserEvent.java | 15 + .../wired/WiredConditionFailedEvent.java | 22 + .../wired/WiredStackExecutedEvent.java | 29 + .../wired/WiredStackTriggeredEvent.java | 29 + .../habbo/plugin/events/games/GameEvent.java | 14 + .../events/games/GameHabboJoinEvent.java | 11 + .../events/games/GameHabboLeaveEvent.java | 11 + .../plugin/events/games/GameStartedEvent.java | 10 + .../plugin/events/games/GameStoppedEvent.java | 10 + .../plugin/events/games/GameUserEvent.java | 16 + .../guilds/GuildAcceptedMembershipEvent.java | 20 + .../events/guilds/GuildChangedBadgeEvent.java | 15 + .../guilds/GuildChangedColorsEvent.java | 19 + .../events/guilds/GuildChangedNameEvent.java | 18 + .../guilds/GuildChangedSettingsEvent.java | 16 + .../guilds/GuildDeclinedMembershipEvent.java | 24 + .../events/guilds/GuildDeletedEvent.java | 16 + .../plugin/events/guilds/GuildEvent.java | 14 + .../events/guilds/GuildFavoriteSetEvent.java | 16 + .../events/guilds/GuildGivenAdminEvent.java | 23 + .../events/guilds/GuildPurchasedEvent.java | 15 + .../events/guilds/GuildRemovedAdminEvent.java | 19 + .../guilds/GuildRemovedFavoriteEvent.java | 15 + .../guilds/GuildRemovedMemberEvent.java | 19 + .../forums/GuildForumThreadBeforeCreated.java | 19 + .../GuildForumThreadCommentBeforeCreated.java | 17 + .../GuildForumThreadCommentCreated.java | 12 + .../forums/GuildForumThreadCreated.java | 12 + .../events/inventory/InventoryEvent.java | 12 + .../inventory/InventoryItemAddedEvent.java | 10 + .../events/inventory/InventoryItemEvent.java | 14 + .../inventory/InventoryItemRemovedEvent.java | 10 + .../inventory/InventoryItemsAddedEvent.java | 14 + .../events/marketplace/MarketPlaceEvent.java | 6 + .../MarketPlaceItemCancelledEvent.java | 11 + .../MarketPlaceItemOfferedEvent.java | 16 + .../marketplace/MarketPlaceItemSoldEvent.java | 18 + .../navigator/NavigatorPopularRoomsEvent.java | 18 + .../navigator/NavigatorRoomCreatedEvent.java | 17 + .../navigator/NavigatorRoomDeletedEvent.java | 15 + .../events/navigator/NavigatorRoomsEvent.java | 19 + .../navigator/NavigatorSearchResultEvent.java | 22 + .../eu/habbo/plugin/events/pets/PetEvent.java | 14 + .../plugin/events/pets/PetTalkEvent.java | 15 + .../habbo/plugin/events/rooms/RoomEvent.java | 14 + .../events/rooms/RoomFloorItemsLoadEvent.java | 30 + .../plugin/events/rooms/RoomLoadedEvent.java | 10 + .../events/rooms/RoomUncachedEvent.java | 10 + .../events/rooms/RoomUnloadedEvent.java | 10 + .../events/rooms/RoomUnloadingEvent.java | 10 + .../events/rooms/UserVoteRoomEvent.java | 15 + .../plugin/events/roomunit/RoomUnitEvent.java | 19 + .../roomunit/RoomUnitLookAtPointEvent.java | 17 + .../events/roomunit/RoomUnitSetGoalEvent.java | 21 + .../events/sanctions/SanctionEvent.java | 17 + .../plugin/events/support/SupportEvent.java | 14 + .../support/SupportRoomActionEvent.java | 28 + .../events/support/SupportTicketEvent.java | 15 + .../SupportTicketStatusChangedEvent.java | 11 + .../support/SupportUserAlertedEvent.java | 20 + .../support/SupportUserAlertedReason.java | 22 + .../support/SupportUserBannedEvent.java | 20 + .../events/support/SupportUserKickEvent.java | 19 + .../events/trading/TradeConfirmEvent.java | 14 + .../events/users/HabboAddedToRoomEvent.java | 21 + .../plugin/events/users/UserCommandEvent.java | 18 + .../plugin/events/users/UserCreditsEvent.java | 15 + .../events/users/UserDisconnectEvent.java | 10 + .../events/users/UserEnterRoomEvent.java | 16 + .../habbo/plugin/events/users/UserEvent.java | 14 + .../events/users/UserExecuteCommandEvent.java | 27 + .../events/users/UserExitRoomEvent.java | 26 + .../events/users/UserGetIPAddressEvent.java | 28 + .../plugin/events/users/UserIdleEvent.java | 23 + .../plugin/events/users/UserKickEvent.java | 15 + .../plugin/events/users/UserLoginEvent.java | 16 + .../events/users/UserNameChangedEvent.java | 14 + .../events/users/UserPickGiftEvent.java | 17 + .../plugin/events/users/UserPointsEvent.java | 19 + .../events/users/UserPublishPictureEvent.java | 22 + .../users/UserPurchasePictureEvent.java | 23 + .../events/users/UserRankChangedEvent.java | 10 + .../events/users/UserRegisteredEvent.java | 10 + .../events/users/UserRespectedEvent.java | 13 + .../events/users/UserRightsGivenEvent.java | 13 + .../events/users/UserRightsTakenEvent.java | 16 + .../plugin/events/users/UserRolledEvent.java | 21 + .../events/users/UserSavedLookEvent.java | 16 + .../events/users/UserSavedMottoEvent.java | 15 + .../events/users/UserSavedSettingsEvent.java | 10 + .../events/users/UserSavedWardrobeEvent.java | 14 + .../plugin/events/users/UserSignEvent.java | 14 + .../events/users/UserTakeStepEvent.java | 20 + .../plugin/events/users/UserTalkEvent.java | 16 + .../users/UserTriggerWordFilterEvent.java | 16 + .../events/users/UserWiredRewardReceived.java | 24 + .../events/users/UsernameTalkEvent.java | 31 + .../achievements/UserAchievementEvent.java | 17 + .../UserAchievementLeveledEvent.java | 21 + .../UserAchievementProgressEvent.java | 16 + .../users/calendar/UserClaimRewardEvent.java | 23 + .../users/catalog/UserCatalogEvent.java | 17 + .../UserCatalogFurnitureBoughtEvent.java | 18 + .../UserCatalogItemPurchasedEvent.java | 32 + .../friends/UserAcceptFriendRequestEvent.java | 11 + .../users/friends/UserFriendChatEvent.java | 16 + .../events/users/friends/UserFriendEvent.java | 16 + .../users/friends/UserRelationShipEvent.java | 15 + .../friends/UserRequestFriendshipEvent.java | 20 + .../UserSubscriptionCreatedEvent.java | 17 + .../UserSubscriptionExpiredEvent.java | 16 + .../UserSubscriptionExtendedEvent.java | 17 + .../habbo/threading/HabboExecutorService.java | 22 + .../RejectedExecutionHandlerImpl.java | 14 + .../com/eu/habbo/threading/ThreadPooling.java | 76 + .../runnables/AchievementUpdater.java | 36 + .../runnables/BackgroundAnimation.java | 31 + .../runnables/BanzaiRandomTeleport.java | 74 + .../runnables/BattleBanzaiTilesFlicker.java | 56 + .../threading/runnables/BotFollowHabbo.java | 59 + .../runnables/CameraClientAutoReconnect.java | 33 + .../threading/runnables/CannonKickAction.java | 50 + .../runnables/CannonResetCooldownAction.java | 18 + .../runnables/ChannelReadHandler.java | 30 + .../threading/runnables/ClearRentedSpace.java | 47 + .../habbo/threading/runnables/CloseGate.java | 27 + .../threading/runnables/CrackableExplode.java | 74 + .../runnables/GuardianNotAccepted.java | 28 + .../GuardianTicketFindMoreSlaves.java | 17 + .../runnables/GuardianVotingFinish.java | 22 + .../runnables/GuideFindNewHelper.java | 29 + .../runnables/HabboGiveHandItemToHabbo.java | 36 + .../runnables/HabboItemNewState.java | 25 + .../runnables/InsertModToolIssue.java | 51 + .../threading/runnables/KickBallAction.java | 79 + .../runnables/LoadCustomHeightMap.java | 17 + .../runnables/OneWayGateActionOne.java | 50 + .../habbo/threading/runnables/OpenGift.java | 107 + .../threading/runnables/PetClearPosture.java | 35 + .../threading/runnables/PetEatAction.java | 60 + .../threading/runnables/PetFollowHabbo.java | 49 + .../runnables/QueryDeleteHabboBadge.java | 30 + .../runnables/QueryDeleteHabboItem.java | 31 + .../runnables/QueryDeleteHabboItems.java | 37 + .../threading/runnables/RandomDiceNumber.java | 42 + .../runnables/RemoveFloorItemTask.java | 29 + .../threading/runnables/RoomTrashing.java | 143 + .../runnables/RoomUnitGiveHanditem.java | 25 + .../threading/runnables/RoomUnitKick.java | 26 + .../threading/runnables/RoomUnitRidePet.java | 48 + .../threading/runnables/RoomUnitTeleport.java | 73 + .../RoomUnitTeleportWalkToAction.java | 47 + .../RoomUnitVendingMachineAction.java | 47 + .../runnables/RoomUnitWalkToLocation.java | 68 + .../runnables/RoomUnitWalkToRoomUnit.java | 82 + .../threading/runnables/SaveScoreForTeam.java | 44 + .../runnables/SendRoomUnitEffectComposer.java | 22 + .../threading/runnables/ShutdownEmulator.java | 24 + .../runnables/TeleportInteraction.java | 129 + .../runnables/UpdateModToolIssue.java | 33 + .../runnables/WiredCollissionRunnable.java | 24 + .../threading/runnables/WiredExecuteTask.java | 42 + .../runnables/WiredRepeatEffectTask.java | 28 + .../threading/runnables/WiredResetTimers.java | 20 + .../threading/runnables/YouAreAPirate.java | 103 + .../runnables/YoutubeAdvanceVideo.java | 33 + .../runnables/freeze/FreezeClearEffects.java | 21 + .../freeze/FreezeHandleSnowballExplosion.java | 108 + .../freeze/FreezeResetExplosionTiles.java | 24 + .../runnables/freeze/FreezeThrowSnowball.java | 33 + .../threading/runnables/games/GameTimer.java | 46 + .../runnables/hopper/HopperActionFive.java | 31 + .../runnables/hopper/HopperActionFour.java | 26 + .../runnables/hopper/HopperActionOne.java | 39 + .../runnables/hopper/HopperActionThree.java | 64 + .../runnables/hopper/HopperActionTwo.java | 57 + .../teleport/TeleportActionFive.java | 77 + .../teleport/TeleportActionFour.java | 34 + .../runnables/teleport/TeleportActionOne.java | 44 + .../teleport/TeleportActionThree.java | 80 + .../runnables/teleport/TeleportActionTwo.java | 99 + .../src/main/java/com/eu/habbo/util/ANSI.java | 16 + .../java/com/eu/habbo/util/DebugUtils.java | 22 + .../main/java/com/eu/habbo/util/HexUtils.java | 41 + .../java/com/eu/habbo/util/PacketUtils.java | 19 + .../eu/habbo/util/callback/HTTPPostError.java | 55 + .../habbo/util/callback/HTTPPostStatus.java | 40 + .../habbo/util/callback/HTTPVersionCheck.java | 68 + .../java/com/eu/habbo/util/crypto/ZIP.java | 27 + .../com/eu/habbo/util/figure/FigureUtil.java | 71 + .../habbo/util/imager/badges/BadgeImager.java | 247 + .../util/logback/SqlExceptionFilter.java | 23 + .../eu/habbo/util/pathfinding/Rotation.java | 25 + Emulator/src/main/resources/logback.xml | 71 + 1824 files changed, 109921 insertions(+) create mode 100644 Emulator/.gitignore create mode 100644 Emulator/.gitlab-ci.yml create mode 100644 Emulator/.gitmodules create mode 100644 Emulator/Dockerfile create mode 100644 Emulator/Example_Start/Linux/emulator create mode 100644 Emulator/Example_Start/Windows/emulator.cmd create mode 100644 Emulator/LICENSE create mode 100644 Emulator/featurelist.md create mode 100644 Emulator/pom.xml create mode 100644 Emulator/src/main/java/com/eu/habbo/Emulator.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/CleanerThread.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/CommandLog.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/ConfigurationManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/CreditsScheduler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/CryptoConfig.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/DatabaseLoggable.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/DatabaseLogger.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/Disposable.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/Easter.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/ErrorLog.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/GotwPointsScheduler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/Logging.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/PixelScheduler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/PointsScheduler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/RoomUserPetComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/Scheduler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/TextsManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleInfoCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleReconnectCameraCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleShutdownCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleTestCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/consolecommands/ShowInteractionsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/consolecommands/ShowRCONCommands.java create mode 100644 Emulator/src/main/java/com/eu/habbo/core/consolecommands/ThankyouArcturusCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/crypto/HabboDiffieHellman.java create mode 100644 Emulator/src/main/java/com/eu/habbo/crypto/HabboEncryption.java create mode 100644 Emulator/src/main/java/com/eu/habbo/crypto/HabboRC4.java create mode 100644 Emulator/src/main/java/com/eu/habbo/crypto/HabboRSACrypto.java create mode 100644 Emulator/src/main/java/com/eu/habbo/crypto/exceptions/HabboCryptoException.java create mode 100644 Emulator/src/main/java/com/eu/habbo/crypto/utils/BigIntegerUtils.java create mode 100644 Emulator/src/main/java/com/eu/habbo/database/Database.java create mode 100644 Emulator/src/main/java/com/eu/habbo/database/DatabasePool.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/GameEnvironment.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/LatencyTracker.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/Achievement.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/AchievementCategories.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/AchievementLevel.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/AchievementManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/TalentTrackLevel.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/TalentTrackType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/bots/Bot.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/bots/BotManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/bots/ButlerBot.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/bots/VisitorBot.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarCampaign.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardClaimed.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardObject.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogFeaturedPage.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogItem.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogLimitedConfiguration.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPage.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPageLayouts.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPageType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPurchaseLogEntry.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/ClothItem.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/ClubOffer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/TargetOffer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/Voucher.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/VoucherHistoryEntry.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BadgeDisplayLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BotsLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BuildersClubAddonsLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BuildersClubFrontPageLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BuildersClubLoyaltyLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/CatalogRootLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ClubBuyLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ClubGiftsLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ColorGroupingLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/Default_3x3Layout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/FrontPageFeaturedLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/FrontpageLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/GuildForumLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/GuildFrontpageLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/GuildFurnitureLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoDucketsLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoLoyaltyLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoMonkeyLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoNikoLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoPetsLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoRentablesLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/LoyaltyVipBuyLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/MadMoneyLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/MarketplaceLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/MarketplaceOwnItems.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/PetCustomizationLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/Pets2Layout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/Pets3Layout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/PetsLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ProductPage1Layout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RecentPurchasesLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RecyclerInfoLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RecyclerLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RecyclerPrizesLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RoomAdsLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RoomBundleLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/SingleBundle.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/SoldLTDItemsLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/SpacesLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/TraxLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/TrophiesLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/VipBuyLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlace.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlaceOffer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlaceState.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/AboutCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/AddYoutubePlaylistCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/AlertCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/AllowTradingCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ArcturusCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/BadgeCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/BanCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/BlockAlertCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/BotsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CalendarCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ChangeNameCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ChatTypeCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/Command.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CommandHandler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CommandsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ConnectCameraCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ControlCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CoordsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CreditsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/DiagonalCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/DisconnectCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EjectAllCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EmptyBotsInventoryCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EmptyInventoryCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EmptyPetsInventoryCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EnableCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EventCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FacelessCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FastwalkCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FilterWordCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FreezeBotsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FreezeCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/GiftCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/GiveRankCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HabnamCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HandItemCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HappyHourCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HideWiredCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HotelAlertCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HotelAlertLinkCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/IPBanCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/InvisibleCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/LayCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MachineBanCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassBadgeCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassCreditsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassGiftCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassPixelsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassPointsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MimicCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MoonwalkCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MultiCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MuteBotsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MuteCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MutePetsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PetInfoCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PickallCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PingCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PixelCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PluginsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PointsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PromoteTargetOfferCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PullCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PushCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RedeemCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ReloadRoomCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomAlertCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomBadgeCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomBundleCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomCreditsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomDanceCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomEffectCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomGiftCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomItemCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomKickCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomMuteCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomPixelsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomPointsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SayAllCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SayCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SetMaxCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SetPollCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SetSpeedCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ShoutAllCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ShoutCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ShutdownCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SitCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SitDownCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SoftKickCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/StaffAlertCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/StaffOnlineCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/StalkCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/StandCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SubscriptionCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SummonCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SummonRankCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SuperPullCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SuperbanCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TakeBadgeCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TeleportCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TestCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TransformCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TrashCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UnbanCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UnloadRoomCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UnmuteCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateAchievements.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateBotsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateCalendarCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateCatalogCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateConfigCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateGuildPartsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateHotelViewCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateItemsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateNavigatorCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdatePermissionsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdatePetDataCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdatePluginsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdatePollsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateTextsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateWordFilterCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateYoutubePlaylistsCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UserInfoCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/commands/WordQuizCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/crafting/CraftingAltar.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/crafting/CraftingManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/crafting/CraftingRecipe.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/gameclients/GameClient.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/gameclients/GameClientManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/Game.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/GamePlayer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/GameState.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/GameTeam.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/GameTeamColors.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGame.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGamePlayer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGameTeam.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/football/FootballGame.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/freeze/FreezeGame.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/freeze/FreezeGamePlayer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/freeze/FreezeGameTeam.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/BunnyrunGame.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/IceTagGame.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/RollerskateGame.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/TagGame.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/TagGamePlayer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/games/wired/WiredGame.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuardianTicket.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuardianVote.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuardianVoteType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuideChatMessage.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuideManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuideRecommendStatus.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuideTour.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/Guild.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildMember.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildMembershipStatus.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildPart.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildPartType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildRank.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildState.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/SettingsState.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumThread.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumThreadComment.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumThreadState.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumView.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/HallOfFame.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/HallOfFameWinner.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/HotelViewManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/NewsList.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/NewsWidget.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/CrackableReward.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/FurnitureType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/ICycleable.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/IEventTriggers.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/Item.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/ItemInteraction.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/ItemManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/NewUserGift.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/PostItColor.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/RandomStateParams.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/RedeemableSubscriptionType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/SoundTrack.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/YoutubeManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBackgroundToner.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBadgeDisplay.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBlackHole.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBuildArea.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCannon.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionClothing.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionColorPlate.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionColorWheel.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCostumeHopper.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCrackable.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCrackableMaster.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCustomValues.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionDefault.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionDice.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectGate.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectGiver.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectTile.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectToggle.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectVendingMachine.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectVendingMachineNoSides.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionExternalImage.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionFXBox.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionFireworks.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGate.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGift.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGroupEffectTile.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGroupPressurePlate.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGuildFurni.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGuildGate.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGymEquipment.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHabboClubGate.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHabboClubHopper.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHabboClubTeleportTile.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHanditem.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHanditemTile.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHopper.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionInformationTerminal.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionJukeBox.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionLoveLock.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMannequin.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMonsterCrackable.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMoodLight.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMultiHeight.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMusicDisc.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMuteArea.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionNoSidesVendingMachine.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionObstacle.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionOneWayGate.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPostIt.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPoster.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPressurePlate.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPushable.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPuzzleBox.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPyramid.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRandomState.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRedeemableSubscriptionBox.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRentableSpace.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRoller.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRoomAds.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRoomOMatic.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionSnowboardSlope.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionStackHelper.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionStickyPole.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionSwitch.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTalkingFurniture.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTeleport.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTeleportTile.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTileEffectProvider.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTrap.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTrophy.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionVendingMachine.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionVikingCotie.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionVoteCounter.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWater.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWaterItem.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWired.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredCondition.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredEffect.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredExtra.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredHighscore.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredTrigger.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionYoutubeTV.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameGate.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameScoreboard.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameTeamItem.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameTimer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiPuck.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiSphere.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiTeleporter.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiTile.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGate.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGateBlue.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGateGreen.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGateRed.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGateYellow.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboard.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboardBlue.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboardGreen.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboardRed.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboardYellow.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionFootball.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionFootballGate.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoal.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoalBlue.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoalGreen.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoalRed.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoalYellow.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboard.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboardBlue.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboardGreen.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboardRed.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboardYellow.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/InteractionFreezeBlock.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/InteractionFreezeExitTile.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/InteractionFreezeTile.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGate.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGateBlue.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGateGreen.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGateRed.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGateYellow.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboard.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboardBlue.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboardGreen.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboardRed.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboardYellow.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/InteractionTagField.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/InteractionTagPole.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/bunnyrun/InteractionBunnyrunField.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/bunnyrun/InteractionBunnyrunPole.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/icetag/InteractionIceTagField.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/icetag/InteractionIceTagPole.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/rollerskate/InteractionRollerskateField.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/interfaces/ConditionalGate.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionMonsterPlantSeed.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionNest.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionPetBreedingNest.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionPetDrink.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionPetFood.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionPetToy.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/InteractionTotemHead.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/InteractionTotemLegs.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/InteractionTotemPlanet.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/TotemColor.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/TotemPlanetType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/TotemType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/WiredSettings.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/WiredSuper.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/WiredTriggerReset.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionDateRangeActive.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniHaveFurni.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniHaveHabbo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniTypeMatch.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionGroupMember.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHabboCount.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHabboHasEffect.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHabboHasHandItem.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHabboWearsBadge.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionLessTimeElapsed.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMatchStatePosition.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMoreTimeElapsed.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniHaveFurni.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniHaveHabbo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniTypeMatch.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotHabboCount.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotHabboHasEffect.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotHabboWearsBadge.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotInGroup.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotInTeam.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotMatchStatePosition.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotTriggerOnFurni.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTeamMember.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTriggerOnFurni.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectAlert.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotClothes.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotFollowHabbo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotGiveHandItem.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTalk.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTalkToHabbo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTeleport.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotWalkToFurni.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectChangeFurniDirection.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveEffect.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveHandItem.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveHotelviewBonusRarePoints.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveHotelviewHofPoints.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveRespect.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveReward.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScore.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScoreToTeam.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectJoinTeam.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectKickHabbo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectLeaveTeam.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMatchFurni.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniAway.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniTo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniTowards.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveRotateFurni.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMuteHabbo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectResetTimers.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectTeleport.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectToggleFurni.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectToggleRandom.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectTriggerStacks.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectWhisper.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredBlob.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredExtraRandom.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredExtraUnseen.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/interfaces/InteractionWiredMatchFurniSettings.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerAtSetTime.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerAtTimeLong.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerBotReachedFurni.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerBotReachedHabbo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerCollision.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerFurniStateToggled.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerGameEnds.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerGameStarts.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboEntersRoom.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboSaysKeyword.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboWalkOffFurni.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboWalkOnFurni.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerRepeater.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerRepeaterLong.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerScoreAchieved.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerTeamLoses.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerTeamWins.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/FriendRequest.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/Message.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/Messenger.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/MessengerBuddy.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/MessengerCategory.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/CfhActionType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/CfhCategory.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/CfhTopic.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolBan.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolBanType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolCategory.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolChatLog.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolChatRecordDataContext.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolChatRecordDataType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolChatlogType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolIssue.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolIssueChatlogType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolPreset.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolRoomVisit.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolSanctionItem.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolSanctionLevelItem.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolSanctions.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolTicketState.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolTicketType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ScripterEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ScripterManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/WordFilter.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/WordFilterWord.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/DisplayMode.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/DisplayOrder.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/EventCategory.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/ListMode.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorFavoriteFilter.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorFilter.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorFilterComparator.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorFilterField.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorHotelFilter.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorPublicCategory.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorPublicFilter.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorRoomAdsFilter.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorSavedSearch.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorUserFilter.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/SearchAction.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/SearchResultList.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/Permission.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/PermissionSetting.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/PermissionsManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/Rank.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/GnomePet.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/HorsePet.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/IPetLook.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/MonsterplantPet.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/Pet.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetAction.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetBreedingReward.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetData.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetGestures.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetRace.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetTasks.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetVocal.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetVocalsType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/RideablePet.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionBeg.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionBreatheFire.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionBreed.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionCroak.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionDip.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionDown.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionDrink.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionEat.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionFollow.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionFollowLeft.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionFollowRight.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionFree.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionHere.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionJump.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionMoveForward.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionNest.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionPlay.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionPlayDead.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionPlayFootball.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionRelax.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionSilent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionSit.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionSpeak.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionStand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionStay.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionTorch.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionTurnLeft.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionTurnRight.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionWave.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionWings.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/polls/Poll.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/polls/PollManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/polls/PollQuestion.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/CustomRoomLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/FurnitureMovementError.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomBan.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomCategory.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatMessage.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatMessageBubbles.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomLayout.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomMoodlightData.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomPromotion.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomRightLevels.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomSpecialTypes.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomState.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTile.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTileState.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTrade.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTradeUser.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnit.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitEffect.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitStatus.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUserAction.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUserRotation.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/TraxManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/DanceType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboBadge.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboGender.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboInfo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboInventory.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboItem.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboNavigatorPersonalDisplayMode.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboNavigatorWindowSettings.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/SignType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/cache/HabboOfferPurchase.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/ClothingValidationManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/Figuredata.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataPalette.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataPaletteColor.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataSettype.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataSettypeSet.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/BotsComponent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/EffectsComponent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/ItemsComponent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/PetsComponent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/WardrobeComponent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/HcPayDayLogEntry.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/Subscription.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionHabboClub.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionScheduler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredChangeDirectionSetting.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredConditionOperator.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredConditionType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredEffectType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredGiveRewardItem.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredHandler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredMatchFurniSetting.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredTriggerType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreClearType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreDataEntry.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreRow.java create mode 100644 Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreScoreType.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/ClientMessage.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/ICallable.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/ISerialize.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/NoAuthMessage.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/PacketManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/PacketNames.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/ServerMessage.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/ServerMessageException.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/Incoming.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/MessageHandler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/achievements/RequestAchievementConfigurationEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/achievements/RequestAchievementsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/ambassadors/AmbassadorAlertCommandEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/ambassadors/AmbassadorVisitCommandEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/CameraPublishToWebEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/CameraPurchaseEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/CameraRoomPictureEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/CameraRoomThumbnailEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/RequestCameraConfigurationEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyClubDiscountEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyItemAsGiftEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogRequestClubDiscountEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogSearchedItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogSelectClubGiftEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CheckPetNameEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/JukeBoxRequestTrackCodeEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/JukeBoxRequestTrackDataEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/PurchaseTargetOfferEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RedeemVoucherEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestCatalogIndexEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestCatalogModeEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestCatalogPageEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestClubDataEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestClubGiftsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestDiscountEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestGiftConfigurationEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestMarketplaceConfigEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestPetBreedsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/TargetOfferStateEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/BuyItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestCreditsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestItemInfoEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestOffersEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestOwnItemsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestSellItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/SellItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/TakeBackItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/OpenRecycleBoxEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/RecycleEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/ReloadRecyclerEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/RequestRecyclerLogicEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingAddRecipeEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingCraftItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingCraftSecretEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/RequestCraftingRecipesAvailableEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/RequestCraftingRecipesEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarForceOpenEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarOpenDayEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorRequestBlockedTilesEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorRequestDoorSettingsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorSaveEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/AcceptFriendRequestEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/ChangeRelationEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/DeclineFriendRequestEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/FindNewFriendsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/FriendListUpdateEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/FriendPrivateMessageEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/FriendRequestEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/InviteFriendsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/RemoveFriendEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/RequestFriendRequestsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/RequestFriendsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/RequestInitFriendsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/SearchUserEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/StalkFriendEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterJoinGameEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterLeaveGameEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterLoadGameEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterRequestAccountStatusEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterRequestGameStatusEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterRequestGamesEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guardians/GuardianAcceptRequestEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guardians/GuardianNoUpdatesWantedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guardians/GuardianVoteEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideCancelHelpRequestEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideCloseHelpRequestEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideHandleHelpRequestEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideInviteUserEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideRecommendHelperEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideReportHelperEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideUserMessageEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideUserTypingEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideVisitUserEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/RequestGuideAssistanceEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/RequestGuideToolEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GetHabboGuildBadgesMessageEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildAcceptMembershipEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeBadgeEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeColorsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeNameDescEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeSettingsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildConfirmRemoveMemberEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildDeclineMembershipEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildDeleteEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildRemoveAdminEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildRemoveFavoriteEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildRemoveMemberEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildSetAdminEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildSetFavoriteEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildBuyEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildBuyRoomsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildFurniWidgetEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildInfoEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildJoinEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildManageEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildMembersEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildPartsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestOwnGuildsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumDataEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumListEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateMessageEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateThreadEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumPostThreadEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadUpdateEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadsMessagesEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumUpdateSettingsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/CompleteDiffieHandshakeEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/InitDiffieHandshakeEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/IsFirstLoginOfDayComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/MachineIDEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/PingEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/ReleaseVersionEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/UsernameEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/helper/MySanctionStatusEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/helper/RequestTalentTrackEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewClaimBadgeRewardEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewDataEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewRequestBadgeRewardEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewRequestBonusRareEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewRequestLTDAvailabilityEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewRequestSecondsUntilEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/RequestNewsListEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryBadgesEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryBotsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryItemsDelete.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryItemsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryPetsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolAlertEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolChangeRoomSettingsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolCloseTicketEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolIssueChangeTopicEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolIssueDefaultSanctionEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolKickEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolPickTicketEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolReleaseTicketEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestIssueChatlogEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestRoomChatlogEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestRoomInfoEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestRoomUserChatlogEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestRoomVisitsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestUserChatlogEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestUserInfoEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRoomAlertEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolSanctionAlertEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolSanctionBanEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolSanctionMuteEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolSanctionTradeLockEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolWarnEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportBullyEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportCommentEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportFriendPrivateChatEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportPhotoEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportThreadEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/RequestReportRoomEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/RequestReportUserBullyingEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/StartSafetyQuizEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/AddSavedSearchEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/DeleteSavedSearchEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/NavigatorCategoryListModeEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/NavigatorCollapseCategoryEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/NavigatorUncollapseCategoryEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/NewNavigatorActionEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestCanCreateRoomEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestCreateRoomEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestDeleteRoomEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestHighestScoreRoomsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestMyRoomsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestNavigatorSettingsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestNewNavigatorDataEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestNewNavigatorRoomsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestPopularRoomsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestPromotedRoomsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestPublicRoomsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestRoomCategoriesEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestTagsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SaveWindowSettingsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsByTagEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsFriendsNowEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsFriendsOwnEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsInGroupEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsMyFavouriteEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsVisitedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsWithRightsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/polls/AnswerPollEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/polls/CancelPollEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/polls/GetPollDataEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/HandleDoorbellEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestHeightmapEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomDataEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomHeightmapEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomLoadEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomRightsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomSettingsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomWordFilterEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomBackgroundEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomFavoriteEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomMuteEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomPlacePaintEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomRemoveAllRightsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomRemoveRightsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomRequestBannedUsersEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomSettingsSaveEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomStaffPickEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomUnFavoriteEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomVoteEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomWordFilterModifyEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/SetHomeRoomEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotPickupEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotPlaceEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotSaveSettingsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotSettingsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/AdvertisingSaveEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/CloseDiceEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/FootballGateSaveLookEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MannequinSaveLookEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MannequinSaveNameEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoodLightSaveSettingsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoodLightSettingsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoodLightTurnOnEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoveWallItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItDeleteEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItPlaceEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItRequestDataEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItSaveDataEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RedeemClothingEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RedeemItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPickupItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPlaceItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RotateMoveItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/SavePostItStickyPoleEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/SetStackHelperHeightEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/ToggleFloorItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/ToggleWallItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/TriggerColorWheelEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/TriggerDiceEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/TriggerOneWayGateEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/UseRandomStateItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxAddSoundTrackEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxEventOne.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxEventTwo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxRemoveSoundTrackEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxRequestPlayListEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/lovelock/LoveLockStartConfirmEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/rentablespace/RentSpaceCancelEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/rentablespace/RentSpaceEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestPlaylistChange.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestPlaylists.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestStateChange.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/BreedMonsterplantsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/CompostMonsterplantEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/ConfirmPetBreedingEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/HorseRemoveSaddleEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/MovePetEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetPackageNameEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetPickupEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetPlaceEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetRideEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetRideSettingsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetUseItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/RequestPetInformationEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/RequestPetTrainingPanelEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/ScratchPetEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/StopBreedingEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/ToggleMonsterplantBreedableEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/promotions/BuyRoomPromotionEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/promotions/RequestPromotionRoomsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/promotions/UpdateRoomPromotionEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/IgnoreRoomUserEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RequestRoomUserTagsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserActionEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserBanEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserDanceEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserDropHandItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserGiveHandItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserGiveRespectEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserGiveRightsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserKickEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserLookAtPoint.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserMuteEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserRemoveRightsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserShoutEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserSignEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserSitEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserStartTypingEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserStopTypingEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserTalkEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserWalkEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserWhisperEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/UnIgnoreRoomUserEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/UnbanRoomUserEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeAcceptEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeCancelEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeCancelOfferItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeCloseEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeConfirmEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeOfferItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeOfferMultipleItemsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeStartEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeUnAcceptEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/unknown/RequestResolutionEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/unknown/UnknownEvent1.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/unknown/UnknownEvent2.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/ActivateEffectEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/ChangeChatBubbleEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/ChangeNameCheckUsernameEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/ConfirmChangeNameEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/EnableEffectEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/PerformanceLogMessageEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/PickNewUserGiftEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestClubCenterEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestMeMenuSettingsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestProfileFriendsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserCitizinShipEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserClubEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserCreditsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserDataEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserProfileEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserWardrobeEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestWearingBadgesEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveBlockCameraFollowEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveIgnoreRoomInvitesEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveMottoEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SavePreferOldChatEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveUserVolumesEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveWardrobeEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UpdateUIFlagsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UserActivityEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UserNuxEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UserSaveLookEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UserWearBadgeEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredApplySetConditionsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredConditionSaveDataEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredEffectSaveDataEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredSaveException.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredTriggerSaveDataEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/MessageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/Outgoing.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/AchievementListComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/AchievementProgressComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/AchievementUnlockedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/talenttrack/TalentLevelUpdateComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/talenttrack/TalentTrackComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraCompetitionStatusComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraPriceComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraPublishWaitMessageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraPurchaseSuccesfullComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraRoomThumbnailSavedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraURLComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/AlertLimitedSoldOutComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/AlertPurchaseFailedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/AlertPurchaseUnavailableComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogModeComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogPageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogPagesListComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogSearchResultComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogUpdatedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/ClubCenterDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/ClubDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/ClubGiftsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/DiscountComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/GiftConfigurationComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/GiftReceiverNotFoundComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/NotEnoughPointsTypeComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/PetBoughtNotificationComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/PetBreedsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/PetNameErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/PurchaseOKComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/RecyclerCompleteComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/RecyclerLogicComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/RedeemVoucherErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/RedeemVoucherOKComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/ReloadRecyclerComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/TargetedOfferComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceBuyErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceCancelSaleComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceConfigComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceItemInfoComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceItemPostedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceOffersComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceOwnItemsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceSellItemComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/crafting/CraftableProductsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/crafting/CraftingRecipeComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/crafting/CraftingRecipesAvailableComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/crafting/CraftingResultComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarProductComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/mysticbox/MysticBoxCloseComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/mysticbox/MysticBoxPrizeComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/mysticbox/MysticBoxStartOpenComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/resolution/NewYearResolutionCompletedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/resolution/NewYearResolutionComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/resolution/NewYearResolutionProgressComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/floorplaneditor/FloorPlanEditorBlockedTilesComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/floorplaneditor/FloorPlanEditorDoorSettingsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendChatMessageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendFindingRoomComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendNotificationComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendRequestComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendRequestErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/LoadFriendRequestsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/MessengerInitComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/RemoveFriendComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/RoomInviteComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/RoomInviteErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/StalkErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/UpdateFriendComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/UserSearchResultComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/GameCenterAccountInfoComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/GameCenterAchievementsConfigurationComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/GameCenterGameComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/GameCenterGameListComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpJoinQueueComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpLeaveQueueComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpLoadGameComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpLoadGameURLComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpUnloadGameComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/MinimailCountComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/PickMonthlyClubGiftNotificationComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/BotErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/BubbleAlertComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/BubbleAlertKeys.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/CustomNotificationComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/GenericAlertComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/GenericErrorMessagesComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/HotelClosedAndOpensComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/HotelClosesAndWillOpenAtComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/HotelWillCloseInMinutesAndBackInComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/HotelWillCloseInMinutesComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/MessagesForYouComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/PetErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/StaffAlertAndOpenHabboWayComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/StaffAlertWIthLinkAndOpenHabboWayComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/StaffAlertWithLinkComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/UpdateFailedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/testcomposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianNewReportReceivedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianVotingRequestedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianVotingResultComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianVotingTimeEnded.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianVotingVotesComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/BullyReportClosedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionAttachedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionDetachedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionEndedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionInvitedToGuideRoomComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionMessageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionPartnerIsPlayingComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionPartnerIsTypingComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionRequesterRoomComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionStartedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideToolsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildAcceptMemberErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildBoughtComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildBuyRoomsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildConfirmRemoveMemberComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildEditFailComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildFavoriteRoomUserUpdateComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildFurniWidgetComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildInfoComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildJoinErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildListComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildManageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildMemberUpdateComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildMembersComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildPartsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildRefreshMembersListComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/RemoveGuildFromRoomComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumAddCommentComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumCommentsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumListComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumThreadMessagesComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumThreadsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumsUnreadMessagesCountComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/PostUpdateMessageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/ThreadUpdatedMessageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/HabboWayQuizComposer1.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/HabboWayQuizComposer2.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/nux/NewUserGiftComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/nux/NewUserIdentityComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/nux/NuxAlertComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/AvailabilityStatusMessageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/CompleteDiffieHandshakeComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/ConnectionErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/EnableNotificationsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/InitDiffieHandshakeComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/MachineIDComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/PingComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/PongComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/SecureLoginOKComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/BonusRareComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HallOfFameComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewBadgeButtonConfigComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewCatalogPageExpiringComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewCommunityGoalComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewConcurrentUsersComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewCustomTimerComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewExpiringCatalogPageCommposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewHideCommunityVoteButtonComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewNextLTDAvailableComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewSecondsUntilComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/NewsListComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/AddBotComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/AddHabboItemComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/AddPetComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/EffectsListAddComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/EffectsListEffectEnableComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/EffectsListRemoveComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryAchievementsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryBadgesComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryBotsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryItemsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryPetsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryRefreshComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryUpdateItemComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/RemoveBotComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/RemoveHabboItemComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/RemovePetComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/UserEffectsListComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/BullyReportRequestComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/BullyReportedMessageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/CfhTopicsMessageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/HelperRequestDisabledComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueChatlogComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueHandledComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueHandlerDimensionsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueInfoComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueResponseAlertComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueUpdateComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolReportReceivedAlertComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolRoomChatlogComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolRoomInfoComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolSanctionInfoComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolUserChatlogComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolUserInfoComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolUserRoomVisitsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ReportRoomFormComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/mysterybox/MysteryBoxKeysComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/CanCreateEventComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/CanCreateRoomComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorCategoryUserCountComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorCollapsedCategoriesComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorEventCategoriesComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorLiftedRoomsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorMetaDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorSavedSearchesComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorSearchResultsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorSettingsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/OpenRoomCreationWindowComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/PrivateRoomsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/RoomCategoriesComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/RoomCreatedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/TagsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/PollQuestionsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/PollStartComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/infobus/SimplePollAnswerComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/infobus/SimplePollAnswersComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/infobus/SimplePollStartComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestCompletedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestExpiredComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestionInfoComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/BotForceOpenContextMenuComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/BotSettingsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/DoorbellAddUserComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/FavoriteRoomChangedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/FloodCounterComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/ForwardToRoomComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/FreezeLivesComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/HideDoorbellComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/KnockKnockUnknownComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomAccessDeniedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomAddRightsListComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomBannedUsersComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomChatSettingsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomEditSettingsErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomEnterErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomEntryInfoComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomFilterWordsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomFloorThicknessUpdatedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomHeightMapComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomModelComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomMutedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomNoRightsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomOpenComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomOwnerComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomPaintComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomPaneComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomQueueStatusMessage.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRelativeMapComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRemoveRightsListComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRightsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRightsListComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomScoreComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomSettingsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomSettingsSavedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomSettingsUpdatedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomThicknessComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/UpdateStackHeightComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/AddFloorItemComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/AddWallItemComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/FloorItemOnRollerComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/FloorItemUpdateComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/ItemExtraDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/ItemIntStateComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/ItemStateComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/ItemsDataUpdateComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/MoodLightDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/PostItDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/PostItStickyPoleOpenComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/PresentItemOpenedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RemoveFloorItemComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RemoveWallItemComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RoomFloorItemsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RoomWallItemsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/UpdateStackHeightTileHeightComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/WallItemUpdateComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxMySongsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxNowPlayingMessageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxPlayListAddSongComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxPlayListComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxPlayListUpdatedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxPlaylistFullComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxTrackCodeComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxTrackDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/lovelock/LoveLockFurniFinishedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/lovelock/LoveLockFurniFriendConfirmedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/lovelock/LoveLockFurniStartComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/rentablespaces/RentableSpaceInfoComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/rentablespaces/RentableSpaceUnknown2Composer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/rentablespaces/RentableSpaceUnknownComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/youtube/YoutubeDisplayListComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/youtube/YoutubeStateChangeComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/youtube/YoutubeVideoComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/CantScratchPetNotOldEnoughComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetInformationComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetLevelUpComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetLevelUpdatedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetPackageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetPackageNameValidationComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetStatusUpdateComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetTrainingPanelComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetExperienceComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetHorseFigureComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetRespectComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingCompleted.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingFailedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingResultComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingStartComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingStartFailedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/promotions/PromoteOwnRoomsListComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/promotions/RoomPromotionMessageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/ChangeNameUpdatedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUnitIdleComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUnitOnRollerComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserActionComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserDanceComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserEffectComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserHandItemComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserIgnoredComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserNameChangedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserReceivedHandItemComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserRemoveComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserRemoveRightsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserRespectComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserShoutComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserStatusComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserTagsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserTalkComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserTypingComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserUnbannedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserWhisperComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUsersAddGuildBadgeComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUsersComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUsersGuildBadgesComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/OtherTradingDisabledComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeAcceptedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeCloseWindowComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeClosedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeCompleteComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeStartComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeStartFailComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeUpdateComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradingWaitingConfirmComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/YouTradingDisabledComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/BuildersClubExpiredComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/CloseWebPageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/CompetitionEntrySubmitResultComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ConvertedForwardToRoomComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/EpicPopupFrameComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ErrorLoginComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ExtendClubMessageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/HabboMallComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/IgnoredUsersComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/MessengerErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/MinimailNewMessageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ModToolComposerOne.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ModToolSanctionDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/MostUselessErrorAlertComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/MysteryPrizeComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RemoveRoomEventComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RentableItemBuyOutPriceComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomAdErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomCategoryUpdateMessageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomMessagesPostedCountComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomUnknown3Composer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomUserQuestionAnsweredComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsAddUserComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsCompose1.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsFullGameStatusComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsGameStartedErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsGenericErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsInitGameArena.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsJoinErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsLevelDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsLoadingArenaComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsLongDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsOnGameEnding.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsOnStageEnding.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsOnStageRunningComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsOnStageStartComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsPlayNowWindowComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsPreviousRoomComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsQuePositionComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsQuickJoinComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsRemoveUserComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsResetTimerComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsStartLobbyCounter.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsUnknownComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsUserChatComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsUserEnteredArenaComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsUserExitArenaComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/TalentTrackEmailFailedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/TalentTrackEmailVerifiedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownAdManagerComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownAvatarEditorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownCatalogPageOfferComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownCompetitionComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownComposer4.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownComposer8.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownFurniModelComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownGuild2Composer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownGuildComposer3.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownHabboWayQuizComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownHelperComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownHintComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownMessengerErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownPollQuestionComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownRoomDesktopComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownRoomViewerComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownStatusComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownTradeComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnkownPetPackageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UserClassificationComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/VipTutorialsStartComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/WatchAndEarnRewardComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/WelcomeGiftComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/WelcomeGiftErrorComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/AddUserBadgeComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/ChangeNameCheckResultComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/ClubGiftReceivedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/FavoriteRoomsCountComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/MeMenuSettingsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/MutedWhisperComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/ProfileFriendsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UpdateUserLookComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserAchievementScoreComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserBCLimitsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserBadgesComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserCitizinShipComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserClothesComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserClubComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserCreditsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserCurrencyComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserHomeRoomComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserPerksComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserPermissionsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserPointsComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserProfileComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserWardrobeComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/verification/VerifyMobileNumberComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/verification/VerifyMobilePhoneCodeWindowComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/verification/VerifyMobilePhoneDoneComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/verification/VerifyMobilePhoneWindowComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredConditionDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredEffectDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredOpenComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredRewardAlertComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredSavedComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredTriggerDataComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/AlertUser.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/ChangeRoomOwner.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/ChangeUsername.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/CreateModToolTicket.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/DisconnectUser.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/ExecuteCommand.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/ForwardUser.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/FriendRequest.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/GiveBadge.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/GiveCredits.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/GivePixels.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/GivePoints.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/GiveRespect.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/GiveUserClothing.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/HotelAlert.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/IgnoreUser.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/ImageAlertUser.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/ImageHotelAlert.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/ModifyUserSubscription.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/MuteUser.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/ProgressAchievement.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/RCONMessage.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/SendGift.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/SendRoomBundle.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/SetMotto.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/SetRank.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/StaffAlert.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/StalkUser.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/TalkUser.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/UpdateCatalog.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/UpdateUser.java create mode 100644 Emulator/src/main/java/com/eu/habbo/messages/rcon/UpdateWordfilter.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/Server.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/camera/CameraClient.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/camera/CameraDecoder.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/camera/CameraHandler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/camera/CameraIncomingMessage.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/camera/CameraMessage.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/camera/CameraOutgoingMessage.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/camera/CameraPacketHandler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/camera/messages/CameraOutgoingHeaders.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraAuthenticationTicketEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraLoginStatusEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraResultURLEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraRoomThumbnailGeneratedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraUpdateNotification.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/camera/messages/outgoing/CameraLoginComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/camera/messages/outgoing/CameraRenderImageComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/gameserver/GameServer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/gameserver/GameServerAttributes.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameByteDecoder.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameByteDecryption.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameByteFrameDecoder.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameClientMessageLogger.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameMessageHandler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameMessageRateLimit.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GamePolicyDecoder.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/gameserver/encoders/GameByteEncryption.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/gameserver/encoders/GameServerMessageEncoder.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/gameserver/encoders/GameServerMessageLogger.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/gameserver/handlers/IdleTimeoutHandler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/rconserver/RCONServer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/rconserver/RCONServerHandler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/websockets/NetworkChannelInitializer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/websockets/codec/WebSocketCodec.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/websockets/handlers/CustomHTTPHandler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/websockets/ssl/SSLCertificateLoader.java create mode 100644 Emulator/src/main/java/com/eu/habbo/networking/websockets/utils/Utils.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/Event.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/EventHandler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/EventListener.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/EventPriority.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/HabboPlugin.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/HabboPluginConfiguration.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/PluginManager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotChatEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotPickUpEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotPlacedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotSavedChatEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotSavedLookEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotSavedNameEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotServerItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotShoutEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotTalkEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotWhisperEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorConfigUpdatedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorLoadCatalogManagerEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorLoadItemsManagerEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorLoadedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorStartShutdownEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorStoppedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/SSOAuthenticationEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureBuildheightEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureDiceRolledEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureMovedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurniturePickedUpEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurniturePlacedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRedeemedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRolledEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRoomTonerEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRotatedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureStackHeightEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureToggleEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureUserEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/wired/WiredConditionFailedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/wired/WiredStackExecutedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/wired/WiredStackTriggeredEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameHabboJoinEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameHabboLeaveEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameStartedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameStoppedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameUserEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildAcceptedMembershipEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildChangedBadgeEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildChangedColorsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildChangedNameEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildChangedSettingsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildDeclinedMembershipEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildDeletedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildFavoriteSetEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildGivenAdminEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildPurchasedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildRemovedAdminEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildRemovedFavoriteEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildRemovedMemberEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/forums/GuildForumThreadBeforeCreated.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/forums/GuildForumThreadCommentBeforeCreated.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/forums/GuildForumThreadCommentCreated.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/forums/GuildForumThreadCreated.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemAddedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemRemovedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemsAddedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/marketplace/MarketPlaceEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/marketplace/MarketPlaceItemCancelledEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/marketplace/MarketPlaceItemOfferedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/marketplace/MarketPlaceItemSoldEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorPopularRoomsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorRoomCreatedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorRoomDeletedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorRoomsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorSearchResultEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/pets/PetEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/pets/PetTalkEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomFloorItemsLoadEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomLoadedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomUncachedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomUnloadedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomUnloadingEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/UserVoteRoomEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/roomunit/RoomUnitEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/roomunit/RoomUnitLookAtPointEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/roomunit/RoomUnitSetGoalEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/sanctions/SanctionEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportRoomActionEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportTicketEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportTicketStatusChangedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportUserAlertedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportUserAlertedReason.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportUserBannedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportUserKickEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/trading/TradeConfirmEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/HabboAddedToRoomEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserCommandEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserCreditsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserDisconnectEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserEnterRoomEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserExecuteCommandEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserExitRoomEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserGetIPAddressEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserIdleEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserKickEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserLoginEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserNameChangedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserPickGiftEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserPointsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserPublishPictureEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserPurchasePictureEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRankChangedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRegisteredEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRespectedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRightsGivenEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRightsTakenEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRolledEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSavedLookEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSavedMottoEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSavedSettingsEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSavedWardrobeEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSignEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserTakeStepEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserTalkEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserTriggerWordFilterEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserWiredRewardReceived.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/UsernameTalkEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/achievements/UserAchievementEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/achievements/UserAchievementLeveledEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/achievements/UserAchievementProgressEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/calendar/UserClaimRewardEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/catalog/UserCatalogEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/catalog/UserCatalogFurnitureBoughtEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/catalog/UserCatalogItemPurchasedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserAcceptFriendRequestEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserFriendChatEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserFriendEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserRelationShipEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserRequestFriendshipEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/subscriptions/UserSubscriptionCreatedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/subscriptions/UserSubscriptionExpiredEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/plugin/events/users/subscriptions/UserSubscriptionExtendedEvent.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/HabboExecutorService.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/RejectedExecutionHandlerImpl.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/ThreadPooling.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/AchievementUpdater.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/BackgroundAnimation.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/BanzaiRandomTeleport.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/BattleBanzaiTilesFlicker.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/BotFollowHabbo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/CameraClientAutoReconnect.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/CannonKickAction.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/CannonResetCooldownAction.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/ChannelReadHandler.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/ClearRentedSpace.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/CloseGate.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/CrackableExplode.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/GuardianNotAccepted.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/GuardianTicketFindMoreSlaves.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/GuardianVotingFinish.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/GuideFindNewHelper.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/HabboGiveHandItemToHabbo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/HabboItemNewState.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/InsertModToolIssue.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/KickBallAction.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/LoadCustomHeightMap.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/OneWayGateActionOne.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/OpenGift.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/PetClearPosture.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/PetEatAction.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/PetFollowHabbo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/QueryDeleteHabboBadge.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/QueryDeleteHabboItem.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/QueryDeleteHabboItems.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/RandomDiceNumber.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/RemoveFloorItemTask.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomTrashing.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitGiveHanditem.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitKick.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitRidePet.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitTeleport.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitTeleportWalkToAction.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitVendingMachineAction.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitWalkToLocation.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitWalkToRoomUnit.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/SaveScoreForTeam.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/SendRoomUnitEffectComposer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/ShutdownEmulator.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/TeleportInteraction.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/UpdateModToolIssue.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/WiredCollissionRunnable.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/WiredExecuteTask.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/WiredRepeatEffectTask.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/WiredResetTimers.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/YouAreAPirate.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/YoutubeAdvanceVideo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/freeze/FreezeClearEffects.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/freeze/FreezeHandleSnowballExplosion.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/freeze/FreezeResetExplosionTiles.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/freeze/FreezeThrowSnowball.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/games/GameTimer.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionFive.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionFour.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionOne.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionThree.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionTwo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFive.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFour.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionOne.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionThree.java create mode 100644 Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionTwo.java create mode 100644 Emulator/src/main/java/com/eu/habbo/util/ANSI.java create mode 100644 Emulator/src/main/java/com/eu/habbo/util/DebugUtils.java create mode 100644 Emulator/src/main/java/com/eu/habbo/util/HexUtils.java create mode 100644 Emulator/src/main/java/com/eu/habbo/util/PacketUtils.java create mode 100644 Emulator/src/main/java/com/eu/habbo/util/callback/HTTPPostError.java create mode 100644 Emulator/src/main/java/com/eu/habbo/util/callback/HTTPPostStatus.java create mode 100644 Emulator/src/main/java/com/eu/habbo/util/callback/HTTPVersionCheck.java create mode 100644 Emulator/src/main/java/com/eu/habbo/util/crypto/ZIP.java create mode 100644 Emulator/src/main/java/com/eu/habbo/util/figure/FigureUtil.java create mode 100644 Emulator/src/main/java/com/eu/habbo/util/imager/badges/BadgeImager.java create mode 100644 Emulator/src/main/java/com/eu/habbo/util/logback/SqlExceptionFilter.java create mode 100644 Emulator/src/main/java/com/eu/habbo/util/pathfinding/Rotation.java create mode 100644 Emulator/src/main/resources/logback.xml diff --git a/Emulator/.gitignore b/Emulator/.gitignore new file mode 100644 index 0000000..94c0cbd --- /dev/null +++ b/Emulator/.gitignore @@ -0,0 +1,17 @@ +logging/ +compiled-builds/ +*.iml +.idea/ +target/** +TODO.txt +packet.pkt +plugins/** +src/test/ +target/ +config.ini +*.txt +*.jar +*.log +*.zip +.DS_Store + diff --git a/Emulator/.gitlab-ci.yml b/Emulator/.gitlab-ci.yml new file mode 100644 index 0000000..e1d0de3 --- /dev/null +++ b/Emulator/.gitlab-ci.yml @@ -0,0 +1,18 @@ +image: maven:latest + +stages: + - build + +build: + stage: build + script: + - mvn package + only: + changes: + - src/**/* + - pom.xml + artifacts: + expire_in: 2 weeks + paths: + - target/Habbo-*.jar + diff --git a/Emulator/.gitmodules b/Emulator/.gitmodules new file mode 100644 index 0000000..efe4ac3 --- /dev/null +++ b/Emulator/.gitmodules @@ -0,0 +1,3 @@ +[submodule "morningstar-default-database"] + path = morningstar-default-database + url = https://git.krews.org/morningstar/morningstar-default-database diff --git a/Emulator/Dockerfile b/Emulator/Dockerfile new file mode 100644 index 0000000..e045ce4 --- /dev/null +++ b/Emulator/Dockerfile @@ -0,0 +1,19 @@ +FROM maven:latest AS builder + +# Copy the Emulator sources to the container +COPY . . +# Package it +RUN mvn package && mv /target/Habbo*-with-dependencies.jar /target/Habbo.jar + +# Use Java 8 for running +FROM java:8 AS runner + +# Copy the generated source +COPY --from=builder /target/Habbo.jar / + +# Save the script to wait for the database, among running the Arcturus Emulator +RUN echo "#!/bin/bash \n java -Dfile.encoding=UTF-8 -jar /Habbo.jar" > /entrypoint.sh +RUN chmod +x /entrypoint.sh + +# Run the Emulator with Java +ENTRYPOINT ["/entrypoint.sh"] diff --git a/Emulator/Example_Start/Linux/emulator b/Emulator/Example_Start/Linux/emulator new file mode 100644 index 0000000..1b071ed --- /dev/null +++ b/Emulator/Example_Start/Linux/emulator @@ -0,0 +1,2 @@ +#!/bin/sh +java -Dfile.encoding=UTF8 -Xmx4096m -jar /PATH_TO_YOUR_EMULATOR/Habbo-3.5.3-jar-with-dependencies.jar \ No newline at end of file diff --git a/Emulator/Example_Start/Windows/emulator.cmd b/Emulator/Example_Start/Windows/emulator.cmd new file mode 100644 index 0000000..54b15c4 --- /dev/null +++ b/Emulator/Example_Start/Windows/emulator.cmd @@ -0,0 +1 @@ +java -Dfile.encoding=UTF8 -Xmx4096m -jar /PATH_TO_YOUR_EMULATOR/Habbo-3.5.3-jar-with-dependencies.jar \ No newline at end of file diff --git a/Emulator/LICENSE b/Emulator/LICENSE new file mode 100644 index 0000000..418dc9a --- /dev/null +++ b/Emulator/LICENSE @@ -0,0 +1,165 @@ +GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/Emulator/featurelist.md b/Emulator/featurelist.md new file mode 100644 index 0000000..7f49499 --- /dev/null +++ b/Emulator/featurelist.md @@ -0,0 +1,208 @@ + + +The following file contains the current feature list for Arcturus Morningstar as of the 4.x Beta Branch. +We hope this file will provide an easy place to find functions in Arcturus Morningstar for new developers, as well as give people the chance to see exactly what Arcturus Morningstar can do! + +If you wish to contribute to this list, features are laid out in the following format: + + + +## ✍️ Example Header: + +##### Example Feature Header- ✔️ (completed) ⭕ (incomplete/ not implemented) + +> [`ExampleLinkToRelatedClasses`](https://google.com) +> +> ###### Example Sub Feature Header - ✔️ +> +> > [`ExampleLinkToRelatedSubClasses`](https://google.com) + + + + + +## 🖥️ Connection / User: + +##### Login via SSO Ticket ✔️ + +> [`SecureLoginEvent`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java) +> [`HabboManager.loadHabbo()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/HabboManager.java#L104) + +##### Support RSA Encryption ✔️ + +> [`HabboRSACrypto`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/crypto/HabboRSACrypto.java) +> [`HabboRC4`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/crypto/HabboRC4.java) +> [`HabboDiffieHellman`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/crypto/HabboDiffieHellman.java) +> [`CompleteDiffieHandshakeEvent`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/incoming/handshake/CompleteDiffieHandshakeEvent.java) +> [`InitDiffieHandshakeEvent`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/incoming/handshake/InitDiffieHandshakeEvent.java) + + + +## 🧸 RCON: + +##### RCON ✔️ + +> [`RCONMessage`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/master/src/main/java/com/eu/habbo/messages/rcon/RCONMessage.java) +> +> ###### RCON Messages - ✔️ +> +> > [`AlertUser`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/master/src/main/java/com/eu/habbo/messages/rcon/AlertUser.java)) +> > [`ChangeRoomOwner`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/master/src/main/java/com/eu/habbo/messages/rcon/ChangeRoomOwner.java) +> > [`CreateModToolTicket`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/master/src/main/java/com/eu/habbo/messages/rcon/CreateModToolTicket.java) +> > [`DisconnectUser`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/master/src/main/java/com/eu/habbo/messages/rcon/DisconnectUser.java) +> > [`ExecuteCommand`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/master/src/main/java/com/eu/habbo/messages/rcon/ExecuteCommand.java) +> > [`ForwardUser`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/master/src/main/java/com/eu/habbo/messages/rcon/ForwardUser.java) +> > // todo finish this + +##### + +## 💠 Subscriptions: + +###### Subscriptions Manager ✔️ + +> > [`Subscription`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/Subscription.java) +> > [`SubscriptionManager`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionManager.java) +> > [`SubscriptionScheduler`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionScheduler.java) +> > [`UserSubscriptionCreatedEvent`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/plugin/events/users/subscriptions/UserSubscriptionCreatedEvent.java) +> > [`UserSubscriptionExpiredEvent`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/plugin/events/users/subscriptions/UserSubscriptionExpiredEvent.java) +> > [`UserSubscriptionExtendedEvent`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/master/src/main/java/com/eu/habbo/messages/rcon/RCONMessage.java) +> > +> > ##### Habbo Club - ✔️ +> > +> > > [`SubscriptionHabboClub`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionHabboClub.java) +> > > [`RequestUserClubEvent`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserClubEvent.java) +> > > [`RequestClubDataEvent`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestClubDataEvent.java) +> > > [`ClubDataComposer`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/outgoing/catalog/ClubDataComposer.java) +> > > [`HabboStats.hasActiveClub()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java#L555) +> > > +> > > ###### HC Catalogue - ✔️ +> > > +> > > > [`ClubBuyLayout`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ClubBuyLayout.java) +> > > > [`ClubOffer`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/catalog/ClubOffer.java) +> > > > [`ClubGiftsLayout`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ClubGiftsLayout.java) +> > > > [`ClubGiftsComposer`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/outgoing/catalog/ClubGiftsComposer.java) +> > > > [`ClubCenterDataComposer`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/outgoing/catalog/ClubCenterDataComposer.java) +> > > > [`ClubGiftReceivedComposer`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/outgoing/users/ClubGiftReceivedComposer.java) +> > > +> > > ###### HC Payday - ✔️ +> > > +> > > > [`SecureLoginEvent`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java#L202) +> > > > [`SubscriptionScheduler`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionScheduler.java) +> > > > [`SubscriptionHabboClub.calculatePayDay()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionHabboClub.java#L184) +> > > > [`SubscriptionHabboClub.executePayDay()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionHabboClub.java#L257) +> > > > [`SubscriptionHabboClub.processUnclaimed()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionHabboClub.java#L316) +> > > > [`SubscriptionHabboClub.claimPayDay()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionHabboClub.java#L368) +> > > > [`SubscriptionHabboClub.progressAchievement()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionHabboClub.java#L419) +> > > +> > > ###### HC Checks on clothing - ✔️ +> > > +> > > > [`ClothingValidationManager`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/ClothingValidationManager.java) +> > > > [`ClothingValidationManager.validateLook()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/ClothingValidationManager.java#L61) +> > > +> > > ###### HC dances - ✔️ +> > > +> > > > [`RoomUserDanceEvent`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserDanceEvent.java) +> > > > [`RoomUserDanceComposer`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserDanceComposer.java) +> > > > [`RoomUnit.getDanceType()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnit.java#L456) +> > > > [`RoomUnit.setDanceType()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnit.java#L460) +> > +> > Builders Club - ⭕ +> > +> > > [`SubscriptionScheduler`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionScheduler.java) +> > > [`BuildersClubExpiredComposer`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/outgoing/unknown/BuildersClubExpiredComposer.java) +> > > +> > > ###### Builders Club Catalogue - ⭕ +> > > +> > > > [`BuildersClubAddonsLayout`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BuildersClubAddonsLayout.java) +> > > > [`BuildersClubLoyaltyLayout`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BuildersClubLoyaltyLayout.java)) +> > > > [`BuildersClubFrontPageLayout`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BuildersClubFrontPageLayout.java) +> > +> > + + + +## 🤹 Entities: + +##### Habbo ✔️ + +> [`Habbo`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java) +> [`Habbo.getClient()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java#L110) +> [`Habbo.isOnline()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java#L64) +> [`Habbo.getHabboInfo()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java#L90) +> [`Habbo.getHabboStats()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java#L94) +> [`Habbo.getRoomUnit()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java#L102) +> [`HabboManager`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/HabboManager.java) +> [`HabboManager.getOfflineHabboInfo()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/HabboManager.java#L47) +> [`HabboManager.getCloneAccounts()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/HabboManager.java#L203) +> [`HabboManager.setRank()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/HabboManager.java#L243) +> [`HabboInfo`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/HabboManager.java) + +> ###### Clothing - ✔️ +> +> +> > [`UserClothesComposer`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/outgoing/users/UserClothesComposer.java) +> > [`HabboInventory.getWardrobeComponent()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/HabboInventory.java#L67) +> > [`HabboInventory.setWardrobeComponent()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/HabboInventory.java#L71) +> +> ###### Inventory - ✔️ +> +> +> > [`HabboInventory`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/HabboInventory.java) +> > [`Habbo.getInventory()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java#L98) +> > [`ItemsComponent.addItem()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/inventory/ItemsComponent.java#L67) +> > [`ItemsComponent.addItems()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/inventory/ItemsComponent.java#L82) +> > [`ItemsComponent.getHabboItem()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/inventory/ItemsComponent.java#L99) +> > [`ItemsComponent.getAndRemoveHabboItem()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/inventory/ItemsComponent.java#L103) +> > [`ItemsComponent.removeHabboItem()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/inventory/ItemsComponent.java#L126) +> > [`ItemsComponent.getItemsAsValueCollection()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/inventory/ItemsComponent.java#L141) +> > [`InventoryItemsComposer`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/HabboInfo.java#L265) +> > [`InventoryBotsComposer`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryBotsComposer.java) +> > [`InventoryPetsComposer`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryPetsComposer.java) +> > [`InventoryAchievementsComposer`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryAchievementsComposer.java) +> > [`InventoryRefreshComposer`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryRefreshComposer.java) +> > [`InventoryItemsAddedEvent`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemsAddedEvent.java) +> > [`InventoryItemEvent`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemEvent.java) +> +> ###### Motto - ✔️ +> +> +> > [`HabboInfo.setMotto()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/HabboInfo.java#L269) +> > [`HabboInfo.getMotto()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/HabboInfo.java#L265) +> +> ###### Badges - ✔️ +> +> +> > [`BadgesComponent`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java) +> > [`BadgesComponent.loadBadges()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java#L28) +> > [`BadgesComponent.getBadgesOfflineHabbo()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java#L75) +> > [`BadgesComponent.createBadge()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java#L90) +> > [`BadgesComponent.deleteBadge()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java#L113) +> > [`BadgesComponent.getWearingBadges()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java#L123) +> > [`BadgesComponent.hasBadge()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java#L147) +> > [`BadgesComponent.getBadge()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java#L151) +> > [`BadgesComponent.removeBadge()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java#L167) +> +> ##### Load Currency and Seasonal Currency - ✔️ +> +> > [`RequestUserCreditsEvent`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserCreditsEvent.java) +> > [`UserCurrencyComposer`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/outgoing/users/UserCurrencyComposer.java) +> > [`UserCreditsComposer`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/messages/outgoing/users/UserCreditsComposer.java) +> > [`Habbo.getHabboInfo()`](https://git.krews.org/morningstar/Arcturus-Community/-/blob/dev/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java#L90) + +> Save/Load Achievements +> +> Save/Load Friends +> +> Save/Load Own Rooms +> +> Save/Load Guilds +> +> Save/Load Currencies +> +> Save/Load Inventory +> +> Save/Load Friendships - Love/Hate/Like + +​ + +- diff --git a/Emulator/pom.xml b/Emulator/pom.xml new file mode 100644 index 0000000..276a08d --- /dev/null +++ b/Emulator/pom.xml @@ -0,0 +1,200 @@ + + + 4.0.0 + + com.eu.habbo + Habbo + 3.6.0 + + + UTF-8 + + -Xdoclint:none + + + + + java8-doclint-disabled + + [1.8,) + + + -Xdoclint:none + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.12.1 + + 16 + 16 + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.6.0 + + + jar-with-dependencies + + + + com.eu.habbo.Emulator + + + + + + make-assembly + package + + single + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.6.3 + + + -Xdoclint:none + + public + + + + + + + + central + https://repo1.maven.org/maven2/ + + + mvnrepo + https://mvnrepository.com/ + + + + + + + io.netty + netty-all + 4.1.106.Final + + + + + com.google.code.gson + gson + 2.10.1 + + + + + + + com.mysql + mysql-connector-j + 8.3.0 + runtime + + + + + net.sf.trove4j + trove4j + 3.0.3 + compile + + + + + com.zaxxer + HikariCP + 5.1.0 + compile + + + + + org.projectlombok + lombok + 1.18.30 + provided + + + + + org.slf4j + jcl-over-slf4j + 2.0.11 + runtime + + + + org.slf4j + slf4j-api + 2.0.11 + + + + org.apache.commons + commons-lang3 + 3.14.0 + compile + + + + org.apache.commons + commons-math3 + 3.6.1 + compile + + + + org.jsoup + jsoup + 1.17.2 + compile + + + + ch.qos.logback + logback-classic + 1.4.7 + compile + + + + org.fusesource.jansi + jansi + 2.4.1 + + + + joda-time + joda-time + 2.12.6 + + + \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/Emulator.java b/Emulator/src/main/java/com/eu/habbo/Emulator.java new file mode 100644 index 0000000..b8ca710 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/Emulator.java @@ -0,0 +1,527 @@ +package com.eu.habbo; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.ConsoleAppender; +import com.eu.habbo.core.*; +import com.eu.habbo.core.consolecommands.ConsoleCommand; +import com.eu.habbo.database.Database; +import com.eu.habbo.habbohotel.GameEnvironment; +import com.eu.habbo.networking.camera.CameraClient; +import com.eu.habbo.networking.gameserver.GameServer; +import com.eu.habbo.networking.rconserver.RCONServer; +import com.eu.habbo.networking.websockets.NetworkChannelInitializer; +import com.eu.habbo.plugin.PluginManager; +import com.eu.habbo.plugin.events.emulator.EmulatorConfigUpdatedEvent; +import com.eu.habbo.plugin.events.emulator.EmulatorLoadedEvent; +import com.eu.habbo.plugin.events.emulator.EmulatorStartShutdownEvent; +import com.eu.habbo.plugin.events.emulator.EmulatorStoppedEvent; +import com.eu.habbo.plugin.events.users.UserGetIPAddressEvent; +import com.eu.habbo.threading.ThreadPooling; +import com.eu.habbo.util.imager.badges.BadgeImager; +import io.netty.channel.Channel; +import io.netty.util.AttributeKey; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.security.MessageDigest; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; +import java.security.SecureRandom; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Slf4j +public final class Emulator { + + private static final String OS_NAME = (System.getProperty("os.name") != null ? System.getProperty("os.name") : "Unknown"); + private static final String CLASS_PATH = (System.getProperty("java.class.path") != null ? System.getProperty("java.class.path") : "Unknown"); + private static final SecureRandom secureRandom = new SecureRandom(); + public final static int MAJOR = 3; + public final static int MINOR = 6; + public final static int BUILD = 0; + public final static String PREVIEW = ""; + + public static final String version = "Arcturus Morningstar" + " " + MAJOR + "." + MINOR + "." + BUILD + " " + PREVIEW; + private static final String logo = + "\n" + + "███╗ ███╗ ██████╗ ██████╗ ███╗ ██╗██╗███╗ ██╗ ██████╗ ███████╗████████╗ █████╗ ██████╗ \n" + + "████╗ ████║██╔═══██╗██╔══██╗████╗ ██║██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██╔══██╗██╔══██╗\n" + + "██╔████╔██║██║ ██║██████╔╝██╔██╗ ██║██║██╔██╗ ██║██║ ███╗███████╗ ██║ ███████║██████╔╝\n" + + "██║╚██╔╝██║██║ ██║██╔══██╗██║╚██╗██║██║██║╚██╗██║██║ ██║╚════██║ ██║ ██╔══██║██╔══██╗\n" + + "██║ ╚═╝ ██║╚██████╔╝██║ ██║██║ ╚████║██║██║ ╚████║╚██████╔╝███████║ ██║ ██║ ██║██║ ██║\n" + + "╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝\n" + + " Extended version"; + + + public static String build = ""; + public static String debuglevel = ""; + public static boolean isReady = false; + public static boolean isShuttingDown = false; + public static boolean stopped = false; + public static boolean debugging = false; + private static int timeStarted = 0; + private static Runtime runtime; + private static ConfigurationManager config; + private static CryptoConfig crypto; + private static TextsManager texts; + private static GameServer gameServer; + private static RCONServer rconServer; + private static CameraClient cameraClient; + private static Logging logging; + private static Database database; + private static DatabaseLogger databaseLogger; + private static ThreadPooling threading; + private static GameEnvironment gameEnvironment; + private static PluginManager pluginManager; + private static BadgeImager badgeImager; + public static final AttributeKey WS_IP = AttributeKey.valueOf("WS_IP"); + + static { + Thread hook = new Thread(new Runnable() { + public synchronized void run() { + Emulator.dispose(); + } + }); + hook.setPriority(10); + Runtime.getRuntime().addShutdownHook(hook); + } + + public static void main(String[] args) throws Exception { + try { + // Check if running on Windows and not in IntelliJ. + // If so, we need to reconfigure the console appender and enable Jansi for colors. + if (OS_NAME.startsWith("Windows") && !CLASS_PATH.contains("idea_rt.jar")) { + ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + ConsoleAppender appender = (ConsoleAppender) root.getAppender("Console"); + + appender.stop(); + appender.setWithJansi(true); + appender.start(); + } + + Locale.setDefault(new Locale("en")); + setBuild(); + Emulator.stopped = false; + ConsoleCommand.load(); + Emulator.logging = new Logging(); + + System.out.println(logo); + + log.info("Version: {}", version); + log.info("Build: {}", build); + + long startTime = System.nanoTime(); + + Emulator.runtime = Runtime.getRuntime(); + Emulator.config = new ConfigurationManager("config.ini"); + Emulator.crypto = new CryptoConfig( + Emulator.getConfig().getBoolean("enc.enabled", false), + Emulator.getConfig().getValue("enc.e"), + Emulator.getConfig().getValue("enc.n"), + Emulator.getConfig().getValue("enc.d")); + Emulator.database = new Database(Emulator.getConfig()); + Emulator.databaseLogger = new DatabaseLogger(); + Emulator.config.loaded = true; + Emulator.config.loadFromDatabase(); + Emulator.threading = new ThreadPooling(Emulator.getConfig().getInt("runtime.threads")); + Emulator.getDatabase().getDataSource().setMaximumPoolSize(Emulator.getConfig().getInt("runtime.threads") * 2); + Emulator.getDatabase().getDataSource().setMinimumIdle(10); + Emulator.pluginManager = new PluginManager(); + Emulator.pluginManager.reload(); + Emulator.getPluginManager().fireEvent(new EmulatorConfigUpdatedEvent()); + Emulator.texts = new TextsManager(); + new CleanerThread(); + Emulator.gameServer = new GameServer(getConfig().getValue("game.host", "127.0.0.1"), getConfig().getInt("game.port", 30000)); + Emulator.rconServer = new RCONServer(getConfig().getValue("rcon.host", "127.0.0.1"), getConfig().getInt("rcon.port", 30001)); + Emulator.gameEnvironment = new GameEnvironment(); + Emulator.gameEnvironment.load(); + Emulator.gameServer.initializePipeline(); + Emulator.gameServer.connect(); + Emulator.rconServer.initializePipeline(); + Emulator.rconServer.connect(); + Emulator.badgeImager = new BadgeImager(); + Emulator.getConfig().register("websockets.whitelist", "localhost"); + Emulator.getConfig().register("ws.nitro.host", "0.0.0.0"); + Emulator.getConfig().register("ws.nitro.port", "2096"); + Emulator.getConfig().register("ws.nitro.ip.header", ""); + NetworkChannelInitializer wsChannelHandler = new NetworkChannelInitializer(); + Emulator.getGameServer().getServerBootstrap().childHandler(wsChannelHandler); + Emulator.getGameServer().getServerBootstrap().bind(Emulator.getConfig().getValue("ws.nitro.host", "0.0.0.0"), Emulator.getConfig().getInt("ws.nitro.port", 2096)).sync(); + log.info("Websockets has started!"); + log.info("Websockets Listening on " + (wsChannelHandler.isSSL() ? "wss://" : "ws://") + Emulator.getConfig().getValue("ws.nitro.host", "0.0.0.0") + ":" + Emulator.getConfig().getInt("ws.nitro.port", 2096)); + log.info("Arcturus Morningstar has successfully loaded."); + log.info("System launched in: {}ms. Using {} threads!", (System.nanoTime() - startTime) / 1e6, Runtime.getRuntime().availableProcessors() * 2); + log.info("Memory: {}/{}MB", (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024), (runtime.freeMemory()) / (1024 * 1024)); + + Emulator.debugging = Emulator.getConfig().getBoolean("debug.mode"); + Emulator.debuglevel = Emulator.getConfig().getValue("debug.level", "DEBUG"); + /* Debug level can be : INFO WARN DEBUG TRACE*/ + + if (debugging) { + ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + root.setLevel(Level.DEBUG); + log.debug("Debugging enabled."); + Level logLevel = Level.toLevel(Emulator.debuglevel); + root.setLevel(logLevel); + log.info("Debugging enabled."); + log.info("The loaded debug mode is {}", Emulator.debuglevel); + } + + Emulator.getPluginManager().fireEvent(new EmulatorLoadedEvent()); + Emulator.isReady = true; + Emulator.timeStarted = getIntUnixTimestamp(); + + if (Emulator.getConfig().getInt("runtime.threads") < (Runtime.getRuntime().availableProcessors() * 2)) { + log.warn("Emulator settings runtime.threads ({}) can be increased to ({}) to possibly increase performance.", + Emulator.getConfig().getInt("runtime.threads"), + Runtime.getRuntime().availableProcessors() * 2); + } + + Emulator.getThreading().run(() -> { + }, 1500); + + // Check if console mode is true or false, default is true + if (Emulator.getConfig().getBoolean("console.mode", true)) { + + BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + + while (!isShuttingDown && isReady) { + try { + String line = reader.readLine(); + + if (line != null) { + ConsoleCommand.handle(line); + } + System.out.println("Waiting for command: "); + } catch (Exception e) { + if (!(e instanceof IOException && e.getMessage().equals("Bad file descriptor"))) { + log.error("Error while reading command", e); + } + } + } + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static void setBuild() { + if (Emulator.class.getProtectionDomain().getCodeSource() == null) { + build = "UNKNOWN"; + return; + } + + StringBuilder sb = new StringBuilder(); + try { + String filepath = new File(Emulator.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getAbsolutePath(); + MessageDigest md = MessageDigest.getInstance("MD5");// MD5 + FileInputStream fis = new FileInputStream(filepath); + byte[] dataBytes = new byte[1024]; + int nread = 0; + while ((nread = fis.read(dataBytes)) != -1) + md.update(dataBytes, 0, nread); + byte[] mdbytes = md.digest(); + for (int i = 0; i < mdbytes.length; i++) + sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1)); + } catch (Exception e) { + build = "UNKNOWN"; + return; + } + + build = sb.toString(); + } + + private static void dispose() { + Emulator.getThreading().setCanAdd(false); + Emulator.isShuttingDown = true; + Emulator.isReady = false; + + log.info("Stopping Arcturus Morningstar {}", version); + + try { + if (Emulator.getPluginManager() != null) + Emulator.getPluginManager().fireEvent(new EmulatorStartShutdownEvent()); + } catch (Exception e) { + } + + try { + if (Emulator.cameraClient != null) + Emulator.cameraClient.disconnect(); + } catch (Exception e) { + } + + try { + if (Emulator.rconServer != null) + Emulator.rconServer.stop(); + } catch (Exception e) { + } + + try { + if (Emulator.gameEnvironment != null) + Emulator.gameEnvironment.dispose(); + } catch (Exception e) { + } + + try { + if (Emulator.getPluginManager() != null) + Emulator.getPluginManager().fireEvent(new EmulatorStoppedEvent()); + } catch (Exception e) { + } + + try { + if (Emulator.pluginManager != null) + Emulator.pluginManager.dispose(); + } catch (Exception e) { + } + + try { + if (Emulator.config != null) { + Emulator.config.saveToDatabase(); + } + } catch (Exception e) { + } + + try { + if (Emulator.gameServer != null) + Emulator.gameServer.stop(); + } catch (Exception e) { + } + + log.info("Stopped Arcturus Morningstar {}", version); + + if (Emulator.database != null) { + Emulator.getDatabase().dispose(); + } + Emulator.stopped = true; + + // if (osName.startsWith("Windows") && (!classPath.contains("idea_rt.jar"))) { + // AnsiConsole.systemUninstall(); + // } + try { + if (Emulator.threading != null) + + Emulator.threading.shutDown(); + } catch (Exception e) { + } + } + + public static ConfigurationManager getConfig() { + return config; + } + + public static CryptoConfig getCrypto() { + return crypto; + } + + public static TextsManager getTexts() { + return texts; + } + + public static Database getDatabase() { + return database; + } + + public static DatabaseLogger getDatabaseLogger() { + return databaseLogger; + } + + public static Runtime getRuntime() { + return runtime; + } + + public static GameServer getGameServer() { + return gameServer; + } + + public static RCONServer getRconServer() { + return rconServer; + } + + public void onUserGetIPEvent(UserGetIPAddressEvent e) { + Channel channel = e.habbo.getClient().getChannel(); + if(channel != null && channel.hasAttr(Emulator.WS_IP)) { + String ip = channel.attr(Emulator.WS_IP).get(); + if(!ip.isEmpty()) { + e.setUpdatedIp(ip); + } + } + } + + /** + * @deprecated Do not use. Please use LoggerFactory.getLogger(YourClass.class) to log. + */ + @Deprecated + public static Logging getLogging() { + return logging; + } + + public static ThreadPooling getThreading() { + return threading; + } + + public static GameEnvironment getGameEnvironment() { + return gameEnvironment; + } + + public static PluginManager getPluginManager() { + return pluginManager; + } + + public static Random getRandom() { + return ThreadLocalRandom.current(); + } + + public static SecureRandom getRandomDice() { + return secureRandom; + } + + public static BadgeImager getBadgeImager() { + return badgeImager; + } + + public static CameraClient getCameraClient() { + return cameraClient; + } + + public static synchronized void setCameraClient(CameraClient client) { + cameraClient = client; + } + + public static int getTimeStarted() { + return timeStarted; + } + + public static int getOnlineTime() { + return getIntUnixTimestamp() - timeStarted; + } + + public static void prepareShutdown() { + System.exit(0); + } + + public static int timeStringToSeconds(String timeString) { + int totalSeconds = 0; + + Matcher m = Pattern.compile("(([0-9]*) (second|minute|hour|day|week|month|year))").matcher(timeString); + Map map = new HashMap() { + { + put("second", 1); + put("minute", 60); + put("hour", 3600); + put("day", 86400); + put("week", 604800); + put("month", 2628000); + put("year", 31536000); + } + }; + + while (m.find()) { + try { + int amount = Integer.parseInt(m.group(2)); + String what = m.group(3); + totalSeconds += amount * map.get(what); + } + catch (Exception ignored) { } + } + + return totalSeconds; + } + + public static Date modifyDate(Date date, String timeString) { + int totalSeconds = 0; + + Calendar c = Calendar.getInstance(); + c.setTime(date); + + Matcher m = Pattern.compile("(([0-9]*) (second|minute|hour|day|week|month|year))").matcher(timeString); + Map map = new HashMap() { + { + put("second", Calendar.SECOND); + put("minute", Calendar.MINUTE); + put("hour", Calendar.HOUR); + put("day", Calendar.DAY_OF_MONTH); + put("week", Calendar.WEEK_OF_MONTH); + put("month", Calendar.MONTH); + put("year", Calendar.YEAR); + } + }; + + while (m.find()) { + try { + int amount = Integer.parseInt(m.group(2)); + String what = m.group(3); + c.add(map.get(what), amount); + } + catch (Exception ignored) { } + } + + return c.getTime(); + } + + private static String dateToUnixTimestamp(Date date) { + String res = ""; + Date aux = stringToDate("1970-01-01 00:00:00"); + Timestamp aux1 = dateToTimeStamp(aux); + Timestamp aux2 = dateToTimeStamp(date); + long difference = aux2.getTime() - aux1.getTime(); + long seconds = difference / 1000L; + return res + seconds; + } + + public static Date stringToDate(String date) { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date res = null; + try { + res = format.parse(date); + } catch (Exception e) { + log.error("Error parsing date", e); + } + return res; + } + + public static Timestamp dateToTimeStamp(Date date) { + return new Timestamp(date.getTime()); + } + + public static Date getDate() { + return new Date(System.currentTimeMillis()); + } + + public static String getUnixTimestamp() { + return dateToUnixTimestamp(getDate()); + } + + public static int getIntUnixTimestamp() { + return (int) (System.currentTimeMillis() / 1000); + } + + public static boolean isNumeric(String string) + throws IllegalArgumentException { + boolean isnumeric = false; + if ((string != null) && (!string.equals(""))) { + isnumeric = true; + char[] chars = string.toCharArray(); + for (char aChar : chars) { + isnumeric = Character.isDigit(aChar); + if (!isnumeric) { + break; + } + } + } + return isnumeric; + } + + public int getUserCount() { + return gameEnvironment.getHabboManager().getOnlineCount(); + } + + public int getRoomCount() { + return gameEnvironment.getRoomManager().getActiveRooms().size(); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/CleanerThread.java b/Emulator/src/main/java/com/eu/habbo/core/CleanerThread.java new file mode 100644 index 0000000..04ee5f4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/CleanerThread.java @@ -0,0 +1,160 @@ +package com.eu.habbo.core; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.forums.ForumThread; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.friends.SearchUserEvent; +import com.eu.habbo.messages.incoming.navigator.SearchRoomsEvent; +import com.eu.habbo.messages.outgoing.users.UserDataComposer; +import com.eu.habbo.threading.runnables.AchievementUpdater; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Map; + +@Slf4j +public class CleanerThread implements Runnable { + + private static final int DELAY = 10000; + private static final int RELOAD_HALL_OF_FAME = 1800; + private static final int RELOAD_NEWS_LIST = 3600; + private static final int REMOVE_INACTIVE_ROOMS = 120; + private static final int REMOVE_INACTIVE_GUILDS = 60; + private static final int REMOVE_INACTIVE_TOURS = 600; + private static final int CLEAR_CACHED_VALUES = 60 * 60; + private static final int CALLBACK_TIME = 60 * 15; + + private static int LAST_HOF_RELOAD = Emulator.getIntUnixTimestamp(); + private static int LAST_NL_RELOAD = Emulator.getIntUnixTimestamp(); + private static int LAST_INACTIVE_ROOMS_CLEARED = Emulator.getIntUnixTimestamp(); + private static int LAST_INACTIVE_GUILDS_CLEARED = Emulator.getIntUnixTimestamp(); + private static int LAST_INACTIVE_TOURS_CLEARED = Emulator.getIntUnixTimestamp(); + private static int LAST_DAILY_REFILL = Emulator.getIntUnixTimestamp(); + private static int LAST_CALLBACK = Emulator.getIntUnixTimestamp(); + private static int LAST_HABBO_CACHE_CLEARED = Emulator.getIntUnixTimestamp(); + + public CleanerThread() { + this.databaseCleanup(); + Emulator.getThreading().run(this, DELAY); + + Emulator.getThreading().run(new AchievementUpdater()); + + // Emulator.getThreading().run(new HTTPVersionCheck(), 10000); + } + + @Override + public void run() { + Emulator.getThreading().run(this, DELAY); + + int time = Emulator.getIntUnixTimestamp(); + + if (time - LAST_HOF_RELOAD > RELOAD_HALL_OF_FAME) { + Emulator.getGameEnvironment().getHotelViewManager().getHallOfFame().reload(); + LAST_HOF_RELOAD = time; + } + + if (time - LAST_NL_RELOAD > RELOAD_NEWS_LIST) { + Emulator.getGameEnvironment().getHotelViewManager().getNewsList().reload(); + LAST_NL_RELOAD = time; + } + + if (time - LAST_INACTIVE_ROOMS_CLEARED > REMOVE_INACTIVE_ROOMS) { + Emulator.getGameEnvironment().getRoomManager().clearInactiveRooms(); + LAST_INACTIVE_ROOMS_CLEARED = time; + } + + if (time - LAST_INACTIVE_GUILDS_CLEARED > REMOVE_INACTIVE_GUILDS) { + Emulator.getGameEnvironment().getGuildManager().clearInactiveGuilds(); + ForumThread.clearCache(); + LAST_INACTIVE_GUILDS_CLEARED = time; + } + + if (time - LAST_INACTIVE_TOURS_CLEARED > REMOVE_INACTIVE_TOURS) { + Emulator.getGameEnvironment().getGuideManager().cleanup(); + LAST_INACTIVE_TOURS_CLEARED = time; + } + + if (time - LAST_CALLBACK > CALLBACK_TIME) { + // Emulator.getThreading().run(new HTTPPostStatus()); + LAST_CALLBACK = time; + } + + if (time - LAST_DAILY_REFILL > Emulator.getConfig().getInt("hotel.refill.daily")) { + this.refillDailyRespects(); + LAST_DAILY_REFILL = time; + } + + if (time - LAST_HABBO_CACHE_CLEARED > CLEAR_CACHED_VALUES) { + this.clearCachedValues(); + LAST_HABBO_CACHE_CLEARED = time; + } + + SearchRoomsEvent.cachedResults.clear(); + SearchUserEvent.cachedResults.clear(); + } + + + void databaseCleanup() { + this.refillDailyRespects(); + + int time = Emulator.getIntUnixTimestamp(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (Statement statement = connection.createStatement()) { + statement.execute("UPDATE users SET online = '0' WHERE online = '1'"); + statement.execute("UPDATE rooms SET users = '0' WHERE users > 0"); + statement.execute("DELETE FROM room_mutes WHERE ends < " + time); + statement.execute("DELETE FROM room_bans WHERE ends < " + time); + statement.execute("DELETE users_favorite_rooms FROM users_favorite_rooms LEFT JOIN rooms ON room_id = rooms.id WHERE rooms.id IS NULL"); + } + + try (PreparedStatement statement = connection.prepareStatement("UPDATE users_effects SET total = total - 1 WHERE activation_timestamp + duration < ? AND activation_timestamp > 0 AND duration > 0")) { + statement.setInt(1, Emulator.getIntUnixTimestamp()); + statement.execute(); + } + + try (Statement statement = connection.createStatement()) { + statement.execute("DELETE FROM users_effects WHERE total <= 0"); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + log.info("Database -> Cleaned!"); + } + + public void refillDailyRespects() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users_settings SET daily_respect_points = ?, daily_pet_respect_points = ?")) { + statement.setInt(1, Emulator.getConfig().getInt("hotel.daily.respect")); + statement.setInt(2, Emulator.getConfig().getInt("hotel.daily.respect.pets")); + statement.executeUpdate(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + if (Emulator.isReady) { + for (Habbo habbo : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().values()) { + habbo.getHabboStats().respectPointsToGive = Emulator.getConfig().getInt("hotel.daily.respect"); + habbo.getHabboStats().petRespectPointsToGive = Emulator.getConfig().getInt("hotel.daily.respect.pets"); + habbo.getClient().sendResponse(new UserDataComposer(habbo)); + } + } + } + + private void clearCachedValues() { + Habbo habbo; + for (Map.Entry map : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + habbo = map.getValue(); + + try { + if (habbo != null) { + habbo.clearCaches(); + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/CommandLog.java b/Emulator/src/main/java/com/eu/habbo/core/CommandLog.java new file mode 100644 index 0000000..a0039a5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/CommandLog.java @@ -0,0 +1,41 @@ +package com.eu.habbo.core; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.commands.Command; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +public class CommandLog implements DatabaseLoggable { + + private static final String INSERT_QUERY = "INSERT INTO commandlogs (`user_id`, `timestamp`, `command`, `params`, `succes`) VALUES (?, ?, ?, ?, ?)"; + + private final int userId; + private final int timestamp = Emulator.getIntUnixTimestamp(); + private final Command command; + private final String params; + private final boolean success; + + public CommandLog(int userId, Command command, String params, boolean success) { + this.userId = userId; + this.command = command; + this.params = params; + this.success = success; + } + + @Override + public String getQuery() { + return CommandLog.INSERT_QUERY; + } + + @Override + public void log(PreparedStatement statement) throws SQLException { + statement.setInt(1, this.userId); + statement.setInt(2, this.timestamp); + statement.setString(3, this.command.getClass().getSimpleName()); + statement.setString(4, this.params); + statement.setString(5, this.success ? "yes" : "no"); + statement.addBatch(); + } + +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/core/ConfigurationManager.java b/Emulator/src/main/java/com/eu/habbo/core/ConfigurationManager.java new file mode 100644 index 0000000..e583ea0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/ConfigurationManager.java @@ -0,0 +1,226 @@ +package com.eu.habbo.core; + +import com.eu.habbo.Emulator; +import com.eu.habbo.plugin.events.emulator.EmulatorConfigUpdatedEvent; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.sql.*; +import java.util.Map; +import java.util.Properties; + +@Slf4j +public class ConfigurationManager { + + private final Properties properties; + private final String configurationPath; + public boolean loaded = false; + public boolean isLoading = false; + + public ConfigurationManager(String configurationPath) { + this.properties = new Properties(); + this.configurationPath = configurationPath; + this.reload(); + } + + public void reload() { + this.isLoading = true; + this.properties.clear(); + + InputStream input = null; + + String envDbHostname = System.getenv("DB_HOSTNAME"); + + boolean useEnvVarsForDbConnection = false; + + if(envDbHostname != null) + { + useEnvVarsForDbConnection = envDbHostname.length() > 1; + } + + if (!useEnvVarsForDbConnection) { + try { + File f = new File(this.configurationPath); + input = new FileInputStream(f); + this.properties.load(input); + + } catch (IOException ex) { + log.error("Failed to load config file.", ex); + ex.printStackTrace(); + } finally { + if (input != null) { + try { + input.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + } else { + + Map envMapping = new THashMap<>(); + + // Database section + envMapping.put("db.hostname", "DB_HOSTNAME"); + envMapping.put("db.port", "DB_PORT"); + envMapping.put("db.database", "DB_DATABASE"); + envMapping.put("db.username", "DB_USERNAME"); + envMapping.put("db.password", "DB_PASSWORD"); + envMapping.put("db.params", "DB_PARAMS"); + + // Game Configuration + envMapping.put("game.host", "EMU_HOST"); + envMapping.put("game.port", "EMU_PORT"); + + // RCON + envMapping.put("rcon.host", "RCON_HOST"); + envMapping.put("rcon.port", "RCON_PORT"); + envMapping.put("rcon.allowed", "RCON_ALLOWED"); + + // Runtime + envMapping.put("runtime.threads", "RT_THREADS"); + envMapping.put("logging.errors.runtime", "RT_LOG_ERRORS"); + + for (Map.Entry entry : envMapping.entrySet()) { + String envValue = System.getenv(entry.getValue()); + + if (envValue == null || envValue.length() == 0) { + log.info("Cannot find environment-value for variable `" + entry.getValue() + "`"); + } else { + this.properties.setProperty(entry.getKey(), envValue); + } + } + } + + if (this.loaded) { + this.loadFromDatabase(); + } + + this.isLoading = false; + log.info("Configuration Manager -> Loaded!"); + + if (Emulator.getPluginManager() != null) { + Emulator.getPluginManager().fireEvent(new EmulatorConfigUpdatedEvent()); + } + } + + public void loadFromDatabase() { + log.info("Loading configuration from database..."); + + long millis = System.currentTimeMillis(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement()) { + if (statement.execute("SELECT * FROM emulator_settings")) { + try (ResultSet set = statement.getResultSet()) { + while (set.next()) { + this.properties.put(set.getString("key"), set.getString("value")); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + log.info("Configuration -> loaded! (" + (System.currentTimeMillis() - millis) + " MS)"); + } + + public void saveToDatabase() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE emulator_settings SET `value` = ? WHERE `key` = ? LIMIT 1")) { + for (Map.Entry entry : this.properties.entrySet()) { + statement.setString(1, entry.getValue().toString()); + statement.setString(2, entry.getKey().toString()); + statement.executeUpdate(); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + + public String getValue(String key) { + return this.getValue(key, ""); + } + + + public String getValue(String key, String defaultValue) { + if (this.isLoading) + return defaultValue; + + if (!this.properties.containsKey(key)) { + log.error("Config key not found {}", key); + } + return this.properties.getProperty(key, defaultValue); + } + + public boolean getBoolean(String key) { + return this.getBoolean(key, false); + } + + public boolean getBoolean(String key, boolean defaultValue) { + if (this.isLoading) + return defaultValue; + + try { + return (this.getValue(key, "0").equals("1")) || (this.getValue(key, "false").equals("true")); + } catch (Exception e) { + log.error("Failed to parse key {} with value '{}' to type boolean.", key, this.getValue(key)); + } + return defaultValue; + } + + public int getInt(String key) { + return this.getInt(key, 0); + } + + public int getInt(String key, Integer defaultValue) { + if (this.isLoading) + return defaultValue; + + try { + return Integer.parseInt(this.getValue(key, defaultValue.toString())); + } catch (Exception e) { + log.error("Failed to parse key {} with value '{}' to type integer.", key, this.getValue(key)); + } + return defaultValue; + } + + public double getDouble(String key) { + return this.getDouble(key, 0.0); + } + + public double getDouble(String key, Double defaultValue) { + if (this.isLoading) + return defaultValue; + + try { + return Double.parseDouble(this.getValue(key, defaultValue.toString())); + } catch (Exception e) { + log.error("Failed to parse key {} with value '{}' to type double.", key, this.getValue(key)); + } + + return defaultValue; + } + + public void update(String key, String value) { + this.properties.setProperty(key, value); + } + + public void register(String key, String value) { + if (this.properties.getProperty(key, null) != null) + return; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO emulator_settings VALUES (?, ?)")) { + statement.setString(1, key); + statement.setString(2, value); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.update(key, value); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/CreditsScheduler.java b/Emulator/src/main/java/com/eu/habbo/core/CreditsScheduler.java new file mode 100644 index 0000000..4265226 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/CreditsScheduler.java @@ -0,0 +1,66 @@ +package com.eu.habbo.core; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import lombok.extern.slf4j.Slf4j; +import java.util.Map; + +@Slf4j +public class CreditsScheduler extends Scheduler { + public static boolean IGNORE_HOTEL_VIEW; + public static boolean IGNORE_IDLED; + public static double HC_MODIFIER; + + public CreditsScheduler() { + + super(Emulator.getConfig().getInt("hotel.auto.credits.interval")); + this.reloadConfig(); + } + + public void reloadConfig() { + if (Emulator.getConfig().getBoolean("hotel.auto.credits.enabled")) { + IGNORE_HOTEL_VIEW = Emulator.getConfig().getBoolean("hotel.auto.credits.ignore.hotelview"); + IGNORE_IDLED = Emulator.getConfig().getBoolean("hotel.auto.credits.ignore.idled"); + HC_MODIFIER = Emulator.getConfig().getDouble("hotel.auto.credits.hc_modifier", 1.0); + + if (this.disposed) { + this.disposed = false; + this.run(); + } + } else { + this.disposed = true; + } + } + + @Override + public void run() { + super.run(); + + Habbo habbo; + for (Map.Entry map : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + habbo = map.getValue(); + + try { + if (habbo != null) { + if (habbo.getHabboInfo().getCurrentRoom() == null && IGNORE_HOTEL_VIEW) + continue; + + if (habbo.getRoomUnit().isIdle() && IGNORE_IDLED) + continue; + + habbo.giveCredits((int)(habbo.getHabboInfo().getRank().getCreditsTimerAmount() * (habbo.getHabboStats().hasActiveClub() ? HC_MODIFIER : 1.0))); + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } + } + + public boolean isDisposed() { + return this.disposed; + } + + public void setDisposed(boolean disposed) { + this.disposed = disposed; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/CryptoConfig.java b/Emulator/src/main/java/com/eu/habbo/core/CryptoConfig.java new file mode 100644 index 0000000..28fbe7c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/CryptoConfig.java @@ -0,0 +1,33 @@ +package com.eu.habbo.core; + +public class CryptoConfig { + + private final boolean enabled; + private final String exponent; + private final String modulus; + private final String privateExponent; + + public CryptoConfig(boolean enabled, String exponent, String modulus, String privateExponent) { + this.enabled = enabled; + this.exponent = exponent; + this.modulus = modulus; + this.privateExponent = privateExponent; + } + + public boolean isEnabled() { + return enabled; + } + + public String getExponent() { + return exponent; + } + + public String getModulus() { + return modulus; + } + + public String getPrivateExponent() { + return privateExponent; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/DatabaseLoggable.java b/Emulator/src/main/java/com/eu/habbo/core/DatabaseLoggable.java new file mode 100644 index 0000000..821ea7a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/DatabaseLoggable.java @@ -0,0 +1,12 @@ +package com.eu.habbo.core; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +public interface DatabaseLoggable { + + String getQuery(); + + void log(PreparedStatement statement) throws SQLException; + +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/DatabaseLogger.java b/Emulator/src/main/java/com/eu/habbo/core/DatabaseLogger.java new file mode 100644 index 0000000..ddb4a97 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/DatabaseLogger.java @@ -0,0 +1,25 @@ +package com.eu.habbo.core; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class DatabaseLogger { + + public void store(final DatabaseLoggable loggable) { + Emulator.getThreading().run(() -> { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement(loggable.getQuery())) { + loggable.log(statement); + statement.executeBatch(); + } + } catch (SQLException e) { + log.error("Exception caught while saving loggable to database.", e); + } + }); + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/Disposable.java b/Emulator/src/main/java/com/eu/habbo/core/Disposable.java new file mode 100644 index 0000000..554ec32 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/Disposable.java @@ -0,0 +1,7 @@ +package com.eu.habbo.core; + +public interface Disposable { + void dispose(); + + boolean disposed(); +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/Easter.java b/Emulator/src/main/java/com/eu/habbo/core/Easter.java new file mode 100644 index 0000000..f358dbc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/Easter.java @@ -0,0 +1,25 @@ +package com.eu.habbo.core; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserRemoveComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserWhisperComposer; +import com.eu.habbo.plugin.EventHandler; +import com.eu.habbo.plugin.events.users.UserSavedMottoEvent; + +public class Easter { + @EventHandler + public static void onUserChangeMotto(UserSavedMottoEvent event) { + if (Emulator.getConfig().getBoolean("easter_eggs.enabled") && event.newMotto.equalsIgnoreCase("crickey!")) { + event.habbo.getClient().sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(event.newMotto, event.habbo, event.habbo, RoomChatMessageBubbles.ALERT))); + + Room room = event.habbo.getHabboInfo().getCurrentRoom(); + + room.sendComposer(new RoomUserRemoveComposer(event.habbo.getRoomUnit()).compose()); + room.sendComposer(new RoomUserPetComposer(2, 1, "FFFFFF", event.habbo).compose()); + + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/ErrorLog.java b/Emulator/src/main/java/com/eu/habbo/core/ErrorLog.java new file mode 100644 index 0000000..31b4fd8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/ErrorLog.java @@ -0,0 +1,63 @@ +package com.eu.habbo.core; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class ErrorLog implements DatabaseLoggable { + private static final String QUERY = "INSERT INTO emulator_errors (timestamp, version, build_hash, type, stacktrace) VALUES (?, ?, ?, ?, ?)"; + public final String version; + public final String buildHash; + public final int timeStamp; + public final String type; + public final String stackTrace; + + public ErrorLog(String type, Throwable e) { + this.version = Emulator.version; + this.buildHash = Emulator.version; + + this.timeStamp = Emulator.getIntUnixTimestamp(); + this.type = type; + + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + this.stackTrace = sw.toString(); + + try { + pw.close(); + sw.close(); + } catch (IOException e1) { + log.error("Exception caught", e1); + } + } + + public ErrorLog(String type, String message) { + this.version = Emulator.version; + this.buildHash = Emulator.build; + + this.timeStamp = Emulator.getIntUnixTimestamp(); + this.type = type; + this.stackTrace = message; + } + + @Override + public String getQuery() { + return QUERY; + } + + @Override + public void log(PreparedStatement statement) throws SQLException { + statement.setInt(1, this.timeStamp); + statement.setString(2, this.version); + statement.setString(3, this.buildHash); + statement.setString(4, this.type); + statement.setString(5, this.stackTrace); + statement.addBatch(); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/GotwPointsScheduler.java b/Emulator/src/main/java/com/eu/habbo/core/GotwPointsScheduler.java new file mode 100644 index 0000000..add7148 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/GotwPointsScheduler.java @@ -0,0 +1,79 @@ +package com.eu.habbo.core; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import lombok.extern.slf4j.Slf4j; +import java.util.Map; + +@Slf4j +public class GotwPointsScheduler extends Scheduler { + public static boolean IGNORE_HOTEL_VIEW; + public static boolean IGNORE_IDLED; + public static String GOTW_POINTS_NAME; + public static double HC_MODIFIER; + + public GotwPointsScheduler() { //TODO MOVE TO A PLUGIN. IS NOT PART OF OFFICIAL HABBO. + + super(Emulator.getConfig().getInt("hotel.auto.gotwpoints.interval")); + this.reloadConfig(); + } + + public void reloadConfig() { + if (Emulator.getConfig().getBoolean("hotel.auto.gotwpoints.enabled")) { + IGNORE_HOTEL_VIEW = Emulator.getConfig().getBoolean("hotel.auto.gotwpoints.ignore.hotelview"); + IGNORE_IDLED = Emulator.getConfig().getBoolean("hotel.auto.gotwpoints.ignore.idled"); + HC_MODIFIER = Emulator.getConfig().getDouble("hotel.auto.gotwpoints.hc_modifier", 1.0); + GOTW_POINTS_NAME = Emulator.getConfig().getValue("hotel.auto.gotwpoints.name"); + + if (this.disposed) { + this.disposed = false; + this.run(); + } + } else { + this.disposed = true; + } + } + + @Override + public void run() { + super.run(); + + Habbo habbo; + for (Map.Entry map : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + habbo = map.getValue(); + + try { + if (habbo != null) { + if (habbo.getHabboInfo().getCurrentRoom() == null && IGNORE_HOTEL_VIEW) + continue; + + if (habbo.getRoomUnit().isIdle() && IGNORE_IDLED) + continue; + + int type; + boolean found = false; + for (String s : Emulator.getConfig().getValue("seasonal.currency.names").split(";")) { + if (s.equalsIgnoreCase(GOTW_POINTS_NAME) || (GOTW_POINTS_NAME.startsWith(s) && Math.abs(s.length() - GOTW_POINTS_NAME.length()) < 3)) { + found = true; + break; + } + } + type = Emulator.getConfig().getInt("seasonal.currency." + GOTW_POINTS_NAME, -1); + if (found || type != -1) { + habbo.givePoints(type, (int)(habbo.getHabboInfo().getRank().getGotwTimerAmount() * (habbo.getHabboStats().hasActiveClub() ? HC_MODIFIER : 1.0))); + } + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } + } + + public boolean isDisposed() { + return this.disposed; + } + + public void setDisposed(boolean disposed) { + this.disposed = disposed; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/Logging.java b/Emulator/src/main/java/com/eu/habbo/core/Logging.java new file mode 100644 index 0000000..b64087c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/Logging.java @@ -0,0 +1,63 @@ +package com.eu.habbo.core; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; +import java.sql.SQLException; + +@Slf4j +public class Logging { + @Deprecated + public void logStart(Object line) { + log.info("[LOADING] {}", line); + } + + @Deprecated + public void logShutdownLine(Object line) { + log.info("[SHUTDOWN] {}", line); + } + + @Deprecated + public void logUserLine(Object line) { + log.info("[USER] {}", line); + } + + @Deprecated + public void logDebugLine(Object line) { + log.debug("[DEBUG] {}", line); + } + + @Deprecated + public void logPacketLine(Object line) { + if (Emulator.getConfig().getBoolean("debug.show.packets")) { + log.debug("[PACKET] {}", line); + } + } + + @Deprecated + public void logUndefinedPacketLine(Object line) { + if (Emulator.getConfig().getBoolean("debug.show.packets.undefined")) { + log.debug("[PACKET] [UNDEFINED] {}", line); + } + } + + @Deprecated + public void logErrorLine(Object line) { + log.error("[ERROR] {}", line); + } + + @Deprecated + public void logSQLException(SQLException e) { + log.error("[ERROR] SQLException", e); + } + + @Deprecated + public void logPacketError(Object e) { + log.error("[ERROR] PacketError {}", e); + } + + @Deprecated + public void handleException(Exception e) { + log.error("[ERROR] Exception", e); + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/PixelScheduler.java b/Emulator/src/main/java/com/eu/habbo/core/PixelScheduler.java new file mode 100644 index 0000000..a75589a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/PixelScheduler.java @@ -0,0 +1,63 @@ +package com.eu.habbo.core; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import lombok.extern.slf4j.Slf4j; +import java.util.Map; + +@Slf4j +public class PixelScheduler extends Scheduler { + public static boolean IGNORE_HOTEL_VIEW; + public static boolean IGNORE_IDLED; + public static double HC_MODIFIER; + + public PixelScheduler() { + super(Emulator.getConfig().getInt("hotel.auto.pixels.interval")); + this.reloadConfig(); + } + + public void reloadConfig() { + if (Emulator.getConfig().getBoolean("hotel.auto.pixels.enabled")) { + IGNORE_HOTEL_VIEW = Emulator.getConfig().getBoolean("hotel.auto.pixels.ignore.hotelview"); + IGNORE_IDLED = Emulator.getConfig().getBoolean("hotel.auto.pixels.ignore.idled"); + HC_MODIFIER = Emulator.getConfig().getDouble("hotel.auto.pixels.hc_modifier", 1.0); + if (this.disposed) { + this.disposed = false; + this.run(); + } + } else { + this.disposed = true; + } + } + + @Override + public void run() { + super.run(); + + Habbo habbo; + for (Map.Entry map : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + habbo = map.getValue(); + try { + if (habbo != null) { + if (habbo.getHabboInfo().getCurrentRoom() == null && IGNORE_HOTEL_VIEW) + continue; + + if (habbo.getRoomUnit().isIdle() && IGNORE_IDLED) + continue; + + habbo.givePixels((int)(habbo.getHabboInfo().getRank().getPixelsTimerAmount() * (habbo.getHabboStats().hasActiveClub() ? HC_MODIFIER : 1.0))); + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } + } + + public boolean isDisposed() { + return this.disposed; + } + + public void setDisposed(boolean disposed) { + this.disposed = disposed; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/PointsScheduler.java b/Emulator/src/main/java/com/eu/habbo/core/PointsScheduler.java new file mode 100644 index 0000000..04a875d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/PointsScheduler.java @@ -0,0 +1,66 @@ +package com.eu.habbo.core; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import lombok.extern.slf4j.Slf4j; +import java.util.Map; + +@Slf4j +public class PointsScheduler extends Scheduler { + public static boolean IGNORE_HOTEL_VIEW; + public static boolean IGNORE_IDLED; + public static double HC_MODIFIER; + + public PointsScheduler() { + + super(Emulator.getConfig().getInt("hotel.auto.points.interval")); + this.reloadConfig(); + } + + public void reloadConfig() { + if (Emulator.getConfig().getBoolean("hotel.auto.points.enabled")) { + IGNORE_HOTEL_VIEW = Emulator.getConfig().getBoolean("hotel.auto.points.ignore.hotelview"); + IGNORE_IDLED = Emulator.getConfig().getBoolean("hotel.auto.points.ignore.idled"); + HC_MODIFIER = Emulator.getConfig().getDouble("hotel.auto.points.hc_modifier", 1.0); + if (this.disposed) { + this.disposed = false; + this.run(); + } + } else { + this.disposed = true; + } + } + + @Override + public void run() { + super.run(); + + Habbo habbo; + for (Map.Entry map : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + habbo = map.getValue(); + + try { + if (habbo != null) { + if (habbo.getHabboInfo().getCurrentRoom() == null && IGNORE_HOTEL_VIEW) + continue; + + if (habbo.getRoomUnit().isIdle() && IGNORE_IDLED) + continue; + + //habbo.givePoints(POINTS); + habbo.givePoints((int)(habbo.getHabboInfo().getRank().getDiamondsTimerAmount() * (habbo.getHabboStats().hasActiveClub() ? HC_MODIFIER : 1.0))); + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } + } + + public boolean isDisposed() { + return this.disposed; + } + + public void setDisposed(boolean disposed) { + this.disposed = disposed; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/RoomUserPetComposer.java b/Emulator/src/main/java/com/eu/habbo/core/RoomUserPetComposer.java new file mode 100644 index 0000000..d593d1f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/RoomUserPetComposer.java @@ -0,0 +1,49 @@ +package com.eu.habbo.core; + +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.Outgoing; + +public class RoomUserPetComposer extends MessageComposer { + private final int petType; + private final int race; + private final String color; + private final Habbo habbo; + + public RoomUserPetComposer(int petType, int race, String color, Habbo habbo) { + this.petType = petType; + this.race = race; + this.color = color; + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUsersComposer); + this.response.appendInt(1); + this.response.appendInt(this.habbo.getHabboInfo().getId()); + this.response.appendString(this.habbo.getHabboInfo().getUsername()); + this.response.appendString(""); + this.response.appendString(this.petType + " " + this.race + " " + this.color + " 2 2 -1 0 3 -1 0"); + this.response.appendInt(this.habbo.getRoomUnit().getId()); + this.response.appendInt(this.habbo.getRoomUnit().getX()); + this.response.appendInt(this.habbo.getRoomUnit().getY()); + this.response.appendString(this.habbo.getRoomUnit().getZ() + ""); + this.response.appendInt(this.habbo.getRoomUnit().getBodyRotation().getValue()); + this.response.appendInt(2); + this.response.appendInt(this.petType); + this.response.appendInt(this.habbo.getHabboInfo().getId()); + this.response.appendString(this.habbo.getHabboInfo().getUsername()); + this.response.appendInt(1); + this.response.appendBoolean(false); + this.response.appendBoolean(true); + this.response.appendBoolean(true); //Can toggle breeding permissions. + this.response.appendBoolean(true); + this.response.appendBoolean(true); //Can treat? + this.response.appendBoolean(true); //Can breed + this.response.appendInt(0); + this.response.appendString(""); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/Scheduler.java b/Emulator/src/main/java/com/eu/habbo/core/Scheduler.java new file mode 100644 index 0000000..17fae17 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/Scheduler.java @@ -0,0 +1,36 @@ +package com.eu.habbo.core; + +import com.eu.habbo.Emulator; + +public class Scheduler implements Runnable { + protected boolean disposed; + protected int interval; + + public Scheduler(int interval) { + this.interval = interval; + } + + public boolean isDisposed() { + return this.disposed; + } + + public void setDisposed(boolean disposed) { + this.disposed = disposed; + } + + public int getInterval() { + return this.interval; + } + + public void setInterval(int interval) { + this.interval = interval; + } + + @Override + public void run() { + if (this.disposed) + return; + + Emulator.getThreading().run(this, this.interval * 1000); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/core/TextsManager.java b/Emulator/src/main/java/com/eu/habbo/core/TextsManager.java new file mode 100644 index 0000000..acb5397 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/TextsManager.java @@ -0,0 +1,97 @@ +package com.eu.habbo.core; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; + +import java.sql.*; +import java.util.Properties; + +@Slf4j +public class TextsManager { + + private final Properties texts; + + public TextsManager() { + long millis = System.currentTimeMillis(); + + this.texts = new Properties(); + + try { + this.reload(); + + log.info("Texts Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void reload() throws Exception { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM emulator_texts")) { + while (set.next()) { + if (this.texts.containsKey(set.getString("key"))) { + this.texts.setProperty(set.getString("key"), set.getString("value")); + } else { + this.texts.put(set.getString("key"), set.getString("value")); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public String getValue(String key) { + return this.getValue(key, ""); + } + + public String getValue(String key, String defaultValue) { + if (!this.texts.containsKey(key)) { + log.error("Text key not found: {}", key); + } + return this.texts.getProperty(key, defaultValue); + } + + public boolean getBoolean(String key) { + return this.getBoolean(key, false); + } + + public boolean getBoolean(String key, Boolean defaultValue) { + try { + return (this.getValue(key, "0").equals("1")) || (this.getValue(key, "false").equals("true")); + } catch (Exception e) { + log.error("Caught exception", e); + } + return defaultValue; + } + + public int getInt(String key) { + return this.getInt(key, 0); + } + + public int getInt(String key, Integer defaultValue) { + try { + return Integer.parseInt(this.getValue(key, defaultValue.toString())); + } catch (NumberFormatException e) { + log.error("Caught exception", e); + } + return defaultValue; + } + + public void update(String key, String value) { + this.texts.setProperty(key, value); + } + + public void register(String key, String value) { + if (this.texts.getProperty(key, null) != null) + return; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO emulator_texts VALUES (?, ?)")) { + statement.setString(1, key); + statement.setString(2, value); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.update(key, value); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleCommand.java b/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleCommand.java new file mode 100644 index 0000000..c4f50ad --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleCommand.java @@ -0,0 +1,62 @@ +package com.eu.habbo.core.consolecommands; + +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class ConsoleCommand { + private static final THashMap commands = new THashMap<>(); + + public final String key; + public final String usage; + + public ConsoleCommand(String key, String usage) { + this.key = key; + this.usage = usage; + } + + public static void load() { + addCommand(new ConsoleShutdownCommand()); + addCommand(new ConsoleInfoCommand()); + addCommand(new ConsoleTestCommand()); + addCommand(new ConsoleReconnectCameraCommand()); + addCommand(new ShowInteractionsCommand()); + addCommand(new ShowRCONCommands()); + addCommand(new ThankyouArcturusCommand()); + } + + public static void addCommand(ConsoleCommand command) { + commands.put(command.key, command); + } + + public static ConsoleCommand findCommand(String key) { + return commands.get(key); + } + + public static boolean handle(String line) { + String[] message = line.split(" "); + + if (message.length > 0) { + ConsoleCommand command = ConsoleCommand.findCommand(message[0]); + + if (command != null) { + try { + command.handle(message); + return true; + } catch (Exception e) { + log.error("Caught exception", e); + } + } else { + log.info("Unknown Console Command " + message[0]); + log.info("Commands Available (" + commands.size() + "): "); + + for (ConsoleCommand c : commands.values()) { + log.info(c.key + " - " + c.usage); + } + } + } + + return false; + } + public abstract void handle(String[] args) throws Exception; +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleInfoCommand.java b/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleInfoCommand.java new file mode 100644 index 0000000..3038210 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleInfoCommand.java @@ -0,0 +1,40 @@ +package com.eu.habbo.core.consolecommands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.CatalogManager; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +@Slf4j +public class ConsoleInfoCommand extends ConsoleCommand { + public ConsoleInfoCommand() { + super("info", "Show current statistics."); + } + + @Override + public void handle(String[] args) throws Exception { + int seconds = Emulator.getIntUnixTimestamp() - Emulator.getTimeStarted(); + int day = (int) TimeUnit.SECONDS.toDays(seconds); + long hours = TimeUnit.SECONDS.toHours(seconds) - (day * 24); + long minute = TimeUnit.SECONDS.toMinutes(seconds) - (TimeUnit.SECONDS.toHours(seconds) * 60); + long second = TimeUnit.SECONDS.toSeconds(seconds) - (TimeUnit.SECONDS.toMinutes(seconds) * 60); + + log.info("Emulator version: " + Emulator.version); + log.info("Emulator build: " + Emulator.build); + + log.info(""); + + log.info("Hotel Statistics"); + log.info("- Users: " + Emulator.getGameEnvironment().getHabboManager().getOnlineCount()); + log.info("- Rooms: " + Emulator.getGameEnvironment().getRoomManager().getActiveRooms().size()); + log.info("- Shop: " + Emulator.getGameEnvironment().getCatalogManager().catalogPages.size() + " pages and " + CatalogManager.catalogItemAmount + " items."); + log.info("- Furni: " + Emulator.getGameEnvironment().getItemManager().getItems().size() + " items."); + log.info(""); + log.info("Server Statistics"); + log.info("- Uptime: " + day + (day > 1 ? " days, " : " day, ") + hours + (hours > 1 ? " hours, " : " hour, ") + minute + (minute > 1 ? " minutes, " : " minute, ") + second + (second > 1 ? " seconds!" : " second!")); + log.info("- RAM Usage: " + (Emulator.getRuntime().totalMemory() - Emulator.getRuntime().freeMemory()) / (1024 * 1024) + "/" + (Emulator.getRuntime().freeMemory()) / (1024 * 1024) + "MB"); + log.info("- CPU Cores: " + Emulator.getRuntime().availableProcessors()); + log.info("- Total Memory: " + Emulator.getRuntime().maxMemory() / (1024 * 1024) + "MB"); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleReconnectCameraCommand.java b/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleReconnectCameraCommand.java new file mode 100644 index 0000000..40f1f9b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleReconnectCameraCommand.java @@ -0,0 +1,17 @@ +package com.eu.habbo.core.consolecommands; + +import com.eu.habbo.networking.camera.CameraClient; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ConsoleReconnectCameraCommand extends ConsoleCommand { + public ConsoleReconnectCameraCommand() { + super("camera", "Attempt to reconnect to the camera server."); + } + + @Override + public void handle(String[] args) throws Exception { + log.info("Connecting to the camera..."); + CameraClient.attemptReconnect = true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleShutdownCommand.java b/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleShutdownCommand.java new file mode 100644 index 0000000..1b033e7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleShutdownCommand.java @@ -0,0 +1,14 @@ +package com.eu.habbo.core.consolecommands; + +import com.eu.habbo.habbohotel.commands.ShutdownCommand; + +public class ConsoleShutdownCommand extends ConsoleCommand { + public ConsoleShutdownCommand() { + super("stop", "Stop the emulator."); + } + + @Override + public void handle(String[] args) throws Exception { + new ShutdownCommand().handle(null, args); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleTestCommand.java b/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleTestCommand.java new file mode 100644 index 0000000..3f69e05 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ConsoleTestCommand.java @@ -0,0 +1,22 @@ +package com.eu.habbo.core.consolecommands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ConsoleTestCommand extends ConsoleCommand { + public ConsoleTestCommand() { + super("test", "This is just a test."); + } + + @Override + public void handle(String[] args) throws Exception { + if (Emulator.debugging) { + log.info("This is a test command for live debugging."); + //AchievementManager.progressAchievement(4, Emulator.getGameEnvironment().getAchievementManager().getAchievement("AllTimeHotelPresence"), 30); + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(1); + habbo.getHabboInfo().getMachineID(); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ShowInteractionsCommand.java b/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ShowInteractionsCommand.java new file mode 100644 index 0000000..1d93112 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ShowInteractionsCommand.java @@ -0,0 +1,19 @@ +package com.eu.habbo.core.consolecommands; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +public class ShowInteractionsCommand extends ConsoleCommand { + public ShowInteractionsCommand() { + super("interactions", "Show a list of available furniture interactions."); + } + + @Override + public void handle(String[] args) throws Exception { + for (String interaction : Emulator.getGameEnvironment().getItemManager().getInteractionList()) { + log.info(interaction); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ShowRCONCommands.java b/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ShowRCONCommands.java new file mode 100644 index 0000000..4da7f13 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ShowRCONCommands.java @@ -0,0 +1,19 @@ +package com.eu.habbo.core.consolecommands; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ShowRCONCommands extends ConsoleCommand { + + public ShowRCONCommands() { + super("rconcommands", "Show a list of all RCON commands"); + } + + @Override + public void handle(String[] args) throws Exception { + for (String command : Emulator.getRconServer().getCommands()) { + log.info(command); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ThankyouArcturusCommand.java b/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ThankyouArcturusCommand.java new file mode 100644 index 0000000..ab53bf8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/core/consolecommands/ThankyouArcturusCommand.java @@ -0,0 +1,42 @@ +package com.eu.habbo.core.consolecommands; + +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +public class ThankyouArcturusCommand extends ConsoleCommand { + + public ThankyouArcturusCommand() { + super("thankyou", "A thankyou message."); + } + + @Override + public void handle(String[] args) throws Exception { + log.info("Arcturus Morningstar is an opensource community fork of Arcturus Emulator by TheGeneral"); + log.info("Thankyou to the following people who have helped with it's development:"); + log.info("TheGeneral - For Creating Arcturus."); + log.info("Capheus - Decompilation"); + log.info("Beny - Lead Developer"); + log.info("Alejandro - Lead Developer"); + log.info("Harmonic - Developer"); + log.info("ArpyAge - Developer"); + log.info("Mike - Developer"); + log.info("Skeletor - Developer"); + log.info("zGrav - Developer"); + log.info("Swirny - Developer"); + log.info("Quadral - Developer"); + log.info("Dome - Developer"); + log.info("Necmi - Developer"); + log.info("Oliver - Support"); + log.info("Rasmus - Support"); + log.info("Layne - Support"); + log.info("Bill - Support"); + log.info("Harmony - Support"); + log.info("Ridge - Catalogue"); + log.info("Tenshie - Catalogue"); + log.info("Wulles - Catalogue"); + log.info("Gizmo - Catalogue"); + log.info("TheJava - Motivation"); + log.info("The Entire Krews.org Community."); + } + } \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/crypto/HabboDiffieHellman.java b/Emulator/src/main/java/com/eu/habbo/crypto/HabboDiffieHellman.java new file mode 100644 index 0000000..f9db196 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/crypto/HabboDiffieHellman.java @@ -0,0 +1,108 @@ +package com.eu.habbo.crypto; + +import com.eu.habbo.crypto.exceptions.HabboCryptoException; +import com.eu.habbo.crypto.utils.BigIntegerUtils; +import com.eu.habbo.util.HexUtils; + +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.ThreadLocalRandom; + +public class HabboDiffieHellman { + + private static final int DH_PRIMES_BIT_SIZE = 128; + private static final int DH_KEY_BIT_SIZE = 128; + + private final HabboRSACrypto crypto; + + private BigInteger DHPrime; + private BigInteger DHGenerator; + private BigInteger DHPrivate; + private BigInteger DHPublic; + + public HabboDiffieHellman(HabboRSACrypto crypto) { + this.crypto = crypto; + this.generateDHPrimes(); + this.generateDHKeys(); + } + + public BigInteger getDHPrime() { + return DHPrime; + } + + public BigInteger getDHGenerator() { + return DHGenerator; + } + + private void generateDHPrimes() { + this.DHPrime = BigInteger.probablePrime(DH_PRIMES_BIT_SIZE, ThreadLocalRandom.current()); + this.DHGenerator = BigInteger.probablePrime(DH_PRIMES_BIT_SIZE, ThreadLocalRandom.current()); + + if (this.DHGenerator.compareTo(this.DHPrime) > 0) { + BigInteger temp = this.DHPrime; + + this.DHPrime = this.DHGenerator; + this.DHGenerator = temp; + } + } + + private void generateDHKeys() { + this.DHPrivate = BigInteger.probablePrime(DH_KEY_BIT_SIZE, ThreadLocalRandom.current()); + this.DHPublic = this.DHGenerator.modPow(this.DHPrivate, this.DHPrime); + } + + private String encryptBigInteger(BigInteger integer) throws HabboCryptoException { + String str = integer.toString(10); + byte[] bytes = str.getBytes(StandardCharsets.UTF_8); + byte[] encrypted = this.crypto.Sign(bytes); + + return HexUtils.toHex(encrypted).toLowerCase(); + } + + private BigInteger decryptBigInteger(String str) throws HabboCryptoException { + byte[] bytes = HexUtils.toBytes(str); + byte[] decrypted = this.crypto.Decrypt(bytes); + String intStr = new String(decrypted, StandardCharsets.UTF_8); + + return new BigInteger(intStr, 10); + } + + public String getPublicKey() throws HabboCryptoException { + return encryptBigInteger(this.DHPublic); + } + + public String getSignedPrime() throws HabboCryptoException { + return encryptBigInteger(this.DHPrime); + } + + public String getSignedGenerator() throws HabboCryptoException { + return encryptBigInteger(this.DHGenerator); + } + + public void doHandshake(String signedPrime, String signedGenerator) throws HabboCryptoException { + this.DHPrime = decryptBigInteger(signedPrime); + this.DHGenerator = decryptBigInteger(signedGenerator); + + if (this.DHPrime == null || this.DHGenerator == null) { + throw new HabboCryptoException("DHPrime or DHGenerator was null."); + } + + if (this.DHPrime.compareTo(BigInteger.valueOf(2)) < 1) { + throw new HabboCryptoException("Prime cannot be <= 2!\nPrime: " + this.DHPrime.toString()); + } + + if (this.DHGenerator.compareTo(this.DHPrime) > -1) { + throw new HabboCryptoException("Generator cannot be >= Prime!\nPrime: " + this.DHPrime.toString() + "\nGenerator: " + this.DHGenerator.toString()); + } + + generateDHKeys(); + } + + public byte[] getSharedKey(String publicKeyStr) throws HabboCryptoException { + BigInteger publicKey = this.decryptBigInteger(publicKeyStr); + BigInteger sharedKey = publicKey.modPow(this.DHPrivate, this.DHPrime); + + return BigIntegerUtils.toUnsignedByteArray(sharedKey); + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/crypto/HabboEncryption.java b/Emulator/src/main/java/com/eu/habbo/crypto/HabboEncryption.java new file mode 100644 index 0000000..42985f6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/crypto/HabboEncryption.java @@ -0,0 +1,21 @@ +package com.eu.habbo.crypto; + +public class HabboEncryption { + + private final HabboRSACrypto crypto; + private final HabboDiffieHellman diffie; + + public HabboEncryption(String e, String n, String d) { + this.crypto = new HabboRSACrypto(e, n, d); + this.diffie = new HabboDiffieHellman(this.crypto); + } + + public HabboRSACrypto getCrypto() { + return crypto; + } + + public HabboDiffieHellman getDiffie() { + return diffie; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/crypto/HabboRC4.java b/Emulator/src/main/java/com/eu/habbo/crypto/HabboRC4.java new file mode 100644 index 0000000..b7959ed --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/crypto/HabboRC4.java @@ -0,0 +1,46 @@ +package com.eu.habbo.crypto; + +public class HabboRC4 { + + private int i; + private int j; + private final int[] table = new int[256]; + + public HabboRC4(byte[] key) { + int length = key.length; + + while (this.i < 256) { + table[this.i] = this.i; + this.i++; + } + + this.i = 0; + this.j = 0; + + while (this.i < 256) { + this.j = ((this.j + this.table[this.i]) + (key[this.i % length] & 0xff)) % 256; + this.swap(this.i, this.j); + this.i++; + } + + this.i = 0; + this.j = 0; + } + + private void swap(int a, int b) { + int num = table[a]; + table[a] = table[b]; + table[b] = num; + } + + public void parse(byte[] bytes) { + for (int index1 = 0; index1 < bytes.length; index1++) { + this.i = (this.i + 1) % 256; + this.j = (this.j + this.table[this.i]) % 256; + this.swap(this.i, this.j); + + bytes[index1] = (byte) ((bytes[index1] & 0xFF) ^ this.table[(this.table[this.i] + this.table[this.j]) % 256]); + } + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/crypto/HabboRSACrypto.java b/Emulator/src/main/java/com/eu/habbo/crypto/HabboRSACrypto.java new file mode 100644 index 0000000..7e1863a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/crypto/HabboRSACrypto.java @@ -0,0 +1,168 @@ +package com.eu.habbo.crypto; + +import com.eu.habbo.crypto.exceptions.HabboCryptoException; +import com.eu.habbo.crypto.utils.BigIntegerUtils; +import org.apache.commons.lang3.mutable.MutableInt; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.util.concurrent.ThreadLocalRandom; + +public class HabboRSACrypto { + + private final BigInteger e; + private final BigInteger n; + private final BigInteger d; + private final int blockSize; + + public HabboRSACrypto(String e, String n) { + this.e = new BigInteger(e, 16); + this.n = new BigInteger(n, 16); + this.d = null; + this.blockSize = (this.n.bitLength() + 7) / 8; + } + + public HabboRSACrypto(String e, String n, String d) { + this.e = new BigInteger(e, 16); + this.n = new BigInteger(n, 16); + this.d = new BigInteger(d, 16); + this.blockSize = (this.n.bitLength() + 7) / 8; + } + + public byte[] Encrypt(byte[] data) throws HabboCryptoException { + return DoEncrypt(data, true, 2); + } + + public byte[] Decrypt(byte[] data) throws HabboCryptoException { + return DoDecrypt(data, false, 2); + } + + public byte[] Sign(byte[] data) throws HabboCryptoException { + return DoEncrypt(data, false, 1); + } + + public byte[] Verify(byte[] data) throws HabboCryptoException { + return DoDecrypt(data, true, 1); + } + + private BigInteger DoPublic(BigInteger x) { + return x.modPow(this.e, this.n); + } + + private BigInteger DoPrivate(BigInteger x) { + return x.modPow(this.d, this.n); + } + + private byte[] DoEncrypt(byte[] data, boolean isPublic, int padType) throws HabboCryptoException { + try (ByteArrayOutputStream dst = new ByteArrayOutputStream()) { + int bl = this.blockSize; + int end = data.length; + MutableInt pos = new MutableInt(0); + + while (pos.intValue() < end) { + byte[] padded = Pkcs1Pad(data, pos, end, bl, padType); + BigInteger block = new BigInteger(padded); + BigInteger chunk = isPublic ? DoPublic(block) : DoPrivate(block); + + for (int b = (int) (bl - Math.ceil(chunk.bitLength() / 8.0)); b > 0; --b) { + dst.write(0x00); + } + + dst.write(BigIntegerUtils.toUnsignedByteArray(chunk)); + } + + return dst.toByteArray(); + } catch (IOException e) { + throw new HabboCryptoException(e); + } + } + + private byte[] DoDecrypt(byte[] data, boolean isPublic, int padType) throws HabboCryptoException { + if (data.length % this.blockSize != 0) { + throw new HabboCryptoException("Decryption data was not in blocks of " + this.blockSize + " bytes, total " + data.length + "."); + } + + try (ByteArrayOutputStream dst = new ByteArrayOutputStream()) { + int end = data.length; + int pos = 0; + + while (pos < end) { + byte[] blockData = new byte[this.blockSize]; + System.arraycopy(data, pos, blockData, 0, this.blockSize); + + BigInteger block = new BigInteger(1, blockData); + BigInteger chunk = isPublic ? DoPublic(block) : DoPrivate(block); + byte[] unpadded = Pkcs1Unpad(chunk.toByteArray(), this.blockSize, padType); + + pos += this.blockSize; + dst.write(unpadded); + } + + return dst.toByteArray(); + } catch (IOException e) { + throw new HabboCryptoException(e); + } + } + + private static byte[] Pkcs1Pad(byte[] src, MutableInt pos, int end, int n, int padType) { + byte[] result = new byte[n]; + int p = pos.intValue(); + end = Math.min(end, Math.min(src.length, p + n - 11)); + pos.setValue(end); + int i = end - 1; + + while (i >= p && n > 11) { + result[--n] = src[i--]; + } + + result[--n] = 0; + + if (padType == 2) { + while (n > 2) { + result[--n] = (byte) ThreadLocalRandom.current().nextInt(1, 256); + } + } else { + while (n > 2) { + result[--n] = (byte) 0xFF; + } + } + + result[--n] = (byte) padType; + result[--n] = 0; + + return result; + } + + private static byte[] Pkcs1Unpad(byte[] b, int n, int padType) throws HabboCryptoException { + byte[] result = new byte[n]; + int resultPos = 0; + int i = 0; + + while (i < b.length && b[i] == 0) { + ++i; + } + + if (b.length - i != n - 1 || b[i] != padType) { + throw new HabboCryptoException("PKCS#1 unpad: i=" + i + ", expected b[i]==" + padType + ", got b[i]=" + b[i]); + } + + ++i; + + while (b[i] != 0) { + if (++i >= b.length) { + throw new HabboCryptoException("PKCS#1 unpad: i=" + i + ", b[i-1]!=0 (=" + b[i-1] + ")"); + } + } + + while (++i < b.length) { + result[resultPos++] = b[i]; + } + + byte[] resultCopy = new byte[resultPos]; + System.arraycopy(result, 0, resultCopy, 0, resultPos); + + return resultCopy; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/crypto/exceptions/HabboCryptoException.java b/Emulator/src/main/java/com/eu/habbo/crypto/exceptions/HabboCryptoException.java new file mode 100644 index 0000000..e2b86a8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/crypto/exceptions/HabboCryptoException.java @@ -0,0 +1,17 @@ +package com.eu.habbo.crypto.exceptions; + +public class HabboCryptoException extends Exception { + + public HabboCryptoException(String message) { + super(message); + } + + public HabboCryptoException(String message, Throwable cause) { + super(message, cause); + } + + public HabboCryptoException(Throwable cause) { + super(cause); + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/crypto/utils/BigIntegerUtils.java b/Emulator/src/main/java/com/eu/habbo/crypto/utils/BigIntegerUtils.java new file mode 100644 index 0000000..4998bde --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/crypto/utils/BigIntegerUtils.java @@ -0,0 +1,17 @@ +package com.eu.habbo.crypto.utils; + +import java.math.BigInteger; +import java.util.Arrays; + +public class BigIntegerUtils { + + public static byte[] toUnsignedByteArray(BigInteger bigInteger) { + byte[] bytes = bigInteger.toByteArray(); + if (bytes[0] == 0) { + bytes = Arrays.copyOfRange(bytes, 1, bytes.length); + } + + return bytes; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/database/Database.java b/Emulator/src/main/java/com/eu/habbo/database/Database.java new file mode 100644 index 0000000..171e7c9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/database/Database.java @@ -0,0 +1,109 @@ +package com.eu.habbo.database; + +import com.eu.habbo.Emulator; +import com.eu.habbo.core.ConfigurationManager; +import com.zaxxer.hikari.HikariDataSource; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Slf4j +public class Database { + private HikariDataSource dataSource; + private DatabasePool databasePool; + + public Database(ConfigurationManager config) { + long millis = System.currentTimeMillis(); + + boolean SQLException = false; + + try { + this.databasePool = new DatabasePool(); + if (!this.databasePool.getStoragePooling(config)) { + log.info("Failed to connect to the database. Please check config.ini and make sure the MySQL process is running. Shutting down..."); + SQLException = true; + return; + } + this.dataSource = this.databasePool.getDatabase(); + } catch (Exception e) { + SQLException = true; + log.error("Failed to connect to your database.", e); + } finally { + if (SQLException) { + Emulator.prepareShutdown(); + } + } + + log.info("Database -> Connected! ({} MS)", System.currentTimeMillis() - millis); + } + + public void dispose() { + if (this.databasePool != null) { + this.databasePool.getDatabase().close(); + } + + this.dataSource.close(); + } + + public HikariDataSource getDataSource() { + return this.dataSource; + } + + public DatabasePool getDatabasePool() { + return this.databasePool; + } + + public static PreparedStatement preparedStatementWithParams(Connection connection, String query, THashMap queryParams) throws SQLException { + THashMap params = new THashMap(); + THashSet quotedParams = new THashSet<>(); + + for(String key : queryParams.keySet()) { + quotedParams.add(Pattern.quote(key)); + } + + String regex = "(" + String.join("|", quotedParams) + ")"; + + Matcher m = Pattern.compile(regex).matcher(query); + + int i = 1; + + while (m.find()) { + try { + params.put(i, queryParams.get(m.group(1))); + i++; + } + catch (Exception ignored) { } + } + + PreparedStatement statement = connection.prepareStatement(query.replaceAll(regex, "?")); + + for(Map.Entry set : params.entrySet()) { + if(set.getValue().getClass() == String.class) { + statement.setString(set.getKey(), (String)set.getValue()); + } + else if(set.getValue().getClass() == Integer.class) { + statement.setInt(set.getKey(), (Integer)set.getValue()); + } + else if(set.getValue().getClass() == Double.class) { + statement.setDouble(set.getKey(), (Double)set.getValue()); + } + else if(set.getValue().getClass() == Float.class) { + statement.setFloat(set.getKey(), (Float)set.getValue()); + } + else if(set.getValue().getClass() == Long.class) { + statement.setLong(set.getKey(), (Long)set.getValue()); + } + else { + statement.setObject(set.getKey(), set.getValue()); + } + } + + return statement; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/database/DatabasePool.java b/Emulator/src/main/java/com/eu/habbo/database/DatabasePool.java new file mode 100644 index 0000000..5e09e06 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/database/DatabasePool.java @@ -0,0 +1,60 @@ +package com.eu.habbo.database; + +import com.eu.habbo.core.ConfigurationManager; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +class DatabasePool { + private static final String DB_POOL_MAX_SIZE = "db.pool.maxsize"; + private static final String DB_POOL_MIN_SIZE = "db.pool.minsize"; + private static final String DB_HOSTNAME_KEY = "db.hostname"; + private static final String DB_PORT_KEY = "db.port"; + private static final String DB_PASSWORD_KEY = "db.password"; + private static final String DB_NAME_KEY = "db.database"; + private static final String DB_USER_KEY = "db.username"; + private static final String DB_PARAMS_KEY = "db.params"; + private HikariDataSource database; + private static DatabasePool instance; + + DatabasePool() { + // Private constructor for singleton pattern + } + public static synchronized DatabasePool getInstance() { + if (instance == null) { + instance = new DatabasePool(); + } + return instance; + } + + public boolean getStoragePooling(ConfigurationManager config) { + try { + HikariConfig databaseConfiguration = new HikariConfig(); + databaseConfiguration.setMaximumPoolSize(config.getInt(DB_POOL_MAX_SIZE, 50)); + databaseConfiguration.setMinimumIdle(config.getInt(DB_POOL_MIN_SIZE, 10)); + databaseConfiguration.setJdbcUrl("jdbc:mysql://" + config.getValue(DB_HOSTNAME_KEY, "localhost") + ":" + config.getValue(DB_PORT_KEY, "3306") + "/" + config.getValue(DB_NAME_KEY) + config.getValue(DB_PARAMS_KEY)); + databaseConfiguration.addDataSourceProperty("serverName", config.getValue(DB_HOSTNAME_KEY, "localhost")); + databaseConfiguration.addDataSourceProperty("port", config.getValue(DB_PORT_KEY, "3306")); + databaseConfiguration.addDataSourceProperty("databaseName", config.getValue(DB_NAME_KEY)); + databaseConfiguration.addDataSourceProperty("user", config.getValue(DB_USER_KEY)); + databaseConfiguration.addDataSourceProperty("password", config.getValue(DB_PASSWORD_KEY)); + log.info("INITIALIZING DATABASE SERVER: " + config.getValue(DB_HOSTNAME_KEY)); + log.info("ON PORT: " + config.getValue(DB_PORT_KEY)); + log.info("HABBO DATABASE: " + config.getValue(DB_NAME_KEY)); + + this.database = new HikariDataSource(databaseConfiguration); + } catch (Exception e) { + log.error("Error initializing database connection pool: {}", e.getMessage()); + return false; + } + return true; + } + + public HikariDataSource getDatabase() { + if (database == null) { + throw new IllegalStateException("Database connection pool is not initialized."); + } + return database; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/GameEnvironment.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/GameEnvironment.java new file mode 100644 index 0000000..db5e3ba --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/GameEnvironment.java @@ -0,0 +1,212 @@ +package com.eu.habbo.habbohotel; + +import com.eu.habbo.Emulator; +import com.eu.habbo.core.*; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.bots.BotManager; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarManager; +import com.eu.habbo.habbohotel.catalog.CatalogManager; +import com.eu.habbo.habbohotel.commands.CommandHandler; +import com.eu.habbo.habbohotel.crafting.CraftingManager; +import com.eu.habbo.habbohotel.guides.GuideManager; +import com.eu.habbo.habbohotel.guilds.GuildManager; +import com.eu.habbo.habbohotel.hotelview.HotelViewManager; +import com.eu.habbo.habbohotel.items.ItemManager; +import com.eu.habbo.habbohotel.modtool.ModToolManager; +import com.eu.habbo.habbohotel.modtool.ModToolSanctions; +import com.eu.habbo.habbohotel.modtool.WordFilter; +import com.eu.habbo.habbohotel.navigation.NavigatorManager; +import com.eu.habbo.habbohotel.permissions.PermissionsManager; +import com.eu.habbo.habbohotel.pets.PetManager; +import com.eu.habbo.habbohotel.polls.PollManager; +import com.eu.habbo.habbohotel.rooms.RoomManager; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionManager; +import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionScheduler; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class GameEnvironment { + public CreditsScheduler creditsScheduler; + public PixelScheduler pixelScheduler; + public PointsScheduler pointsScheduler; + public GotwPointsScheduler gotwPointsScheduler; + public SubscriptionScheduler subscriptionScheduler; + + private HabboManager habboManager; + private NavigatorManager navigatorManager; + private GuildManager guildManager; + private ItemManager itemManager; + private CatalogManager catalogManager; + private HotelViewManager hotelViewManager; + private RoomManager roomManager; + private CommandHandler commandHandler; + private PermissionsManager permissionsManager; + private BotManager botManager; + private ModToolManager modToolManager; + private ModToolSanctions modToolSanctions; + private PetManager petManager; + private AchievementManager achievementManager; + private GuideManager guideManager; + private WordFilter wordFilter; + private CraftingManager craftingManager; + private PollManager pollManager; + private SubscriptionManager subscriptionManager; + private CalendarManager calendarManager; + + public void load() throws Exception { + log.info("GameEnvironment -> Loading..."); + + this.permissionsManager = new PermissionsManager(); + this.habboManager = new HabboManager(); + this.hotelViewManager = new HotelViewManager(); + this.itemManager = new ItemManager(); + this.itemManager.load(); + this.botManager = new BotManager(); + this.petManager = new PetManager(); + this.guildManager = new GuildManager(); + this.catalogManager = new CatalogManager(); + this.roomManager = new RoomManager(); + this.navigatorManager = new NavigatorManager(); + this.commandHandler = new CommandHandler(); + this.modToolManager = new ModToolManager(); + this.modToolSanctions = new ModToolSanctions(); + this.achievementManager = new AchievementManager(); + this.achievementManager.reload(); + this.guideManager = new GuideManager(); + this.wordFilter = new WordFilter(); + this.craftingManager = new CraftingManager(); + this.pollManager = new PollManager(); + this.calendarManager = new CalendarManager(); + + this.roomManager.loadPublicRooms(); + this.navigatorManager.loadNavigator(); + + this.creditsScheduler = new CreditsScheduler(); + Emulator.getThreading().run(this.creditsScheduler); + this.pixelScheduler = new PixelScheduler(); + Emulator.getThreading().run(this.pixelScheduler); + this.pointsScheduler = new PointsScheduler(); + Emulator.getThreading().run(this.pointsScheduler); + this.gotwPointsScheduler = new GotwPointsScheduler(); + Emulator.getThreading().run(this.gotwPointsScheduler); + + this.subscriptionManager = new SubscriptionManager(); + this.subscriptionManager.init(); + + this.subscriptionScheduler = new SubscriptionScheduler(); + Emulator.getThreading().run(this.subscriptionScheduler); + + log.info("GameEnvironment -> Loaded!"); + } + + public void dispose() { + this.pointsScheduler.setDisposed(true); + this.pixelScheduler.setDisposed(true); + this.creditsScheduler.setDisposed(true); + this.gotwPointsScheduler.setDisposed(true); + this.craftingManager.dispose(); + this.habboManager.dispose(); + this.commandHandler.dispose(); + this.guildManager.dispose(); + this.catalogManager.dispose(); + this.roomManager.dispose(); + this.itemManager.dispose(); + this.hotelViewManager.dispose(); + this.subscriptionManager.dispose(); + this.calendarManager.dispose(); + log.info("GameEnvironment -> Disposed!"); + } + + public HabboManager getHabboManager() { + return this.habboManager; + } + + public NavigatorManager getNavigatorManager() { + return this.navigatorManager; + } + + public GuildManager getGuildManager() { + return this.guildManager; + } + + public ItemManager getItemManager() { + return this.itemManager; + } + + public CatalogManager getCatalogManager() { + return this.catalogManager; + } + + public HotelViewManager getHotelViewManager() { + return this.hotelViewManager; + } + + public RoomManager getRoomManager() { + return this.roomManager; + } + + public CommandHandler getCommandHandler() { + return this.commandHandler; + } + + public PermissionsManager getPermissionsManager() { + return this.permissionsManager; + } + + public BotManager getBotManager() { + return this.botManager; + } + + public ModToolManager getModToolManager() { + return this.modToolManager; + } + + public ModToolSanctions getModToolSanctions() { + return this.modToolSanctions; + } + + public PetManager getPetManager() { + return this.petManager; + } + + public AchievementManager getAchievementManager() { + return this.achievementManager; + } + + public GuideManager getGuideManager() { + return this.guideManager; + } + + public WordFilter getWordFilter() { + return this.wordFilter; + } + + public CraftingManager getCraftingManager() { + return this.craftingManager; + } + + public PollManager getPollManager() { + return this.pollManager; + } + + public CreditsScheduler getCreditsScheduler() { + return this.creditsScheduler; + } + + public PixelScheduler getPixelScheduler() { + return this.pixelScheduler; + } + + public PointsScheduler getPointsScheduler() { return this.pointsScheduler; + } + + public GotwPointsScheduler getGotwPointsScheduler() { return this.gotwPointsScheduler; + } + + public SubscriptionManager getSubscriptionManager() { + return this.subscriptionManager; + } + + public CalendarManager getCalendarManager() { return this.calendarManager; } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/LatencyTracker.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/LatencyTracker.java new file mode 100644 index 0000000..b2ffb9d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/LatencyTracker.java @@ -0,0 +1,47 @@ +package com.eu.habbo.habbohotel; + +import com.eu.habbo.habbohotel.gameclients.GameClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.TimeUnit; + +public class LatencyTracker { + + private static final Logger LOGGER = LoggerFactory.getLogger(GameClient.class); + + private boolean initialPing; + + private long last; + private long average; + + public LatencyTracker() { + this.initialPing = true; + this.average = 0; + } + + public void update(long latencyInNano) { + this.last = latencyInNano; + + if (this.initialPing) { + this.initialPing = false; + this.average = latencyInNano; + return; + } + + this.average = (long) (this.average * .7f + latencyInNano * .3f); + } + + public boolean hasInitialized() { + return !this.initialPing; + } + + public long getLastMs() { + return TimeUnit.NANOSECONDS.toMillis(this.last); + } + + public long getAverageMs() { + return TimeUnit.NANOSECONDS.toMillis(this.average); + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/Achievement.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/Achievement.java new file mode 100644 index 0000000..dcf34c1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/Achievement.java @@ -0,0 +1,77 @@ +package com.eu.habbo.habbohotel.achievements; + +import gnu.trove.map.hash.THashMap; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class Achievement { + + public final int id; + + + public final String name; + + + public final AchievementCategories category; + + + public final THashMap levels; + + + public Achievement(ResultSet set) throws SQLException { + this.levels = new THashMap<>(); + + this.id = set.getInt("id"); + this.name = set.getString("name"); + this.category = AchievementCategories.valueOf(set.getString("category").toUpperCase()); + + this.addLevel(new AchievementLevel(set)); + } + + + public void addLevel(AchievementLevel level) { + synchronized (this.levels) { + this.levels.put(level.level, level); + } + } + + + public AchievementLevel getLevelForProgress(int progress) { + AchievementLevel l = null; + if (progress > 0) { + for (AchievementLevel level : this.levels.values()) { + if (progress >= level.progress) { + if (l != null) { + if (l.level > level.level) { + continue; + } + } + + l = level; + } + } + } + return l; + } + + + public AchievementLevel getNextLevel(int currentLevel) { + AchievementLevel l = null; + + for (AchievementLevel level : this.levels.values()) { + if (level.level == (currentLevel + 1)) + return level; + } + + return null; + } + + public AchievementLevel firstLevel() { + return this.levels.get(1); + } + + public void clearLevels() { + this.levels.clear(); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/AchievementCategories.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/AchievementCategories.java new file mode 100644 index 0000000..f5e8ba6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/AchievementCategories.java @@ -0,0 +1,39 @@ +package com.eu.habbo.habbohotel.achievements; + +public enum AchievementCategories { + + IDENTITY, + + + EXPLORE, + + + MUSIC, + + + SOCIAL, + + + GAMES, + + + ROOM_BUILDER, + + + PETS, + + + TOOLS, + + + OTHER, + + + TEST, + + + INVISIBLE, + + + EVENTS +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/AchievementLevel.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/AchievementLevel.java new file mode 100644 index 0000000..28868aa --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/AchievementLevel.java @@ -0,0 +1,29 @@ +package com.eu.habbo.habbohotel.achievements; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class AchievementLevel { + + public final int level; + + + public final int rewardAmount; + + + public final int rewardType; + + + public final int points; + + + public final int progress; + + public AchievementLevel(ResultSet set) throws SQLException { + this.level = set.getInt("level"); + this.rewardAmount = set.getInt("reward_amount"); + this.rewardType = set.getInt("reward_type"); + this.points = set.getInt("points"); + this.progress = set.getInt("progress_needed"); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/AchievementManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/AchievementManager.java new file mode 100644 index 0000000..5e614aa --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/AchievementManager.java @@ -0,0 +1,394 @@ +package com.eu.habbo.habbohotel.achievements; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.achievements.AchievementProgressComposer; +import com.eu.habbo.messages.outgoing.achievements.AchievementUnlockedComposer; +import com.eu.habbo.messages.outgoing.achievements.talenttrack.TalentLevelUpdateComposer; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer; +import com.eu.habbo.messages.outgoing.users.AddUserBadgeComposer; +import com.eu.habbo.messages.outgoing.users.UserBadgesComposer; +import com.eu.habbo.plugin.Event; +import com.eu.habbo.plugin.events.users.achievements.UserAchievementLeveledEvent; +import com.eu.habbo.plugin.events.users.achievements.UserAchievementProgressEvent; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectIntProcedure; +import lombok.extern.slf4j.Slf4j; + +import java.sql.*; +import java.util.LinkedHashMap; +import java.util.Map; + +@Slf4j +public class AchievementManager { + public static boolean TALENTTRACK_ENABLED = false; + + private final THashMap achievements; + private final THashMap> talentTrackLevels; + + public AchievementManager() { + this.achievements = new THashMap<>(); + this.talentTrackLevels = new THashMap<>(); + } + + public static void progressAchievement(int habboId, Achievement achievement) { + progressAchievement(habboId, achievement, 1); + } + + public static void progressAchievement(int habboId, Achievement achievement, int amount) { + if (achievement != null) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(habboId); + + if (habbo != null) { + progressAchievement(habbo, achievement, amount); + } else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("" + + "INSERT INTO users_achievements_queue (user_id, achievement_id, amount) VALUES (?, ?, ?) " + + "ON DUPLICATE KEY UPDATE amount = amount + ?")) { + statement.setInt(1, habboId); + statement.setInt(2, achievement.id); + statement.setInt(3, amount); + statement.setInt(4, amount); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + } + + public static void progressAchievement(Habbo habbo, Achievement achievement) { + progressAchievement(habbo, achievement, 1); + } + + public static void progressAchievement(Habbo habbo, Achievement achievement, int amount) { + if (achievement == null) + return; + + if (habbo == null) + return; + + if (!habbo.isOnline()) + return; + + int currentProgress = habbo.getHabboStats().getAchievementProgress(achievement); + + if (currentProgress == -1) { + currentProgress = 0; + createUserEntry(habbo, achievement); + habbo.getHabboStats().setProgress(achievement, 0); + } + + if (Emulator.getPluginManager().isRegistered(UserAchievementProgressEvent.class, true)) { + Event userAchievementProgressedEvent = new UserAchievementProgressEvent(habbo, achievement, amount); + Emulator.getPluginManager().fireEvent(userAchievementProgressedEvent); + + if (userAchievementProgressedEvent.isCancelled()) + return; + } + + AchievementLevel oldLevel = achievement.getLevelForProgress(currentProgress); + + if (oldLevel != null && (oldLevel.level == achievement.levels.size() && currentProgress >= oldLevel.progress)) //Maximum achievement gotten. + return; + + habbo.getHabboStats().setProgress(achievement, currentProgress + amount); + + AchievementLevel newLevel = achievement.getLevelForProgress(currentProgress + amount); + + if (AchievementManager.TALENTTRACK_ENABLED) { + for (TalentTrackType type : TalentTrackType.values()) { + if (Emulator.getGameEnvironment().getAchievementManager().talentTrackLevels.containsKey(type)) { + for (Map.Entry entry : Emulator.getGameEnvironment().getAchievementManager().talentTrackLevels.get(type).entrySet()) { + if (entry.getValue().achievements.containsKey(achievement)) { + Emulator.getGameEnvironment().getAchievementManager().handleTalentTrackAchievement(habbo, type, achievement); + break; + } + } + } + } + } + + if (newLevel == null || + (oldLevel != null && (oldLevel.level == newLevel.level && newLevel.level < achievement.levels.size()))) { + habbo.getClient().sendResponse(new AchievementProgressComposer(habbo, achievement)); + } else { + if (Emulator.getPluginManager().isRegistered(UserAchievementLeveledEvent.class, true)) { + Event userAchievementLeveledEvent = new UserAchievementLeveledEvent(habbo, achievement, oldLevel, newLevel); + Emulator.getPluginManager().fireEvent(userAchievementLeveledEvent); + + if (userAchievementLeveledEvent.isCancelled()) + return; + } + + habbo.getClient().sendResponse(new AchievementProgressComposer(habbo, achievement)); + habbo.getClient().sendResponse(new AchievementUnlockedComposer(habbo, achievement)); + + //Exception could possibly arise when the user disconnects while being in tour. + //The achievement is then progressed but the user is already disposed so fetching + //the badge would result in an nullpointer exception. This is normal behaviour. + HabboBadge badge = null; + + if (oldLevel != null) { + try { + badge = habbo.getInventory().getBadgesComponent().getBadge(("ACH_" + achievement.name + oldLevel.level).toLowerCase()); + } catch (Exception e) { + log.error("Caught exception", e); + return; + } + } + + String newBadgCode = "ACH_" + achievement.name + newLevel.level; + + if (badge != null) { + badge.setCode(newBadgCode); + badge.needsInsert(false); + badge.needsUpdate(true); + } else { + if (habbo.getInventory().getBadgesComponent().hasBadge(newBadgCode)) + return; + + badge = new HabboBadge(0, newBadgCode, 0, habbo); + habbo.getClient().sendResponse(new AddUserBadgeComposer(badge)); + badge.needsInsert(true); + badge.needsUpdate(true); + habbo.getInventory().getBadgesComponent().addBadge(badge); + } + + Emulator.getThreading().run(badge); + + if (badge.getSlot() > 0) { + if (habbo.getHabboInfo().getCurrentRoom() != null) { + habbo.getHabboInfo().getCurrentRoom().sendComposer(new UserBadgesComposer(habbo.getInventory().getBadgesComponent().getWearingBadges(), habbo.getHabboInfo().getId()).compose()); + } + } + + habbo.getClient().sendResponse(new AddHabboItemComposer(badge.getId(), AddHabboItemComposer.AddHabboItemCategory.BADGE)); + + habbo.getHabboStats().addAchievementScore(newLevel.points); + + if (newLevel.rewardAmount > 0) { + habbo.givePoints(newLevel.rewardType, newLevel.rewardAmount); + } + + if (habbo.getHabboInfo().getCurrentRoom() != null) { + habbo.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserDataComposer(habbo).compose()); + } + } + } + + public static boolean hasAchieved(Habbo habbo, Achievement achievement) { + int currentProgress = habbo.getHabboStats().getAchievementProgress(achievement); + + if (currentProgress == -1) { + return false; + } + + AchievementLevel level = achievement.getLevelForProgress(currentProgress); + + if (level == null) + return false; + + AchievementLevel nextLevel = achievement.levels.get(level.level + 1); + + return nextLevel == null && currentProgress >= level.progress; + } + + public static void createUserEntry(Habbo habbo, Achievement achievement) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO users_achievements (user_id, achievement_name, progress) VALUES (?, ?, ?)")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + statement.setString(2, achievement.name); + statement.setInt(3, 1); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public static void saveAchievements(Habbo habbo) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users_achievements SET progress = ? WHERE achievement_name = ? AND user_id = ? LIMIT 1")) { + statement.setInt(3, habbo.getHabboInfo().getId()); + for (Map.Entry map : habbo.getHabboStats().getAchievementProgress().entrySet()) { + statement.setInt(1, map.getValue()); + statement.setString(2, map.getKey().name); + statement.addBatch(); + } + statement.executeBatch(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public static int getAchievementProgressForHabbo(int userId, Achievement achievement) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT progress FROM users_achievements WHERE user_id = ? AND achievement_name = ? LIMIT 1")) { + statement.setInt(1, userId); + statement.setString(2, achievement.name); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + return set.getInt("progress"); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return 0; + } + + public void reload() { + long millis = System.currentTimeMillis(); + synchronized (this.achievements) { + for (Achievement achievement : this.achievements.values()) { + achievement.clearLevels(); + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM achievements")) { + while (set.next()) { + if (!this.achievements.containsKey(set.getString("name"))) { + this.achievements.put(set.getString("name"), new Achievement(set)); + } else { + this.achievements.get(set.getString("name")).addLevel(new AchievementLevel(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } catch (Exception e) { + log.error("Caught exception", e); + } + + + synchronized (this.talentTrackLevels) { + this.talentTrackLevels.clear(); + + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM achievements_talents ORDER BY level ASC")) { + while (set.next()) { + TalentTrackLevel level = new TalentTrackLevel(set); + + if (!this.talentTrackLevels.containsKey(level.type)) { + this.talentTrackLevels.put(level.type, new LinkedHashMap<>()); + } + + this.talentTrackLevels.get(level.type).put(level.level, level); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + log.error("Achievement Manager -> Failed to load!"); + return; + } + } + + log.info("Achievement Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)"); + } + + public Achievement getAchievement(String name) { + return this.achievements.get(name); + } + + public Achievement getAchievement(int id) { + synchronized (this.achievements) { + for (Map.Entry set : this.achievements.entrySet()) { + if (set.getValue().id == id) { + return set.getValue(); + } + } + } + + return null; + } + + public THashMap getAchievements() { + return this.achievements; + } + + public LinkedHashMap getTalenTrackLevels(TalentTrackType type) { + return this.talentTrackLevels.get(type); + } + + public TalentTrackLevel calculateTalenTrackLevel(Habbo habbo, TalentTrackType type) { + TalentTrackLevel level = null; + + for (Map.Entry entry : this.talentTrackLevels.get(type).entrySet()) { + final boolean[] allCompleted = {true}; + entry.getValue().achievements.forEachEntry(new TObjectIntProcedure() { + @Override + public boolean execute(Achievement a, int b) { + if (habbo.getHabboStats().getAchievementProgress(a) < b) { + allCompleted[0] = false; + } + + return allCompleted[0]; + } + }); + + if (allCompleted[0]) { + if (level == null || level.level < entry.getValue().level) { + level = entry.getValue(); + } + } else { + break; + } + } + + return level; + } + + public void handleTalentTrackAchievement(Habbo habbo, TalentTrackType type, Achievement achievement) { + TalentTrackLevel currentLevel = this.calculateTalenTrackLevel(habbo, type); + + if (currentLevel != null) { + if (currentLevel.level > habbo.getHabboStats().talentTrackLevel(type)) { + for (int i = habbo.getHabboStats().talentTrackLevel(type); i <= currentLevel.level; i++) { + TalentTrackLevel level = this.getTalentTrackLevel(type, i); + + if (level != null) { + if (level.items != null && !level.items.isEmpty()) { + for (Item item : level.items) { + HabboItem rewardItem = Emulator.getGameEnvironment().getItemManager().createItem(habbo.getHabboInfo().getId(), item, 0, 0, ""); + habbo.getInventory().getItemsComponent().addItem(rewardItem); + habbo.getClient().sendResponse(new AddHabboItemComposer(rewardItem)); + habbo.getClient().sendResponse(new InventoryRefreshComposer()); + } + } + + if (level.badges != null && level.badges.length > 0) { + for (String badge : level.badges) { + if (!badge.isEmpty()) { + if (!habbo.getInventory().getBadgesComponent().hasBadge(badge)) { + HabboBadge b = new HabboBadge(0, badge, 0, habbo); + Emulator.getThreading().run(b); + habbo.getInventory().getBadgesComponent().addBadge(b); + habbo.getClient().sendResponse(new AddUserBadgeComposer(b)); + } + } + } + } + + if (level.perks != null && level.perks.length > 0) { + for (String perk : level.perks) { + if (perk.equalsIgnoreCase("TRADE")) { + habbo.getHabboStats().perkTrade = true; + } + } + } + habbo.getClient().sendResponse(new TalentLevelUpdateComposer(type, level)); + } + } + } + + habbo.getHabboStats().setTalentLevel(type, currentLevel.level); + } + } + + public TalentTrackLevel getTalentTrackLevel(TalentTrackType type, int level) { + return this.talentTrackLevels.get(type).get(level); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/TalentTrackLevel.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/TalentTrackLevel.java new file mode 100644 index 0000000..b9425a7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/TalentTrackLevel.java @@ -0,0 +1,64 @@ +package com.eu.habbo.habbohotel.achievements; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import gnu.trove.map.TObjectIntMap; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; + +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class TalentTrackLevel { + + public TalentTrackType type; + public int level; + public TObjectIntMap achievements; + public THashSet items; + public String[] perks; + public String[] badges; + + public TalentTrackLevel(ResultSet set) throws SQLException { + this.type = TalentTrackType.valueOf(set.getString("type").toUpperCase()); + this.level = set.getInt("level"); + this.achievements = new TObjectIntHashMap<>(); + this.items = new THashSet<>(); + + String[] achievements = set.getString("achievement_ids").split(","); + String[] achievementLevels = set.getString("achievement_levels").split(","); + if (achievementLevels.length == achievements.length) { + for (int i = 0; i < achievements.length; i++) { + if (achievements[i].isEmpty() || achievementLevels[i].isEmpty()) + continue; + + Achievement achievement = Emulator.getGameEnvironment().getAchievementManager().getAchievement(Integer.valueOf(achievements[i])); + + if (achievement != null) { + this.achievements.put(achievement, Integer.valueOf(achievementLevels[i])); + } else { + log.error("Could not find achievement with ID " + achievements[i] + " for talenttrack level " + this.level + " of type " + this.type); + } + } + } + + for (String s : set.getString("reward_furni").split(",")) { + Item item = Emulator.getGameEnvironment().getItemManager().getItem(Integer.valueOf(s)); + + if (item != null) { + this.items.add(item); + } else { + log.error("Incorrect reward furni (ID: " + s + ") for talent track level " + this.level); + } + } + + if (!set.getString("reward_perks").isEmpty()) { + this.perks = set.getString("reward_perks").split(","); + } + + if (!set.getString("reward_badges").isEmpty()) { + this.badges = set.getString("reward_badges").split(","); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/TalentTrackType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/TalentTrackType.java new file mode 100644 index 0000000..6c3d9b8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/achievements/TalentTrackType.java @@ -0,0 +1,9 @@ +package com.eu.habbo.habbohotel.achievements; + +public enum TalentTrackType { + + CITIZENSHIP, + + + HELPER +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/bots/Bot.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/bots/Bot.java new file mode 100644 index 0000000..189106c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/bots/Bot.java @@ -0,0 +1,485 @@ +package com.eu.habbo.habbohotel.bots; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.outgoing.rooms.users.*; +import com.eu.habbo.plugin.events.bots.BotChatEvent; +import com.eu.habbo.plugin.events.bots.BotShoutEvent; +import com.eu.habbo.plugin.events.bots.BotTalkEvent; +import com.eu.habbo.plugin.events.bots.BotWhisperEvent; +import com.eu.habbo.threading.runnables.BotFollowHabbo; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; + +@Slf4j +public class Bot implements Runnable { + public static final String NO_CHAT_SET = "${bot.skill.chatter.configuration.text.placeholder}"; + public static String[] PLACEMENT_MESSAGES = "Yo!;Hello I'm a real party animal!;Hello!".split(";"); + + private final ArrayList chatLines; + private transient int id; + private String name; + private String motto; + private String figure; + private HabboGender gender; + private int ownerId; + private String ownerName; + private Room room; + private RoomUnit roomUnit; + private boolean chatAuto; + private boolean chatRandom; + private short chatDelay; + private int chatTimeOut; + private int chatTimestamp; + private short lastChatIndex; + private int bubble; + + + private String type; + + + private int effect; + + private transient boolean canWalk = true; + + + private boolean needsUpdate; + + + private transient int followingHabboId; + + public Bot(int id, String name, String motto, String figure, HabboGender gender, int ownerId, String ownerName) { + this.id = id; + this.name = name; + this.motto = motto; + this.figure = figure; + this.gender = gender; + this.ownerId = ownerId; + this.ownerName = ownerName; + this.chatAuto = false; + this.chatRandom = false; + this.chatDelay = 1000; + this.chatLines = new ArrayList<>(); + this.type = "generic_bot"; + this.room = null; + this.bubble = RoomChatMessageBubbles.BOT_RENTABLE.getType(); + } + + public Bot(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.name = set.getString("name"); + this.motto = set.getString("motto"); + this.figure = set.getString("figure"); + this.gender = HabboGender.valueOf(set.getString("gender")); + this.ownerId = set.getInt("user_id"); + this.ownerName = set.getString("owner_name"); + this.chatAuto = set.getString("chat_auto").equals("1"); + this.chatRandom = set.getString("chat_random").equals("1"); + this.chatDelay = set.getShort("chat_delay"); + 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.room = null; + this.roomUnit = null; + this.chatTimeOut = Emulator.getIntUnixTimestamp() + this.chatDelay; + this.needsUpdate = false; + this.bubble = set.getInt("bubble_id"); + } + + public Bot(Bot bot) { + this.name = bot.getName(); + this.motto = bot.getMotto(); + this.figure = bot.getFigure(); + this.gender = bot.getGender(); + this.ownerId = bot.getOwnerId(); + this.ownerName = bot.getOwnerName(); + this.chatAuto = true; + this.chatRandom = false; + this.chatDelay = 10; + this.chatTimeOut = Emulator.getIntUnixTimestamp() + this.chatDelay; + this.chatLines = new ArrayList<>(Arrays.asList("Default Message :D")); + this.type = bot.getType(); + this.effect = bot.getEffect(); + this.bubble = bot.getBubbleId(); + + this.needsUpdate = false; + } + + public static void initialise() { + + } + + public static void dispose() { + + } + + public void needsUpdate(boolean needsUpdate) { + this.needsUpdate = needsUpdate; + } + + public boolean needsUpdate() { + return this.needsUpdate; + } + + @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_id = ? WHERE id = ?")) { + statement.setString(1, this.name); + statement.setString(2, this.motto); + statement.setString(3, this.figure); + statement.setString(4, this.gender.toString()); + statement.setInt(5, this.ownerId); + statement.setInt(6, this.room == null ? 0 : this.room.getId()); + statement.setInt(7, this.roomUnit == null ? 0 : this.roomUnit.getX()); + statement.setInt(8, this.roomUnit == null ? 0 : this.roomUnit.getY()); + statement.setDouble(9, this.roomUnit == null ? 0 : this.roomUnit.getZ()); + statement.setInt(10, this.roomUnit == null ? 0 : this.roomUnit.getBodyRotation().getValue()); + statement.setInt(11, this.roomUnit == null ? 0 : this.roomUnit.getDanceType().getType()); + statement.setString(12, this.canWalk ? "1" : "0"); + StringBuilder text = new StringBuilder(); + for (String s : this.chatLines) { + text.append(s).append("\r"); + } + statement.setString(13, text.toString()); + statement.setString(14, this.chatAuto ? "1" : "0"); + statement.setString(15, this.chatRandom ? "1" : "0"); + statement.setInt(16, this.chatDelay); + statement.setInt(17, this.effect); + statement.setInt(18, this.bubble); + statement.setInt(19, this.id); + statement.execute(); + this.needsUpdate = false; + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public void cycle(boolean allowBotsWalk) { + if (this.roomUnit != null) { + if (allowBotsWalk && this.canWalk) { + if (!this.roomUnit.isWalking()) { + if (this.roomUnit.getWalkTimeOut() < Emulator.getIntUnixTimestamp() && this.followingHabboId == 0) { + this.roomUnit.setGoalLocation(this.room.getRandomWalkableTile()); + int timeOut = Emulator.getRandom().nextInt(20) * 2; + this.roomUnit.setWalkTimeOut((timeOut < 10 ? 5 : timeOut) + Emulator.getIntUnixTimestamp()); + } + }/* else { + for (RoomTile t : this.room.getLayout().getTilesAround(this.room.getLayout().getTile(this.getRoomUnit().getX(), this.getRoomUnit().getY()))) { + WiredHandler.handle(WiredTriggerType.BOT_REACHED_STF, this.roomUnit, this.room, this.room.getItemsAt(t).toArray()); + } + }*/ + } + + if (!this.chatLines.isEmpty() && this.chatTimeOut <= Emulator.getIntUnixTimestamp() && this.chatAuto) { + if (this.room != null) { + this.lastChatIndex = (this.chatRandom ? (short) Emulator.getRandom().nextInt(this.chatLines.size()) : (this.lastChatIndex == (this.chatLines.size() - 1) ? 0 : this.lastChatIndex++)); + + if (this.lastChatIndex >= this.chatLines.size()) { + this.lastChatIndex = 0; + } + + String message = this.chatLines.get(this.lastChatIndex) + .replace(Emulator.getTexts().getValue("wired.variable.owner", "%owner%"), this.room.getOwnerName()) + .replace(Emulator.getTexts().getValue("wired.variable.item_count", "%item_count%"), this.room.itemCount() + "") + .replace(Emulator.getTexts().getValue("wired.variable.name", "%name%"), this.name) + .replace(Emulator.getTexts().getValue("wired.variable.roomname", "%roomname%"), this.room.getName()) + .replace(Emulator.getTexts().getValue("wired.variable.user_count", "%user_count%"), this.room.getUserCount() + ""); // TODO: Should getUserCount be replaced with getUsersWithoutInvisibleHabbos? + + if(!WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, this.getRoomUnit(), room, new Object[]{ message })) { + this.talk(message); + } + + this.chatTimeOut = Emulator.getIntUnixTimestamp() + this.chatDelay; + } + } + } + } + + public void talk(String message) { + if (this.room != null) { + BotChatEvent event = new BotTalkEvent(this, message); + if (Emulator.getPluginManager().fireEvent(event).isCancelled()) + return; + + this.chatTimestamp = Emulator.getIntUnixTimestamp(); + 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()); + } + } + } + + public void shout(String message) { + if (this.room != null) { + BotChatEvent event = new BotShoutEvent(this, message); + if (Emulator.getPluginManager().fireEvent(event).isCancelled()) + return; + + this.chatTimestamp = Emulator.getIntUnixTimestamp(); + 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()); + } + } + } + + public void whisper(String message, Habbo habbo) { + if (this.room != null && habbo != null) { + BotWhisperEvent event = new BotWhisperEvent(this, message, habbo); + if (Emulator.getPluginManager().fireEvent(event).isCancelled()) + return; + + this.chatTimestamp = Emulator.getIntUnixTimestamp(); + event.target.getClient().sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(event.message, this.roomUnit, RoomChatMessageBubbles.getBubble(this.getBubbleId())))); + } + } + + public void onPlace(Habbo habbo, Room room) { + if (this.roomUnit != null) { + room.giveEffect(this.roomUnit, this.effect, -1); + } + + if(PLACEMENT_MESSAGES.length > 0) { + String message = PLACEMENT_MESSAGES[Emulator.getRandom().nextInt(PLACEMENT_MESSAGES.length)]; + if (!WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, this.getRoomUnit(), room, new Object[]{message})) { + this.talk(message); + } + } + } + + public void onPickUp(Habbo habbo, Room room) { + + } + + public void onUserSay(final RoomChatMessage message) { + + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public int getBubbleId() { + return bubble; + } + + public void setName(String name) { + this.name = name; + this.needsUpdate = true; + + //if(this.room != null) + //this.room.sendComposer(new ChangeNameUpdatedComposer(this.getRoomUnit(), this.getName()).compose()); + } + + public String getMotto() { + return this.motto; + } + + public void setMotto(String motto) { + this.motto = motto; + this.needsUpdate = true; + } + + public String getFigure() { + return this.figure; + } + + public void setFigure(String figure) { + this.figure = figure; + this.needsUpdate = true; + + if (this.room != null) + this.room.sendComposer(new RoomUsersComposer(this).compose()); + } + + public HabboGender getGender() { + return this.gender; + } + + public void setGender(HabboGender gender) { + this.gender = gender; + this.needsUpdate = true; + + if (this.room != null) + this.room.sendComposer(new RoomUsersComposer(this).compose()); + } + + public int getOwnerId() { + return this.ownerId; + } + + public void setOwnerId(int ownerId) { + this.ownerId = ownerId; + this.needsUpdate = true; + + if (this.room != null) + this.room.sendComposer(new RoomUsersComposer(this).compose()); + } + + public String getOwnerName() { + return this.ownerName; + } + + public void setOwnerName(String ownerName) { + this.ownerName = ownerName; + this.needsUpdate = true; + + if (this.room != null) + this.room.sendComposer(new RoomUsersComposer(this).compose()); + } + + public Room getRoom() { + return this.room; + } + + public void setRoom(Room room) { + this.room = room; + } + + public RoomUnit getRoomUnit() { + return this.roomUnit; + } + + public void setRoomUnit(RoomUnit roomUnit) { + this.roomUnit = roomUnit; + } + + public boolean isChatAuto() { + return this.chatAuto; + } + + public void setChatAuto(boolean chatAuto) { + this.chatAuto = chatAuto; + this.needsUpdate = true; + } + + public boolean isChatRandom() { + return this.chatRandom; + } + + public void setChatRandom(boolean chatRandom) { + this.chatRandom = chatRandom; + this.needsUpdate = true; + } + + public boolean hasChat() { + return !this.chatLines.isEmpty(); + } + + public int getChatDelay() { + return this.chatDelay; + } + + public void setChatDelay(short chatDelay) { + this.chatDelay = (short) Math.min(Math.max(chatDelay, BotManager.MINIMUM_CHAT_SPEED), BotManager.MAXIMUM_CHAT_SPEED); + this.needsUpdate = true; + this.chatTimeOut = Emulator.getIntUnixTimestamp() + this.chatDelay; + } + + public int getChatTimestamp() { + return this.chatTimestamp; + } + + public void clearChat() { + synchronized (this.chatLines) { + this.chatLines.clear(); + this.needsUpdate = true; + } + } + + public String getType() { + return this.type; + } + + public int getEffect() { + return this.effect; + } + + public void setEffect(int effect, int duration) { + this.effect = effect; + this.needsUpdate = true; + + if (this.roomUnit != null) { + if (this.room != null) { + this.room.giveEffect(this.roomUnit, this.effect, duration); + } + } + } + + public void addChatLines(ArrayList chatLines) { + synchronized (this.chatLines) { + this.chatLines.addAll(chatLines); + this.needsUpdate = true; + } + } + + public void addChatLine(String chatLine) { + synchronized (this.chatLines) { + this.chatLines.add(chatLine); + this.needsUpdate = true; + } + } + + public ArrayList getChatLines() { + return this.chatLines; + } + + public int getFollowingHabboId() { + return this.followingHabboId; + } + + public void startFollowingHabbo(Habbo habbo) { + this.followingHabboId = habbo.getHabboInfo().getId(); + + Emulator.getThreading().run(new BotFollowHabbo(this, habbo, habbo.getHabboInfo().getCurrentRoom())); + } + + public void stopFollowingHabbo() { + this.followingHabboId = 0; + } + + public boolean canWalk() { + return this.canWalk; + } + + public void setCanWalk(boolean canWalk) { + this.canWalk = canWalk; + } + + public void lookAt(Habbo habbo) { + this.lookAt(habbo.getRoomUnit().getCurrentLocation()); + } + + public void lookAt(RoomUnit roomUnit) { + this.lookAt(roomUnit.getCurrentLocation()); + } + + public void lookAt(RoomTile tile) { + this.roomUnit.lookAtPoint(tile); + this.roomUnit.statusUpdate(true); + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/bots/BotManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/bots/BotManager.java new file mode 100644 index 0000000..fa6182e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/bots/BotManager.java @@ -0,0 +1,242 @@ +package com.eu.habbo.habbohotel.bots; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.generic.alerts.BotErrorComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.inventory.AddBotComposer; +import com.eu.habbo.messages.outgoing.inventory.RemoveBotComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUsersComposer; +import com.eu.habbo.plugin.events.bots.BotPickUpEvent; +import com.eu.habbo.plugin.events.bots.BotPlacedEvent; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; + +import java.lang.reflect.Method; +import java.sql.*; +import java.util.Map; + +@Slf4j +public class BotManager { + final private static THashMap> botDefenitions = new THashMap<>(); + public static int MINIMUM_CHAT_SPEED = 7; + public static int MAXIMUM_CHAT_SPEED = 604800; + public static int MAXIMUM_CHAT_LENGTH = 120; + public static int MAXIMUM_NAME_LENGTH = 15; + public static int MAXIMUM_BOT_INVENTORY_SIZE = 25; + + public BotManager() throws Exception { + long millis = System.currentTimeMillis(); + + addBotDefinition("generic", Bot.class); + addBotDefinition("bartender", ButlerBot.class); + addBotDefinition("visitor_log", VisitorBot.class); + + this.reload(); + + log.info("Bot Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)"); + } + + public static void addBotDefinition(String type, Class botClazz) throws Exception { + botClazz.getDeclaredConstructor(ResultSet.class).setAccessible(true); + botDefenitions.put(type, botClazz); + } + + public boolean reload() { + for (Map.Entry> set : botDefenitions.entrySet()) { + try { + Method m = set.getValue().getMethod("initialise"); + m.setAccessible(true); + m.invoke(null); + } catch (NoSuchMethodException e) { + log.info("Bot Manager -> Failed to execute initialise method upon bot type '" + set.getKey() + "'. No Such Method!"); + return false; + } catch (Exception e) { + log.info("Bot Manager -> Failed to execute initialise method upon bot type '" + set.getKey() + "'. Error: " + e.getMessage()); + return false; + } + } + + return true; + } + + 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)) { + statement.setString(1, data.get("name")); + statement.setString(2, data.get("motto")); + statement.setString(3, data.get("figure")); + statement.setString(4, data.get("gender").toUpperCase()); + statement.setString(5, type); + 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")) { + stmt.setInt(1, set.getInt(1)); + try (ResultSet resultSet = stmt.executeQuery()) { + if (resultSet.next()) { + bot = this.loadBot(resultSet); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return bot; + } + + public void placeBot(Bot bot, Habbo habbo, Room room, RoomTile location) { + BotPlacedEvent event = new BotPlacedEvent(bot, location, habbo); + Emulator.getPluginManager().fireEvent(event); + + if (event.isCancelled()) + return; + + if (room != null && bot != null && habbo != null) { + if (room.getOwnerId() == habbo.getHabboInfo().getId() || habbo.hasPermission(Permission.ACC_ANYROOMOWNER) || habbo.hasPermission(Permission.ACC_PLACEFURNI)) { + if (room.getCurrentBots().size() >= Room.MAXIMUM_BOTS && !habbo.hasPermission(Permission.ACC_UNLIMITED_BOTS)) { + habbo.getClient().sendResponse(new BotErrorComposer(BotErrorComposer.ROOM_ERROR_MAX_BOTS)); + return; + } + + if (room.hasHabbosAt(location.x, location.y) || (!location.isWalkable() && location.state != RoomTileState.SIT && location.state != RoomTileState.LAY)) + return; + + if (room.hasBotsAt(location.x, location.y)) { + habbo.getClient().sendResponse(new BotErrorComposer(BotErrorComposer.ROOM_ERROR_BOTS_SELECTED_TILE_NOT_FREE)); + return; + } + + RoomUnit roomUnit = new RoomUnit(); + roomUnit.setRotation(RoomUserRotation.SOUTH); + roomUnit.setLocation(location); + + double stackHeight = location.getStackHeight(); + roomUnit.setPreviousLocationZ(stackHeight); + roomUnit.setZ(stackHeight); + + roomUnit.setPathFinderRoom(room); + roomUnit.setRoomUnitType(RoomUnitType.BOT); + roomUnit.setCanWalk(room.isAllowBotsWalk()); + bot.setRoomUnit(roomUnit); + bot.setRoom(room); + bot.needsUpdate(true); + room.addBot(bot); + Emulator.getThreading().run(bot); + room.sendComposer(new RoomUsersComposer(bot).compose()); + room.sendComposer(new RoomUserStatusComposer(bot.getRoomUnit()).compose()); + habbo.getInventory().getBotsComponent().removeBot(bot); + habbo.getClient().sendResponse(new RemoveBotComposer(bot)); + bot.onPlace(habbo, room); + + HabboItem topItem = room.getTopItemAt(location.x, location.y); + + if (topItem != null) { + try { + topItem.onWalkOn(bot.getRoomUnit(), room, null); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + bot.cycle(false); + } else { + habbo.getClient().sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, FurnitureMovementError.NO_RIGHTS.errorCode)); + } + } + } + + public void pickUpBot(int botId, Habbo habbo) { + if (habbo.getHabboInfo().getCurrentRoom() != null) { + this.pickUpBot(habbo.getHabboInfo().getCurrentRoom().getBot(Math.abs(botId)), habbo); + } + } + + public void pickUpBot(Bot bot, Habbo habbo) { + HabboInfo receiverInfo = habbo == null ? Emulator.getGameEnvironment().getHabboManager().getHabboInfo(bot.getOwnerId()) : habbo.getHabboInfo(); + + if (bot != null) { + BotPickUpEvent pickedUpEvent = new BotPickUpEvent(bot, habbo); + Emulator.getPluginManager().fireEvent(pickedUpEvent); + + if (pickedUpEvent.isCancelled()) + return; + + if (habbo == null || (bot.getOwnerId() == habbo.getHabboInfo().getId() || habbo.hasPermission(Permission.ACC_ANYROOMOWNER))) { + if (habbo != null && !habbo.hasPermission(Permission.ACC_UNLIMITED_BOTS) && habbo.getInventory().getBotsComponent().getBots().size() >= BotManager.MAXIMUM_BOT_INVENTORY_SIZE) { + habbo.alert(Emulator.getTexts().getValue("error.bots.max.inventory").replace("%amount%", BotManager.MAXIMUM_BOT_INVENTORY_SIZE + "")); + return; + } + + bot.onPickUp(habbo, receiverInfo.getCurrentRoom()); + receiverInfo.getCurrentRoom().removeBot(bot); + bot.stopFollowingHabbo(); + bot.setOwnerId(receiverInfo.getId()); + bot.setOwnerName(receiverInfo.getUsername()); + bot.needsUpdate(true); + Emulator.getThreading().run(bot); + + Habbo receiver = habbo == null ? Emulator.getGameEnvironment().getHabboManager().getHabbo(receiverInfo.getId()) : habbo; + if (receiver != null) { + receiver.getInventory().getBotsComponent().addBot(bot); + receiver.getClient().sendResponse(new AddBotComposer(bot)); + } + } + } + } + + public Bot loadBot(ResultSet set) { + try { + String type = set.getString("type"); + Class botClazz = botDefenitions.get(type); + + if (botClazz != null) + return botClazz.getDeclaredConstructor(ResultSet.class).newInstance(set); + else + log.error("Unknown Bot Type: " + type); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } catch (Exception e) { + log.error("Caught exception", e); + } + + return null; + } + + public boolean deleteBot(Bot bot) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM bots WHERE id = ? LIMIT 1")) { + statement.setInt(1, bot.getId()); + return statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return false; + } + + public void dispose() { + for (Map.Entry> set : botDefenitions.entrySet()) { + try { + Method m = set.getValue().getMethod("dispose"); + m.setAccessible(true); + m.invoke(null); + } catch (NoSuchMethodException e) { + log.info("Bot Manager -> Failed to execute dispose method upon bot type '" + set.getKey() + "'. No Such Method!"); + } catch (Exception e) { + log.info("Bot Manager -> Failed to execute dispose method upon bot type '" + set.getKey() + "'. Error: " + e.getMessage()); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/bots/ButlerBot.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/bots/ButlerBot.java new file mode 100644 index 0000000..99ad733 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/bots/ButlerBot.java @@ -0,0 +1,142 @@ +package com.eu.habbo.habbohotel.bots; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.plugin.events.bots.BotServerItemEvent; +import com.eu.habbo.threading.runnables.RoomUnitGiveHanditem; +import com.eu.habbo.threading.runnables.RoomUnitWalkToRoomUnit; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +@Slf4j +public class ButlerBot extends Bot { + public static THashMap, Integer> serveItems = new THashMap<>(); + + public ButlerBot(ResultSet set) throws SQLException { + super(set); + } + + public ButlerBot(Bot bot) { + super(bot); + } + + public static void initialise() { + if (serveItems == null) + serveItems = new THashMap<>(); + + serveItems.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM bot_serves")) { + while (set.next()) { + String[] keys = set.getString("keys").split(";"); + THashSet ks = new THashSet<>(); + Collections.addAll(ks, keys); + serveItems.put(ks, set.getInt("item")); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public static void dispose() { + serveItems.clear(); + } + + @Override + public void onUserSay(final RoomChatMessage message) { + if (this.getRoomUnit().hasStatus(RoomUnitStatus.MOVE) || this.getRoom() == null) { + return; + } + + double distanceBetweenBotAndHabbo = this.getRoomUnit().getCurrentLocation().distance(message.getHabbo().getRoomUnit().getCurrentLocation()); + + if (distanceBetweenBotAndHabbo <= Emulator.getConfig().getInt("hotel.bot.butler.commanddistance")) { + + if (message.getUnfilteredMessage() != null) { + for (Map.Entry, Integer> set : serveItems.entrySet()) { + for (String keyword : set.getKey()) { + + // Check if the string contains a certain keyword using a regex. + // If keyword = tea, teapot wouldn't trigger it. + if (message.getUnfilteredMessage().toLowerCase().matches("\\b" + keyword + "\\b")) { + + // Enable plugins to cancel this event + BotServerItemEvent serveEvent = new BotServerItemEvent(this, message.getHabbo(), set.getValue()); + if (Emulator.getPluginManager().fireEvent(serveEvent).isCancelled()) { + return; + } + + // Start give handitem process + if (this.getRoomUnit().canWalk()) { + final String key = keyword; + final Bot bot = this; + + // Step 1: Look at Habbo + bot.lookAt(serveEvent.habbo); + + // Step 2: Prepare tasks for when the Bot (carrying the handitem) reaches the Habbo + final List tasks = new ArrayList<>(); + tasks.add(new RoomUnitGiveHanditem(serveEvent.habbo.getRoomUnit(), serveEvent.habbo.getHabboInfo().getCurrentRoom(), serveEvent.itemId)); + tasks.add(new RoomUnitGiveHanditem(this.getRoomUnit(), serveEvent.habbo.getHabboInfo().getCurrentRoom(), 0)); + + tasks.add(() -> { + if(this.getRoom() != null) { + String botMessage = Emulator.getTexts() + .getValue("bots.butler.given") + .replace("%key%", key) + .replace("%username%", serveEvent.habbo.getHabboInfo().getUsername()); + + if (!WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, this.getRoomUnit(), this.getRoom(), new Object[]{ botMessage })) { + bot.talk(botMessage); + } + } + }); + + List failedReached = new ArrayList<>(); + failedReached.add(() -> { + if (distanceBetweenBotAndHabbo <= Emulator.getConfig().getInt("hotel.bot.butler.servedistance", 8)) { + for (Runnable task : tasks) { + task.run(); + } + } + }); + + // Give bot the handitem that it's going to give the Habbo + Emulator.getThreading().run(new RoomUnitGiveHanditem(this.getRoomUnit(), serveEvent.habbo.getHabboInfo().getCurrentRoom(), serveEvent.itemId)); + + if (distanceBetweenBotAndHabbo > Emulator.getConfig().getInt("hotel.bot.butler.reachdistance", 3)) { + Emulator.getThreading().run(new RoomUnitWalkToRoomUnit(this.getRoomUnit(), serveEvent.habbo.getRoomUnit(), serveEvent.habbo.getHabboInfo().getCurrentRoom(), tasks, failedReached, Emulator.getConfig().getInt("hotel.bot.butler.reachdistance", 3))); + } else { + Emulator.getThreading().run(failedReached.get(0), 1000); + } + } else { + if(this.getRoom() != null) { + this.getRoom().giveHandItem(serveEvent.habbo, serveEvent.itemId); + + String msg = Emulator.getTexts().getValue("bots.butler.given").replace("%key%", keyword).replace("%username%", serveEvent.habbo.getHabboInfo().getUsername()); + if (!WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, this.getRoomUnit(), this.getRoom(), new Object[]{msg})) { + this.talk(msg); + } + } + } + return; + } + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/bots/VisitorBot.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/bots/VisitorBot.java new file mode 100644 index 0000000..dd6f084 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/bots/VisitorBot.java @@ -0,0 +1,70 @@ +package com.eu.habbo.habbohotel.bots; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolRoomVisit; +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.habbohotel.users.Habbo; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class VisitorBot extends Bot { + private static SimpleDateFormat DATE_FORMAT; + private boolean showedLog = false; + private THashSet visits = new THashSet<>(3); + + public VisitorBot(ResultSet set) throws SQLException { + super(set); + } + + public VisitorBot(Bot bot) { + super(bot); + } + + public static void initialise() { + DATE_FORMAT = new SimpleDateFormat(Emulator.getConfig().getValue("bots.visitor.dateformat")); + } + + @Override + public void onUserSay(final RoomChatMessage message) { + if (!this.showedLog) { + if (message.getMessage().equalsIgnoreCase(Emulator.getTexts().getValue("generic.yes"))) { + this.showedLog = true; + + String visitMessage = Emulator.getTexts().getValue("bots.visitor.list").replace("%count%", this.visits.size() + ""); + + StringBuilder list = new StringBuilder(); + for (ModToolRoomVisit visit : this.visits) { + list.append("\r"); + list.append(visit.roomName).append(" "); + list.append(Emulator.getTexts().getValue("generic.time.at")).append(" "); + list.append(DATE_FORMAT.format(new Date((visit.timestamp * 1000L)))); + } + + visitMessage = visitMessage.replace("%list%", list.toString()); + + this.talk(visitMessage); + + this.visits.clear(); + } + } + } + + public void onUserEnter(Habbo habbo) { + if (!this.showedLog) { + if (habbo.getHabboInfo().getCurrentRoom() != null) { + this.visits = Emulator.getGameEnvironment().getModToolManager().getVisitsForRoom(habbo.getHabboInfo().getCurrentRoom(), 10, true, habbo.getHabboInfo().getLastOnline(), Emulator.getIntUnixTimestamp(), habbo.getHabboInfo().getCurrentRoom().getOwnerName()); + + if (this.visits.isEmpty()) { + this.talk(Emulator.getTexts().getValue("bots.visitor.no_visits")); + } else { + this.talk(Emulator.getTexts().getValue("bots.visitor.visits").replace("%count%", this.visits.size() + "").replace("%positive%", Emulator.getTexts().getValue("generic.yes"))); + } + } + } + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarCampaign.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarCampaign.java new file mode 100644 index 0000000..29733dd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarCampaign.java @@ -0,0 +1,64 @@ +package com.eu.habbo.habbohotel.campaign.calendar; + +import gnu.trove.map.hash.THashMap; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.Map; + +public class CalendarCampaign { + private int id; + private final String name; + private final String image; + private Map rewards = new THashMap<>(); + private final Integer start_timestamp; + private final int total_days; + private final boolean lock_expired; + + public CalendarCampaign(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.name = set.getString("name"); + this.image = set.getString("image"); + this.start_timestamp = set.getInt("start_timestamp"); + this.total_days = set.getInt("total_days"); + this.lock_expired = set.getInt("lock_expired") == 1; + } + + public CalendarCampaign(int id, String name, String image, Integer start_timestamp, int total_days, boolean lock_expired) { + this.id = id; + this.name = name; + this.image = image; + this.start_timestamp = start_timestamp; + this.total_days = total_days; + this.lock_expired = lock_expired; + } + + public int getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public String getImage() { + return this.image; + } + + public Integer getStartTimestamp() { + return this.start_timestamp; + } + + public int getTotalDays() { return this.total_days; } + + public boolean getLockExpired() { return this.lock_expired; } + + public Map getRewards() { return rewards; } + + public void setId(int id) { this.id = id; } + + public void setRewards(Map rewards) { this.rewards = rewards; } + + public void addReward(CalendarRewardObject reward) { this.rewards.put(reward.getId(), reward); } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarManager.java new file mode 100644 index 0000000..e384ace --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarManager.java @@ -0,0 +1,151 @@ +package com.eu.habbo.habbohotel.campaign.calendar; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.events.calendar.AdventCalendarProductComposer; +import com.eu.habbo.plugin.events.users.calendar.UserClaimRewardEvent; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; + +import java.sql.*; +import java.util.*; +import java.util.Date; + +import static java.time.temporal.ChronoUnit.DAYS; + +@Slf4j +public class CalendarManager { + final private static Map calendarCampaigns = new THashMap<>(); + public static double HC_MODIFIER; + + public CalendarManager() { + long millis = System.currentTimeMillis(); + this.reload(); + log.info("Calendar Manager -> Loaded! ({} MS)", (System.currentTimeMillis() - millis)); + } + + public void dispose(){ + calendarCampaigns.clear(); + } + + public boolean reload() { + this.dispose(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM calendar_campaigns WHERE enabled = 1")) { + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + calendarCampaigns.put(set.getInt("id"), new CalendarCampaign(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + return false; + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM calendar_rewards")) { + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + CalendarCampaign campaign = calendarCampaigns.get(set.getInt("campaign_id")); + if(campaign != null){ + campaign.addReward(new CalendarRewardObject(set)); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + return false; + } + + HC_MODIFIER = Emulator.getConfig().getDouble("hotel.calendar.pixels.hc_modifier", 2.0); + + return true; + } + + public void addCampaign(CalendarCampaign campaign) { + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO calendar_campaigns ( name, image, start_timestamp, total_days, lock_expired) VALUES (?, ?, ?, ? , ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setString(1, campaign.getName()); + statement.setString(2, campaign.getImage()); + statement.setInt(3, campaign.getStartTimestamp()); + statement.setInt(4, campaign.getTotalDays()); + statement.setBoolean(5, campaign.getLockExpired()); + int affectedRows = statement.executeUpdate(); + + if (affectedRows == 0) { + throw new SQLException("Creating calendar campaign failed, no rows affected."); + } + + try (ResultSet generatedKeys = statement.getGeneratedKeys()) { + if (generatedKeys.next()) { + campaign.setId(generatedKeys.getInt(1)); + } else { + throw new SQLException("Creating calendar campaign failed, no ID found."); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + calendarCampaigns.put(campaign.getId(), campaign); + } + + public boolean deleteCampaign(CalendarCampaign campaign) { + calendarCampaigns.remove(campaign.getId()); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM calendar_campaigns WHERE id = ? LIMIT 1")) { + statement.setInt(1, campaign.getId()); + return statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return false; + } + + public CalendarCampaign getCalendarCampaign(String campaignName) { + return calendarCampaigns.values().stream().filter(cc -> Objects.equals(cc.getName(), campaignName)).findFirst().orElse(null); + } + public Map getCalendarCampaigns() { + return calendarCampaigns; + } + + public void claimCalendarReward(Habbo habbo, String campaignName, int day, boolean force) { + CalendarCampaign campaign = calendarCampaigns.values().stream().filter(cc -> Objects.equals(cc.getName(), campaignName)).findFirst().orElse(null); + if(campaign == null) return; + if (habbo.getHabboStats().calendarRewardsClaimed.stream().noneMatch(claimed -> claimed.getCampaignId() == campaign.getId() && claimed.getDay() == day)) { + + Set keys = campaign.getRewards().keySet(); + Map rewards = new THashMap<>(); + if(keys.isEmpty()) return; + keys.forEach(key -> rewards.put(rewards.size() + 1, key)); + int rand = Emulator.getRandom().nextInt(rewards.size() - 1 + 1) + 1; + int random = rewards.get(rand); + CalendarRewardObject object = campaign.getRewards().get(random); + if (object == null) return; + int daysBetween = (int) DAYS.between(new Timestamp(campaign.getStartTimestamp() * 1000L).toInstant(), new Date().toInstant()); + if(daysBetween >= 0 && daysBetween <= campaign.getTotalDays()) { + int diff = (daysBetween - day); + if ((((diff <= 2 || !campaign.getLockExpired()) && diff >= 0) || (force && habbo.hasPermission("acc_calendar_force")))) { + + if (Emulator.getPluginManager().fireEvent(new UserClaimRewardEvent(habbo, campaign, day, object, force)).isCancelled()) { + return; + } + + habbo.getHabboStats().calendarRewardsClaimed.add(new CalendarRewardClaimed(habbo.getHabboInfo().getId(), campaign.getId(), day, object.getId(), new Timestamp(System.currentTimeMillis()))); + habbo.getClient().sendResponse(new AdventCalendarProductComposer(true, object, habbo)); + object.give(habbo); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO calendar_rewards_claimed (user_id, campaign_id, day, reward_id, timestamp) VALUES (?, ?, ?, ?, ?)")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + statement.setInt(2, campaign.getId()); + statement.setInt(3, day); + statement.setInt(4, object.getId()); + statement.setInt(5, Emulator.getIntUnixTimestamp()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + } + } +} + diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardClaimed.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardClaimed.java new file mode 100644 index 0000000..7b6a183 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardClaimed.java @@ -0,0 +1,50 @@ +package com.eu.habbo.habbohotel.campaign.calendar; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; + +public class CalendarRewardClaimed { + private final int user_id; + private final int campaign; + private final int day; + private final int reward_id; + private final Timestamp timestamp; + + public CalendarRewardClaimed(ResultSet set) throws SQLException { + this.user_id = set.getInt("user_id"); + this.campaign = set.getInt("campaign_id"); + this.day = set.getInt("day"); + this.reward_id = set.getInt("reward_id"); + this.timestamp = new Timestamp(set.getInt("timestamp") * 1000L); + } + + public CalendarRewardClaimed(int user_id, int campaign, int day, int reward_id, Timestamp timestamp) { + this.user_id = user_id; + this.campaign = campaign; + this.day = day; + this.reward_id = reward_id; + this.timestamp = timestamp; + } + + public int getUserId() { + return this.user_id; + } + + public int getCampaignId() { + return this.campaign; + } + + public int getDay() { + return this.day; + } + + public int getRewardId() { + return this.reward_id; + } + + public Timestamp getTimestamp() { + return this.timestamp; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardObject.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardObject.java new file mode 100644 index 0000000..efe8f91 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardObject.java @@ -0,0 +1,132 @@ +package com.eu.habbo.habbohotel.campaign.calendar; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.users.subscriptions.Subscription; +import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionHabboClub; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class CalendarRewardObject { + private static final Logger LOGGER = LoggerFactory.getLogger(CalendarRewardObject.class); + + private final int id; + private final String productName; + private final String customImage; + private final int credits; + private final int pixels; + private final int points; + private final int pointsType; + private final String badge; + private final int itemId; + private final String subscription_type; + private final int subscription_days; + + public CalendarRewardObject(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.productName = set.getString("product_name"); + this.customImage = set.getString("custom_image"); + this.credits = set.getInt("credits"); + this.pixels = set.getInt("pixels"); + this.points = set.getInt("points"); + this.pointsType = set.getInt("points_type"); + this.badge = set.getString("badge"); + this.itemId = set.getInt("item_id"); + this.subscription_type = set.getString("subscription_type"); + this.subscription_days = set.getInt("subscription_days"); + } + + public void give(Habbo habbo) { + if (this.credits > 0) { + habbo.giveCredits(this.credits); + } + + if (this.pixels > 0) { + habbo.givePixels((int)(this.pixels * (habbo.getHabboStats().hasActiveClub() ? CalendarManager.HC_MODIFIER : 1.0))); + } + + if (this.points > 0) { + habbo.givePoints(this.pointsType, this.points); + } + + if (!this.badge.isEmpty()) { + habbo.addBadge(this.badge); + } + + if(this.subscription_type != null && !this.subscription_type.isEmpty()) { + if ("HABBO_CLUB".equals(this.subscription_type)) { + habbo.getHabboStats().createSubscription(SubscriptionHabboClub.HABBO_CLUB, this.subscription_days * 86400); + } else { + habbo.getHabboStats().createSubscription(this.subscription_type, this.subscription_days * 86400); + } + } + + if (this.itemId > 0) { + Item item = getItem(); + + if (item != null) { + HabboItem habboItem = Emulator.getGameEnvironment().getItemManager().createItem( + habbo.getHabboInfo().getId(), + item, + 0, + 0, + ""); + habbo.getInventory().getItemsComponent().addItem(habboItem); + habbo.getClient().sendResponse(new AddHabboItemComposer(habboItem)); + habbo.getClient().sendResponse(new InventoryRefreshComposer()); + } + } + } + + public int getId() { + return this.id; + } + + public String getCustomImage() { + return this.customImage; + } + + public int getCredits() { + return this.credits; + } + + public int getPixels() { + return this.pixels; + } + public int getPoints() { + return this.points; + } + + public int getPointsType() { + return this.pointsType; + } + + public String getProductName() { + return productName; + } + + public String getSubscriptionType() { + return subscription_type; + } + + public int getSubscriptionDays() { + return subscription_days; + } + + public String getBadge() { + return this.badge; + } + + public Item getItem() { + return Emulator.getGameEnvironment().getItemManager().getItem(this.itemId); + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogFeaturedPage.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogFeaturedPage.java new file mode 100644 index 0000000..30da0eb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogFeaturedPage.java @@ -0,0 +1,58 @@ +package com.eu.habbo.habbohotel.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; + +public class CatalogFeaturedPage implements ISerialize { + private final int slotId; + private final String caption; + private final String image; + private final Type type; + private final int expireTimestamp; + private final String pageName; + private final int pageId; + private final String productName; + public CatalogFeaturedPage(int slotId, String caption, String image, Type type, int expireTimestamp, String pageName, int pageId, String productName) { + this.slotId = slotId; + this.caption = caption; + this.image = image; + this.type = type; + this.expireTimestamp = expireTimestamp; + this.pageName = pageName; + this.pageId = pageId; + this.productName = productName; + } + + @Override + public void serialize(ServerMessage message) { + message.appendInt(this.slotId); + message.appendString(this.caption); + message.appendString(this.image); + message.appendInt(this.type.type); + switch (this.type) { + case PAGE_NAME: + message.appendString(this.pageName); + break; + case PAGE_ID: + message.appendInt(this.pageId); + break; + case PRODUCT_NAME: + message.appendString(this.productName); + break; + } + message.appendInt(Emulator.getIntUnixTimestamp() - this.expireTimestamp); + } + + public enum Type { + PAGE_NAME(0), + PAGE_ID(1), + PRODUCT_NAME(2); + + public final int type; + + Type(int type) { + this.type = type; + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogItem.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogItem.java new file mode 100644 index 0000000..6cb29e7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogItem.java @@ -0,0 +1,354 @@ +package com.eu.habbo.habbohotel.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.FurnitureType; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; + +@Slf4j +public class CatalogItem implements ISerialize, Runnable, Comparable { + int id; + int limitedStack; + private int pageId; + private String itemId; + private String name; + private int credits; + private int points; + private short pointsType; + private int amount; + private boolean allowGift = false; + private int limitedSells; + private String extradata; + private boolean clubOnly; + private boolean haveOffer; + private int offerId; + private boolean needsUpdate; + private int orderNumber; + private HashMap bundle; + + public CatalogItem(ResultSet set) throws SQLException { + this.load(set); + this.needsUpdate = false; + } + + public static boolean haveOffer(CatalogItem item) { + if (!item.haveOffer) + return false; + + if (item.getAmount() != 1) + return false; + + if (item.isLimited()) + return false; + + if (item.bundle.size() > 1) + return false; + + if (item.getName().toLowerCase().startsWith("cf_") || item.getName().toLowerCase().startsWith("cfc_")) + return false; + + for (Item i : item.getBaseItems()) { + if (i.getName().toLowerCase().startsWith("cf_") || i.getName().toLowerCase().startsWith("cfc_") || i.getName().toLowerCase().startsWith("rentable_bot")) + return false; + } + + return !item.getName().toLowerCase().startsWith("rentable_bot_"); + } + + public void update(ResultSet set) throws SQLException { + this.load(set); + } + + private void load(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.pageId = set.getInt("page_id"); + this.itemId = set.getString("item_Ids"); + this.name = set.getString("catalog_name"); + this.credits = set.getInt("cost_credits"); + this.points = set.getInt("cost_points"); + this.pointsType = set.getShort("points_type"); + this.amount = set.getInt("amount"); + this.limitedStack = set.getInt("limited_stack"); + this.limitedSells = set.getInt("limited_sells"); + this.extradata = set.getString("extradata"); + this.clubOnly = set.getBoolean("club_only"); + this.haveOffer = set.getBoolean("have_offer"); + this.offerId = set.getInt("offer_id"); + this.orderNumber = set.getInt("order_number"); + + this.bundle = new HashMap<>(); + this.loadBundle(); + } + + public int getId() { + return this.id; + } + + public int getPageId() { + return this.pageId; + } + + public void setPageId(int pageId) { + this.pageId = pageId; + } + + public String getItemId() { + return this.itemId; + } + + public void setItemId(String itemId) { + this.itemId = itemId; + } + + public String getName() { + return this.name; + } + + public int getCredits() { + return this.credits; + } + + public int getPoints() { + return this.points; + } + + public int getPointsType() { + return this.pointsType; + } + + public int getAmount() { + return this.amount; + } + + public int getLimitedStack() { + return this.limitedStack; + } + + public int getLimitedSells() { + CatalogLimitedConfiguration ltdConfig = Emulator.getGameEnvironment().getCatalogManager().getLimitedConfig(this); + + if (ltdConfig != null) { + return this.limitedStack - ltdConfig.available(); + } + + return this.limitedStack; + } + + public String getExtradata() { + return this.extradata; + } + + public boolean isClubOnly() { + return this.clubOnly; + } + + public boolean isHaveOffer() { + return this.haveOffer; + } + + public int getOfferId() { + return this.offerId; + } + + public boolean isLimited() { + return this.limitedStack > 0; + } + + private int getOrderNumber() { + return this.orderNumber; + } + + public void setNeedsUpdate(boolean needsUpdate) { + this.needsUpdate = needsUpdate; + } + + public synchronized void sellRare() { + this.limitedSells++; + + this.needsUpdate = true; + + if (this.limitedSells == this.limitedStack) { + Emulator.getGameEnvironment().getCatalogManager().moveCatalogItem(this, Emulator.getConfig().getInt("catalog.ltd.page.soldout")); + } + + Emulator.getThreading().run(this); + } + + public THashSet getBaseItems() { + THashSet items = new THashSet<>(); + + if (!this.itemId.isEmpty()) { + String[] itemIds = this.itemId.split(";"); + + for (String itemId : itemIds) { + if (itemId.isEmpty()) + continue; + + if (itemId.contains(":")) { + itemId = itemId.split(":")[0]; + } + + int identifier; + try { + + identifier = Integer.parseInt(itemId); + } catch (Exception e) { + log.info("Invalid value (" + itemId + ") for items_base column for catalog_item id (" + this.id + "). Value must be integer or of the format of integer:amount;integer:amount"); + continue; + } + if (identifier > 0) { + Item item = Emulator.getGameEnvironment().getItemManager().getItem(identifier); + + if (item != null) + items.add(item); + } + } + } + + return items; + } + + public int getItemAmount(int id) { + if (this.bundle.containsKey(id)) + return this.bundle.get(id); + else + return this.amount; + } + + public HashMap getBundle() { + return this.bundle; + } + + public void loadBundle() { + int intItemId; + + if (this.itemId.contains(";")) { + try { + String[] itemIds = this.itemId.split(";"); + + for (String itemId : itemIds) { + if (itemId.contains(":")) { + String[] data = itemId.split(":"); + if (data.length > 1 && Integer.parseInt(data[0]) > 0 && Integer.parseInt(data[1]) > 0) { + this.bundle.put(Integer.parseInt(data[0]), Integer.parseInt(data[1])); + } + } else { + if (!itemId.isEmpty()) { + intItemId = (Integer.parseInt(itemId)); + this.bundle.put(intItemId, 1); + } + } + } + } catch (Exception e) { + log.debug("Failed to load " + this.itemId); + log.error("Caught exception", e); + } + } else { + try { + Item item = Emulator.getGameEnvironment().getItemManager().getItem(Integer.valueOf(this.itemId)); + + if (item != null) { + this.allowGift = item.allowGift(); + } + } catch (Exception e) { + } + } + } + + @Override + public void serialize(ServerMessage message) { + message.appendInt(this.getId()); + message.appendString(this.getName()); + message.appendBoolean(false); + message.appendInt(this.getCredits()); + message.appendInt(this.getPoints()); + message.appendInt(this.getPointsType()); + message.appendBoolean(this.allowGift); //Can gift + + THashSet items = this.getBaseItems(); + + message.appendInt(items.size()); + + for (Item item : items) { + message.appendString(item.getType().code.toLowerCase()); + + if (item.getType() == FurnitureType.BADGE) { + message.appendString(item.getName()); + } else { + message.appendInt(item.getSpriteId()); + + if (this.getName().contains("wallpaper_single") || this.getName().contains("floor_single") || this.getName().contains("landscape_single")) { + message.appendString(this.getName().split("_")[2]); + } else if (item.getName().contains("bot") && item.getType() == FurnitureType.ROBOT) { + boolean lookFound = false; + for (String s : this.getExtradata().split(";")) { + if (s.startsWith("figure:")) { + lookFound = true; + message.appendString(s.replace("figure:", "")); + break; + } + } + + if (!lookFound) { + message.appendString(this.getExtradata()); + } + } else if (item.getType() == FurnitureType.ROBOT) { + message.appendString(this.getExtradata()); + } else if (item.getName().equalsIgnoreCase("poster")) { + message.appendString(this.getExtradata()); + } else if (this.getName().startsWith("SONG ")) { + message.appendString(this.getExtradata()); + } else { + message.appendString(""); + } + message.appendInt(this.getItemAmount(item.getId())); + message.appendBoolean(this.isLimited()); + if (this.isLimited()) { + message.appendInt(this.getLimitedStack()); + message.appendInt(this.getLimitedStack() - this.getLimitedSells()); + } + } + } + + message.appendInt(this.clubOnly); + message.appendBoolean(haveOffer(this)); + message.appendBoolean(false); //unknown + message.appendString(this.name + ".png"); + } + + @Override + public void run() { + if (this.needsUpdate) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE catalog_items SET limited_sells = ?, page_id = ? WHERE id = ?")) { + statement.setInt(1, this.getLimitedSells()); + statement.setInt(2, this.pageId); + statement.setInt(3, this.getId()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.needsUpdate = false; + } + } + + @SuppressWarnings("NullableProblems") + @Override + public int compareTo(CatalogItem catalogItem) { + if (CatalogManager.SORT_USING_ORDERNUM) { + return this.getOrderNumber() - catalogItem.getOrderNumber(); + } else { + return this.getId() - catalogItem.getId(); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogLimitedConfiguration.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogLimitedConfiguration.java new file mode 100644 index 0000000..c87cb33 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogLimitedConfiguration.java @@ -0,0 +1,106 @@ +package com.eu.habbo.habbohotel.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Collections; +import java.util.LinkedList; + +@Slf4j +public class CatalogLimitedConfiguration implements Runnable { + private final int itemId; + private final LinkedList limitedNumbers; + private int totalSet; + + public CatalogLimitedConfiguration(int itemId, LinkedList availableNumbers, int totalSet) { + this.itemId = itemId; + this.totalSet = totalSet; + this.limitedNumbers = availableNumbers; + + if (Emulator.getConfig().getBoolean("catalog.ltd.random", true)) { + Collections.shuffle(this.limitedNumbers); + } else { + Collections.reverse(this.limitedNumbers); + } + } + + public int getNumber() { + synchronized (this.limitedNumbers) { + int num = this.limitedNumbers.pop(); + if (this.limitedNumbers.isEmpty()) { + Emulator.getGameEnvironment().getCatalogManager().moveCatalogItem(Emulator.getGameEnvironment().getCatalogManager().getCatalogItem(this.itemId), Emulator.getConfig().getInt("catalog.ltd.page.soldout")); + } + return num; + } + } + + public void limitedSold(int catalogItemId, Habbo habbo, HabboItem item) { + synchronized (this.limitedNumbers) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE catalog_items_limited SET user_id = ?, timestamp = ?, item_id = ? WHERE catalog_item_id = ? AND number = ? AND user_id = 0 LIMIT 1")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + statement.setInt(2, Emulator.getIntUnixTimestamp()); + statement.setInt(3, item.getId()); + statement.setInt(4, catalogItemId); + statement.setInt(5, item.getLimitedSells()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public void generateNumbers(int starting, int amount) { + synchronized (this.limitedNumbers) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO catalog_items_limited (catalog_item_id, number) VALUES (?, ?)")) { + statement.setInt(1, this.itemId); + + for (int i = starting; i <= amount; i++) { + statement.setInt(2, i); + statement.addBatch(); + this.limitedNumbers.push(i); + } + + statement.executeBatch(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.totalSet += amount; + + if (Emulator.getConfig().getBoolean("catalog.ltd.random", true)) { + Collections.shuffle(this.limitedNumbers); + } else { + Collections.reverse(this.limitedNumbers); + } + } + } + + public int available() { + return this.limitedNumbers.size(); + } + + public int getTotalSet() { + return this.totalSet; + } + + public void setTotalSet(int totalSet) { + this.totalSet = totalSet; + } + + @Override + public void run() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE catalog_items SET limited_stack = ?, limited_sells = ? WHERE id = ?")) { + statement.setInt(1, this.totalSet); + statement.setInt(2, this.totalSet - this.available()); + statement.setInt(3, this.itemId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java new file mode 100644 index 0000000..abe0f5e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java @@ -0,0 +1,1191 @@ +package com.eu.habbo.habbohotel.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarRewardObject; +import com.eu.habbo.habbohotel.catalog.layouts.*; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.items.FurnitureType; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.SoundTrack; +import com.eu.habbo.habbohotel.items.interactions.*; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.catalog.*; +import com.eu.habbo.messages.outgoing.events.calendar.AdventCalendarProductComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.inventory.AddBotComposer; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.AddPetComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.modtool.ModToolIssueHandledComposer; +import com.eu.habbo.messages.outgoing.users.AddUserBadgeComposer; +import com.eu.habbo.messages.outgoing.users.UserCreditsComposer; +import com.eu.habbo.messages.outgoing.users.UserPointsComposer; +import com.eu.habbo.plugin.events.emulator.EmulatorLoadCatalogManagerEvent; +import com.eu.habbo.plugin.events.users.catalog.UserCatalogFurnitureBoughtEvent; +import com.eu.habbo.plugin.events.users.catalog.UserCatalogItemPurchasedEvent; +import gnu.trove.TCollections; +import gnu.trove.iterator.TIntObjectIterator; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntIntHashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; + +import java.sql.*; +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +public class CatalogManager { + + public static final THashMap> pageDefinitions = new THashMap>(CatalogPageLayouts.values().length) { + { + for (CatalogPageLayouts layout : CatalogPageLayouts.values()) { + switch (layout) { + case frontpage: + this.put(layout.name().toLowerCase(), FrontpageLayout.class); + break; + case badge_display: + this.put(layout.name().toLowerCase(), BadgeDisplayLayout.class); + break; + case spaces_new: + this.put(layout.name().toLowerCase(), SpacesLayout.class); + break; + case trophies: + this.put(layout.name().toLowerCase(), TrophiesLayout.class); + break; + case bots: + this.put(layout.name().toLowerCase(), BotsLayout.class); + break; + case club_buy: + this.put(layout.name().toLowerCase(), ClubBuyLayout.class); + break; + case club_gift: + this.put(layout.name().toLowerCase(), ClubGiftsLayout.class); + break; + case sold_ltd_items: + this.put(layout.name().toLowerCase(), SoldLTDItemsLayout.class); + break; + case single_bundle: + this.put(layout.name().toLowerCase(), SingleBundle.class); + break; + case roomads: + this.put(layout.name().toLowerCase(), RoomAdsLayout.class); + break; + case recycler: + if (Emulator.getConfig().getBoolean("hotel.ecotron.enabled")) + this.put(layout.name().toLowerCase(), RecyclerLayout.class); + break; + case recycler_info: + if (Emulator.getConfig().getBoolean("hotel.ecotron.enabled")) + this.put(layout.name().toLowerCase(), RecyclerInfoLayout.class); + case recycler_prizes: + if (Emulator.getConfig().getBoolean("hotel.ecotron.enabled")) + this.put(layout.name().toLowerCase(), RecyclerPrizesLayout.class); + break; + case marketplace: + if (Emulator.getConfig().getBoolean("hotel.marketplace.enabled")) + this.put(layout.name().toLowerCase(), MarketplaceLayout.class); + break; + case marketplace_own_items: + if (Emulator.getConfig().getBoolean("hotel.marketplace.enabled")) + this.put(layout.name().toLowerCase(), MarketplaceOwnItems.class); + break; + case info_duckets: + this.put(layout.name().toLowerCase(), InfoDucketsLayout.class); + break; + case info_pets: + this.put(layout.name().toLowerCase(), InfoPetsLayout.class); + break; + case info_rentables: + this.put(layout.name().toLowerCase(), InfoRentablesLayout.class); + break; + case info_loyalty: + this.put(layout.name().toLowerCase(), InfoLoyaltyLayout.class); + break; + case loyalty_vip_buy: + this.put(layout.name().toLowerCase(), LoyaltyVipBuyLayout.class); + break; + case guilds: + this.put(layout.name().toLowerCase(), GuildFrontpageLayout.class); + break; + case guild_furni: + this.put(layout.name().toLowerCase(), GuildFurnitureLayout.class); + break; + case guild_forum: + this.put(layout.name().toLowerCase(), GuildForumLayout.class); + break; + case pets: + this.put(layout.name().toLowerCase(), PetsLayout.class); + break; + case pets2: + this.put(layout.name().toLowerCase(), Pets2Layout.class); + break; + case pets3: + this.put(layout.name().toLowerCase(), Pets3Layout.class); + break; + case soundmachine: + this.put(layout.name().toLowerCase(), TraxLayout.class); + break; + case default_3x3_color_grouping: + this.put(layout.name().toLowerCase(), ColorGroupingLayout.class); + break; + case recent_purchases: + this.put(layout.name().toLowerCase(), RecentPurchasesLayout.class); + break; + case room_bundle: + this.put(layout.name().toLowerCase(), RoomBundleLayout.class); + break; + case petcustomization: + this.put(layout.name().toLowerCase(), PetCustomizationLayout.class); + break; + case vip_buy: + this.put(layout.name().toLowerCase(), VipBuyLayout.class); + break; + case frontpage_featured: + this.put(layout.name().toLowerCase(), FrontPageFeaturedLayout.class); + break; + case builders_club_addons: + this.put(layout.name().toLowerCase(), BuildersClubAddonsLayout.class); + break; + case builders_club_frontpage: + this.put(layout.name().toLowerCase(), BuildersClubFrontPageLayout.class); + break; + case builders_club_loyalty: + this.put(layout.name().toLowerCase(), BuildersClubLoyaltyLayout.class); + break; + case monkey: + this.put(layout.name().toLowerCase(), InfoMonkeyLayout.class); + break; + case niko: + this.put(layout.name().toLowerCase(), InfoNikoLayout.class); + break; + case mad_money: + this.put(layout.name().toLowerCase(), MadMoneyLayout.class); + break; + case default_3x3: + default: + this.put("default_3x3", Default_3x3Layout.class); + break; + } + } + } + }; + public static int catalogItemAmount; + public static int PURCHASE_COOLDOWN = 1; + public static boolean SORT_USING_ORDERNUM = false; + public final TIntObjectMap catalogPages; + public final TIntObjectMap catalogFeaturedPages; + public final THashMap> prizes; + public final THashMap giftWrappers; + public final THashMap giftFurnis; + public final THashSet clubItems; + public final THashMap clubOffers; + public final THashMap targetOffers; + public final THashMap clothing; + public final TIntIntHashMap offerDefs; + public final Item ecotronItem; + public final THashMap limitedNumbers; + private final List vouchers; + + public CatalogManager() { + long millis = System.currentTimeMillis(); + this.catalogPages = TCollections.synchronizedMap(new TIntObjectHashMap<>()); + this.catalogFeaturedPages = new TIntObjectHashMap<>(); + this.prizes = new THashMap<>(); + this.giftWrappers = new THashMap<>(); + this.giftFurnis = new THashMap<>(); + this.clubItems = new THashSet<>(); + this.clubOffers = new THashMap<>(); + this.targetOffers = new THashMap<>(); + this.clothing = new THashMap<>(); + this.offerDefs = new TIntIntHashMap(); + this.vouchers = new ArrayList<>(); + this.limitedNumbers = new THashMap<>(); + + this.initialize(); + + this.ecotronItem = Emulator.getGameEnvironment().getItemManager().getItem("ecotron_box"); + + log.info("Catalog Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)"); + } + + + public synchronized void initialize() { + Emulator.getPluginManager().fireEvent(new EmulatorLoadCatalogManagerEvent()); + + this.loadLimitedNumbers(); + this.loadCatalogPages(); + this.loadCatalogFeaturedPages(); + this.loadCatalogItems(); + this.loadClubOffers(); + this.loadTargetOffers(); + this.loadVouchers(); + this.loadClothing(); + this.loadRecycler(); + this.loadGiftWrappers(); + } + + private synchronized void loadLimitedNumbers() { + this.limitedNumbers.clear(); + + THashMap> limiteds = new THashMap<>(); + TIntIntHashMap totals = new TIntIntHashMap(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM catalog_items_limited")) { + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + if (!limiteds.containsKey(set.getInt("catalog_item_id"))) { + limiteds.put(set.getInt("catalog_item_id"), new LinkedList<>()); + } + + totals.adjustOrPutValue(set.getInt("catalog_item_id"), 1, 1); + + if (set.getInt("user_id") == 0) { + limiteds.get(set.getInt("catalog_item_id")).push(set.getInt("number")); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + for (Map.Entry> set : limiteds.entrySet()) { + this.limitedNumbers.put(set.getKey(), new CatalogLimitedConfiguration(set.getKey(), set.getValue(), totals.get(set.getKey()))); + } + } + + + private synchronized void loadCatalogPages() { + this.catalogPages.clear(); + + final THashMap pages = new THashMap<>(); + pages.put(-1, new CatalogRootLayout()); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM catalog_pages ORDER BY parent_id, id")) { + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + Class pageClazz = pageDefinitions.get(set.getString("page_layout")); + + if (pageClazz == null) { + log.info("Unknown Page Layout: " + set.getString("page_layout")); + continue; + } + + try { + CatalogPage page = pageClazz.getConstructor(ResultSet.class).newInstance(set); + pages.put(page.getId(), page); + } catch (Exception e) { + log.error("Failed to load layout: {}", set.getString("page_layout")); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + pages.forEachValue((object) -> { + CatalogPage page = pages.get(object.parentId); + + if (page != null) { + if (page.id != object.id) { + page.addChildPage(object); + } + } else { + if (object.parentId != -2) { + log.info("Parent Page not found for " + object.getPageName() + " (ID: " + object.id + ", parent_id: " + object.parentId + ")"); + } + } + return true; + }); + + this.catalogPages.putAll(pages); + + log.info("Loaded " + this.catalogPages.size() + " Catalog Pages!"); + } + + + private synchronized void loadCatalogFeaturedPages() { + this.catalogFeaturedPages.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM catalog_featured_pages ORDER BY slot_id ASC")) { + while (set.next()) { + this.catalogFeaturedPages.put(set.getInt("slot_id"), new CatalogFeaturedPage( + set.getInt("slot_id"), + set.getString("caption"), + set.getString("image"), + CatalogFeaturedPage.Type.valueOf(set.getString("type").toUpperCase()), + set.getInt("expire_timestamp"), + set.getString("page_name"), + set.getInt("page_id"), + set.getString("product_name") + )); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + private synchronized void loadCatalogItems() { + this.clubItems.clear(); + catalogItemAmount = 0; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM catalog_items")) { + CatalogItem item; + while (set.next()) { + if (set.getString("item_ids").equals("0")) + continue; + + if (set.getString("catalog_name").contains("HABBO_CLUB_")) { + this.clubItems.add(new CatalogItem(set)); + continue; + } + + CatalogPage page = this.catalogPages.get(set.getInt("page_id")); + + if (page == null) + continue; + + item = page.getCatalogItem(set.getInt("id")); + + if (item == null) { + catalogItemAmount++; + item = new CatalogItem(set); + page.addItem(item); + + if (item.getOfferId() != -1) { + page.addOfferId(item.getOfferId()); + + this.offerDefs.put(item.getOfferId(), item.getId()); + } + } else + item.update(set); + + if (item.isLimited()) { + this.createOrUpdateLimitedConfig(item); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + for (CatalogPage page : this.catalogPages.valueCollection()) { + for (Integer id : page.getIncluded()) { + CatalogPage p = this.catalogPages.get(id); + + if (p != null) { + page.getCatalogItems().putAll(p.getCatalogItems()); + } + } + } + } + + private void loadClubOffers() { + this.clubOffers.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM catalog_club_offers WHERE enabled = ?")) { + statement.setString(1, "1"); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + this.clubOffers.put(set.getInt("id"), new ClubOffer(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + private void loadTargetOffers() { + synchronized (this.targetOffers) { + this.targetOffers.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM catalog_target_offers WHERE end_timestamp > ?")) { + statement.setInt(1, Emulator.getIntUnixTimestamp()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + this.targetOffers.put(set.getInt("id"), new TargetOffer(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + + private void loadVouchers() { + synchronized (this.vouchers) { + this.vouchers.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM vouchers")) { + while (set.next()) { + this.vouchers.add(new Voucher(set)); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + + public void loadRecycler() { + synchronized (this.prizes) { + this.prizes.clear(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM recycler_prizes")) { + while (set.next()) { + Item item = Emulator.getGameEnvironment().getItemManager().getItem(set.getInt("item_id")); + + if (item != null) { + if (this.prizes.get(set.getInt("rarity")) == null) { + this.prizes.put(set.getInt("rarity"), new THashSet<>()); + } + + this.prizes.get(set.getInt("rarity")).add(item); + } else { + log.error("Cannot load item with ID: {} as recycler reward!", set.getInt("item_id")); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + + public void loadGiftWrappers() { + synchronized (this.giftWrappers) { + synchronized (this.giftFurnis) { + this.giftWrappers.clear(); + this.giftFurnis.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM gift_wrappers ORDER BY sprite_id DESC")) { + while (set.next()) { + switch (set.getString("type")) { + case "wrapper": + this.giftWrappers.put(set.getInt("sprite_id"), set.getInt("item_id")); + break; + + case "gift": + this.giftFurnis.put(set.getInt("sprite_id"), set.getInt("item_id")); + break; + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + } + + private void loadClothing() { + synchronized (this.clothing) { + this.clothing.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM catalog_clothing")) { + while (set.next()) { + this.clothing.put(set.getInt("id"), new ClothItem(set)); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public ClothItem getClothing(String name) { + for (ClothItem item : this.clothing.values()) { + if (item.name.equalsIgnoreCase(name)) { + return item; + } + } + + return null; + } + + public Voucher getVoucher(String code) { + synchronized (this.vouchers) { + for (Voucher voucher : this.vouchers) { + if (voucher.code.equals(code)) { + return voucher; + } + } + } + return null; + } + + public void redeemVoucher(GameClient client, String voucherCode) { + Habbo habbo = client.getHabbo(); + if (habbo == null) + return; + + Voucher voucher = Emulator.getGameEnvironment().getCatalogManager().getVoucher(voucherCode); + if (voucher == null) { + client.sendResponse(new RedeemVoucherErrorComposer(RedeemVoucherErrorComposer.INVALID_CODE)); + return; + } + + if (voucher.isExhausted()) { + client.sendResponse(new RedeemVoucherErrorComposer(Emulator.getGameEnvironment().getCatalogManager().deleteVoucher(voucher) ? RedeemVoucherErrorComposer.INVALID_CODE : RedeemVoucherErrorComposer.TECHNICAL_ERROR)); + return; + } + + if (voucher.hasUserExhausted(habbo.getHabboInfo().getId())) { + client.sendResponse(new ModToolIssueHandledComposer("You have exceeded the limit for redeeming this voucher.")); + return; + } + + voucher.addHistoryEntry(habbo.getHabboInfo().getId()); + + if (voucher.points > 0) { + client.getHabbo().givePoints(voucher.pointsType, voucher.points); + } + + if (voucher.credits > 0) { + client.getHabbo().giveCredits(voucher.credits); + } + + if (voucher.catalogItemId > 0) { + CatalogItem item = this.getCatalogItem(voucher.catalogItemId); + if (item != null) { + this.purchaseItem(null, item, client.getHabbo(), 1, "", true); + } + } + + client.sendResponse(new RedeemVoucherOKComposer()); + } + + public boolean deleteVoucher(Voucher voucher) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM vouchers WHERE code = ?")) { + statement.setString(1, voucher.code); + + synchronized (this.vouchers) { + this.vouchers.remove(voucher); + } + + return statement.executeUpdate() >= 1; + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return false; + } + + + public CatalogPage getCatalogPage(int pageId) { + return this.catalogPages.get(pageId); + } + + public CatalogPage getCatalogPage(String captionSafe) { + return this.catalogPages.valueCollection().stream() + .filter(p -> p != null && p.getPageName() != null && p.getPageName().equalsIgnoreCase(captionSafe)) + .findAny().orElse(null); + } + + public CatalogPage getCatalogPageByLayout(String layoutName) { + return this.catalogPages.valueCollection().stream() + .filter(p -> p != null && + p.isVisible() && + p.isEnabled() && + p.getRank() < 2 && + p.getLayout() != null && p.getLayout().equalsIgnoreCase(layoutName) + ) + .findAny().orElse(null); + } + + public CatalogItem getCatalogItem(int id) { + final CatalogItem[] item = {null}; + synchronized (this.catalogPages) { + this.catalogPages.forEachValue(new TObjectProcedure() { + @Override + public boolean execute(CatalogPage object) { + item[0] = object.getCatalogItem(id); + + return item[0] == null; + } + }); + } + + return item[0]; + } + + + public List getCatalogPages(int parentId, final Habbo habbo) { + final List pages = new ArrayList<>(); + + this.catalogPages.get(parentId).childPages.forEachValue(new TObjectProcedure() { + @Override + public boolean execute(CatalogPage object) { + + boolean isVisiblePage = object.visible; + boolean hasRightRank = object.getRank() <= habbo.getHabboInfo().getRank().getId(); + + boolean clubRightsOkay = true; + + if(object.isClubOnly() && !habbo.getHabboInfo().getHabboStats().hasActiveClub()) { + clubRightsOkay = false; + } + + if (isVisiblePage && hasRightRank && clubRightsOkay) { + pages.add(object); + } + return true; + } + }); + Collections.sort(pages); + + return pages; + } + + public TIntObjectMap getCatalogFeaturedPages() { + return this.catalogFeaturedPages; + } + + + public CatalogItem getClubItem(int itemId) { + synchronized (this.clubItems) { + for (CatalogItem item : this.clubItems) { + if (item.getId() == itemId) + return item; + } + } + + return null; + } + + + public boolean moveCatalogItem(CatalogItem item, int pageId) { + CatalogPage page = this.getCatalogPage(item.getPageId()); + + if (page == null) + return false; + + page.getCatalogItems().remove(item.getId()); + + page = this.getCatalogPage(pageId); + + if (page == null) + return false; + + page.getCatalogItems().put(item.getId(), item); + + item.setPageId(pageId); + item.setNeedsUpdate(true); + + item.run(); + return true; + } + + + public Item getRandomRecyclerPrize() { + int level = 1; + + if (Emulator.getRandom().nextInt(Emulator.getConfig().getInt("hotel.ecotron.rarity.chance.5")) + 1 == Emulator.getConfig().getInt("hotel.ecotron.rarity.chance.5")) { + level = 5; + } else if (Emulator.getRandom().nextInt(Emulator.getConfig().getInt("hotel.ecotron.rarity.chance.4")) + 1 == Emulator.getConfig().getInt("hotel.ecotron.rarity.chance.4")) { + level = 4; + } else if (Emulator.getRandom().nextInt(Emulator.getConfig().getInt("hotel.ecotron.rarity.chance.3")) + 1 == Emulator.getConfig().getInt("hotel.ecotron.rarity.chance.3")) { + level = 3; + } else if (Emulator.getRandom().nextInt(Emulator.getConfig().getInt("hotel.ecotron.rarity.chance.2")) + 1 == Emulator.getConfig().getInt("hotel.ecotron.rarity.chance.2")) { + level = 2; + } + + if (this.prizes.containsKey(level) && !this.prizes.get(level).isEmpty()) { + return (Item) this.prizes.get(level).toArray()[Emulator.getRandom().nextInt(this.prizes.get(level).size())]; + } else { + log.error("No rewards specified for rarity level {}", level); + } + + return null; + } + + + public CatalogPage createCatalogPage(String caption, String captionSave, int roomId, int icon, CatalogPageLayouts layout, int minRank, int parentId) { + CatalogPage catalogPage = null; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO catalog_pages (parent_id, caption, caption_save, icon_image, visible, enabled, min_rank, page_layout, room_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, parentId); + statement.setString(2, caption); + statement.setString(3, captionSave); + statement.setInt(4, icon); + statement.setString(5, "1"); + statement.setString(6, "1"); + statement.setInt(7, minRank); + statement.setString(8, layout.name()); + statement.setInt(9, roomId); + statement.execute(); + try (ResultSet set = statement.getGeneratedKeys()) { + if (set.next()) { + try (PreparedStatement stmt = connection.prepareStatement("SELECT * FROM catalog_pages WHERE id = ?")) { + stmt.setInt(1, set.getInt(1)); + try (ResultSet page = stmt.executeQuery()) { + if (page.next()) { + Class pageClazz = pageDefinitions.get(page.getString("page_layout")); + + if (pageClazz != null) { + try { + catalogPage = pageClazz.getConstructor(ResultSet.class).newInstance(page); + } catch (Exception e) { + log.error("Caught exception", e); + } + } else { + log.error("Unknown page layout: {}", page.getString("page_layout")); + } + } + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + if (catalogPage != null) { + this.catalogPages.put(catalogPage.getId(), catalogPage); + } + + return catalogPage; + } + + + public CatalogLimitedConfiguration getLimitedConfig(CatalogItem item) { + synchronized (this.limitedNumbers) { + return this.limitedNumbers.get(item.getId()); + } + } + + + public CatalogLimitedConfiguration createOrUpdateLimitedConfig(CatalogItem item) { + if (item.isLimited()) { + CatalogLimitedConfiguration limitedConfiguration = this.limitedNumbers.get(item.getId()); + + if (limitedConfiguration == null) { + limitedConfiguration = new CatalogLimitedConfiguration(item.getId(), new LinkedList<>(), 0); + limitedConfiguration.generateNumbers(1, item.limitedStack); + this.limitedNumbers.put(item.getId(), limitedConfiguration); + } else { + if (limitedConfiguration.getTotalSet() != item.limitedStack) { + if (limitedConfiguration.getTotalSet() == 0) { + limitedConfiguration.setTotalSet(item.limitedStack); + } else if (item.limitedStack > limitedConfiguration.getTotalSet()) { + limitedConfiguration.generateNumbers(item.limitedStack + 1, item.limitedStack - limitedConfiguration.getTotalSet()); + } else { + item.limitedStack = limitedConfiguration.getTotalSet(); + } + } + } + + return limitedConfiguration; + } + + return null; + } + + + public void dispose() { + TIntObjectIterator pageIterator = this.catalogPages.iterator(); + + while (pageIterator.hasNext()) { + pageIterator.advance(); + + for (CatalogItem item : pageIterator.value().getCatalogItems().valueCollection()) { + item.run(); + if (item.isLimited()) { + this.limitedNumbers.get(item.getId()).run(); + } + } + } + + log.info("Catalog Manager -> Disposed!"); + } + + + public void purchaseItem(CatalogPage page, CatalogItem item, Habbo habbo, int amount, String extradata, boolean free) { + Item cBaseItem = null; + + if (item == null || habbo.getHabboStats().isPurchasingFurniture) { + habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + return; + } + + habbo.getHabboStats().isPurchasingFurniture = true; + + try { + if (item.isClubOnly() && !habbo.getClient().getHabbo().getHabboStats().hasActiveClub()) { + habbo.getClient().sendResponse(new AlertPurchaseUnavailableComposer(AlertPurchaseUnavailableComposer.REQUIRES_CLUB)); + return; + } + + if (amount <= 0) { + habbo.getClient().sendResponse(new AlertPurchaseUnavailableComposer(AlertPurchaseUnavailableComposer.ILLEGAL)); + return; + } + + try { + CatalogLimitedConfiguration limitedConfiguration = null; + int limitedStack = 0; + int limitedNumber = 0; + if (item.isLimited()) { + amount = 1; + if (this.getLimitedConfig(item).available() == 0) { + habbo.getClient().sendResponse(new AlertLimitedSoldOutComposer()); + return; + } + + if (Emulator.getConfig().getBoolean("hotel.catalog.ltd.limit.enabled")) { + int ltdLimit = Emulator.getConfig().getInt("hotel.purchase.ltd.limit.daily.total"); + if (habbo.getHabboStats().totalLtds() >= ltdLimit) { + habbo.alert(Emulator.getTexts().getValue("error.catalog.buy.limited.daily.total").replace("%itemname%", item.getBaseItems().iterator().next().getFullName()).replace("%limit%", ltdLimit + "")); + return; + } + + ltdLimit = Emulator.getConfig().getInt("hotel.purchase.ltd.limit.daily.item"); + if (habbo.getHabboStats().totalLtds(item.id) >= ltdLimit) { + habbo.alert(Emulator.getTexts().getValue("error.catalog.buy.limited.daily.item").replace("%itemname%", item.getBaseItems().iterator().next().getFullName()).replace("%limit%", ltdLimit + "")); + return; + } + } + } + + if (amount > 1) { + if (amount == item.getAmount()) { + amount = 1; + } else { + if (amount * item.getAmount() > 100) { + habbo.alert("Whoops! You tried to buy this " + (amount * item.getAmount()) + " times. This must've been a mistake."); + habbo.getClient().sendResponse(new AlertPurchaseUnavailableComposer(AlertPurchaseUnavailableComposer.ILLEGAL)); + return; + } + } + } + + THashSet itemsList = new THashSet<>(); + + + if (amount > 1 && !CatalogItem.haveOffer(item)) { + String message = Emulator.getTexts().getValue("scripter.warning.catalog.amount").replace("%username%", habbo.getHabboInfo().getUsername()).replace("%itemname%", item.getName()).replace("%pagename%", page.getCaption()); + ScripterManager.scripterDetected(habbo.getClient(), message); + log.info(message); + habbo.getClient().sendResponse(new AlertPurchaseUnavailableComposer(AlertPurchaseUnavailableComposer.ILLEGAL)); + return; + } + + if (item.isLimited()) { + limitedConfiguration = this.getLimitedConfig(item); + + if (limitedConfiguration == null) { + limitedConfiguration = this.createOrUpdateLimitedConfig(item); + } + + limitedNumber = limitedConfiguration.getNumber(); + limitedStack = limitedConfiguration.getTotalSet(); + } + + int totalCredits = free ? 0 : this.calculateDiscountedPrice(item.getCredits(), amount, item); + int totalPoints = free ? 0 : this.calculateDiscountedPrice(item.getPoints(), amount, item); + + if (totalCredits > 0 && habbo.getHabboInfo().getCredits() - totalCredits < 0) return; + if (totalPoints > 0 && habbo.getHabboInfo().getCurrencyAmount(item.getPointsType()) - totalPoints < 0) + return; + + List badges = new ArrayList<>(); + Map> unseenItems = new HashMap<>(); + boolean badgeFound = false; + + for (int i = 0; i < amount; i++) { + if(item.isLimited()) { + habbo.getHabboStats().addLtdLog(item.getId(), Emulator.getIntUnixTimestamp()); + } + + for (Item baseItem : item.getBaseItems()) { + for (int k = 0; k < item.getItemAmount(baseItem.getId()); k++) { + if (baseItem.getName().startsWith("rentable_bot_") || baseItem.getName().startsWith("bot_")) { + String type = item.getName().replace("rentable_bot_", ""); + type = type.replace("bot_", ""); + type = type.replace("visitor_logger", "visitor_log"); + + THashMap data = new THashMap<>(); + + for (String s : item.getExtradata().split(";")) { + if (s.contains(":")) { + data.put(s.split(":")[0], s.split(":")[1]); + } + } + + Bot bot = Emulator.getGameEnvironment().getBotManager().createBot(data, type); + + if (bot != null) { + bot.setOwnerId(habbo.getClient().getHabbo().getHabboInfo().getId()); + bot.setOwnerName(habbo.getClient().getHabbo().getHabboInfo().getUsername()); + bot.needsUpdate(true); + Emulator.getThreading().run(bot); + habbo.getClient().getHabbo().getInventory().getBotsComponent().addBot(bot); + habbo.getClient().sendResponse(new AddBotComposer(bot)); + + if (!unseenItems.containsKey(AddHabboItemComposer.AddHabboItemCategory.BOT)) { + unseenItems.put(AddHabboItemComposer.AddHabboItemCategory.BOT, new ArrayList<>()); + } + + unseenItems.get(AddHabboItemComposer.AddHabboItemCategory.BOT).add(bot.getId()); + } else { + throw new Exception("Failed to create bot of type: " + type); + } + } else if (baseItem.getType() == FurnitureType.EFFECT) { + int effectId = baseItem.getEffectM(); + + if (habbo.getHabboInfo().getGender().equals(HabboGender.F)) { + effectId = baseItem.getEffectF(); + } + + if (effectId > 0) { + habbo.getInventory().getEffectsComponent().createEffect(effectId); + } + } else if (Item.isPet(baseItem)) { + String[] data = extradata.split("\n"); + + if (data.length < 3) { + habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + + Pet pet = null; + try { + pet = Emulator.getGameEnvironment().getPetManager().createPet(baseItem, data[0], data[1], data[2], habbo.getClient()); + } catch (Exception e) { + log.error("Caught exception", e); + habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + } + + if (pet == null) { + habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + + habbo.getClient().getHabbo().getInventory().getPetsComponent().addPet(pet); + habbo.getClient().sendResponse(new AddPetComposer(pet)); + habbo.getClient().sendResponse(new PetBoughtNotificationComposer(pet, false)); + + AchievementManager.progressAchievement(habbo.getClient().getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("PetLover")); + + if (!unseenItems.containsKey(AddHabboItemComposer.AddHabboItemCategory.PET)) { + unseenItems.put(AddHabboItemComposer.AddHabboItemCategory.PET, new ArrayList<>()); + } + + unseenItems.get(AddHabboItemComposer.AddHabboItemCategory.PET).add(pet.getId()); + } else if (baseItem.getType() == FurnitureType.BADGE) { + if (!habbo.getInventory().getBadgesComponent().hasBadge(baseItem.getName())) { + if (!badges.contains(baseItem.getName())) { + badges.add(baseItem.getName()); + } + } else { + badgeFound = true; + } + } else { + if (baseItem.getInteractionType().getType() == InteractionTrophy.class || baseItem.getInteractionType().getType() == InteractionBadgeDisplay.class) { + if (baseItem.getInteractionType().getType() == InteractionBadgeDisplay.class && !habbo.getClient().getHabbo().getInventory().getBadgesComponent().hasBadge(extradata)) { + ScripterManager.scripterDetected(habbo.getClient(), Emulator.getTexts().getValue("scripter.warning.catalog.badge_display").replace("%username%", habbo.getClient().getHabbo().getHabboInfo().getUsername()).replace("%badge%", extradata)); + extradata = "UMAD"; + } + + if (extradata.length() > Emulator.getConfig().getInt("hotel.trophies.length.max", 300)) { + extradata = extradata.substring(0, Emulator.getConfig().getInt("hotel.trophies.length.max", 300)); + } + + extradata = habbo.getClient().getHabbo().getHabboInfo().getUsername() + (char) 9 + Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + "-" + (Calendar.getInstance().get(Calendar.MONTH) + 1) + "-" + Calendar.getInstance().get(Calendar.YEAR) + (char) 9 + Emulator.getGameEnvironment().getWordFilter().filter(extradata.replace(((char) 9) + "", ""), habbo); + } + + if (InteractionTeleport.class.isAssignableFrom(baseItem.getInteractionType().getType())) { + HabboItem teleportOne = Emulator.getGameEnvironment().getItemManager().createItem(habbo.getClient().getHabbo().getHabboInfo().getId(), baseItem, limitedStack, limitedNumber, extradata); + HabboItem teleportTwo = Emulator.getGameEnvironment().getItemManager().createItem(habbo.getClient().getHabbo().getHabboInfo().getId(), baseItem, limitedStack, limitedNumber, extradata); + Emulator.getGameEnvironment().getItemManager().insertTeleportPair(teleportOne.getId(), teleportTwo.getId()); + itemsList.add(teleportOne); + itemsList.add(teleportTwo); + } else if (baseItem.getInteractionType().getType() == InteractionHopper.class) { + HabboItem hopper = Emulator.getGameEnvironment().getItemManager().createItem(habbo.getClient().getHabbo().getHabboInfo().getId(), baseItem, limitedStack, limitedNumber, extradata); + + Emulator.getGameEnvironment().getItemManager().insertHopper(hopper); + + itemsList.add(hopper); + } else if (baseItem.getInteractionType().getType() == InteractionGuildFurni.class || baseItem.getInteractionType().getType() == InteractionGuildGate.class) { + int guildId; + try { + guildId = Integer.parseInt(extradata); + } catch (Exception e) { + log.error("Caught exception", e); + habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (guild != null && Emulator.getGameEnvironment().getGuildManager().getGuildMember(guild, habbo) != null) { + InteractionGuildFurni habboItem = (InteractionGuildFurni) Emulator.getGameEnvironment().getItemManager().createItem(habbo.getClient().getHabbo().getHabboInfo().getId(), baseItem, limitedStack, limitedNumber, extradata); + habboItem.setExtradata(""); + habboItem.needsUpdate(true); + + Emulator.getThreading().run(habboItem); + Emulator.getGameEnvironment().getGuildManager().setGuild(habboItem, guildId); + itemsList.add(habboItem); + + if (baseItem.getName().equals("guild_forum")) { + guild.setForum(true); + guild.needsUpdate = true; + guild.run(); + } + } + } else if (baseItem.getInteractionType().getType() == InteractionMusicDisc.class) { + SoundTrack track = Emulator.getGameEnvironment().getItemManager().getSoundTrack(item.getExtradata()); + + if (track == null) { + habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + + InteractionMusicDisc habboItem = (InteractionMusicDisc) Emulator.getGameEnvironment().getItemManager().createItem(habbo.getClient().getHabbo().getHabboInfo().getId(), baseItem, limitedStack, limitedNumber, habbo.getClient().getHabbo().getHabboInfo().getUsername() + "\n" + Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + "\n" + (Calendar.getInstance().get(Calendar.MONTH) + 1) + "\n" + Calendar.getInstance().get(Calendar.YEAR) + "\n" + track.getLength() + "\n" + track.getName() + "\n" + track.getId()); + habboItem.needsUpdate(true); + + Emulator.getThreading().run(habboItem); + itemsList.add(habboItem); + + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("MusicCollector")); + } else { + HabboItem habboItem = Emulator.getGameEnvironment().getItemManager().createItem(habbo.getClient().getHabbo().getHabboInfo().getId(), baseItem, limitedStack, limitedNumber, extradata); + itemsList.add(habboItem); + } + } + } + } + } + + if (badgeFound && item.getBaseItems().size() == 1) { + habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.ALREADY_HAVE_BADGE)); + return; + } + + UserCatalogItemPurchasedEvent purchasedEvent = new UserCatalogItemPurchasedEvent(habbo, item, itemsList, totalCredits, totalPoints, badges); + Emulator.getPluginManager().fireEvent(purchasedEvent); + + if (!free && !habbo.getClient().getHabbo().hasPermission(Permission.ACC_INFINITE_CREDITS)) { + if (purchasedEvent.totalCredits > 0) { + habbo.getClient().getHabbo().giveCredits(-purchasedEvent.totalCredits); + } + } + + if (!free && !habbo.getClient().getHabbo().hasPermission(Permission.ACC_INFINITE_POINTS)) { + if (purchasedEvent.totalPoints > 0) { + habbo.getClient().getHabbo().givePoints(item.getPointsType(), -purchasedEvent.totalPoints); + } + } + + if (purchasedEvent.itemsList != null && !purchasedEvent.itemsList.isEmpty()) { + habbo.getClient().getHabbo().getInventory().getItemsComponent().addItems(purchasedEvent.itemsList); + unseenItems.put(AddHabboItemComposer.AddHabboItemCategory.OWNED_FURNI, purchasedEvent.itemsList.stream().map(HabboItem::getId).collect(Collectors.toList())); + + Emulator.getPluginManager().fireEvent(new UserCatalogFurnitureBoughtEvent(habbo, item, purchasedEvent.itemsList)); + + if (limitedConfiguration != null) { + for (HabboItem itm : purchasedEvent.itemsList) { + limitedConfiguration.limitedSold(item.getId(), habbo, itm); + } + } + } + + if (!purchasedEvent.badges.isEmpty() && !unseenItems.containsKey(AddHabboItemComposer.AddHabboItemCategory.BADGE)) { + unseenItems.put(AddHabboItemComposer.AddHabboItemCategory.BADGE, new ArrayList<>()); + } + + for (String b : purchasedEvent.badges) { + HabboBadge badge = new HabboBadge(0, b, 0, habbo); + Emulator.getThreading().run(badge); + habbo.getInventory().getBadgesComponent().addBadge(badge); + habbo.getClient().sendResponse(new AddUserBadgeComposer(badge)); + THashMap keys = new THashMap<>(); + keys.put("display", "BUBBLE"); + keys.put("image", "${image.library.url}album1584/" + badge.getCode() + ".gif"); + keys.put("message", Emulator.getTexts().getValue("commands.generic.cmd_badge.received")); + habbo.getClient().sendResponse(new BubbleAlertComposer(BubbleAlertKeys.RECEIVED_BADGE.key, keys)); + unseenItems.get(AddHabboItemComposer.AddHabboItemCategory.BADGE).add(badge.getId()); + } + habbo.getClient().getHabbo().getHabboStats().addPurchase(purchasedEvent.catalogItem); + + habbo.getClient().sendResponse(new AddHabboItemComposer(unseenItems)); + + habbo.getClient().sendResponse(new PurchaseOKComposer(purchasedEvent.catalogItem)); + habbo.getClient().sendResponse(new InventoryRefreshComposer()); + + THashSet itemIds = new THashSet<>(); + + for(HabboItem ix : purchasedEvent.itemsList) { + itemIds.add(ix.getId() + ""); + } + + if(!free) { + Emulator.getThreading().run(new CatalogPurchaseLogEntry( + Emulator.getIntUnixTimestamp(), + purchasedEvent.habbo.getHabboInfo().getId(), + purchasedEvent.catalogItem != null ? purchasedEvent.catalogItem.getId() : 0, + String.join(";", itemIds), + purchasedEvent.catalogItem != null ? purchasedEvent.catalogItem.getName() : "", + purchasedEvent.totalCredits, + purchasedEvent.totalPoints, + item != null ? item.getPointsType() : 0, + amount + )); + } + + } catch (Exception e) { + log.error("Exception caught", e); + habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + } + } finally { + habbo.getHabboStats().isPurchasingFurniture = false; + } + } + + public List getClubOffers() { + List offers = new ArrayList<>(); + + for (Map.Entry entry : this.clubOffers.entrySet()) { + if (!entry.getValue().isDeal()) { + offers.add(entry.getValue()); + } + } + + return offers; + } + + public TargetOffer getTargetOffer(int offerId) { + return this.targetOffers.get(offerId); + } + + private int calculateDiscountedPrice(int originalPrice, int amount, CatalogItem item) { + if (!CatalogItem.haveOffer(item)) return originalPrice * amount; + + int basicDiscount = amount / DiscountComposer.DISCOUNT_BATCH_SIZE; + + int bonusDiscount = 0; + if (basicDiscount >= DiscountComposer.MINIMUM_DISCOUNTS_FOR_BONUS) { + if (amount % DiscountComposer.DISCOUNT_BATCH_SIZE == DiscountComposer.DISCOUNT_BATCH_SIZE - 1) { + bonusDiscount = 1; + } + + bonusDiscount += basicDiscount - DiscountComposer.MINIMUM_DISCOUNTS_FOR_BONUS; + } + + int additionalDiscounts = 0; + for (int threshold : DiscountComposer.ADDITIONAL_DISCOUNT_THRESHOLDS) { + if (amount >= threshold) additionalDiscounts++; + } + + int totalDiscountedItems = (basicDiscount * DiscountComposer.DISCOUNT_AMOUNT_PER_BATCH) + bonusDiscount + additionalDiscounts; + + return Math.max(0, originalPrice * (amount - totalDiscountedItems)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPage.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPage.java new file mode 100644 index 0000000..96c46db --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPage.java @@ -0,0 +1,206 @@ +package com.eu.habbo.habbohotel.catalog; + +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.TCollections; +import gnu.trove.list.array.TIntArrayList; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import lombok.extern.slf4j.Slf4j; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; + +@Slf4j +public abstract class CatalogPage implements Comparable, ISerialize { + + protected final TIntArrayList offerIds = new TIntArrayList(); + protected final THashMap childPages = new THashMap<>(); + private final TIntObjectMap catalogItems = TCollections.synchronizedMap(new TIntObjectHashMap<>()); + private final ArrayList included = new ArrayList<>(); + protected int id; + protected int parentId; + protected int rank; + protected String caption; + protected String pageName; + protected int iconColor; + protected int iconImage; + protected int orderNum; + protected boolean visible; + protected boolean enabled; + protected boolean clubOnly; + protected String layout; + protected String headerImage; + protected String teaserImage; + protected String specialImage; + protected String textOne; + protected String textTwo; + protected String textDetails; + protected String textTeaser; + + public CatalogPage() { + } + + public CatalogPage(ResultSet set) throws SQLException { + if (set == null) + return; + + this.id = set.getInt("id"); + this.parentId = set.getInt("parent_id"); + this.rank = set.getInt("min_rank"); + this.caption = set.getString("caption"); + this.pageName = set.getString("caption_save"); + this.iconColor = set.getInt("icon_color"); + this.iconImage = set.getInt("icon_image"); + this.orderNum = set.getInt("order_num"); + this.visible = set.getBoolean("visible"); + this.enabled = set.getBoolean("enabled"); + this.clubOnly = set.getBoolean("club_only"); + this.layout = set.getString("page_layout"); + this.headerImage = set.getString("page_headline"); + this.teaserImage = set.getString("page_teaser"); + this.specialImage = set.getString("page_special"); + this.textOne = set.getString("page_text1"); + this.textTwo = set.getString("page_text2"); + this.textDetails = set.getString("page_text_details"); + this.textTeaser = set.getString("page_text_teaser"); + + if (!set.getString("includes").isEmpty()) { + for (String id : set.getString("includes").split(";")) { + try { + this.included.add(Integer.valueOf(id)); + } catch (Exception e) { + log.error("Caught exception", e); + log.error("Failed to parse includes column value of (" + id + ") for catalog page (" + this.id + ")"); + } + } + } + } + + public int getId() { + return this.id; + } + + public int getParentId() { + return this.parentId; + } + + public int getRank() { + return this.rank; + } + + public void setRank(int rank) { + this.rank = rank; + } + + public String getCaption() { + return this.caption; + } + + public String getPageName() { + return this.pageName; + } + + public int getIconColor() { + return this.iconColor; + } + + public int getIconImage() { + return this.iconImage; + } + + public int getOrderNum() { + return this.orderNum; + } + + public boolean isVisible() { + return this.visible; + } + + public boolean isEnabled() { + return this.enabled; + } + + public boolean isClubOnly() { + return this.clubOnly; + } + + public String getLayout() { + return this.layout; + } + + public String getHeaderImage() { + return this.headerImage; + } + + public String getTeaserImage() { + return this.teaserImage; + } + + public String getSpecialImage() { + return this.specialImage; + } + + public String getTextOne() { + return this.textOne; + } + + public String getTextTwo() { + return this.textTwo; + } + + public String getTextDetails() { + return this.textDetails; + } + + public String getTextTeaser() { + return this.textTeaser; + } + + public TIntArrayList getOfferIds() { + return this.offerIds; + } + + public void addOfferId(int offerId) { + this.offerIds.add(offerId); + } + + public void addItem(CatalogItem item) { + this.catalogItems.put(item.getId(), item); + } + + public TIntObjectMap getCatalogItems() { + return this.catalogItems; + } + + public CatalogItem getCatalogItem(int id) { + return this.catalogItems.get(id); + } + + public ArrayList getIncluded() { + return this.included; + } + + public THashMap getChildPages() { + return this.childPages; + } + + public void addChildPage(CatalogPage page) { + this.childPages.put(page.getId(), page); + + if (page.getRank() < this.getRank()) { + page.setRank(this.getRank()); + } + } + + @SuppressWarnings("NullableProblems") + @Override + public int compareTo(CatalogPage page) { + return this.getOrderNum() - page.getOrderNum(); + } + + @Override + public abstract void serialize(ServerMessage message); +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPageLayouts.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPageLayouts.java new file mode 100644 index 0000000..ff6d01a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPageLayouts.java @@ -0,0 +1,47 @@ +package com.eu.habbo.habbohotel.catalog; + +public enum CatalogPageLayouts { + + default_3x3, + guild_furni, + guilds, + guild_forum, + info_duckets, + info_rentables, + info_loyalty, + loyalty_vip_buy, + bots, + pets, + pets2, + pets3, + club_gift, + frontpage, + badge_display, + spaces_new, + soundmachine, + info_pets, + club_buy, + roomads, + trophies, + single_bundle, + marketplace, + marketplace_own_items, + recycler, + recycler_info, + recycler_prizes, + sold_ltd_items, + plasto, + default_3x3_color_grouping, + recent_purchases, + room_bundle, + petcustomization, + root, + vip_buy, + frontpage_featured, + builders_club_addons, + builders_club_frontpage, + builders_club_loyalty, + monkey, + niko, + mad_money +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPageType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPageType.java new file mode 100644 index 0000000..d270395 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPageType.java @@ -0,0 +1,9 @@ +package com.eu.habbo.habbohotel.catalog; + +public enum CatalogPageType { + + NORMAL, + + + BUILDER +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPurchaseLogEntry.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPurchaseLogEntry.java new file mode 100644 index 0000000..5f6febd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPurchaseLogEntry.java @@ -0,0 +1,61 @@ +package com.eu.habbo.habbohotel.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.core.DatabaseLoggable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +public class CatalogPurchaseLogEntry implements Runnable, DatabaseLoggable { + + private static final Logger LOGGER = LoggerFactory.getLogger(CatalogPurchaseLogEntry.class); + private static final String QUERY = "INSERT INTO `logs_shop_purchases` (timestamp, user_id, catalog_item_id, item_ids, catalog_name, cost_credits, cost_points, points_type, amount) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + + private final int timestamp; + private final int userId; + private final int catalogItemId; + private final String itemIds; + private final String catalogName; + private final int costCredits; + private final int costPoints; + private final int pointsType; + private final int amount; + + public CatalogPurchaseLogEntry(int timestamp, int userId, int catalogItemId, String itemIds, String catalogName, int costCredits, int costPoints, int pointsType, int amount) { + this.timestamp = timestamp; + this.userId = userId; + this.catalogItemId = catalogItemId; + this.itemIds = itemIds; + this.catalogName = catalogName; + this.costCredits = costCredits; + this.costPoints = costPoints; + this.pointsType = pointsType; + this.amount = amount; + } + + @Override + public String getQuery() { + return QUERY; + } + + @Override + public void log(PreparedStatement statement) throws SQLException { + statement.setInt(1, this.timestamp); + statement.setInt(2, this.userId); + statement.setInt(3, this.catalogItemId); + statement.setString(4, this.itemIds); + statement.setString(5, this.catalogName); + statement.setInt(6, this.costCredits); + statement.setInt(7, this.costPoints); + statement.setInt(8, this.pointsType); + statement.setInt(9, this.amount); + statement.addBatch(); + } + + @Override + public void run() { + Emulator.getDatabaseLogger().store(this); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/ClothItem.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/ClothItem.java new file mode 100644 index 0000000..c99f81d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/ClothItem.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.catalog; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class ClothItem { + + public int id; + + + public String name; + + + public int[] setId; + + public ClothItem(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.name = set.getString("name"); + String[] parts = set.getString("setid").split(","); + + this.setId = new int[parts.length]; + for (int i = 0; i < this.setId.length; i++) { + this.setId[i] = Integer.valueOf(parts[i]); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/ClubOffer.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/ClubOffer.java new file mode 100644 index 0000000..3be967b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/ClubOffer.java @@ -0,0 +1,122 @@ +package com.eu.habbo.habbohotel.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Calendar; +import java.util.TimeZone; + +public class ClubOffer implements ISerialize { + + private final int id; + + + private final String name; + + + private final int days; + + + private final int credits; + + + private final int points; + + + private final int pointsType; + + + private final boolean vip; + + + private final boolean deal; + + public ClubOffer(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.name = set.getString("name"); + this.days = set.getInt("days"); + this.credits = set.getInt("credits"); + this.points = set.getInt("points"); + this.pointsType = set.getInt("points_type"); + this.vip = set.getString("type").equalsIgnoreCase("vip"); + this.deal = set.getString("deal").equals("1"); + } + + public int getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public int getDays() { + return this.days; + } + + public int getCredits() { + return this.credits; + } + + public int getPoints() { + return this.points; + } + + public int getPointsType() { + return this.pointsType; + } + + public boolean isVip() { + return this.vip; + } + + public boolean isDeal() { + return this.deal; + } + + @Override + public void serialize(ServerMessage message) { + serialize(message, Emulator.getIntUnixTimestamp()); + } + + public void serialize(ServerMessage message, int hcExpireTimestamp) { + hcExpireTimestamp = Math.max(Emulator.getIntUnixTimestamp(), hcExpireTimestamp); + message.appendInt(this.id); + message.appendString(this.name); + message.appendBoolean(false); //unused + message.appendInt(this.credits); + message.appendInt(this.points); + message.appendInt(this.pointsType); + message.appendBoolean(this.vip); + + long seconds = this.days * 86400; + + long secondsTotal = seconds; + + int totalYears = (int) Math.floor((int) seconds / (86400.0 * 31 * 12)); + seconds -= totalYears * (86400 * 31 * 12); + + int totalMonths = (int) Math.floor((int) seconds / (86400.0 * 31)); + seconds -= totalMonths * (86400 * 31); + + int totalDays = (int) Math.floor((int) seconds / 86400.0); + seconds -= totalDays * 86400; + + message.appendInt((int) secondsTotal / 86400 / 31); + message.appendInt((int) seconds); + message.appendBoolean(false); //giftable + message.appendInt((int) seconds); + + hcExpireTimestamp += secondsTotal; + + Calendar cal = Calendar.getInstance(); + cal.setTimeZone(TimeZone.getTimeZone("UTC")); + cal.setTimeInMillis(hcExpireTimestamp * 1000L); + message.appendInt(cal.get(Calendar.YEAR)); + message.appendInt(cal.get(Calendar.MONTH) + 1); + message.appendInt(cal.get(Calendar.DAY_OF_MONTH)); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/TargetOffer.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/TargetOffer.java new file mode 100644 index 0000000..3766c16 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/TargetOffer.java @@ -0,0 +1,116 @@ +package com.eu.habbo.habbohotel.catalog; + + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.cache.HabboOfferPurchase; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class TargetOffer { + public static int ACTIVE_TARGET_OFFER_ID = 0; + + private final int id; + private final int catalogItem; + private final String identifier; + private final int priceInCredits; + private final int priceInActivityPoints; + private final int activityPointsType; + private final int purchaseLimit; + private final int expirationTime; + private final String title; + private final String description; + private final String imageUrl; + private final String icon; + private final String[] vars; + + public TargetOffer(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.identifier = set.getString("offer_code"); + this.priceInCredits = set.getInt("credits"); + this.priceInActivityPoints = set.getInt("points"); + this.activityPointsType = set.getInt("points_type"); + this.title = set.getString("title"); + this.description = set.getString("description"); + this.imageUrl = set.getString("image"); + this.icon = set.getString("icon"); + this.purchaseLimit = set.getInt("purchase_limit"); + this.expirationTime = set.getInt("end_timestamp"); + this.vars = set.getString("vars").split(";"); + this.catalogItem = set.getInt("catalog_item"); + } + + public void serialize(ServerMessage message, HabboOfferPurchase purchase) { + message.appendInt(purchase.getState()); + message.appendInt(this.id); + message.appendString(this.identifier); + message.appendString(this.identifier); + message.appendInt(this.priceInCredits); + message.appendInt(this.priceInActivityPoints); + message.appendInt(this.activityPointsType); + message.appendInt(Math.max(this.purchaseLimit - purchase.getAmount(), 0)); + message.appendInt(Math.max(this.expirationTime - Emulator.getIntUnixTimestamp(), 0)); + message.appendString(this.title); + message.appendString(this.description); + message.appendString(this.imageUrl); + message.appendString(this.icon); + message.appendInt(0); + message.appendInt(this.vars.length); + for (String variable : this.vars) { + message.appendString(variable); + } + } + + public int getId() { + return this.id; + } + + public String getIdentifier() { + return this.identifier; + } + + public int getPriceInCredits() { + return this.priceInCredits; + } + + public int getPriceInActivityPoints() { + return this.priceInActivityPoints; + } + + public int getActivityPointsType() { + return this.activityPointsType; + } + + public int getPurchaseLimit() { + return this.purchaseLimit; + } + + public int getExpirationTime() { + return this.expirationTime; + } + + public String getTitle() { + return this.title; + } + + public String getDescription() { + return this.description; + } + + public String getImageUrl() { + return this.imageUrl; + } + + public String getIcon() { + return this.icon; + } + + public String[] getVars() { + return this.vars; + } + + public int getCatalogItem() { + return this.catalogItem; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/Voucher.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/Voucher.java new file mode 100644 index 0000000..18a23df --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/Voucher.java @@ -0,0 +1,75 @@ +package com.eu.habbo.habbohotel.catalog; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; + + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +public class Voucher { + + public final int id; + public final String code; + public final int credits; + public final int points; + public final int pointsType; + public final int catalogItemId; + public final int amount; + public final int limit; + private final List history = new ArrayList<>(); + + public Voucher(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.code = set.getString("code"); + this.credits = set.getInt("credits"); + this.points = set.getInt("points"); + this.pointsType = set.getInt("points_type"); + this.catalogItemId = set.getInt("catalog_item_id"); + this.amount = set.getInt("amount"); + this.limit = set.getInt("limit"); + + this.loadHistory(); + } + + private void loadHistory() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM voucher_history WHERE voucher_id = ?")) { + statement.setInt(1, this.id); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + this.history.add(new VoucherHistoryEntry(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public boolean hasUserExhausted(int userId) { + return this.limit > 0 && Math.toIntExact(this.history.stream().filter(h -> h.getUserId() == userId).count()) >= this.limit; + } + + public boolean isExhausted() { + return this.amount > 0 && this.history.size() >= this.amount; + } + + public void addHistoryEntry(int userId) { + int timestamp = Emulator.getIntUnixTimestamp(); + this.history.add(new VoucherHistoryEntry(this.id, userId, timestamp)); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO voucher_history (`voucher_id`, `user_id`, `timestamp`) VALUES (?, ?, ?)")) { + statement.setInt(1, this.id); + statement.setInt(2, userId); + statement.setInt(3, timestamp); + + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/VoucherHistoryEntry.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/VoucherHistoryEntry.java new file mode 100644 index 0000000..300c7c8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/VoucherHistoryEntry.java @@ -0,0 +1,34 @@ +package com.eu.habbo.habbohotel.catalog; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class VoucherHistoryEntry { + private final int voucherId; + private final int userId; + private final int timestamp; + + public VoucherHistoryEntry(ResultSet set) throws SQLException { + this.voucherId = set.getInt("voucher_id"); + this.userId = set.getInt("user_id"); + this.timestamp = set.getInt("timestamp"); + } + + public VoucherHistoryEntry(int voucherId, int userId, int timestamp) { + this.voucherId = voucherId; + this.userId = userId; + this.timestamp = timestamp; + } + + public int getVoucherId() { + return voucherId; + } + + public int getUserId() { + return userId; + } + + public int getTimestamp() { + return timestamp; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BadgeDisplayLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BadgeDisplayLayout.java new file mode 100644 index 0000000..de8cf5e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BadgeDisplayLayout.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + + +public class BadgeDisplayLayout extends CatalogPage { + public BadgeDisplayLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("badge_display"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BotsLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BotsLayout.java new file mode 100644 index 0000000..57815b9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BotsLayout.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + + +public class BotsLayout extends CatalogPage { + public BotsLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("bots"); + message.appendInt(2); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTwo()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BuildersClubAddonsLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BuildersClubAddonsLayout.java new file mode 100644 index 0000000..d3f64da --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BuildersClubAddonsLayout.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + + +public class BuildersClubAddonsLayout extends CatalogPage { + public BuildersClubAddonsLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("builders_club_addons"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BuildersClubFrontPageLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BuildersClubFrontPageLayout.java new file mode 100644 index 0000000..d53bbe9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BuildersClubFrontPageLayout.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + + +public class BuildersClubFrontPageLayout extends CatalogPage { + public BuildersClubFrontPageLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("builders_club_frontpage"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BuildersClubLoyaltyLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BuildersClubLoyaltyLayout.java new file mode 100644 index 0000000..cdedbf0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/BuildersClubLoyaltyLayout.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + + +public class BuildersClubLoyaltyLayout extends CatalogPage { + public BuildersClubLoyaltyLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("builders_club_loyalty"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/CatalogRootLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/CatalogRootLayout.java new file mode 100644 index 0000000..d73e77a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/CatalogRootLayout.java @@ -0,0 +1,44 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class CatalogRootLayout extends CatalogPage { + public CatalogRootLayout() { + super(); + + this.id = -1; + this.parentId = -2; + this.rank = 0; + this.caption = "root"; + this.pageName = "root"; + this.iconColor = 0; + this.iconImage = 0; + this.orderNum = -10; + this.visible = true; + this.enabled = true; + } + + public CatalogRootLayout(ResultSet set) throws SQLException { + super(null); + + this.id = -1; + this.parentId = -2; + this.rank = 0; + this.caption = "root"; + this.pageName = "root"; + this.iconColor = 0; + this.iconImage = 0; + this.orderNum = -10; + this.visible = true; + this.enabled = true; + } + + @Override + public void serialize(ServerMessage message) { + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ClubBuyLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ClubBuyLayout.java new file mode 100644 index 0000000..1f7d474 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ClubBuyLayout.java @@ -0,0 +1,22 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class ClubBuyLayout extends CatalogPage { + public ClubBuyLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("club_buy"); + message.appendInt(2); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendInt(0); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ClubGiftsLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ClubGiftsLayout.java new file mode 100644 index 0000000..0f0e4cc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ClubGiftsLayout.java @@ -0,0 +1,22 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class ClubGiftsLayout extends CatalogPage { + public ClubGiftsLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("club_gifts"); + message.appendInt(1); + message.appendString(super.getHeaderImage()); + message.appendInt(1); + message.appendString(super.getTextOne()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ColorGroupingLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ColorGroupingLayout.java new file mode 100644 index 0000000..1cfbe35 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ColorGroupingLayout.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class ColorGroupingLayout extends CatalogPage { + public ColorGroupingLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("default_3x3_color_grouping"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/Default_3x3Layout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/Default_3x3Layout.java new file mode 100644 index 0000000..2846ce2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/Default_3x3Layout.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class Default_3x3Layout extends CatalogPage { + + public Default_3x3Layout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("default_3x3"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/FrontPageFeaturedLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/FrontPageFeaturedLayout.java new file mode 100644 index 0000000..e2380be --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/FrontPageFeaturedLayout.java @@ -0,0 +1,75 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.CatalogFeaturedPage; +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class FrontPageFeaturedLayout extends CatalogPage { + public FrontPageFeaturedLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("frontpage_featured"); + String[] teaserImages = super.getTeaserImage().split(";"); + String[] specialImages = super.getSpecialImage().split(";"); + + message.appendInt(1 + teaserImages.length + specialImages.length); + message.appendString(super.getHeaderImage()); + for (String s : teaserImages) { + message.appendString(s); + } + + for (String s : specialImages) { + message.appendString(s); + } + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } + + public void serializeExtra(ServerMessage message) { + + message.appendInt(Emulator.getGameEnvironment().getCatalogManager().getCatalogFeaturedPages().size()); + + for (CatalogFeaturedPage page : Emulator.getGameEnvironment().getCatalogManager().getCatalogFeaturedPages().valueCollection()) { + page.serialize(message); + } + message.appendInt(1); //Position + message.appendString("NUOVO: Affare Stanza di Rilassamento"); + message.appendString("catalogue/feature_cata_vert_oly16bundle4.png"); + message.appendInt(0); //Type + //0 : String //Page Name + //1 : Int //Page ID + //2 : String //Productdata + message.appendString(""); + message.appendInt(-1); + + message.appendInt(2); + message.appendString("Il RITORNO di Habburgers! (TUTTI furni nuovi)"); + message.appendString("catalogue/feature_cata_hort_habbergerbundle.png"); + message.appendInt(0); + message.appendString(""); + message.appendInt(-1); + + message.appendInt(3); + message.appendString("Habbolympics"); + message.appendString("catalogue/feature_cata_hort_olympic16.png"); + message.appendInt(0); + message.appendString(""); + message.appendInt(-1); + + message.appendInt(4); + message.appendString("Diventa un Membro HC"); + message.appendString("catalogue/feature_cata_hort_HC_b.png"); + message.appendInt(0); + message.appendString("habbo_club"); + message.appendInt(-1); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/FrontpageLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/FrontpageLayout.java new file mode 100644 index 0000000..93d7409 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/FrontpageLayout.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class FrontpageLayout extends CatalogPage { + + public FrontpageLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("frontpage4"); + message.appendInt(2); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextTwo()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/GuildForumLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/GuildForumLayout.java new file mode 100644 index 0000000..40de36a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/GuildForumLayout.java @@ -0,0 +1,25 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class GuildForumLayout extends CatalogPage { + public GuildForumLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("guild_forum"); + message.appendInt(2); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/GuildFrontpageLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/GuildFrontpageLayout.java new file mode 100644 index 0000000..a2adeb2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/GuildFrontpageLayout.java @@ -0,0 +1,25 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class GuildFrontpageLayout extends CatalogPage { + public GuildFrontpageLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("guild_frontpage"); + message.appendInt(2); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/GuildFurnitureLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/GuildFurnitureLayout.java new file mode 100644 index 0000000..e6c3c85 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/GuildFurnitureLayout.java @@ -0,0 +1,25 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class GuildFurnitureLayout extends CatalogPage { + public GuildFurnitureLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("guild_custom_furni"); + message.appendInt(2); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoDucketsLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoDucketsLayout.java new file mode 100644 index 0000000..5591249 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoDucketsLayout.java @@ -0,0 +1,23 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InfoDucketsLayout extends CatalogPage { + public InfoDucketsLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("info_duckets"); + message.appendInt(1); + message.appendString(this.getHeaderImage()); + message.appendInt(1); + message.appendString(this.getTextOne()); + message.appendInt(0); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoLoyaltyLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoLoyaltyLayout.java new file mode 100644 index 0000000..2c09de8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoLoyaltyLayout.java @@ -0,0 +1,23 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InfoLoyaltyLayout extends CatalogPage { + public InfoLoyaltyLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("info_loyalty"); + message.appendInt(1); + message.appendString(this.getHeaderImage()); + message.appendInt(1); + message.appendString(this.getTextOne()); + message.appendInt(0); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoMonkeyLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoMonkeyLayout.java new file mode 100644 index 0000000..1de28f5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoMonkeyLayout.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InfoMonkeyLayout extends CatalogPage { + + public InfoMonkeyLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("monkey"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoNikoLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoNikoLayout.java new file mode 100644 index 0000000..f6cd516 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoNikoLayout.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InfoNikoLayout extends CatalogPage { + + public InfoNikoLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("monkey"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoPetsLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoPetsLayout.java new file mode 100644 index 0000000..1e70f75 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoPetsLayout.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InfoPetsLayout extends CatalogPage { + public InfoPetsLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("info_pets"); + message.appendInt(2); + message.appendString(this.getHeaderImage()); + message.appendString(this.getTeaserImage()); + message.appendInt(3); + message.appendString(this.getTextOne()); + message.appendString(""); + message.appendString(this.getTextTeaser()); + message.appendInt(0); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoRentablesLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoRentablesLayout.java new file mode 100644 index 0000000..ab7dc18 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoRentablesLayout.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InfoRentablesLayout extends CatalogPage { + public InfoRentablesLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + String[] data = this.getTextOne().split("\\|\\|"); + message.appendString("info_rentables"); + message.appendInt(1); + message.appendString(this.getHeaderImage()); + message.appendInt(data.length); + for (String d : data) { + message.appendString(d); + } + message.appendInt(0); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/LoyaltyVipBuyLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/LoyaltyVipBuyLayout.java new file mode 100644 index 0000000..fbcd15f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/LoyaltyVipBuyLayout.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class LoyaltyVipBuyLayout extends CatalogPage { + public LoyaltyVipBuyLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("loyalty_vip_buy"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/MadMoneyLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/MadMoneyLayout.java new file mode 100644 index 0000000..7e73ce1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/MadMoneyLayout.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class MadMoneyLayout extends CatalogPage { + + public MadMoneyLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("mad_money"); + message.appendInt(2); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendInt(2); + message.appendString(super.getTextOne()); + message.appendString(super.getTextTwo()); + // message.appendString("MH"); + message.appendInt(0); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/MarketplaceLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/MarketplaceLayout.java new file mode 100644 index 0000000..a959dda --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/MarketplaceLayout.java @@ -0,0 +1,20 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class MarketplaceLayout extends CatalogPage { + public MarketplaceLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("marketplace"); + message.appendInt(0); + message.appendInt(0); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/MarketplaceOwnItems.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/MarketplaceOwnItems.java new file mode 100644 index 0000000..b38ea07 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/MarketplaceOwnItems.java @@ -0,0 +1,21 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class MarketplaceOwnItems extends CatalogPage { + public MarketplaceOwnItems(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("marketplace_own_items"); + message.appendInt(0); + message.appendInt(0); + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/PetCustomizationLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/PetCustomizationLayout.java new file mode 100644 index 0000000..5474a42 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/PetCustomizationLayout.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class PetCustomizationLayout extends CatalogPage { + public PetCustomizationLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("petcustomization"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/Pets2Layout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/Pets2Layout.java new file mode 100644 index 0000000..7ebbf45 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/Pets2Layout.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class Pets2Layout extends CatalogPage { + public Pets2Layout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("pets2"); + message.appendInt(2); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendInt(4); + message.appendString(super.getTextOne()); + message.appendString(super.getTextTwo()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/Pets3Layout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/Pets3Layout.java new file mode 100644 index 0000000..0c43051 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/Pets3Layout.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class Pets3Layout extends CatalogPage { + public Pets3Layout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("pets3"); + message.appendInt(2); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendInt(4); + message.appendString(super.getTextOne()); + message.appendString(super.getTextTwo()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/PetsLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/PetsLayout.java new file mode 100644 index 0000000..d708b01 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/PetsLayout.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class PetsLayout extends CatalogPage { + public PetsLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("pets"); + message.appendInt(2); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendInt(4); + message.appendString(super.getTextOne()); + message.appendString(super.getTextTwo()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ProductPage1Layout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ProductPage1Layout.java new file mode 100644 index 0000000..b8cfe13 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/ProductPage1Layout.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class ProductPage1Layout extends CatalogPage { + public ProductPage1Layout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("productpage1"); + message.appendInt(2); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendInt(4); + message.appendString(super.getTextOne()); + message.appendString(super.getTextTwo()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RecentPurchasesLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RecentPurchasesLayout.java new file mode 100644 index 0000000..11485a1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RecentPurchasesLayout.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class RecentPurchasesLayout extends CatalogPage { + public RecentPurchasesLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("default_3x3"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RecyclerInfoLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RecyclerInfoLayout.java new file mode 100644 index 0000000..9d923b5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RecyclerInfoLayout.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class RecyclerInfoLayout extends CatalogPage { + public RecyclerInfoLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("recycler_info"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RecyclerLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RecyclerLayout.java new file mode 100644 index 0000000..6022cd3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RecyclerLayout.java @@ -0,0 +1,25 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class RecyclerLayout extends CatalogPage { + public RecyclerLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("recycler"); + message.appendInt(2); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendInt(1); + message.appendString(super.getTextOne()); + message.appendInt(-1); + message.appendBoolean(false); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RecyclerPrizesLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RecyclerPrizesLayout.java new file mode 100644 index 0000000..fe5693b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RecyclerPrizesLayout.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class RecyclerPrizesLayout extends CatalogPage { + public RecyclerPrizesLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("recycler_prizes"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RoomAdsLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RoomAdsLayout.java new file mode 100644 index 0000000..e5a2cec --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RoomAdsLayout.java @@ -0,0 +1,24 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class RoomAdsLayout extends CatalogPage { + public RoomAdsLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("roomads"); + message.appendInt(2); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendInt(2); + message.appendString(super.getTextOne()); + message.appendString(super.getTextTwo()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RoomBundleLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RoomBundleLayout.java new file mode 100644 index 0000000..06d2053 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/RoomBundleLayout.java @@ -0,0 +1,246 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomManager; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.navigator.CanCreateRoomComposer; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectProcedure; +import lombok.extern.slf4j.Slf4j; + +import java.sql.*; +import java.util.Map; + +@Slf4j +public class RoomBundleLayout extends SingleBundle { + + public int roomId; + public Room room; + private int lastUpdate = 0; + private boolean loaded = false; + + public RoomBundleLayout(ResultSet set) throws SQLException { + super(set); + + this.roomId = set.getInt("room_id"); + } + + @Override + public TIntObjectMap getCatalogItems() { + if (Emulator.getIntUnixTimestamp() - this.lastUpdate < 120) { + this.lastUpdate = Emulator.getIntUnixTimestamp(); + return super.getCatalogItems(); + } + + if (this.room == null) { + if (this.roomId > 0) { + this.room = Emulator.getGameEnvironment().getRoomManager().loadRoom(this.roomId); + + if (this.room != null) + this.room.preventUnloading = true; + } else { + log.error("No room id specified for room bundle " + this.getPageName() + "(" + this.getId() + ")"); + } + } + + if (this.room == null) { + return super.getCatalogItems(); + } + + final CatalogItem[] item = {null}; + + super.getCatalogItems().forEachValue(new TObjectProcedure() { + @Override + public boolean execute(CatalogItem object) { + if (object == null) + return true; + + item[0] = object; + return false; + } + }); + + if (this.room.isPreLoaded()) { + this.room.loadData(); + this.room.preventUncaching = true; + this.room.preventUnloading = true; + } + if (item[0] != null) { + item[0].getBundle().clear(); + + THashMap items = new THashMap<>(); + + for (HabboItem i : this.room.getFloorItems()) { + if (!items.contains(i.getBaseItem())) { + items.put(i.getBaseItem(), 0); + } + + items.put(i.getBaseItem(), items.get(i.getBaseItem()) + 1); + } + + for (HabboItem i : this.room.getWallItems()) { + if (!items.contains(i.getBaseItem())) { + items.put(i.getBaseItem(), 0); + } + + items.put(i.getBaseItem(), items.get(i.getBaseItem()) + 1); + } + + if (!item[0].getExtradata().isEmpty()) { + items.put(Emulator.getGameEnvironment().getItemManager().getItem(Integer.valueOf(item[0].getExtradata())), 1); + } + + StringBuilder data = new StringBuilder(); + + for (Map.Entry set : items.entrySet()) { + data.append(set.getKey().getId()).append(":").append(set.getValue()).append(";"); + } + + item[0].setItemId(data.toString()); + item[0].loadBundle(); + } + + return super.getCatalogItems(); + } + + public void loadItems(Room room) { + if (this.room != null) { + this.room.preventUnloading = false; + } + + this.room = room; + this.room.preventUnloading = true; + this.getCatalogItems(); + this.loaded = true; + } + + public void buyRoom(Habbo habbo) { + this.buyRoom(habbo, habbo.getHabboInfo().getId(), habbo.getHabboInfo().getUsername()); + } + + public void buyRoom(Habbo habbo, int userId, String userName) { + if (!this.loaded) { + this.loadItems(Emulator.getGameEnvironment().getRoomManager().loadRoom(this.roomId)); + } + + if (habbo != null) { + int count = Emulator.getGameEnvironment().getRoomManager().getRoomsForHabbo(habbo).size(); + int max = habbo.getHabboStats().hasActiveClub() ? RoomManager.MAXIMUM_ROOMS_HC : RoomManager.MAXIMUM_ROOMS_USER; + + if (count >= max) { + habbo.getClient().sendResponse(new CanCreateRoomComposer(count, max)); + return; + } + } + + if (this.room == null) + return; + + this.room.save(); + + for (HabboItem item : this.room.getFloorItems()) { + item.run(); + } + + for (HabboItem item : this.room.getWallItems()) { + item.run(); + } + + this.getCatalogItems(); + int roomId = 0; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO rooms (owner_id, owner_name, name, description, model, password, state, users_max, category, paper_floor, paper_wall, paper_landscape, thickness_wall, thickness_floor, moodlight_data, override_model) (SELECT ?, ?, name, description, model, password, state, users_max, category, paper_floor, paper_wall, paper_landscape, thickness_wall, thickness_floor, moodlight_data, override_model FROM rooms WHERE id = ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, userId); + statement.setString(2, userName); + statement.setInt(3, this.room.getId()); + statement.execute(); + try (ResultSet set = statement.getGeneratedKeys()) { + if (set.next()) { + roomId = set.getInt(1); + } + } + } + + if (roomId == 0) + return; + + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO items (user_id, room_id, item_id, wall_pos, x, y, z, rot, extra_data, wired_data, limited_data, guild_id) (SELECT ?, ?, item_id, wall_pos, x, y, z, rot, extra_data, wired_data, ?, ? FROM items WHERE room_id = ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, userId); + statement.setInt(2, roomId); + statement.setString(3, "0:0"); + statement.setInt(4, 0); + statement.setInt(5, this.room.getId()); + statement.execute(); + } + + if (this.room.hasCustomLayout()) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO room_models_custom (id, name, door_x, door_y, door_dir, heightmap) (SELECT ?, ?, door_x, door_y, door_dir, heightmap FROM room_models_custom WHERE id = ? LIMIT 1)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, roomId); + statement.setString(2, "custom_" + roomId); + statement.setInt(3, this.room.getId()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + if (Emulator.getConfig().getBoolean("bundle.bots.enabled")) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO bots (user_id, room_id, name, motto, figure, gender, x, y, z, chat_lines, chat_auto, chat_random, chat_delay, dance, type) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + synchronized (this.room.getCurrentBots()) { + statement.setInt(1, userId); + statement.setInt(2, roomId); + for (Bot bot : this.room.getCurrentBots().valueCollection()) { + statement.setString(3, bot.getName()); + statement.setString(4, bot.getMotto()); + statement.setString(5, bot.getFigure()); + statement.setString(6, bot.getGender().name()); + statement.setInt(7, bot.getRoomUnit().getX()); + statement.setInt(8, bot.getRoomUnit().getY()); + statement.setDouble(9, bot.getRoomUnit().getZ()); + StringBuilder text = new StringBuilder(); + for (String s : bot.getChatLines()) { + text.append(s).append("\r"); + } + statement.setString(10, text.toString()); + statement.setString(11, bot.isChatAuto() ? "1" : "0"); + statement.setString(12, bot.isChatRandom() ? "1" : "0"); + statement.setInt(13, bot.getChatDelay()); + statement.setInt(14, bot.getRoomUnit().getDanceType().getType()); + statement.setString(15, bot.getType()); + statement.addBatch(); + } + } + statement.executeBatch(); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + Room r = Emulator.getGameEnvironment().getRoomManager().loadRoom(roomId); + r.setWallHeight(this.room.getWallHeight()); + r.setFloorSize(this.room.getFloorSize()); + r.setWallPaint(this.room.getWallPaint()); + r.setFloorPaint(this.room.getFloorPaint()); + r.setScore(0); + r.setNeedsUpdate(true); + THashMap keys = new THashMap<>(); + keys.put("ROOMNAME", r.getName()); + keys.put("ROOMID", r.getId() + ""); + keys.put("OWNER", r.getOwnerName()); + keys.put("image", "${image.library.url}/notifications/room_bundle_" + this.getId() + ".png"); + + if (habbo != null) { + habbo.getClient().sendResponse(new BubbleAlertComposer(BubbleAlertKeys.PURCHASING_ROOM.key, keys)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/SingleBundle.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/SingleBundle.java new file mode 100644 index 0000000..db6bddd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/SingleBundle.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class SingleBundle extends CatalogPage { + public SingleBundle(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("single_bundle"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(""); + message.appendInt(4); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + message.appendString(super.getTextTwo()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/SoldLTDItemsLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/SoldLTDItemsLayout.java new file mode 100644 index 0000000..4a68b0a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/SoldLTDItemsLayout.java @@ -0,0 +1,23 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class SoldLTDItemsLayout extends CatalogPage { + public SoldLTDItemsLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("sold_ltd_items"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(0); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/SpacesLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/SpacesLayout.java new file mode 100644 index 0000000..752673d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/SpacesLayout.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class SpacesLayout extends CatalogPage { + + public SpacesLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("spaces_new"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/TraxLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/TraxLayout.java new file mode 100644 index 0000000..f14d950 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/TraxLayout.java @@ -0,0 +1,24 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class TraxLayout extends CatalogPage { + public TraxLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("soundmachine"); + message.appendInt(2); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendInt(2); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/TrophiesLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/TrophiesLayout.java new file mode 100644 index 0000000..4823491 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/TrophiesLayout.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class TrophiesLayout extends CatalogPage { + + public TrophiesLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("trophies"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/VipBuyLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/VipBuyLayout.java new file mode 100644 index 0000000..ce96341 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/VipBuyLayout.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.catalog.layouts; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class VipBuyLayout extends CatalogPage { + public VipBuyLayout(ResultSet set) throws SQLException { + super(set); + } + + @Override + public void serialize(ServerMessage message) { + message.appendString("vip_buy"); + message.appendInt(3); + message.appendString(super.getHeaderImage()); + message.appendString(super.getTeaserImage()); + message.appendString(super.getSpecialImage()); + message.appendInt(3); + message.appendString(super.getTextOne()); + message.appendString(super.getTextDetails()); + message.appendString(super.getTextTeaser()); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlace.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlace.java new file mode 100644 index 0000000..610f038 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlace.java @@ -0,0 +1,400 @@ +package com.eu.habbo.habbohotel.catalog.marketplace; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.catalog.marketplace.RequestOffersEvent; +import com.eu.habbo.messages.outgoing.catalog.marketplace.MarketplaceBuyErrorComposer; +import com.eu.habbo.messages.outgoing.catalog.marketplace.MarketplaceCancelSaleComposer; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.inventory.RemoveHabboItemComposer; +import com.eu.habbo.messages.outgoing.users.UserCreditsComposer; +import com.eu.habbo.plugin.events.marketplace.MarketPlaceItemCancelledEvent; +import com.eu.habbo.plugin.events.marketplace.MarketPlaceItemOfferedEvent; +import com.eu.habbo.plugin.events.marketplace.MarketPlaceItemSoldEvent; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + + +@Slf4j +public class MarketPlace { + //Configuration. Loaded from database & updated accordingly. + public static boolean MARKETPLACE_ENABLED = true; + + //Currency to use. + public static int MARKETPLACE_CURRENCY = 0; + + + public static THashSet getOwnOffers(Habbo habbo) { + THashSet offers = new THashSet<>(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT items_base.type AS type, items.item_id AS base_item_id, items.limited_data AS ltd_data, marketplace_items.* FROM marketplace_items INNER JOIN items ON marketplace_items.item_id = items.id INNER JOIN items_base ON items.item_id = items_base.id WHERE marketplace_items.user_id = ?")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + offers.add(new MarketPlaceOffer(set, true)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return offers; + } + + + public static void takeBackItem(Habbo habbo, int offerId) { + MarketPlaceOffer offer = habbo.getInventory().getOffer(offerId); + + if (!Emulator.getPluginManager().fireEvent(new MarketPlaceItemCancelledEvent(offer)).isCancelled()) { + takeBackItem(habbo, offer); + } + } + + + private static void takeBackItem(Habbo habbo, MarketPlaceOffer offer) { + if (offer != null && habbo.getInventory().getMarketplaceItems().contains(offer)) { + RequestOffersEvent.cachedResults.clear(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement ownerCheck = connection.prepareStatement("SELECT user_id FROM marketplace_items WHERE id = ?", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) { + ownerCheck.setInt(1, offer.getOfferId()); + try (ResultSet ownerSet = ownerCheck.executeQuery()) { + ownerSet.last(); + + if (ownerSet.getRow() == 0) { + return; + } + + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM marketplace_items WHERE id = ? AND state != 2")) { + statement.setInt(1, offer.getOfferId()); + int count = statement.executeUpdate(); + + if (count != 0) { + habbo.getInventory().removeMarketplaceOffer(offer); + try (PreparedStatement updateItems = connection.prepareStatement("UPDATE items SET user_id = ? WHERE id = ? LIMIT 1")) { + updateItems.setInt(1, habbo.getHabboInfo().getId()); + updateItems.setInt(2, offer.getSoldItemId()); + updateItems.execute(); + + try (PreparedStatement selectItem = connection.prepareStatement("SELECT * FROM items WHERE id = ? LIMIT 1")) { + selectItem.setInt(1, offer.getSoldItemId()); + try (ResultSet set = selectItem.executeQuery()) { + while (set.next()) { + HabboItem item = Emulator.getGameEnvironment().getItemManager().loadHabboItem(set); + habbo.getInventory().getItemsComponent().addItem(item); + habbo.getClient().sendResponse(new MarketplaceCancelSaleComposer(offer, true)); + habbo.getClient().sendResponse(new AddHabboItemComposer(item)); + habbo.getClient().sendResponse(new InventoryRefreshComposer()); + } + } + } + } + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + habbo.getClient().sendResponse(new MarketplaceCancelSaleComposer(offer, false)); + } + } + } + + + public static List getOffers(int minPrice, int maxPrice, String search, int sort) { + List offers = new ArrayList<>(10); + String query = "SELECT B.* FROM marketplace_items a INNER JOIN (SELECT b.item_id AS base_item_id, b.limited_data AS ltd_data, marketplace_items.*, AVG(price) as avg, MIN(marketplace_items.price) as minPrice, MAX(marketplace_items.price) as maxPrice, COUNT(*) as number, (SELECT COUNT(*) FROM marketplace_items c INNER JOIN items as items_b ON c.item_id = items_b.id WHERE state = 2 AND items_b.item_id = base_item_id AND DATE(from_unixtime(sold_timestamp)) = CURDATE()) as sold_count_today FROM marketplace_items INNER JOIN items b ON marketplace_items.item_id = b.id INNER JOIN items_base bi ON b.item_id = bi.id INNER JOIN catalog_items ci ON bi.id = ci.item_ids WHERE price = (SELECT MIN(e.price) FROM marketplace_items e, items d WHERE e.item_id = d.id AND d.item_id = b.item_id AND e.state = 1 AND e.timestamp > ? GROUP BY d.item_id) AND state = 1 AND timestamp > ?"; + if (minPrice > 0) { + query += " AND CEIL(price + (price / 100)) >= " + minPrice; + } + if (maxPrice > 0 && maxPrice > minPrice) { + query += " AND CEIL(price + (price / 100)) <= " + maxPrice; + } + if (search.length() > 0) { + query += " AND ( bi.public_name LIKE ? OR ci.catalog_name LIKE ? ) "; + } + + query += " GROUP BY base_item_id, ltd_data"; + + switch (sort) { + case 6: + query += " ORDER BY number ASC"; + break; + case 5: + query += " ORDER BY number DESC"; + break; + case 4: + query += " ORDER BY sold_count_today ASC"; + break; + case 3: + query += " ORDER BY sold_count_today DESC"; + break; + case 2: + query += " ORDER BY minPrice ASC"; + break; + default: + case 1: + query += " ORDER BY minPrice DESC"; + break; + } + + query += ")"; + + query += " AS B ON a.id = B.id"; + + query += " LIMIT 250"; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement(query)) { + statement.setInt(1, Emulator.getIntUnixTimestamp() - 172800); + statement.setInt(2, Emulator.getIntUnixTimestamp() - 172800); + if (search.length() > 0) { + statement.setString(3, "%" + search + "%"); + statement.setString(4, "%" + search + "%"); + } + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + offers.add(new MarketPlaceOffer(set, false)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return offers; + } + + + public static void serializeItemInfo(int itemId, ServerMessage message) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT avg(marketplace_items.price) as price, COUNT(*) as sold, (datediff(NOW(), DATE(from_unixtime(marketplace_items.timestamp)))) as day FROM marketplace_items INNER JOIN items ON items.id = marketplace_items.item_id INNER JOIN items_base ON items.item_id = items_base.id WHERE items.limited_data = '0:0' AND marketplace_items.state = 2 AND items_base.sprite_id = ? AND DATE(from_unixtime(marketplace_items.timestamp)) >= NOW() - INTERVAL 30 DAY GROUP BY DATE(from_unixtime(marketplace_items.timestamp))", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) { + statement.setInt(1, itemId); + + message.appendInt(avarageLastXDays(itemId, 7)); + message.appendInt(itemsOnSale(itemId)); + message.appendInt(30); + + try (ResultSet set = statement.executeQuery()) { + set.last(); + message.appendInt(set.getRow()); + set.beforeFirst(); + + while (set.next()) { + message.appendInt(-set.getInt("day")); + message.appendInt(MarketPlace.calculateCommision(set.getInt("price"))); + message.appendInt(set.getInt("sold")); + } + } + + message.appendInt(1); + message.appendInt(itemId); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + + public static int itemsOnSale(int baseItemId) { + int number = 0; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT COUNT(*) as number, AVG(price) as avg FROM marketplace_items INNER JOIN items ON marketplace_items.item_id = items.id INNER JOIN items_base ON items.item_id = items_base.id WHERE state = 1 AND timestamp >= ? AND items_base.sprite_id = ?", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) { + statement.setInt(1, Emulator.getIntUnixTimestamp() - 172800); + statement.setInt(2, baseItemId); + try (ResultSet set = statement.executeQuery()) { + set.first(); + number = set.getInt("number"); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return number; + } + + + private static int avarageLastXDays(int baseItemId, int days) { + int avg = 0; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT AVG(price) as avg FROM marketplace_items INNER JOIN items ON marketplace_items.item_id = items.id INNER JOIN items_base ON items.item_id = items_base.id WHERE state = 2 AND DATE(from_unixtime(timestamp)) >= NOW() - INTERVAL ? DAY AND items_base.sprite_id = ?", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) { + statement.setInt(1, days); + statement.setInt(2, baseItemId); + + try (ResultSet set = statement.executeQuery()) { + set.first(); + avg = set.getInt("avg"); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return calculateCommision(avg); + } + + + public static void buyItem(int offerId, GameClient client) { + RequestOffersEvent.cachedResults.clear(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM marketplace_items WHERE id = ? LIMIT 1")) { + statement.setInt(1, offerId); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + try (PreparedStatement itemStatement = connection.prepareStatement("SELECT * FROM items WHERE id = ? LIMIT 1", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) { + itemStatement.setInt(1, set.getInt("item_id")); + try (ResultSet itemSet = itemStatement.executeQuery()) { + itemSet.first(); + + if (itemSet.getRow() > 0) { + int price = MarketPlace.calculateCommision(set.getInt("price")); + if (set.getInt("state") != 1) { + sendErrorMessage(client, set.getInt("item_id"), offerId); + } else if ((MARKETPLACE_CURRENCY == 0 && price > client.getHabbo().getHabboInfo().getCredits()) || (MARKETPLACE_CURRENCY > 0 && price > client.getHabbo().getHabboInfo().getCurrencyAmount(MARKETPLACE_CURRENCY))) { + client.sendResponse(new MarketplaceBuyErrorComposer(MarketplaceBuyErrorComposer.NOT_ENOUGH_CREDITS, 0, offerId, price)); + } else { + try (PreparedStatement updateOffer = connection.prepareStatement("UPDATE marketplace_items SET state = 2, sold_timestamp = ? WHERE id = ?")) { + updateOffer.setInt(1, Emulator.getIntUnixTimestamp()); + updateOffer.setInt(2, offerId); + updateOffer.execute(); + } + Habbo habbo = Emulator.getGameServer().getGameClientManager().getHabbo(set.getInt("user_id")); + HabboItem item = Emulator.getGameEnvironment().getItemManager().loadHabboItem(itemSet); + + MarketPlaceItemSoldEvent event = new MarketPlaceItemSoldEvent(habbo, client.getHabbo(), item, set.getInt("price")); + if (Emulator.getPluginManager().fireEvent(event).isCancelled()) { + return; + } + event.price = calculateCommision(event.price); + + item.setUserId(client.getHabbo().getHabboInfo().getId()); + item.needsUpdate(true); + Emulator.getThreading().run(item); + + client.getHabbo().getInventory().getItemsComponent().addItem(item); + + if (MARKETPLACE_CURRENCY == 0) { + client.getHabbo().giveCredits(-event.price); + } else { + client.getHabbo().givePoints(MARKETPLACE_CURRENCY, -event.price); + } + + client.sendResponse(new AddHabboItemComposer(item)); + client.sendResponse(new InventoryRefreshComposer()); + client.sendResponse(new MarketplaceBuyErrorComposer(MarketplaceBuyErrorComposer.REFRESH, 0, offerId, price)); + + if (habbo != null) { + habbo.getInventory().getOffer(offerId).setState(MarketPlaceState.SOLD); + } + } + } + } + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + + public static void sendErrorMessage(GameClient client, int baseItemId, int offerId) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT marketplace_items.*, COUNT( * ) AS count\n" + + "FROM marketplace_items\n" + + "INNER JOIN items ON marketplace_items.item_id = items.id\n" + + "INNER JOIN items_base ON items.item_id = items_base.id\n" + + "WHERE items_base.sprite_id = ( \n" + + "SELECT items_base.sprite_id\n" + + "FROM items_base\n" + + "WHERE items_base.id = ? LIMIT 1)\n" + + "ORDER BY price ASC\n" + + "LIMIT 1", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) { + statement.setInt(1, baseItemId); + try (ResultSet countSet = statement.executeQuery()) { + countSet.last(); + if (countSet.getRow() == 0) + client.sendResponse(new MarketplaceBuyErrorComposer(MarketplaceBuyErrorComposer.SOLD_OUT, 0, offerId, 0)); + else { + countSet.first(); + client.sendResponse(new MarketplaceBuyErrorComposer(MarketplaceBuyErrorComposer.UPDATES, countSet.getInt("count"), countSet.getInt("id"), MarketPlace.calculateCommision(countSet.getInt("price")))); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + + public static boolean sellItem(GameClient client, HabboItem item, int price) { + if (item == null || client == null) + return false; + + if (!item.getBaseItem().allowMarketplace() || price < 0) + return false; + + MarketPlaceItemOfferedEvent event = new MarketPlaceItemOfferedEvent(client.getHabbo(), item, price); + if (Emulator.getPluginManager().fireEvent(event).isCancelled()) { + return false; + } + + RequestOffersEvent.cachedResults.clear(); + + client.sendResponse(new RemoveHabboItemComposer(event.item.getGiftAdjustedId())); + client.sendResponse(new InventoryRefreshComposer()); + + event.item.setFromGift(false); + + MarketPlaceOffer offer = new MarketPlaceOffer(event.item, event.price, client.getHabbo()); + client.getHabbo().getInventory().addMarketplaceOffer(offer); + client.getHabbo().getInventory().getItemsComponent().removeHabboItem(event.item); + item.setUserId(-1); + item.needsUpdate(true); + Emulator.getThreading().run(item); + + return true; + } + + + public static void getCredits(GameClient client) { + int credits = 0; + + THashSet offers = new THashSet<>(); + offers.addAll(client.getHabbo().getInventory().getMarketplaceItems()); + + for (MarketPlaceOffer offer : offers) { + if (offer.getState().equals(MarketPlaceState.SOLD)) { + client.getHabbo().getInventory().removeMarketplaceOffer(offer); + credits += offer.getPrice(); + removeUser(offer); + offer.needsUpdate(true); + Emulator.getThreading().run(offer); + } + } + + offers.clear(); + + if (MARKETPLACE_CURRENCY == 0) { + client.getHabbo().giveCredits(credits); + } else { + client.getHabbo().givePoints(MARKETPLACE_CURRENCY, credits); + } + } + + private static void removeUser(MarketPlaceOffer offer) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE marketplace_items SET user_id = ? WHERE id = ?")) { + statement.setInt(1, -1); + statement.setInt(2, offer.getOfferId()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + + public static int calculateCommision(int price) { + return price + (int) Math.ceil(price / 100.0); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlaceOffer.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlaceOffer.java new file mode 100644 index 0000000..d242648 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlaceOffer.java @@ -0,0 +1,168 @@ +package com.eu.habbo.habbohotel.catalog.marketplace; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.FurnitureType; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import lombok.extern.slf4j.Slf4j; +import java.sql.*; + +@Slf4j +public class MarketPlaceOffer implements Runnable { + public int avarage; + public int count; + private int offerId; + private Item baseItem; + private int itemId; + private int price; + private int limitedStack; + private int limitedNumber; + private int timestamp = Emulator.getIntUnixTimestamp(); + private int soldTimestamp = 0; + private MarketPlaceState state = MarketPlaceState.OPEN; + private boolean needsUpdate = false; + + public MarketPlaceOffer(ResultSet set, boolean privateOffer) throws SQLException { + this.offerId = set.getInt("id"); + this.price = set.getInt("price"); + this.timestamp = set.getInt("timestamp"); + this.soldTimestamp = set.getInt("sold_timestamp"); + this.baseItem = Emulator.getGameEnvironment().getItemManager().getItem(set.getInt("base_item_id")); + this.state = MarketPlaceState.getType(set.getInt("state")); + this.itemId = set.getInt("item_id"); + + if (!set.getString("ltd_data").split(":")[1].equals("0")) { + this.limitedStack = Integer.valueOf(set.getString("ltd_data").split(":")[0]); + this.limitedNumber = Integer.valueOf(set.getString("ltd_data").split(":")[1]); + } + + if (!privateOffer) { + this.avarage = set.getInt("avg"); + this.count = set.getInt("number"); + this.price = set.getInt("minPrice"); + } + } + + public MarketPlaceOffer(HabboItem item, int price, Habbo habbo) { + this.price = price; + this.baseItem = item.getBaseItem(); + this.itemId = item.getId(); + if (item.getLimitedSells() > 0) { + this.limitedNumber = item.getLimitedSells(); + this.limitedStack = item.getLimitedStack(); + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO marketplace_items (item_id, user_id, price, timestamp, state) VALUES (?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, item.getId()); + statement.setInt(2, habbo.getHabboInfo().getId()); + statement.setInt(3, this.price); + statement.setInt(4, this.timestamp); + statement.setString(5, this.state.getState() + ""); + statement.execute(); + + try (ResultSet id = statement.getGeneratedKeys()) { + while (id.next()) { + this.offerId = id.getInt(1); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public static void insert(MarketPlaceOffer offer, Habbo habbo) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO marketplace_items VALUES (?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, offer.getItemId()); + statement.setInt(2, habbo.getHabboInfo().getId()); + statement.setInt(3, offer.getPrice()); + statement.setInt(4, offer.getTimestamp()); + statement.setInt(5, offer.getSoldTimestamp()); + statement.setString(6, offer.getState().getState() + ""); + statement.execute(); + + try (ResultSet id = statement.getGeneratedKeys()) { + while (id.next()) { + offer.setOfferId(id.getInt(1)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public int getOfferId() { + return this.offerId; + } + + public void setOfferId(int offerId) { + this.offerId = offerId; + } + + public int getItemId() { + return this.baseItem.getSpriteId(); + } + + public int getPrice() { + return this.price; + } + + public MarketPlaceState getState() { + return this.state; + } + + public void setState(MarketPlaceState state) { + this.state = state; + } + + public int getTimestamp() { + return this.timestamp; + } + + public int getSoldTimestamp() { + return this.soldTimestamp; + } + + public void setSoldTimestamp(int soldTimestamp) { + this.soldTimestamp = soldTimestamp; + } + + public int getLimitedStack() { + return this.limitedStack; + } + + public int getLimitedNumber() { + return this.limitedNumber; + } + + public int getSoldItemId() { + return this.itemId; + } + + public void needsUpdate(boolean value) { + this.needsUpdate = value; + } + + public int getType() { + if (this.limitedStack > 0) { + return 3; + } + + return this.baseItem.getType().equals(FurnitureType.WALL) ? 2 : 1; + } + + @Override + public void run() { + if (this.needsUpdate) { + this.needsUpdate = false; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE marketplace_items SET state = ?, sold_timestamp = ? WHERE id = ?")) { + statement.setInt(1, this.state.getState()); + statement.setInt(2, this.soldTimestamp); + statement.setInt(3, this.offerId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlaceState.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlaceState.java new file mode 100644 index 0000000..3cd7386 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlaceState.java @@ -0,0 +1,36 @@ +package com.eu.habbo.habbohotel.catalog.marketplace; + +public enum MarketPlaceState { + + OPEN(1), + + + SOLD(2), + + + CLOSED(3); + + private final int state; + + MarketPlaceState(int state) { + this.state = state; + } + + public static MarketPlaceState getType(int type) { + switch (type) { + case 1: + return OPEN; + case 2: + return SOLD; + case 3: + return CLOSED; + } + + return CLOSED; + } + + public int getState() { + return this.state; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/AboutCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/AboutCommand.java new file mode 100644 index 0000000..b3a111a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/AboutCommand.java @@ -0,0 +1,55 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.CatalogManager; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.eu.habbo.messages.outgoing.generic.alerts.MessagesForYouComposer; + +import java.util.Collections; +import java.util.concurrent.TimeUnit; + + +public class AboutCommand extends Command { + public AboutCommand() { + super(null, new String[]{"about", "info", "online", "server"}); + } + public static String credits = "Arcturus Morningstar is an opensource project based on Arcturus By TheGeneral \n" + + "The Following people have all contributed to this emulator:\n" + + " TheGeneral\n Beny\n Alejandro\n Capheus\n Skeletor\n Harmonic\n Mike\n Remco\n zGrav \n Quadral \n Harmony\n Swirny\n ArpyAge\n Mikkel\n Rodolfo\n Rasmus\n Kitt Mustang\n Snaiker\n nttzx\n necmi\n Dome\n Jose Flores\n Cam\n Oliver\n Narzo\n Tenshie\n MartenM\n Ridge\n SenpaiDipper\n Snaiker\n Thijmen"; + @Override + public boolean handle(GameClient gameClient, String[] params) { + + Emulator.getRuntime().gc(); + + int seconds = Emulator.getIntUnixTimestamp() - Emulator.getTimeStarted(); + int day = (int) TimeUnit.SECONDS.toDays(seconds); + long hours = TimeUnit.SECONDS.toHours(seconds) - (day * 24); + long minute = TimeUnit.SECONDS.toMinutes(seconds) - (TimeUnit.SECONDS.toHours(seconds) * 60); + long second = TimeUnit.SECONDS.toSeconds(seconds) - (TimeUnit.SECONDS.toMinutes(seconds) * 60); + + String message = "" + Emulator.version + "\r\n"; + + if (Emulator.getConfig().getBoolean("info.shown", true)) { + message += "Hotel Statistics\r" + + "- Online Users: " + Emulator.getGameEnvironment().getHabboManager().getOnlineCount() + "\r" + + "- Active Rooms: " + Emulator.getGameEnvironment().getRoomManager().getActiveRooms().size() + "\r" + + "- Shop: " + Emulator.getGameEnvironment().getCatalogManager().catalogPages.size() + " pages and " + CatalogManager.catalogItemAmount + " items. \r" + + "- Furni: " + Emulator.getGameEnvironment().getItemManager().getItems().size() + " item definitions" + "\r" + + "\n" + + "Server Statistics\r" + + "- Uptime: " + day + (day > 1 ? " days, " : " day, ") + hours + (hours > 1 ? " hours, " : " hour, ") + minute + (minute > 1 ? " minutes, " : " minute, ") + second + (second > 1 ? " seconds!" : " second!") + "\r" + + "- RAM Usage: " + (Emulator.getRuntime().totalMemory() - Emulator.getRuntime().freeMemory()) / (1024 * 1024) + "/" + (Emulator.getRuntime().freeMemory()) / (1024 * 1024) + "MB\r" + + "- CPU Cores: " + Emulator.getRuntime().availableProcessors() + "\r" + + "- Total Memory: " + Emulator.getRuntime().maxMemory() / (1024 * 1024) + "MB" + "\r\n"; + } + + message += "\r" + + + "Thanks for using Arcturus. Report issues on the forums. http://arcturus.wf \r\r" + + " - The General"; + gameClient.getHabbo().alert(message); + gameClient.sendResponse(new MessagesForYouComposer(Collections.singletonList(credits))); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/AddYoutubePlaylistCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/AddYoutubePlaylistCommand.java new file mode 100644 index 0000000..cf58ac5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/AddYoutubePlaylistCommand.java @@ -0,0 +1,62 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.YoutubeManager; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class AddYoutubePlaylistCommand extends Command { + + public AddYoutubePlaylistCommand() { + super("cmd_add_youtube_playlist", Emulator.getTexts().getValue("commands.keys.cmd_add_youtube_playlist").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length < 3) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_add_youtube_playlist.usage")); + return true; + } + + int itemId; + + try { + itemId = Integer.parseInt(params[1]); + } catch (NumberFormatException e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_add_youtube_playlist.no_base_item")); + return true; + } + + if (Emulator.getGameEnvironment().getItemManager().getItem(itemId) == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_add_youtube_playlist.no_base_item")); + return true; + } + + YoutubeManager.YoutubePlaylist playlist = Emulator.getGameEnvironment().getItemManager().getYoutubeManager().getPlaylistDataById(params[2]); + + if (playlist == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_add_youtube_playlist.failed_playlist")); + return true; + } + + Emulator.getGameEnvironment().getItemManager().getYoutubeManager().addPlaylistToItem(itemId, playlist); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO `youtube_playlists` (`item_id`, `playlist_id`) VALUES (?, ?)")) { + statement.setInt(1, itemId); + statement.setString(2, params[2]); + + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_add_youtube_playlist")); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/AlertCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/AlertCommand.java new file mode 100644 index 0000000..17c2042 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/AlertCommand.java @@ -0,0 +1,42 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +public class AlertCommand extends Command { + + public AlertCommand() { + super("cmd_alert", Emulator.getTexts().getValue("commands.keys.cmd_alert").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) { + if (params.length < 2) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_alert.forgot_username"), RoomChatMessageBubbles.ALERT); + return true; + } + if (params.length < 3) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_alert.forgot_message"), RoomChatMessageBubbles.ALERT); + return true; + } + + String targetUsername = params[1]; + StringBuilder message = new StringBuilder(); + + for (int i = 2; i < params.length; i++) { + message.append(params[i]).append(" "); + } + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(targetUsername); + + if (habbo != null) { + habbo.alert(message + "\r\n -" + gameClient.getHabbo().getHabboInfo().getUsername()); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_alert.message_send").replace("%user%", targetUsername), RoomChatMessageBubbles.ALERT); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_alert.user_offline").replace("%user%", targetUsername), RoomChatMessageBubbles.ALERT); + } + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/AllowTradingCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/AllowTradingCommand.java new file mode 100644 index 0000000..649d513 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/AllowTradingCommand.java @@ -0,0 +1,69 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.users.UserPerksComposer; + +import java.sql.Connection; +import java.sql.PreparedStatement; + +public class AllowTradingCommand extends Command { + public AllowTradingCommand() { + super("cmd_allow_trading", Emulator.getTexts().getValue("commands.keys.cmd_allow_trading").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 1) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_allow_trading.forgot_username")); + return true; + } + + if (params.length == 2) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_allow_trading.forgot_trade").replace("%username%", params[1])); + return true; + } + + final String username = params[1]; + final String option = params[2]; + + if (option.equalsIgnoreCase(Emulator.getTexts().getValue("generic.yes")) || option.equalsIgnoreCase(Emulator.getTexts().getValue("generic.no"))) { + final boolean enabled = option.equalsIgnoreCase(Emulator.getTexts().getValue("generic.yes")); + final Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(username); + + if (habbo != null) { + if (!enabled) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("UPDATE users_settings SET tradelock_amount = tradelock_amount + 1 WHERE user_id = ?")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + statement.executeUpdate(); + } + } + habbo.getHabboStats().setAllowTrade(enabled); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_allow_trading." + (enabled ? "enabled" : "disabled")).replace("%username%", params[1])); + habbo.getClient().sendResponse(new UserPerksComposer(habbo)); + return true; + } else { + boolean found; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("UPDATE users_settings INNER JOIN users ON users.id = users_settings.user_id SET can_trade = ?, tradelock_amount = tradelock_amount + ? WHERE users.username LIKE ?")) { + statement.setString(1, enabled ? "1" : "0"); + statement.setInt(2, enabled ? 0 : 1); + statement.setString(3, username); + found = statement.executeUpdate() > 0; + } + + if (!found) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_allow_trading.user_not_found").replace("%username%", params[1])); + return true; + } + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_allow_trading." + (enabled ? "enabled" : "disabled")).replace("%username%", params[1])); + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_allow_trading.incorrect_setting").replace("%enabled%", Emulator.getTexts().getValue("generic.yes")).replace("%disabled%", Emulator.getTexts().getValue("generic.no"))); + } + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ArcturusCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ArcturusCommand.java new file mode 100644 index 0000000..d3a786c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ArcturusCommand.java @@ -0,0 +1,25 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class ArcturusCommand extends Command { + public ArcturusCommand() { + super(null, new String[]{"arcturus", "emulator"}); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + gameClient.getHabbo().whisper("This hotel is powered by Arcturus Emulator! \r" + + "Cet hôtel est alimenté par Arcturus émulateur! \r" + + "Dit hotel draait op Arcturus Emulator! \r" + + "Este hotel está propulsado por Arcturus emulador! \r" + + "Hotellet drivs av Arcturus Emulator! \r" + + "Das Hotel gehört zu Arcturus Emulator betrieben!" + , RoomChatMessageBubbles.ALERT); + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/BadgeCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/BadgeCommand.java new file mode 100644 index 0000000..e5a25e8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/BadgeCommand.java @@ -0,0 +1,85 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboManager; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class BadgeCommand extends Command { + + public BadgeCommand() { + super("cmd_badge", Emulator.getTexts().getValue("commands.keys.cmd_badge").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 1) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_badge.forgot_username"), RoomChatMessageBubbles.ALERT); + return true; + } + if (params.length == 2) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_badge.forgot_badge").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + + if (params.length == 3) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(params[1]); + + if (habbo != null) { + if (habbo.addBadge(params[2])) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_badge.given").replace("%user%", params[1]).replace("%badge%", params[2]), RoomChatMessageBubbles.ALERT); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_badge.already_owned").replace("%user%", params[1]).replace("%badge%", params[2]), RoomChatMessageBubbles.ALERT); + } + + return true; + } else { + HabboInfo habboInfo = HabboManager.getOfflineHabboInfo(params[1]); + + if (habboInfo == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_badge.unknown_user"), RoomChatMessageBubbles.ALERT); + return true; + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + boolean found; + + try (PreparedStatement statement = connection.prepareStatement("SELECT `badge_code` FROM `users_badges` WHERE `user_id` = ? AND `badge_code` = ? LIMIT 1")) { + statement.setInt(1, habboInfo.getId()); + statement.setString(2, params[2]); + try (ResultSet set = statement.executeQuery()) { + found = set.next(); + } + } + + if (found) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_badge.already_owns").replace("%user%", params[1]).replace("%badge%", params[2]), RoomChatMessageBubbles.ALERT); + return true; + } else { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO users_badges (`id`, `user_id`, `slot_id`, `badge_code`) VALUES (null, ?, 0, ?)")) { + statement.setInt(1, habboInfo.getId()); + statement.setString(2, params[2]); + statement.execute(); + } + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_badge.given").replace("%user%", params[1]).replace("%badge%", params[2]), RoomChatMessageBubbles.ALERT); + return true; + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/BanCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/BanCommand.java new file mode 100644 index 0000000..b9946ff --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/BanCommand.java @@ -0,0 +1,80 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.modtool.ModToolBan; +import com.eu.habbo.habbohotel.modtool.ModToolBanType; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboManager; + +public class BanCommand extends Command { + public BanCommand() { + super("cmd_ban", Emulator.getTexts().getValue("commands.keys.cmd_ban").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length < 2) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.forgot_user"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (params.length < 3) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.forgot_time"), RoomChatMessageBubbles.ALERT); + return true; + } + + int banTime; + try { + banTime = Integer.valueOf(params[2]); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.invalid_time"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (banTime < 600) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.time_to_short"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (params[1].toLowerCase().equals(gameClient.getHabbo().getHabboInfo().getUsername().toLowerCase())) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.ban_self"), RoomChatMessageBubbles.ALERT); + return true; + } + + Habbo t = Emulator.getGameEnvironment().getHabboManager().getHabbo(params[1]); + + HabboInfo target; + if (t != null) { + target = t.getHabboInfo(); + } else { + target = HabboManager.getOfflineHabboInfo(params[1]); + } + + if (target == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.user_offline"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (target.getRank().getId() >= gameClient.getHabbo().getHabboInfo().getRank().getId()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT); + return true; + } + + + StringBuilder reason = new StringBuilder(); + + if (params.length > 3) { + for (int i = 3; i < params.length; i++) { + reason.append(params[i]).append(" "); + } + } + + ModToolBan ban = Emulator.getGameEnvironment().getModToolManager().ban(target.getId(), gameClient.getHabbo(), reason.toString(), banTime, ModToolBanType.ACCOUNT, -1).get(0); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_ban.ban_issued").replace("%user%", target.getUsername()).replace("%time%", ban.expireDate - Emulator.getIntUnixTimestamp() + "").replace("%reason%", ban.reason), RoomChatMessageBubbles.ALERT); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/BlockAlertCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/BlockAlertCommand.java new file mode 100644 index 0000000..b2fc711 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/BlockAlertCommand.java @@ -0,0 +1,23 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class BlockAlertCommand extends Command { + public BlockAlertCommand() { + super("cmd_blockalert", Emulator.getTexts().getValue("commands.keys.cmd_blockalert").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + gameClient.getHabbo().getHabboStats().blockStaffAlerts = !gameClient.getHabbo().getHabboStats().blockStaffAlerts; + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_blockalert").replace("%state%", (gameClient.getHabbo().getHabboStats().blockStaffAlerts ? Emulator.getTexts().getValue("generic.on") : Emulator.getTexts().getValue("generic.off"))), RoomChatMessageBubbles.ALERT); + + return true; + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/BotsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/BotsCommand.java new file mode 100644 index 0000000..10650e1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/BotsCommand.java @@ -0,0 +1,30 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.gameclients.GameClient; + +public class BotsCommand extends Command { + public BotsCommand() { + super("cmd_bots", Emulator.getTexts().getValue("commands.keys.cmd_bots").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() == null || !gameClient.getHabbo().getHabboInfo().getCurrentRoom().hasRights(gameClient.getHabbo())) + return false; + + StringBuilder data = new StringBuilder(Emulator.getTexts().getValue("total") + ": " + gameClient.getHabbo().getHabboInfo().getCurrentRoom().getCurrentBots().values().length); + + for (Object bot : gameClient.getHabbo().getHabboInfo().getCurrentRoom().getCurrentBots().values()) { + if (bot instanceof Bot) { + data.append("\r"); + data.append("").append(Emulator.getTexts().getValue("generic.bot.name")).append(": ").append(((Bot) bot).getName()).append(" ").append(Emulator.getTexts().getValue("generic.bot.id")).append(": ").append(((Bot) bot).getId()); + } + } + + gameClient.getHabbo().alert(data.toString()); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CalendarCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CalendarCommand.java new file mode 100644 index 0000000..dd2a773 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CalendarCommand.java @@ -0,0 +1,38 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarCampaign; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.messages.outgoing.events.calendar.AdventCalendarDataComposer; +import com.eu.habbo.messages.outgoing.habboway.nux.NuxAlertComposer; + +import java.sql.Timestamp; +import java.time.Duration; +import java.util.Date; + +import static java.time.temporal.ChronoUnit.DAYS; + +public class CalendarCommand extends Command { + public CalendarCommand() { + super("cmd_calendar", Emulator.getTexts().getValue("commands.keys.cmd_calendar").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (Emulator.getConfig().getBoolean("hotel.calendar.enabled")) { + String campaignName = Emulator.getConfig().getValue("hotel.calendar.default"); + + if(params.length > 1 && gameClient.getHabbo().hasPermission("cmd_calendar_staff")) { + campaignName = params[1]; + } + CalendarCampaign campaign = Emulator.getGameEnvironment().getCalendarManager().getCalendarCampaign(campaignName); + if(campaign == null) return false; + int daysBetween = (int) DAYS.between(new Timestamp(campaign.getStartTimestamp() * 1000L).toInstant(), new Date().toInstant()); + if(daysBetween >= 0) { + gameClient.sendResponse(new AdventCalendarDataComposer(campaign.getName(), campaign.getImage(), campaign.getTotalDays(), daysBetween, gameClient.getHabbo().getHabboStats().calendarRewardsClaimed, campaign.getLockExpired())); + } + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ChangeNameCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ChangeNameCommand.java new file mode 100644 index 0000000..0fa9bbc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ChangeNameCommand.java @@ -0,0 +1,18 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.messages.outgoing.users.UserDataComposer; + +public class ChangeNameCommand extends Command { + public ChangeNameCommand() { + super("cmd_changename", Emulator.getTexts().getValue("commands.keys.cmd_changename").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + gameClient.getHabbo().getHabboStats().allowNameChange = !gameClient.getHabbo().getHabboStats().allowNameChange; + gameClient.sendResponse(new UserDataComposer(gameClient.getHabbo())); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ChatTypeCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ChatTypeCommand.java new file mode 100644 index 0000000..6afc6dc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ChatTypeCommand.java @@ -0,0 +1,54 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.messages.outgoing.users.MeMenuSettingsComposer; + +public class ChatTypeCommand extends Command { + public ChatTypeCommand() { + super("cmd_chatcolor", Emulator.getTexts().getValue("commands.keys.cmd_chatcolor").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + + if (params.length >= 2) { + int chatColor; + try { + chatColor = Integer.valueOf(params[1]); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_chatcolor.numbers"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (RoomChatMessageBubbles.values().length < chatColor) { + chatColor = 0; + } + + if (chatColor < 0) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_chatcolor.numbers"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (!gameClient.getHabbo().hasPermission(Permission.ACC_ANYCHATCOLOR)) { + for (String s : Emulator.getConfig().getValue("commands.cmd_chatcolor.banned_numbers").split(";")) { + if (Integer.valueOf(s) == chatColor) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_chatcolor.banned"), RoomChatMessageBubbles.ALERT); + return true; + } + } + } + + gameClient.getHabbo().getHabboStats().chatColor = RoomChatMessageBubbles.getBubble(chatColor); + gameClient.sendResponse(new MeMenuSettingsComposer(gameClient.getHabbo())); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_chatcolor.set").replace("%chat%", RoomChatMessageBubbles.values()[chatColor].name().replace("_", " ").toLowerCase()), RoomChatMessageBubbles.ALERT); + return true; + } else { + gameClient.getHabbo().getHabboStats().chatColor = RoomChatMessageBubbles.NORMAL; + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_chatcolor.reset"), RoomChatMessageBubbles.ALERT); + return true; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/Command.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/Command.java new file mode 100644 index 0000000..6c71c7a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/Command.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.habbohotel.gameclients.GameClient; + +public abstract class Command { + + public final String permission; + + + public final String[] keys; + + public Command(String permission, String[] keys) { + this.permission = permission; + this.keys = keys; + } + + + public abstract boolean handle(GameClient gameClient, String[] params) throws Exception; +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CommandHandler.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CommandHandler.java new file mode 100644 index 0000000..90751de --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CommandHandler.java @@ -0,0 +1,311 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.core.CommandLog; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.permissions.PermissionSetting; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetCommand; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.pets.RideablePet; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomRightLevels; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserTypingComposer; +import com.eu.habbo.plugin.events.users.UserCommandEvent; +import com.eu.habbo.plugin.events.users.UserExecuteCommandEvent; +import gnu.trove.iterator.TIntObjectIterator; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.NoSuchElementException; + +@Slf4j +public class CommandHandler { + + private final static THashMap commands = new THashMap<>(5); + private static final Comparator ALPHABETICAL_ORDER = new Comparator() { + public int compare(Command c1, Command c2) { + int res = String.CASE_INSENSITIVE_ORDER.compare(c1.permission, c2.permission); + return (res != 0) ? res : c1.permission.compareTo(c2.permission); + } + }; + + public CommandHandler() { + long millis = System.currentTimeMillis(); + this.reloadCommands(); + log.info("Command Handler -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)"); + } + + public static void addCommand(Command command) { + if (command == null) + return; + + commands.put(command.getClass().getName(), command); + } + public static boolean handleCommand(GameClient gameClient, String commandLine) { + if (gameClient != null && commandLine != null) { + if (commandLine.startsWith(":")) { + commandLine = commandLine.replaceFirst(":", ""); + + String[] parts = commandLine.split(" "); + + if (parts.length >= 1) { + for (Command command : commands.values()) { + for (String s : command.keys) { + if (s.toLowerCase().equals(parts[0].toLowerCase())) { + boolean succes = false; + if (command.permission == null || gameClient.getHabbo().hasPermission(command.permission, gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null && (gameClient.getHabbo().getHabboInfo().getCurrentRoom().hasRights(gameClient.getHabbo())) || gameClient.getHabbo().hasPermission(Permission.ACC_PLACEFURNI) || (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null && gameClient.getHabbo().getHabboInfo().getCurrentRoom().getGuildId() > 0 && gameClient.getHabbo().getHabboInfo().getCurrentRoom().getGuildRightLevel(gameClient.getHabbo()).isEqualOrGreaterThan(RoomRightLevels.GUILD_RIGHTS)))) { + try { + UserExecuteCommandEvent userExecuteCommandEvent = new UserExecuteCommandEvent(gameClient.getHabbo(), command, parts); + Emulator.getPluginManager().fireEvent(userExecuteCommandEvent); + + if(userExecuteCommandEvent.isCancelled()) { + return userExecuteCommandEvent.isSuccess(); + } + + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) + gameClient.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserTypingComposer(gameClient.getHabbo().getRoomUnit(), false).compose()); + + UserCommandEvent event = new UserCommandEvent(gameClient.getHabbo(), parts, command.handle(gameClient, parts)); + Emulator.getPluginManager().fireEvent(event); + + succes = event.succes; + } catch (Exception e) { + log.error("Caught exception", e); + } + + if (gameClient.getHabbo().getHabboInfo().getRank().isLogCommands()) { + Emulator.getDatabaseLogger().store(new CommandLog(gameClient.getHabbo().getHabboInfo().getId(), command, commandLine, succes)); + } + } + + return succes; + } + } + } + } + } else { + String[] args = commandLine.split(" "); + + if (args.length <= 1) + return false; + + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + Room room = gameClient.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room.getCurrentPets().isEmpty()) + return false; + + TIntObjectIterator petIterator = room.getCurrentPets().iterator(); + + for (int j = room.getCurrentPets().size(); j-- > 0; ) { + try { + petIterator.advance(); + } catch (NoSuchElementException e) { + break; + } + + Pet pet = petIterator.value(); + + if (pet != null) { + if (pet.getName().equalsIgnoreCase(args[0])) { + StringBuilder s = new StringBuilder(); + + for (int i = 1; i < args.length; i++) { + s.append(args[i]).append(" "); + } + + s = new StringBuilder(s.substring(0, s.length() - 1)); + + for (PetCommand command : pet.getPetData().getPetCommands()) { + if (command.key.equalsIgnoreCase(s.toString())) { + if (pet instanceof RideablePet && ((RideablePet) pet).getRider() != null) { + if (((RideablePet) pet).getRider().getHabboInfo().getId() == gameClient.getHabbo().getHabboInfo().getId()) { + ((RideablePet) pet).getRider().getHabboInfo().dismountPet(); + } + break; + } + + if (command.level <= pet.getLevel()) + pet.handleCommand(command, gameClient.getHabbo(), args); + else + pet.say(pet.getPetData().randomVocal(PetVocalsType.UNKNOWN_COMMAND)); + + break; + } + } + } + } + } + } + } + } + return false; + } + + public static Command getCommand(String key) { + for (Command command : commands.values()) { + for (String k : command.keys) { + if (key.equalsIgnoreCase(k)) { + return command; + } + } + } + + return null; + } + + public void reloadCommands() { + addCommand(new AboutCommand()); + addCommand(new AlertCommand()); + addCommand(new AllowTradingCommand()); + addCommand(new ArcturusCommand()); + addCommand(new BadgeCommand()); + addCommand(new BanCommand()); + addCommand(new BlockAlertCommand()); + addCommand(new BotsCommand()); + addCommand(new CalendarCommand()); + addCommand(new ChangeNameCommand()); + addCommand(new ChatTypeCommand()); + addCommand(new CommandsCommand()); + addCommand(new ConnectCameraCommand()); + addCommand(new ControlCommand()); + addCommand(new CoordsCommand()); + addCommand(new CreditsCommand()); + addCommand(new DiagonalCommand()); + addCommand(new DisconnectCommand()); + addCommand(new EjectAllCommand()); + addCommand(new EmptyInventoryCommand()); + addCommand(new EmptyBotsInventoryCommand()); + addCommand(new EmptyPetsInventoryCommand()); + addCommand(new EnableCommand()); + addCommand(new EventCommand()); + addCommand(new FacelessCommand()); + addCommand(new FastwalkCommand()); + addCommand(new FilterWordCommand()); + addCommand(new FreezeBotsCommand()); + addCommand(new FreezeCommand()); + addCommand(new GiftCommand()); + addCommand(new GiveRankCommand()); + addCommand(new HabnamCommand()); + addCommand(new HandItemCommand()); + addCommand(new HappyHourCommand()); + addCommand(new HideWiredCommand()); + addCommand(new HotelAlertCommand()); + addCommand(new HotelAlertLinkCommand()); + addCommand(new InvisibleCommand()); + addCommand(new IPBanCommand()); + addCommand(new LayCommand()); + addCommand(new MachineBanCommand()); + addCommand(new MassBadgeCommand()); + addCommand(new RoomBadgeCommand()); + addCommand(new MassCreditsCommand()); + addCommand(new MassGiftCommand()); + addCommand(new MassPixelsCommand()); + addCommand(new MassPointsCommand()); + addCommand(new MimicCommand()); + addCommand(new MoonwalkCommand()); + addCommand(new MultiCommand()); + addCommand(new MuteBotsCommand()); + addCommand(new MuteCommand()); + addCommand(new MutePetsCommand()); + addCommand(new PetInfoCommand()); + addCommand(new PickallCommand()); + addCommand(new PixelCommand()); + addCommand(new PluginsCommand()); + addCommand(new PointsCommand()); + addCommand(new PromoteTargetOfferCommand()); + addCommand(new PullCommand()); + addCommand(new PushCommand()); + addCommand(new RedeemCommand()); + addCommand(new ReloadRoomCommand()); + addCommand(new RoomAlertCommand()); + addCommand(new RoomBundleCommand()); + addCommand(new RoomCreditsCommand()); + addCommand(new RoomDanceCommand()); + addCommand(new RoomEffectCommand()); + addCommand(new RoomItemCommand()); + addCommand(new RoomKickCommand()); + addCommand(new RoomMuteCommand()); + addCommand(new RoomPixelsCommand()); + addCommand(new RoomPointsCommand()); + addCommand(new SayAllCommand()); + addCommand(new SayCommand()); + addCommand(new SetMaxCommand()); + addCommand(new SetPollCommand()); + addCommand(new SetSpeedCommand()); + addCommand(new ShoutAllCommand()); + addCommand(new ShoutCommand()); + addCommand(new ShutdownCommand()); + addCommand(new SitCommand()); + addCommand(new StandCommand()); + addCommand(new SitDownCommand()); + addCommand(new StaffAlertCommand()); + addCommand(new StaffOnlineCommand()); + addCommand(new StalkCommand()); + addCommand(new SummonCommand()); + addCommand(new SummonRankCommand()); + addCommand(new SuperbanCommand()); + addCommand(new SuperPullCommand()); + addCommand(new TakeBadgeCommand()); + addCommand(new TeleportCommand()); + addCommand(new TransformCommand()); + addCommand(new TrashCommand()); + addCommand(new UnbanCommand()); + addCommand(new UnloadRoomCommand()); + addCommand(new UnmuteCommand()); + addCommand(new UpdateAchievements()); + addCommand(new UpdateBotsCommand()); + addCommand(new UpdateCalendarCommand()); + addCommand(new UpdateCatalogCommand()); + addCommand(new UpdateConfigCommand()); + addCommand(new UpdateGuildPartsCommand()); + addCommand(new UpdateHotelViewCommand()); + addCommand(new UpdateItemsCommand()); + addCommand(new UpdateNavigatorCommand()); + addCommand(new UpdatePermissionsCommand()); + addCommand(new UpdatePetDataCommand()); + addCommand(new UpdatePluginsCommand()); + addCommand(new UpdatePollsCommand()); + addCommand(new UpdateTextsCommand()); + addCommand(new UpdateWordFilterCommand()); + addCommand(new UserInfoCommand()); + addCommand(new WordQuizCommand()); + addCommand(new UpdateYoutubePlaylistsCommand()); + addCommand(new AddYoutubePlaylistCommand()); + addCommand(new SoftKickCommand()); + addCommand(new SubscriptionCommand()); + addCommand(new PingCommand()); + + addCommand(new TestCommand()); + } + + public List getCommandsForRank(int rankId) { + List allowedCommands = new ArrayList<>(); + if (Emulator.getGameEnvironment().getPermissionsManager().rankExists(rankId)) { + THashMap permissions = Emulator.getGameEnvironment().getPermissionsManager().getRank(rankId).getPermissions(); + + for (Command command : commands.values()) { + if (allowedCommands.contains(command)) + continue; + + if (permissions.contains(command.permission) && permissions.get(command.permission).setting != PermissionSetting.DISALLOWED) { + allowedCommands.add(command); + } + } + } + + allowedCommands.sort(CommandHandler.ALPHABETICAL_ORDER); + + return allowedCommands; + } + + public void dispose() { + commands.clear(); + log.info("Command Handler -> Disposed!"); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CommandsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CommandsCommand.java new file mode 100644 index 0000000..358f426 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CommandsCommand.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; + +import java.util.List; + +public class CommandsCommand extends Command { + public CommandsCommand() { + super("cmd_commands", Emulator.getTexts().getValue("commands.keys.cmd_commands").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + StringBuilder message = new StringBuilder(Emulator.getTexts().getValue("commands.generic.cmd_commands.text")); + List commands = Emulator.getGameEnvironment().getCommandHandler().getCommandsForRank(gameClient.getHabbo().getHabboInfo().getRank().getId()); + message.append("(").append(commands.size()).append("):\r\n"); + + for (Command c : commands) { + message.append(Emulator.getTexts().getValue("commands.description." + c.permission, "commands.description." + c.permission)).append("\r"); + } + + gameClient.getHabbo().alert(new String[]{message.toString()}); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ConnectCameraCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ConnectCameraCommand.java new file mode 100644 index 0000000..34ba2b0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ConnectCameraCommand.java @@ -0,0 +1,15 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; + +public class ConnectCameraCommand extends Command { + public ConnectCameraCommand() { + super("cmd_connect_camera", Emulator.getTexts().getValue("commands.keys.cmd_connect_camera").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + return false; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ControlCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ControlCommand.java new file mode 100644 index 0000000..d14bdb1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ControlCommand.java @@ -0,0 +1,53 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ControlCommand extends Command { + public ControlCommand() { + super("cmd_control", Emulator.getTexts().getValue("commands.keys.cmd_control").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + if (params.length == 2) { + Habbo target = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbo(params[1]); + + if (target == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_control.not_found").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + + if (target == gameClient.getHabbo()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_control.not_self"), RoomChatMessageBubbles.ALERT); + return true; + } + + Habbo oldHabbo = (Habbo) gameClient.getHabbo().getRoomUnit().getCacheable().remove("control"); + + if (oldHabbo != null) { + oldHabbo.getRoomUnit().getCacheable().remove("controller"); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_control.stopped").replace("%user%", oldHabbo.getHabboInfo().getUsername()), RoomChatMessageBubbles.ALERT); + } + gameClient.getHabbo().getRoomUnit().getCacheable().put("control", target); + target.getRoomUnit().getCacheable().put("controller", gameClient.getHabbo()); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_control.controlling").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } else { + Object habbo = gameClient.getHabbo().getRoomUnit().getCacheable().get("control"); + + if (habbo != null) { + gameClient.getHabbo().getRoomUnit().getCacheable().remove("control"); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_control.stopped").replace("%user%", ((Habbo) habbo).getHabboInfo().getUsername()), RoomChatMessageBubbles.ALERT); + } + return true; + } + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CoordsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CoordsCommand.java new file mode 100644 index 0000000..405dbfd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CoordsCommand.java @@ -0,0 +1,50 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; + +public class CoordsCommand extends Command { + + public CoordsCommand() { + super("cmd_coords", Emulator.getTexts().getValue("commands.keys.cmd_coords").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getRoomUnit() == null || gameClient.getHabbo().getHabboInfo().getCurrentRoom() == null) + return false; + + if (params.length == 1) { + gameClient.getHabbo().alert(Emulator.getTexts().getValue("commands.generic.cmd_coords.title") + "\r\n" + + "x: " + gameClient.getHabbo().getRoomUnit().getX() + "\r" + + "y: " + gameClient.getHabbo().getRoomUnit().getY() + "\r" + + "z: " + (gameClient.getHabbo().getRoomUnit().hasStatus(RoomUnitStatus.SIT) ? gameClient.getHabbo().getRoomUnit().getStatus(RoomUnitStatus.SIT) : gameClient.getHabbo().getRoomUnit().getZ()) + "\r" + + Emulator.getTexts().getValue("generic.rotation.head") + ": " + gameClient.getHabbo().getRoomUnit().getHeadRotation() + "-" + gameClient.getHabbo().getRoomUnit().getHeadRotation().getValue() + "\r" + + Emulator.getTexts().getValue("generic.rotation.body") + ": " + gameClient.getHabbo().getRoomUnit().getBodyRotation() + "-" + gameClient.getHabbo().getRoomUnit().getBodyRotation().getValue() + "\r" + + Emulator.getTexts().getValue("generic.sitting") + ": " + (gameClient.getHabbo().getRoomUnit().hasStatus(RoomUnitStatus.SIT) ? Emulator.getTexts().getValue("generic.yes") : Emulator.getTexts().getValue("generic.no")) + "\r" + + "Tile State: " + gameClient.getHabbo().getHabboInfo().getCurrentRoom().getLayout().getTile(gameClient.getHabbo().getRoomUnit().getX(), gameClient.getHabbo().getRoomUnit().getY()).state.name() + "\r" + + "Tile Walkable: " + gameClient.getHabbo().getHabboInfo().getCurrentRoom().getLayout().getTile(gameClient.getHabbo().getRoomUnit().getX(), gameClient.getHabbo().getRoomUnit().getY()).isWalkable() + "\r" + + "Tile relative height: " + gameClient.getHabbo().getHabboInfo().getCurrentRoom().getLayout().getTile(gameClient.getHabbo().getRoomUnit().getX(), gameClient.getHabbo().getRoomUnit().getY()).relativeHeight() + "\r" + + "Tile stack height: " + gameClient.getHabbo().getHabboInfo().getCurrentRoom().getLayout().getTile(gameClient.getHabbo().getRoomUnit().getX(), gameClient.getHabbo().getRoomUnit().getY()).getStackHeight()); + + } else { + RoomTile tile = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getLayout().getTile(Short.valueOf(params[1]), Short.valueOf(params[2])); + + if (tile != null) { + gameClient.getHabbo().alert(Emulator.getTexts().getValue("commands.generic.cmd_coords.title") + "\r\n" + + "x: " + tile.x + "\r" + + "y: " + tile.y + "\r" + + "z: " + tile.z + "\r" + + "Tile State: " + tile.state.name() + "\r" + + "Tile Relative Height: " + tile.relativeHeight() + "\r" + + "Tile Stack Height: " + tile.getStackHeight() + "\r" + + "Tile Walkable: " + (tile.isWalkable() ? "Yes" : "No") + "\r"); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("generic.tile.not.exists")); + } + } + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CreditsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CreditsCommand.java new file mode 100644 index 0000000..4e6dc38 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/CreditsCommand.java @@ -0,0 +1,56 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboManager; + +public class CreditsCommand extends Command { + public CreditsCommand() { + super("cmd_credits", Emulator.getTexts().getValue("commands.keys.cmd_credits").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 3) { + HabboInfo info = HabboManager.getOfflineHabboInfo(params[1]); + + if (info != null) { + Habbo habbo = Emulator.getGameServer().getGameClientManager().getHabbo(params[1]); + + int credits; + try { + credits = Integer.parseInt(params[2]); + } catch (NumberFormatException e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_credits.invalid_amount"), RoomChatMessageBubbles.ALERT); + return true; + } + if (habbo != null) { + if (credits != 0) { + habbo.giveCredits(credits); + if (habbo.getHabboInfo().getCurrentRoom() != null) + habbo.whisper(Emulator.getTexts().getValue("commands.generic.cmd_credits.received").replace("%amount%", Integer.parseInt(params[2]) + ""), RoomChatMessageBubbles.ALERT); + else + habbo.alert(Emulator.getTexts().getValue("commands.generic.cmd_credits.received").replace("%amount%", Integer.parseInt(params[2]) + "")); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_credits.send").replace("%amount%", Integer.parseInt(params[2]) + "").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_credits.invalid_amount"), RoomChatMessageBubbles.ALERT); + } + } else { + Emulator.getGameEnvironment().getHabboManager().giveCredits(info.getId(), credits); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_credits.send").replace("%amount%", Integer.parseInt(params[2]) + "").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_credits.user_not_found").replace("%amount%", Integer.parseInt(params[2]) + "").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_credits.invalid_amount"), RoomChatMessageBubbles.ALERT); + } + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/DiagonalCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/DiagonalCommand.java new file mode 100644 index 0000000..002393b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/DiagonalCommand.java @@ -0,0 +1,30 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class DiagonalCommand extends Command { + public DiagonalCommand() { + super("cmd_diagonal", Emulator.getTexts().getValue("commands.keys.cmd_diagonal").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom().hasRights(gameClient.getHabbo())) { + gameClient.getHabbo().getHabboInfo().getCurrentRoom().moveDiagonally(!gameClient.getHabbo().getHabboInfo().getCurrentRoom().moveDiagonally()); + + if (!gameClient.getHabbo().getHabboInfo().getCurrentRoom().moveDiagonally()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_diagonal.disabled"), RoomChatMessageBubbles.ALERT); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_diagonal.enabled"), RoomChatMessageBubbles.ALERT); + } + + return true; + } + } + + return false; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/DisconnectCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/DisconnectCommand.java new file mode 100644 index 0000000..867e7a9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/DisconnectCommand.java @@ -0,0 +1,42 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +public class DisconnectCommand extends Command { + public DisconnectCommand() { + super("cmd_disconnect", Emulator.getTexts().getValue("commands.keys.cmd_disconnect").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length < 2) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_disconnect.forgot_username"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (params[1].toLowerCase().equals(gameClient.getHabbo().getHabboInfo().getUsername().toLowerCase())) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_disconnect.disconnect_self"), RoomChatMessageBubbles.ALERT); + return true; + } + + Habbo target = Emulator.getGameEnvironment().getHabboManager().getHabbo(params[1]); + + if (target == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_disconnect.user_offline"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (target.getHabboInfo().getRank().getId() > gameClient.getHabbo().getHabboInfo().getRank().getId()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_disconnect.higher_rank"), RoomChatMessageBubbles.ALERT); + return true; + } + + target.getClient().getChannel().close(); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_disconnect.disconnected").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EjectAllCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EjectAllCommand.java new file mode 100644 index 0000000..51fa958 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EjectAllCommand.java @@ -0,0 +1,25 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomRightLevels; + +public class EjectAllCommand extends Command { + public EjectAllCommand() { + super("cmd_ejectall", Emulator.getTexts().getValue("commands.keys.cmd_ejectall").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Room room = gameClient.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + if (room.isOwner(gameClient.getHabbo()) || (room.hasGuild() && room.getGuildRightLevel(gameClient.getHabbo()).equals(RoomRightLevels.GUILD_ADMIN))) { + room.ejectAll(gameClient.getHabbo()); + } + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EmptyBotsInventoryCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EmptyBotsInventoryCommand.java new file mode 100644 index 0000000..64ff851 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EmptyBotsInventoryCommand.java @@ -0,0 +1,57 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.inventory.InventoryBotsComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.procedure.TObjectProcedure; + +public class EmptyBotsInventoryCommand extends Command { + public EmptyBotsInventoryCommand() { + super("cmd_empty_bots", Emulator.getTexts().getValue("commands.keys.cmd_empty_bots").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 1 || (params.length >= 2 && !params[1].equals(Emulator.getTexts().getValue("generic.yes")))) { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom().getUserCount() > 10) { + gameClient.getHabbo().alert(Emulator.getTexts().getValue("commands.succes.cmd_empty_bots.verify").replace("%generic.yes%", Emulator.getTexts().getValue("generic.yes"))); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_empty_bots.verify").replace("%generic.yes%", Emulator.getTexts().getValue("generic.yes")), RoomChatMessageBubbles.ALERT); + } + } + + return true; + } + + if (params.length >= 2 && params[1].equalsIgnoreCase(Emulator.getTexts().getValue("generic.yes"))) { + + Habbo habbo = (params.length == 3 && gameClient.getHabbo().hasPermission(Permission.ACC_EMPTY_OTHERS)) ? Emulator.getGameEnvironment().getHabboManager().getHabbo(params[2]) : gameClient.getHabbo(); + + if (habbo != null) { + TIntObjectHashMap bots = new TIntObjectHashMap<>(); + bots.putAll(habbo.getInventory().getBotsComponent().getBots()); + habbo.getInventory().getBotsComponent().getBots().clear(); + bots.forEachValue(object -> { + Emulator.getGameEnvironment().getBotManager().deleteBot(object); + return true; + }); + + habbo.getClient().sendResponse(new InventoryRefreshComposer()); + habbo.getClient().sendResponse(new InventoryBotsComposer(habbo)); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_empty_bots.cleared").replace("%username%", habbo.getHabboInfo().getUsername()), RoomChatMessageBubbles.ALERT); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_empty_bots"), RoomChatMessageBubbles.ALERT); + } + } + + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EmptyInventoryCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EmptyInventoryCommand.java new file mode 100644 index 0000000..66af755 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EmptyInventoryCommand.java @@ -0,0 +1,56 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.inventory.InventoryItemsComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.threading.runnables.QueryDeleteHabboItems; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.TIntObjectHashMap; + +public class EmptyInventoryCommand extends Command { + public EmptyInventoryCommand() { + super("cmd_empty", Emulator.getTexts().getValue("commands.keys.cmd_empty").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 1 || (params.length == 2 && !params[1].equals(Emulator.getTexts().getValue("generic.yes")))) { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom().getUserCount() > 10) { + gameClient.getHabbo().alert(Emulator.getTexts().getValue("commands.succes.cmd_empty.verify").replace("%generic.yes%", Emulator.getTexts().getValue("generic.yes"))); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_empty.verify").replace("%generic.yes%", Emulator.getTexts().getValue("generic.yes")), RoomChatMessageBubbles.ALERT); + } + } + + return true; + } + + if (params.length >= 2 && params[1].equalsIgnoreCase(Emulator.getTexts().getValue("generic.yes"))) { + + Habbo habbo = (params.length == 3 && gameClient.getHabbo().hasPermission(Permission.ACC_EMPTY_OTHERS)) ? Emulator.getGameEnvironment().getHabboManager().getHabbo(params[2]) : gameClient.getHabbo(); + + if (habbo != null) { + TIntObjectMap items = new TIntObjectHashMap<>(); + items.putAll(habbo.getInventory().getItemsComponent().getItems()); + habbo.getInventory().getItemsComponent().getItems().clear(); + Emulator.getThreading().run(new QueryDeleteHabboItems(items)); + + habbo.getClient().sendResponse(new InventoryRefreshComposer()); + habbo.getClient().sendResponse(new InventoryItemsComposer(0, 1, gameClient.getHabbo().getInventory().getItemsComponent().getItems())); + + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_empty.cleared").replace("%username%", habbo.getHabboInfo().getUsername()), RoomChatMessageBubbles.ALERT); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_empty"), RoomChatMessageBubbles.ALERT); + } + } + + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EmptyPetsInventoryCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EmptyPetsInventoryCommand.java new file mode 100644 index 0000000..f4b4079 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EmptyPetsInventoryCommand.java @@ -0,0 +1,57 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.inventory.InventoryPetsComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.procedure.TObjectProcedure; + +public class EmptyPetsInventoryCommand extends Command { + public EmptyPetsInventoryCommand() { + super("cmd_empty_pets", Emulator.getTexts().getValue("commands.keys.cmd_empty_pets").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 1 || (params.length >= 2 && !params[1].equals(Emulator.getTexts().getValue("generic.yes")))) { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom().getUserCount() > 10) { + gameClient.getHabbo().alert(Emulator.getTexts().getValue("commands.succes.cmd_empty_pets.verify").replace("%generic.yes%", Emulator.getTexts().getValue("generic.yes"))); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_empty_pets.verify").replace("%generic.yes%", Emulator.getTexts().getValue("generic.yes")), RoomChatMessageBubbles.ALERT); + } + } + + return true; + } + + if (params.length >= 2 && params[1].equalsIgnoreCase(Emulator.getTexts().getValue("generic.yes"))) { + + Habbo habbo = (params.length == 3 && gameClient.getHabbo().hasPermission(Permission.ACC_EMPTY_OTHERS)) ? Emulator.getGameEnvironment().getHabboManager().getHabbo(params[2]) : gameClient.getHabbo(); + + if (habbo != null) { + TIntObjectHashMap pets = new TIntObjectHashMap<>(); + pets.putAll(habbo.getInventory().getPetsComponent().getPets()); + habbo.getInventory().getPetsComponent().getPets().clear(); + pets.forEachValue(object -> { + Emulator.getGameEnvironment().getPetManager().deletePet(object); + return true; + }); + + habbo.getClient().sendResponse(new InventoryRefreshComposer()); + habbo.getClient().sendResponse(new InventoryPetsComposer(habbo)); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_empty_pets.cleared").replace("%username%", habbo.getHabboInfo().getUsername()), RoomChatMessageBubbles.ALERT); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_empty_pets"), RoomChatMessageBubbles.ALERT); + } + } + + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EnableCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EnableCommand.java new file mode 100644 index 0000000..43800a0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EnableCommand.java @@ -0,0 +1,52 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class EnableCommand extends Command { + + public EnableCommand() { + super("cmd_enable", Emulator.getTexts().getValue("commands.keys.cmd_enable").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length >= 2) { + int effectId; + try { + effectId = Integer.parseInt(params[1]); + } catch (Exception e) { + return false; + } + Habbo target = gameClient.getHabbo(); + if (params.length == 3) { + target = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbo(params[2]); + } + + if (target != null) { + if (target == gameClient.getHabbo() || gameClient.getHabbo().hasPermission(Permission.ACC_ENABLE_OTHERS)) { + try { + if (target.getHabboInfo().getCurrentRoom() != null) { + if (target.getHabboInfo().getRiding() == null) { + if (Emulator.getGameEnvironment().getPermissionsManager().isEffectBlocked(effectId, target.getHabboInfo().getRank().getId())) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_enable.not_allowed"), RoomChatMessageBubbles.ALERT); + return true; + } + + target.getHabboInfo().getCurrentRoom().giveEffect(target, effectId, -1); + } + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } + } + } + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EventCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EventCommand.java new file mode 100644 index 0000000..21d5783 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/EventCommand.java @@ -0,0 +1,52 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import gnu.trove.map.hash.THashMap; + +import java.util.Map; + +public class EventCommand extends Command { + public EventCommand() { + super("cmd_event", Emulator.getTexts().getValue("commands.keys.cmd_event").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + if (params.length >= 2) { + StringBuilder message = new StringBuilder(); + + for (int i = 1; i < params.length; i++) { + message.append(params[i]); + message.append(" "); + } + + THashMap codes = new THashMap<>(); + codes.put("ROOMNAME", gameClient.getHabbo().getHabboInfo().getCurrentRoom().getName()); + codes.put("ROOMID", gameClient.getHabbo().getHabboInfo().getCurrentRoom().getId() + ""); + codes.put("USERNAME", gameClient.getHabbo().getHabboInfo().getUsername()); + codes.put("LOOK", gameClient.getHabbo().getHabboInfo().getLook()); + codes.put("TIME", Emulator.getDate().toString()); + codes.put("MESSAGE", message.toString()); + + ServerMessage msg = new BubbleAlertComposer("hotel.event", codes).compose(); + + for (Map.Entry set : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + Habbo habbo = set.getValue(); + if (habbo.getHabboStats().blockStaffAlerts) + continue; + + habbo.getClient().sendResponse(msg); + } + + return true; + } + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FacelessCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FacelessCommand.java new file mode 100644 index 0000000..cbcdf4e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FacelessCommand.java @@ -0,0 +1,46 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer; +import com.eu.habbo.messages.outgoing.users.UpdateUserLookComposer; + + +public class FacelessCommand extends Command { + public FacelessCommand() { + super("cmd_faceless", Emulator.getTexts().getValue("commands.keys.cmd_faceless").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + try { + + String[] figureParts = gameClient.getHabbo().getHabboInfo().getLook().split("\\."); + + for (String part : figureParts) { + if (part.startsWith("hd")) { + String[] headParts = part.split("-"); + + if (!headParts[1].equals("99999")) + headParts[1] = "99999"; + else + break; + + String newHead = "hd-" + headParts[1] + "-" + headParts[2]; + + gameClient.getHabbo().getHabboInfo().setLook(gameClient.getHabbo().getHabboInfo().getLook().replace(part, newHead)); + gameClient.sendResponse(new UpdateUserLookComposer(gameClient.getHabbo())); + gameClient.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserDataComposer(gameClient.getHabbo()).compose()); + return true; + } + } + + } catch (Exception e) { + + } + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FastwalkCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FastwalkCommand.java new file mode 100644 index 0000000..51c4c39 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FastwalkCommand.java @@ -0,0 +1,37 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.users.Habbo; + +public class FastwalkCommand extends Command { + public FastwalkCommand() { + super("cmd_fastwalk", Emulator.getTexts().getValue("commands.keys.cmd_fastwalk").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + if (gameClient.getHabbo().getHabboInfo().getRiding() != null) //TODO Make this an event plugin which fires that can be cancelled + return true; + } + + Habbo habbo = gameClient.getHabbo(); + + if (params.length >= 2) { + String username = params[1]; + + habbo = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbo(username); + + if (habbo == null) + return false; + } + habbo.getRoomUnit().setFastWalk(!habbo.getRoomUnit().isFastWalk()); + + return true; + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FilterWordCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FilterWordCommand.java new file mode 100644 index 0000000..e1f1647 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FilterWordCommand.java @@ -0,0 +1,49 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.modtool.WordFilter; +import com.eu.habbo.habbohotel.modtool.WordFilterWord; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class FilterWordCommand extends Command { + public FilterWordCommand() { + super("cmd_filterword", Emulator.getTexts().getValue("commands.keys.cmd_filterword").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length < 2) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_filterword.missing_word")); + return true; + } + + String word = params[1]; + + String replacement = WordFilter.DEFAULT_REPLACEMENT; + if (params.length == 3) { + replacement = params[2]; + } + + WordFilterWord wordFilterWord = new WordFilterWord(word, replacement); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO wordfilter (`key`, `replacement`) VALUES (?, ?)")) { + statement.setString(1, word); + statement.setString(2, replacement); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_filterword.error")); + return true; + } + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_filterword.added").replace("%word%", word).replace("%replacement%", replacement)); + Emulator.getGameEnvironment().getWordFilter().addWord(wordFilterWord); + + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FreezeBotsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FreezeBotsCommand.java new file mode 100644 index 0000000..37b57aa --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FreezeBotsCommand.java @@ -0,0 +1,28 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class FreezeBotsCommand extends Command { + public FreezeBotsCommand() { + super("cmd_freeze_bots", Emulator.getTexts().getValue("commands.keys.cmd_freeze_bots").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + if (gameClient.getHabbo().getHabboInfo().getId() == gameClient.getHabbo().getHabboInfo().getCurrentRoom().getOwnerId() || gameClient.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER)) { + gameClient.getHabbo().getHabboInfo().getCurrentRoom().setAllowBotsWalk(!gameClient.getHabbo().getHabboInfo().getCurrentRoom().isAllowBotsWalk()); + gameClient.getHabbo().whisper(gameClient.getHabbo().getHabboInfo().getCurrentRoom().isAllowBotsWalk() ? Emulator.getTexts().getValue("commands.succes.cmd_freeze_bots.unfrozen") : Emulator.getTexts().getValue("commands.succes.cmd_freeze_bots.frozen"), RoomChatMessageBubbles.ALERT); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("generic.cannot_do_that"), RoomChatMessageBubbles.ALERT); + } + + return true; + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FreezeCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FreezeCommand.java new file mode 100644 index 0000000..b640a80 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/FreezeCommand.java @@ -0,0 +1,39 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +public class FreezeCommand extends Command { + public FreezeCommand() { + super("cmd_freeze", Emulator.getTexts().getValue("commands.keys.cmd_freeze").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 2) { + Habbo habbo = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbo(params[1]); + + if (habbo == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_freeze.not_found").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } else { + if (habbo.getRoomUnit().canWalk()) { + habbo.getRoomUnit().setCanWalk(false); + habbo.whisper(Emulator.getTexts().getValue("commands.succes.cmd_freeze.frozen"), RoomChatMessageBubbles.ALERT); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_freeze.user_frozen").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } else { + habbo.getRoomUnit().setCanWalk(true); + habbo.whisper(Emulator.getTexts().getValue("commands.succes.cmd_freeze.unfrozen"), RoomChatMessageBubbles.ALERT); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_freeze.user_unfrozen").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_freeze.not_found").replace("%user%", ""), RoomChatMessageBubbles.ALERT); + return true; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/GiftCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/GiftCommand.java new file mode 100644 index 0000000..e0a3390 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/GiftCommand.java @@ -0,0 +1,90 @@ +package com.eu.habbo.habbohotel.commands; + +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.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import gnu.trove.map.hash.THashMap; + +public class GiftCommand extends Command { + public GiftCommand() { + super("cmd_gift", Emulator.getTexts().getValue("commands.keys.cmd_gift").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length >= 3) { + String username = params[1]; + int itemId; + + try { + itemId = Integer.valueOf(params[2]); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_gift.not_a_number"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (itemId <= 0) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_gift.not_a_number"), RoomChatMessageBubbles.ALERT); + return true; + } + + Item baseItem = Emulator.getGameEnvironment().getItemManager().getItem(itemId); + + if (baseItem == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_gift.not_found").replace("%itemid%", itemId + ""), RoomChatMessageBubbles.ALERT); + return true; + } + + HabboInfo habboInfo = HabboManager.getOfflineHabboInfo(username); + + if (habboInfo == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_gift.user_not_found").replace("%username%", username), RoomChatMessageBubbles.ALERT); + return true; + } + + StringBuilder message = new StringBuilder(); + + if (params.length > 3) { + for (int i = 3; i < params.length; i++) { + message.append(params[i]).append(" "); + } + } + + final String finalMessage = message.toString(); + + HabboItem item = Emulator.getGameEnvironment().getItemManager().createItem(0, baseItem, 0, 0, ""); + + Item giftItem = Emulator.getGameEnvironment().getItemManager().getItem((Integer) Emulator.getGameEnvironment().getCatalogManager().giftFurnis.values().toArray()[Emulator.getRandom().nextInt(Emulator.getGameEnvironment().getCatalogManager().giftFurnis.size())]); + + String extraData = "1\t" + item.getId(); + extraData += "\t0\t0\t0\t" + finalMessage + "\t0\t0"; + + Emulator.getGameEnvironment().getItemManager().createGift(username, giftItem, extraData, 0, 0); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_gift").replace("%username%", username).replace("%itemname%", item.getBaseItem().getName()), RoomChatMessageBubbles.ALERT); + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(habboInfo.getId()); + + if (habbo != null) { + habbo.getClient().sendResponse(new InventoryRefreshComposer()); + + THashMap keys = new THashMap<>(); + keys.put("display", "BUBBLE"); + keys.put("image", "${image.library.url}notifications/gift.gif"); + keys.put("message", Emulator.getTexts().getValue("generic.gift.received.anonymous")); + habbo.getClient().sendResponse(new BubbleAlertComposer(BubbleAlertKeys.RECEIVED_BADGE.key, keys)); + } + return true; + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/GiveRankCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/GiveRankCommand.java new file mode 100644 index 0000000..274368c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/GiveRankCommand.java @@ -0,0 +1,66 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.permissions.Rank; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboManager; +import org.apache.commons.lang3.StringUtils; + +public class GiveRankCommand extends Command { + public GiveRankCommand() { + super("cmd_give_rank", Emulator.getTexts().getValue("commands.keys.cmd_give_rank").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Rank rank = null; + if (params.length == 1) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_give_rank.missing_username") + Emulator.getTexts().getValue("commands.description.cmd_give_rank"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (params.length == 2) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_give_rank.missing_rank") + Emulator.getTexts().getValue("commands.description.cmd_give_rank"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (params.length == 3) { + if (StringUtils.isNumeric(params[2])) { + int rankId = Integer.valueOf(params[2]); + if (Emulator.getGameEnvironment().getPermissionsManager().rankExists(rankId)) + rank = Emulator.getGameEnvironment().getPermissionsManager().getRank(rankId); + } else { + rank = Emulator.getGameEnvironment().getPermissionsManager().getRankByName(params[2]); + } + + if (rank != null) { + if (rank.getId() > gameClient.getHabbo().getHabboInfo().getRank().getId()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_give_rank.higher").replace("%username%", params[1]).replace("%id%", rank.getName()), RoomChatMessageBubbles.ALERT); + return true; + } + + HabboInfo habbo = HabboManager.getOfflineHabboInfo(params[1]); + + if (habbo != null) { + if (habbo.getRank().getId() > gameClient.getHabbo().getHabboInfo().getRank().getId()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_give_rank.higher.other").replace("%username%", params[1]).replace("%id%", rank.getName()), RoomChatMessageBubbles.ALERT); + return true; + } + + Emulator.getGameEnvironment().getHabboManager().setRank(habbo.getId(), rank.getId()); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_give_rank.updated").replace("%id%", rank.getName()).replace("%username%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_give_rank.user_offline").replace("%id%", rank.getName()).replace("%username%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + } + } + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.errors.cmd_give_rank.not_found").replace("%id%", params[2]).replace("%username%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HabnamCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HabnamCommand.java new file mode 100644 index 0000000..b1ccb3a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HabnamCommand.java @@ -0,0 +1,21 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.habbohotel.gameclients.GameClient; + +public class HabnamCommand extends Command { + public HabnamCommand() { + super(null, new String[]{"habnam", "gangnam"}); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboStats().hasActiveClub()) { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + gameClient.getHabbo().getHabboInfo().getCurrentRoom().giveEffect(gameClient.getHabbo(), 140, 30); + return true; + } + } + + return false; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HandItemCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HandItemCommand.java new file mode 100644 index 0000000..1cef1e9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HandItemCommand.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserHandItemComposer; + +public class HandItemCommand extends Command { + public HandItemCommand() { + super("cmd_hand_item", Emulator.getTexts().getValue("commands.keys.cmd_hand_item").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 2) { + try { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + int effectId = Integer.parseInt(params[1]); + gameClient.getHabbo().getRoomUnit().setHandItem(effectId); + gameClient.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserHandItemComposer(gameClient.getHabbo().getRoomUnit()).compose()); + } + } catch (Exception e) { + //Don't handle incorrect parse exceptions :P + } + } + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HappyHourCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HappyHourCommand.java new file mode 100644 index 0000000..845195d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HappyHourCommand.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.generic.alerts.GenericAlertComposer; + +import java.util.Map; + +public class HappyHourCommand extends Command { + public HappyHourCommand() { + super("cmd_happyhour", Emulator.getTexts().getValue("commands.keys.cmd_happyhour").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new GenericAlertComposer("Happy Hour!")); + + for (Map.Entry set : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + AchievementManager.progressAchievement(set.getValue(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("HappyHour")); + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HideWiredCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HideWiredCommand.java new file mode 100644 index 0000000..8141d02 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HideWiredCommand.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; + +public class HideWiredCommand extends Command { + public HideWiredCommand() { + super("cmd_hidewired", Emulator.getTexts().getValue("commands.keys.cmd_hidewired").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Room room = gameClient.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + if (room.isOwner(gameClient.getHabbo())) { + room.setHideWired(!room.isHideWired()); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_hidewired." + (room.isHideWired() ? "hidden" : "shown"))); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.errors.cmd_hidewired.permission")); + } + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HotelAlertCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HotelAlertCommand.java new file mode 100644 index 0000000..119b1ef --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HotelAlertCommand.java @@ -0,0 +1,40 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.generic.alerts.StaffAlertWithLinkComposer; + +import java.util.Map; + +public class HotelAlertCommand extends Command { + + public HotelAlertCommand() { + super("cmd_ha", Emulator.getTexts().getValue("commands.keys.cmd_ha").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) { + if (params.length > 1) { + StringBuilder message = new StringBuilder(); + for (int i = 1; i < params.length; i++) { + message.append(params[i]).append(" "); + } + + ServerMessage msg = new StaffAlertWithLinkComposer(message + "\r\n\r\nVan:" + gameClient.getHabbo().getHabboInfo().getUsername(), "").compose(); + + for (Map.Entry set : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + Habbo habbo = set.getValue(); + if (habbo.getHabboStats().blockStaffAlerts) + continue; + + habbo.getClient().sendResponse(msg); + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ha.forgot_message"), RoomChatMessageBubbles.ALERT); + } + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HotelAlertLinkCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HotelAlertLinkCommand.java new file mode 100644 index 0000000..fca733f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/HotelAlertLinkCommand.java @@ -0,0 +1,30 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.messages.outgoing.generic.alerts.StaffAlertWithLinkComposer; + +public class HotelAlertLinkCommand extends Command { + public HotelAlertLinkCommand() { + super("cmd_hal", Emulator.getTexts().getValue("commands.keys.cmd_hal").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length < 3) { + return true; + } + + String url = params[1]; + StringBuilder message = new StringBuilder(); + for (int i = 2; i < params.length; i++) { + message.append(params[i]); + message.append(" "); + } + + message.append("\r\r-").append(gameClient.getHabbo().getHabboInfo().getUsername()).append(""); + + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new StaffAlertWithLinkComposer(message.toString(), url).compose()); + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/IPBanCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/IPBanCommand.java new file mode 100644 index 0000000..e37bb1e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/IPBanCommand.java @@ -0,0 +1,70 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.modtool.ModToolBanType; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboManager; + +public class IPBanCommand extends Command { + public final static int TEN_YEARS = 315569260; + + public IPBanCommand() { + super("cmd_ip_ban", Emulator.getTexts().getValue("commands.keys.cmd_ip_ban").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + HabboInfo habbo; + StringBuilder reason = new StringBuilder(); + if (params.length >= 2) { + Habbo h = Emulator.getGameEnvironment().getHabboManager().getHabbo(params[1]); + + if (h != null) { + habbo = h.getHabboInfo(); + } else { + habbo = HabboManager.getOfflineHabboInfo(params[1]); + } + } else { + return true; + } + + if (params.length > 2) { + for (int i = 2; i < params.length; i++) { + reason.append(params[i]); + reason.append(" "); + } + } + + int count = 0; + if (habbo != null) { + if (habbo == gameClient.getHabbo().getHabboInfo()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ip_ban.ban_self"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (habbo.getRank().getId() >= gameClient.getHabbo().getHabboInfo().getRank().getId()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT); + return true; + } + + Emulator.getGameEnvironment().getModToolManager().ban(habbo.getId(), gameClient.getHabbo(), reason.toString(), TEN_YEARS, ModToolBanType.IP, -1); + count++; + for (Habbo h : Emulator.getGameServer().getGameClientManager().getHabbosWithIP(habbo.getIpLogin())) { + if (h != null) { + count++; + Emulator.getGameEnvironment().getModToolManager().ban(h.getHabboInfo().getId(), gameClient.getHabbo(), reason.toString(), TEN_YEARS, ModToolBanType.IP, -1); + } + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.user_offline"), RoomChatMessageBubbles.ALERT); + return true; + } + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_ip_ban").replace("%count%", count + ""), RoomChatMessageBubbles.ALERT); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/InvisibleCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/InvisibleCommand.java new file mode 100644 index 0000000..7f40f52 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/InvisibleCommand.java @@ -0,0 +1,50 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomLayout; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserRemoveComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUsersComposer; +import com.eu.habbo.threading.runnables.RoomUnitTeleport; + +public class InvisibleCommand extends Command { + public InvisibleCommand() { + super("cmd_invisible", Emulator.getTexts().getValue("commands.keys.cmd_invisible").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + HabboInfo habboInfo = gameClient.getHabbo().getHabboInfo(); + RoomUnit roomUnit = gameClient.getHabbo().getRoomUnit(); + + habboInfo.toggleInvisibility(); + + if (!habboInfo.isInvisibleInRooms() && !roomUnit.isInRoom()) { + RoomLayout roomLayout = roomUnit.getRoom().getLayout(); + + new RoomUnitTeleport(roomUnit, roomUnit.getRoom(), roomLayout.getDoorTile().x, roomLayout.getDoorTile().y, roomLayout.getDoorTile().z, 0).run(); + + roomUnit.setInRoom(true); + + roomUnit.getRoom().sendComposer(new RoomUsersComposer(gameClient.getHabbo()).compose()); + roomUnit.getRoom().sendComposer(new RoomUserStatusComposer(roomUnit).compose()); + + WiredHandler.handle(WiredTriggerType.ENTER_ROOM, roomUnit, roomUnit.getRoom(), null); + roomUnit.getRoom().habboEntered(gameClient.getHabbo()); + + gameClient.getHabbo().whisper("Je bent weer zichtbaar voor anderen."); + + return true; + } + + gameClient.getHabbo().whisper("Je bent nu onzichtbaar. Typ opnieuw :invisible om weer zichtbaar te zijn in kamers."); + gameClient.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserRemoveComposer(roomUnit).compose()); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/LayCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/LayCommand.java new file mode 100644 index 0000000..abc534b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/LayCommand.java @@ -0,0 +1,41 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; + +public class LayCommand extends Command { + public LayCommand() { + super(null, Emulator.getTexts().getValue("commands.keys.cmd_lay").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getRoomUnit() == null || !gameClient.getHabbo().getRoomUnit().canForcePosture()) + return true; + + gameClient.getHabbo().getRoomUnit().cmdLay = true; + gameClient.getHabbo().getHabboInfo().getCurrentRoom().updateHabbo(gameClient.getHabbo()); + gameClient.getHabbo().getRoomUnit().cmdSit = true; + gameClient.getHabbo().getRoomUnit().setBodyRotation(RoomUserRotation.values()[gameClient.getHabbo().getRoomUnit().getBodyRotation().getValue() - gameClient.getHabbo().getRoomUnit().getBodyRotation().getValue() % 2]); + + RoomTile tile = gameClient.getHabbo().getRoomUnit().getCurrentLocation(); + if (tile == null) { + return false; + } + + for (int i = 0; i < 3; i++) { + RoomTile t = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getLayout().getTileInFront(tile, gameClient.getHabbo().getRoomUnit().getBodyRotation().getValue(), i); + if (t == null || !t.isWalkable()) { + return false; + } + } + + gameClient.getHabbo().getRoomUnit().setStatus(RoomUnitStatus.LAY, 0.5 + ""); + gameClient.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserStatusComposer(gameClient.getHabbo().getRoomUnit()).compose()); + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MachineBanCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MachineBanCommand.java new file mode 100644 index 0000000..56f5b0f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MachineBanCommand.java @@ -0,0 +1,61 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.modtool.ModToolBanType; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboManager; + +public class MachineBanCommand extends Command { + public MachineBanCommand() { + super("cmd_machine_ban", Emulator.getTexts().getValue("commands.keys.cmd_machine_ban").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + HabboInfo habbo = null; + StringBuilder reason = new StringBuilder(); + if (params.length >= 2) { + Habbo h = Emulator.getGameEnvironment().getHabboManager().getHabbo(params[1]); + + if (h != null) { + habbo = h.getHabboInfo(); + } else { + habbo = HabboManager.getOfflineHabboInfo(params[1]); + } + } + + if (params.length > 2) { + for (int i = 2; i < params.length; i++) { + reason.append(params[i]); + reason.append(" "); + } + } + + int count; + if (habbo != null) { + if (habbo == gameClient.getHabbo().getHabboInfo()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_machine_ban.ban_self"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (habbo.getRank().getId() >= gameClient.getHabbo().getHabboInfo().getRank().getId()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT); + return true; + } + + count = Emulator.getGameEnvironment().getModToolManager().ban(habbo.getId(), gameClient.getHabbo(), reason.toString(), IPBanCommand.TEN_YEARS, ModToolBanType.MACHINE, -1).size(); + + + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.user_offline"), RoomChatMessageBubbles.ALERT); + return true; + } + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_machine_ban").replace("%count%", count + ""), RoomChatMessageBubbles.ALERT); + + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassBadgeCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassBadgeCommand.java new file mode 100644 index 0000000..b584ee6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassBadgeCommand.java @@ -0,0 +1,57 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.habbohotel.users.inventory.BadgesComponent; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.users.AddUserBadgeComposer; +import gnu.trove.map.hash.THashMap; + +import java.util.Map; + +public class MassBadgeCommand extends Command { + public MassBadgeCommand() { + super("cmd_massbadge", Emulator.getTexts().getValue("commands.keys.cmd_massbadge").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 2) { + String badge; + + badge = params[1]; + + if (!badge.isEmpty()) { + THashMap keys = new THashMap<>(); + keys.put("display", "BUBBLE"); + keys.put("image", "${image.library.url}album1584/" + badge + ".gif"); + keys.put("message", Emulator.getTexts().getValue("commands.generic.cmd_badge.received")); + ServerMessage message = new BubbleAlertComposer(BubbleAlertKeys.RECEIVED_BADGE.key, keys).compose(); + + for (Map.Entry set : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + Habbo habbo = set.getValue(); + + if (habbo.isOnline()) { + if (habbo.getInventory() != null && habbo.getInventory().getBadgesComponent() != null && !habbo.getInventory().getBadgesComponent().hasBadge(badge)) { + HabboBadge b = BadgesComponent.createBadge(badge, habbo); + + if (b != null) { + habbo.getClient().sendResponse(new AddUserBadgeComposer(b)); + + habbo.getClient().sendResponse(message); + } + } + } + } + } + return true; + } + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_massbadge.no_badge"), RoomChatMessageBubbles.ALERT); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassCreditsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassCreditsCommand.java new file mode 100644 index 0000000..24f1800 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassCreditsCommand.java @@ -0,0 +1,42 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.util.Map; + +public class MassCreditsCommand extends Command { + public MassCreditsCommand() { + super("cmd_masscredits", Emulator.getTexts().getValue("commands.keys.cmd_masscredits").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 2) { + int amount; + + try { + amount = Integer.valueOf(params[1]); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_masscredits.invalid_amount"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (amount != 0) { + for (Map.Entry set : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + Habbo habbo = set.getValue(); + + habbo.giveCredits(amount); + + if (habbo.getHabboInfo().getCurrentRoom() != null) + habbo.whisper(Emulator.getTexts().getValue("commands.generic.cmd_credits.received").replace("%amount%", amount + ""), RoomChatMessageBubbles.ALERT); + } + } + return true; + } + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_masscredits.invalid_amount"), RoomChatMessageBubbles.ALERT); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassGiftCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassGiftCommand.java new file mode 100644 index 0000000..1c1055b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassGiftCommand.java @@ -0,0 +1,86 @@ +package com.eu.habbo.habbohotel.commands; + +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.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import gnu.trove.map.hash.THashMap; + +import java.util.Map; + +public class MassGiftCommand extends Command { + public MassGiftCommand() { + super("cmd_massgift", Emulator.getTexts().getValue("commands.keys.cmd_massgift").split(";")); + } + + @Override + public boolean handle(final GameClient gameClient, String[] params) throws Exception { + if (params.length >= 2) { + int itemId; + + try { + itemId = Integer.valueOf(params[1]); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_gift.not_a_number"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (itemId <= 0) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_gift.not_a_number"), RoomChatMessageBubbles.ALERT); + return true; + } + + final Item baseItem = Emulator.getGameEnvironment().getItemManager().getItem(itemId); + + if (baseItem == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_gift.not_found").replace("%itemid%", itemId + ""), RoomChatMessageBubbles.ALERT); + return true; + } + + StringBuilder message = new StringBuilder(); + + if (params.length > 2) { + for (int i = 2; i < params.length; i++) { + message.append(params[i]).append(" "); + } + } + + final String finalMessage = message.toString(); + + THashMap keys = new THashMap<>(); + keys.put("display", "BUBBLE"); + keys.put("image", "${image.library.url}notifications/gift.gif"); + keys.put("message", Emulator.getTexts().getValue("generic.gift.received.anonymous")); + ServerMessage giftNotificiationMessage = new BubbleAlertComposer(BubbleAlertKeys.RECEIVED_BADGE.key, keys).compose(); + + Emulator.getThreading().run(() -> { + for (Map.Entry set : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + Habbo habbo = set.getValue(); + + HabboItem item = Emulator.getGameEnvironment().getItemManager().createItem(0, baseItem, 0, 0, ""); + + Item giftItem = Emulator.getGameEnvironment().getItemManager().getItem((Integer) Emulator.getGameEnvironment().getCatalogManager().giftFurnis.values().toArray()[Emulator.getRandom().nextInt(Emulator.getGameEnvironment().getCatalogManager().giftFurnis.size())]); + + String extraData = "1\t" + item.getId(); + extraData += "\t0\t0\t0\t" + finalMessage + "\t0\t0"; + + Emulator.getGameEnvironment().getItemManager().createGift(habbo.getHabboInfo().getUsername(), giftItem, extraData, 0, 0); + + habbo.getClient().sendResponse(new InventoryRefreshComposer()); + habbo.getClient().sendResponse(giftNotificiationMessage); + } + }); + + + return true; + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassPixelsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassPixelsCommand.java new file mode 100644 index 0000000..7d4fd95 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassPixelsCommand.java @@ -0,0 +1,42 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.util.Map; + +public class MassPixelsCommand extends Command { + public MassPixelsCommand() { + super("cmd_massduckets", Emulator.getTexts().getValue("commands.keys.cmd_massduckets").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 2) { + int amount; + + try { + amount = Integer.valueOf(params[1]); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_massduckets.invalid_amount"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (amount != 0) { + for (Map.Entry set : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + Habbo habbo = set.getValue(); + + habbo.givePixels(amount); + + if (habbo.getHabboInfo().getCurrentRoom() != null) + habbo.whisper(Emulator.getTexts().getValue("commands.generic.cmd_duckets.received").replace("%amount%", amount + ""), RoomChatMessageBubbles.ALERT); + } + } + return true; + } + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_massduckets.invalid_amount"), RoomChatMessageBubbles.ALERT); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassPointsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassPointsCommand.java new file mode 100644 index 0000000..79103ea --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MassPointsCommand.java @@ -0,0 +1,72 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.util.Map; + +public class MassPointsCommand extends Command { + public MassPointsCommand() { + super("cmd_masspoints", Emulator.getTexts().getValue("commands.keys.cmd_masspoints").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + int type = Emulator.getConfig().getInt("seasonal.primary.type"); + String amountString; + if (params.length == 3) { + amountString = params[1]; + try { + type = Integer.valueOf(params[2]); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_masspoints.invalid_type").replace("%types%", Emulator.getConfig().getValue("seasonal.types").replace(";", ", ")), RoomChatMessageBubbles.ALERT); + return true; + } + + } else if (params.length == 2) { + amountString = params[1]; + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_masspoints.invalid_amount"), RoomChatMessageBubbles.ALERT); + return true; + } + + boolean found = false; + for (String s : Emulator.getConfig().getValue("seasonal.types").split(";")) { + if (s.equalsIgnoreCase(type + "")) { + found = true; + break; + } + } + + if (!found) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_masspoints.invalid_type").replace("%types%", Emulator.getConfig().getValue("seasonal.types").replace(";", ", ")), RoomChatMessageBubbles.ALERT); + return true; + } + + int amount; + + try { + amount = Integer.valueOf(amountString); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_masspoints.invalid_amount"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (amount != 0) { + String message = Emulator.getTexts().getValue("commands.generic.cmd_points.received").replace("%amount%", amount + "").replace("%type%", Emulator.getTexts().getValue("seasonal.name." + type)); + + for (Map.Entry set : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + Habbo habbo = set.getValue(); + habbo.givePoints(type, amount); + + if (habbo.getHabboInfo().getCurrentRoom() != null) + habbo.whisper(message, RoomChatMessageBubbles.ALERT); + else + habbo.alert(message); + } + } + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MimicCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MimicCommand.java new file mode 100644 index 0000000..dadb88b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MimicCommand.java @@ -0,0 +1,48 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.habbohotel.users.clothingvalidation.ClothingValidationManager; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer; +import com.eu.habbo.messages.outgoing.users.UserDataComposer; +import com.eu.habbo.util.figure.FigureUtil; + +public class MimicCommand extends Command { + public MimicCommand() { + super("cmd_mimic", Emulator.getTexts().getValue("commands.keys.cmd_mimic").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 2) { + Habbo habbo = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbo(params[1]); + + if (habbo == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_mimic.not_found").replace("%user%", ""), RoomChatMessageBubbles.ALERT); + return true; + } + + if (habbo == gameClient.getHabbo()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_mimic.not_self"), RoomChatMessageBubbles.ALERT); + return true; + } else if (habbo.hasPermission(Permission.ACC_NOT_MIMICED) && !gameClient.getHabbo().hasPermission(Permission.ACC_NOT_MIMICED)) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_mimic.blocked").replace("%user%", params[1]).replace("%gender_name%", (habbo.getHabboInfo().getGender().equals(HabboGender.M) ? Emulator.getTexts().getValue("gender.him") : Emulator.getTexts().getValue("gender.her"))), RoomChatMessageBubbles.ALERT); + return true; + } else { + gameClient.getHabbo().getHabboInfo().setLook(ClothingValidationManager.VALIDATE_ON_MIMIC ? ClothingValidationManager.validateLook(gameClient.getHabbo(), habbo.getHabboInfo().getLook(), habbo.getHabboInfo().getGender().name()) : habbo.getHabboInfo().getLook()); + gameClient.getHabbo().getHabboInfo().setGender(habbo.getHabboInfo().getGender()); + gameClient.sendResponse(new UserDataComposer(gameClient.getHabbo())); + gameClient.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserDataComposer(gameClient.getHabbo()).compose()); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_mimic.copied").replace("%user%", params[1]).replace("%gender_name%", (habbo.getHabboInfo().getGender().equals(HabboGender.M) ? Emulator.getTexts().getValue("gender.him") : Emulator.getTexts().getValue("gender.her"))), RoomChatMessageBubbles.ALERT); + return true; + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_mimic.not_found").replace("%user%", ""), RoomChatMessageBubbles.ALERT); + return true; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MoonwalkCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MoonwalkCommand.java new file mode 100644 index 0000000..676871d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MoonwalkCommand.java @@ -0,0 +1,25 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; + +public class MoonwalkCommand extends Command { + public MoonwalkCommand() { + super("cmd_moonwalk", Emulator.getTexts().getValue("commands.keys.cmd_moonwalk").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null && gameClient.getHabbo().getHabboStats().hasActiveClub()) { + int effect = 136; + if (gameClient.getHabbo().getRoomUnit().getEffectId() == 136) + effect = 0; + + gameClient.getHabbo().getHabboInfo().getCurrentRoom().giveEffect(gameClient.getHabbo(), effect, -1); + + return true; + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MultiCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MultiCommand.java new file mode 100644 index 0000000..04009bf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MultiCommand.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.messages.outgoing.rooms.items.PostItStickyPoleOpenComposer; + +public class MultiCommand extends Command { + public MultiCommand() { + super("cmd_multi", Emulator.getTexts().getValue("commands.keys.cmd_multi").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + gameClient.sendResponse(new PostItStickyPoleOpenComposer(null)); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MuteBotsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MuteBotsCommand.java new file mode 100644 index 0000000..768a42e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MuteBotsCommand.java @@ -0,0 +1,18 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class MuteBotsCommand extends Command { + public MuteBotsCommand() { + super(null, Emulator.getTexts().getValue("commands.keys.cmd_mute_bots").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + gameClient.getHabbo().getHabboStats().ignoreBots = !gameClient.getHabbo().getHabboStats().ignoreBots; + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_mute_bots." + (gameClient.getHabbo().getHabboStats().ignoreBots ? "ignored" : "unignored")), RoomChatMessageBubbles.ALERT); + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MuteCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MuteCommand.java new file mode 100644 index 0000000..24425e2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MuteCommand.java @@ -0,0 +1,57 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserIgnoredComposer; + +public class MuteCommand extends Command { + public MuteCommand() { + super("cmd_mute", Emulator.getTexts().getValue("commands.keys.cmd_mute").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 1) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_mute.not_specified"), RoomChatMessageBubbles.ALERT); + return true; + } + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(params[1]); + + if (habbo == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_mute.not_found").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } else { + if (habbo == gameClient.getHabbo()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_mute.self"), RoomChatMessageBubbles.ALERT); + return true; + } + + int duration = Integer.MAX_VALUE; + + if (params.length == 3) { + try { + duration = Integer.valueOf(params[2]); + + if (duration <= 0) + throw new Exception(""); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_mute.time"), RoomChatMessageBubbles.ALERT); + return true; + } + } + + habbo.mute(duration, false); + + if (habbo.getHabboInfo().getCurrentRoom() != null) { + habbo.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserIgnoredComposer(habbo, RoomUserIgnoredComposer.MUTED).compose()); //: RoomUserIgnoredComposer.UNIGNORED + } + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_mute.muted").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MutePetsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MutePetsCommand.java new file mode 100644 index 0000000..6dcb697 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/MutePetsCommand.java @@ -0,0 +1,18 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class MutePetsCommand extends Command { + public MutePetsCommand() { + super(null, Emulator.getTexts().getValue("commands.keys.cmd_mute_pets").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + gameClient.getHabbo().getHabboStats().ignorePets = !gameClient.getHabbo().getHabboStats().ignorePets; + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_mute_pets." + (gameClient.getHabbo().getHabboStats().ignorePets ? "ignored" : "unignored")), RoomChatMessageBubbles.ALERT); + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PetInfoCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PetInfoCommand.java new file mode 100644 index 0000000..00a8164 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PetInfoCommand.java @@ -0,0 +1,53 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetManager; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import gnu.trove.procedure.TIntObjectProcedure; + +public class PetInfoCommand extends Command { + public PetInfoCommand() { + super("cmd_pet_info", Emulator.getTexts().getValue("commands.keys.cmd_pet_info").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length > 1) { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() == null) + return false; + + String name = params[1]; + + gameClient.getHabbo().getHabboInfo().getCurrentRoom().getCurrentPets().forEachEntry(new TIntObjectProcedure() { + @Override + public boolean execute(int a, Pet pet) { + if (pet.getName().equalsIgnoreCase(name)) { + gameClient.getHabbo().alert("" + + Emulator.getTexts().getValue("commands.generic.cmd_pet_info.title") + ": " + pet.getName() + "\r\n" + + Emulator.getTexts().getValue("generic.pet.id") + ": " + pet.getId() + "\r" + + Emulator.getTexts().getValue("generic.pet.name") + ": " + pet.getName() + "\r" + + Emulator.getTexts().getValue("generic.pet.age") + ": " + pet.daysAlive() + " " + Emulator.getTexts().getValue("generic.pet.days.alive") + "\r" + + Emulator.getTexts().getValue("generic.pet.level") + ": " + pet.getLevel() + "\r" + + "\r" + + Emulator.getTexts().getValue("commands.generic.cmd_pet_info.stats") + "\r\n" + + Emulator.getTexts().getValue("generic.pet.scratches") + ": " + pet.getRespect() + "\r" + + Emulator.getTexts().getValue("generic.pet.energy") + ": " + pet.getEnergy() + "/" + PetManager.maxEnergy(pet.getLevel()) + "\r" + + Emulator.getTexts().getValue("generic.pet.happyness") + ": " + pet.getHappyness() + "\r" + + Emulator.getTexts().getValue("generic.pet.level.thirst") + ": " + pet.levelThirst + "\r" + + Emulator.getTexts().getValue("generic.pet.level.hunger") + ": " + pet.levelHunger + "\r" + + Emulator.getTexts().getValue("generic.pet.current_action") + ": " + (pet.getTask() == null ? Emulator.getTexts().getValue("generic.nothing") : pet.getTask().name()) + "\r" + + Emulator.getTexts().getValue("generic.can.walk") + ": " + (pet.getRoomUnit().canWalk() ? Emulator.getTexts().getValue("generic.yes") : Emulator.getTexts().getValue("generic.no")) + "" + ); + } + + return true; + } + }); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_pet_info.pet_not_found"), RoomChatMessageBubbles.ALERT); + } + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PickallCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PickallCommand.java new file mode 100644 index 0000000..2e7b8d7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PickallCommand.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; + +public class PickallCommand extends Command { + public PickallCommand() { + super("cmd_pickall", Emulator.getTexts().getValue("commands.keys.cmd_pickall").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Room room = gameClient.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + if (room.isOwner(gameClient.getHabbo())) { + room.ejectAll(); + return true; + } + + room.ejectUserFurni(gameClient.getHabbo().getHabboInfo().getId()); + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PingCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PingCommand.java new file mode 100644 index 0000000..c76429e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PingCommand.java @@ -0,0 +1,29 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.habbohotel.LatencyTracker; +import com.eu.habbo.habbohotel.gameclients.GameClient; + +public class PingCommand extends Command { + public PingCommand() { + super(null, new String[]{"ping"}); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getRoomUnit() == null) { + return true; + } + + final LatencyTracker latencyTracker = gameClient.getLatencyTracker(); + + if (latencyTracker.hasInitialized()) { + gameClient.getHabbo().whisper(String.format("Gemiddelde ping %dms, laatste ping %dms", + latencyTracker.getAverageMs(), + latencyTracker.getLastMs())); + } else { + gameClient.getHabbo().whisper("Ping-snelheid is nog niet berekend, probeer het over een minuut opnieuw."); + } + + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PixelCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PixelCommand.java new file mode 100644 index 0000000..327dc4e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PixelCommand.java @@ -0,0 +1,43 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +public class PixelCommand extends Command { + public PixelCommand() { + super("cmd_duckets", Emulator.getTexts().getValue("commands.keys.cmd_duckets").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 3) { + Habbo habbo = Emulator.getGameServer().getGameClientManager().getHabbo(params[1]); + + if (habbo != null) { + try { + if (Integer.parseInt(params[2]) != 0) { + habbo.givePixels(Integer.parseInt(params[2])); + if (habbo.getHabboInfo().getCurrentRoom() != null) + habbo.whisper(Emulator.getTexts().getValue("commands.generic.cmd_duckets.received").replace("%amount%", Integer.valueOf(params[2]) + ""), RoomChatMessageBubbles.ALERT); + else + habbo.alert(Emulator.getTexts().getValue("commands.generic.cmd_duckets.received").replace("%amount%", Integer.valueOf(params[2]) + "")); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_duckets.send").replace("%amount%", Integer.valueOf(params[2]) + "").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_duckets.invalid_amount"), RoomChatMessageBubbles.ALERT); + } + } catch (NumberFormatException e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_duckets.invalid_amount"), RoomChatMessageBubbles.ALERT); + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_duckets.user_offline").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_duckets.invalid_amount"), RoomChatMessageBubbles.ALERT); + } + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PluginsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PluginsCommand.java new file mode 100644 index 0000000..c468e0d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PluginsCommand.java @@ -0,0 +1,32 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.messages.outgoing.generic.alerts.MessagesForYouComposer; +import com.eu.habbo.plugin.HabboPlugin; + +import java.util.Collections; + +public class PluginsCommand extends Command { + public PluginsCommand() { + super(null, Emulator.getTexts().getValue("commands.keys.cmd_plugins").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + StringBuilder message = new StringBuilder("Plugins (" + Emulator.getPluginManager().getPlugins().size() + ")\r"); + + for (HabboPlugin plugin : Emulator.getPluginManager().getPlugins()) { + message.append("\r").append(plugin.configuration.name).append(" By ").append(plugin.configuration.author); + } + + + if (Emulator.getConfig().getBoolean("commands.plugins.oldstyle")) { + gameClient.sendResponse(new MessagesForYouComposer(Collections.singletonList(message.toString()))); + } else { + gameClient.getHabbo().alert(message.toString()); + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PointsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PointsCommand.java new file mode 100644 index 0000000..0580188 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PointsCommand.java @@ -0,0 +1,66 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +public class PointsCommand extends Command { + public PointsCommand() { + super("cmd_points", Emulator.getTexts().getValue("commands.keys.cmd_points").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length >= 3) { + Habbo habbo = Emulator.getGameServer().getGameClientManager().getHabbo(params[1]); + + if (habbo != null) { + try { + int type = Emulator.getConfig().getInt("seasonal.primary.type"); + + if (params.length == 4) { + try { + type = Integer.valueOf(params[3]); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_points.invalid_type").replace("%types%", Emulator.getConfig().getValue("seasonal.types").replace(";", ", ")), RoomChatMessageBubbles.ALERT); + return true; + } + } + + int amount; + + try { + amount = Integer.valueOf(params[2]); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_points.invalid_amount"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (amount != 0) { + habbo.givePoints(type, amount); + + if (habbo.getHabboInfo().getCurrentRoom() != null) + habbo.whisper(Emulator.getTexts().getValue("commands.generic.cmd_points.received").replace("%amount%", amount + "").replace("%type%", Emulator.getTexts().getValue("seasonal.name." + type)), RoomChatMessageBubbles.ALERT); + else + habbo.alert(Emulator.getTexts().getValue("commands.generic.cmd_points.received").replace("%amount%", amount + "").replace("%type%", Emulator.getTexts().getValue("seasonal.name." + type))); + + // habbo.getClient().sendResponse(new UserPointsComposer(habbo.getHabboInfo().getCurrencyAmount(type), amount, type)); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_points.send").replace("%amount%", amount + "").replace("%user%", params[1]).replace("%type%", Emulator.getTexts().getValue("seasonal.name." + type)), RoomChatMessageBubbles.ALERT); + + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_points.invalid_amount"), RoomChatMessageBubbles.ALERT); + } + } catch (NumberFormatException e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_points.invalid_amount"), RoomChatMessageBubbles.ALERT); + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_points.user_offline").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_points.invalid_amount"), RoomChatMessageBubbles.ALERT); + } + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PromoteTargetOfferCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PromoteTargetOfferCommand.java new file mode 100644 index 0000000..0ffe541 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PromoteTargetOfferCommand.java @@ -0,0 +1,73 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.TargetOffer; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.catalog.TargetedOfferComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.MessagesForYouComposer; +import gnu.trove.map.hash.THashMap; + +import java.util.ArrayList; +import java.util.List; + +public class PromoteTargetOfferCommand extends Command { + + public PromoteTargetOfferCommand() { + super("cmd_promote_offer", Emulator.getTexts().getValue("commands.keys.cmd_promote_offer").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length <= 1) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_promote_offer.not_found")); + return true; + } + + String offerKey = params[1]; + + if (offerKey.equalsIgnoreCase(Emulator.getTexts().getValue("commands.cmd_promote_offer.info"))) { + THashMap targetOffers = Emulator.getGameEnvironment().getCatalogManager().targetOffers; + String[] textConfig = Emulator.getTexts().getValue("commands.cmd_promote_offer.list").replace("%amount%", targetOffers.size() + "").split("
"); + + String entryConfig = Emulator.getTexts().getValue("commands.cmd_promote_offer.list.entry"); + List message = new ArrayList<>(); + + for (String pair : textConfig) { + if (pair.contains("%list%")) { + for (TargetOffer offer : targetOffers.values()) { + message.add(entryConfig.replace("%id%", offer.getId() + "").replace("%title%", offer.getTitle()).replace("%description%", offer.getDescription().substring(0, 25))); + } + } else { + message.add(pair); + } + } + + gameClient.sendResponse(new MessagesForYouComposer(message)); + } else { + int offerId = 0; + try { + offerId = Integer.valueOf(offerKey); + } catch (Exception e) { + } + + if (offerId > 0) { + TargetOffer offer = Emulator.getGameEnvironment().getCatalogManager().getTargetOffer(offerId); + + if (offer != null) { + TargetOffer.ACTIVE_TARGET_OFFER_ID = offer.getId(); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_promote_offer").replace("%id%", offerKey).replace("%title%", offer.getTitle())); + + for (Habbo habbo : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().values()) { + habbo.getClient().sendResponse(new TargetedOfferComposer(habbo, offer)); + } + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_promote_offer.not_found")); + return true; + } + } + + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PullCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PullCommand.java new file mode 100644 index 0000000..3a45e0a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PullCommand.java @@ -0,0 +1,53 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +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.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserTalkComposer; + +public class PullCommand extends Command { + public PullCommand() { + super("cmd_pull", Emulator.getTexts().getValue("commands.keys.cmd_pull").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 2) { + Habbo habbo = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbo(params[1]); + + if (habbo == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_pull.not_found").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } else if (habbo == gameClient.getHabbo()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_pull.pull_self"), RoomChatMessageBubbles.ALERT); + return true; + } else { + int distanceX = habbo.getRoomUnit().getX() - gameClient.getHabbo().getRoomUnit().getX(); + int distanceY = habbo.getRoomUnit().getY() - gameClient.getHabbo().getRoomUnit().getY(); + + if (distanceX < -2 || distanceX > 2 || distanceY < -2 || distanceY > 2) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_pull.cant_reach").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } else { + RoomTile tile = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getLayout().getTileInFront(gameClient.getHabbo().getRoomUnit().getCurrentLocation(), gameClient.getHabbo().getRoomUnit().getBodyRotation().getValue()); + + if (tile != null && tile.isWalkable()) { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom().getLayout().getDoorTile() == tile) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_pull.invalid").replace("%username%", params[1])); + return true; + } + habbo.getRoomUnit().setGoalLocation(tile); + gameClient.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserTalkComposer(new RoomChatMessage(Emulator.getTexts().getValue("commands.succes.cmd_pull.pull").replace("%user%", params[1]).replace("%gender_name%", (gameClient.getHabbo().getHabboInfo().getGender().equals(HabboGender.M) ? Emulator.getTexts().getValue("gender.him") : Emulator.getTexts().getValue("gender.her"))), gameClient.getHabbo(), gameClient.getHabbo(), RoomChatMessageBubbles.NORMAL)).compose()); + } + } + } + return true; + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PushCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PushCommand.java new file mode 100644 index 0000000..d9518c0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/PushCommand.java @@ -0,0 +1,54 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +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.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserTalkComposer; + +public class PushCommand extends Command { + public PushCommand() { + super("cmd_push", Emulator.getTexts().getValue("commands.keys.cmd_push").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 2) { + Habbo habbo = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbo(params[1]); + + if (habbo == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_push.not_found").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } else if (habbo == gameClient.getHabbo()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_push.push_self"), RoomChatMessageBubbles.ALERT); + return true; + } else { + RoomTile tFront = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getLayout().getTileInFront(gameClient.getHabbo().getRoomUnit().getCurrentLocation(), gameClient.getHabbo().getRoomUnit().getBodyRotation().getValue()); + + if (tFront != null && tFront.isWalkable()) { + if (tFront.x == habbo.getRoomUnit().getX() && tFront.y == habbo.getRoomUnit().getY()) { + RoomTile tFrontTarget = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getLayout().getTileInFront(habbo.getRoomUnit().getCurrentLocation(), gameClient.getHabbo().getRoomUnit().getBodyRotation().getValue()); + + if (tFrontTarget != null && tFrontTarget.isWalkable()) { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom().getLayout().getDoorTile() == tFrontTarget) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_push.invalid").replace("%username%", params[1])); + return true; + } + habbo.getRoomUnit().setGoalLocation(tFrontTarget); + gameClient.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserTalkComposer(new RoomChatMessage(Emulator.getTexts().getValue("commands.succes.cmd_push.push").replace("%user%", params[1]).replace("%gender_name%", (gameClient.getHabbo().getHabboInfo().getGender().equals(HabboGender.M) ? Emulator.getTexts().getValue("gender.him") : Emulator.getTexts().getValue("gender.her"))), gameClient.getHabbo(), gameClient.getHabbo(), RoomChatMessageBubbles.NORMAL)).compose()); + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_push.cant_reach").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + } + } + return true; + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RedeemCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RedeemCommand.java new file mode 100644 index 0000000..9d38947 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RedeemCommand.java @@ -0,0 +1,106 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.threading.runnables.QueryDeleteHabboItems; +import gnu.trove.map.TIntIntMap; +import gnu.trove.map.hash.TIntIntHashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.procedure.TIntIntProcedure; + +import java.util.ArrayList; + +public class RedeemCommand extends Command { + public RedeemCommand() { + super("cmd_redeem", Emulator.getTexts().getValue("commands.keys.cmd_redeem").split(";")); + } + + @Override + public boolean handle(final GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom().getActiveTradeForHabbo(gameClient.getHabbo()) != null) + return false; + ArrayList items = new ArrayList<>(); + + int credits = 0; + int pixels = 0; + + TIntIntMap points = new TIntIntHashMap(); + + for (HabboItem item : gameClient.getHabbo().getInventory().getItemsComponent().getItemsAsValueCollection()) { + if (item.getBaseItem().getName().startsWith("CF_") || item.getBaseItem().getName().startsWith("CFC_") || item.getBaseItem().getName().startsWith("DF_") || item.getBaseItem().getName().startsWith("PF_")) { + if (item.getUserId() == gameClient.getHabbo().getHabboInfo().getId()) { + items.add(item); + if ((item.getBaseItem().getName().startsWith("CF_") || item.getBaseItem().getName().startsWith("CFC_")) && !item.getBaseItem().getName().contains("_diamond_")) { + try { + credits += Integer.valueOf(item.getBaseItem().getName().split("_")[1]); + } catch (Exception e) { + } + + } else if (item.getBaseItem().getName().startsWith("PF_")) { + try { + pixels += Integer.valueOf(item.getBaseItem().getName().split("_")[1]); + } catch (Exception e) { + } + } else if (item.getBaseItem().getName().startsWith("DF_")) { + int pointsType; + int pointsAmount; + + pointsType = Integer.valueOf(item.getBaseItem().getName().split("_")[1]); + pointsAmount = Integer.valueOf(item.getBaseItem().getName().split("_")[2]); + + points.adjustOrPutValue(pointsType, pointsAmount, pointsAmount); + } + else if (item.getBaseItem().getName().startsWith("CF_diamond_")) { + int pointsType; + int pointsAmount; + + pointsType = 5; + pointsAmount = Integer.valueOf(item.getBaseItem().getName().split("_")[2]); + + points.adjustOrPutValue(pointsType, pointsAmount, pointsAmount); + } + } + } + } + + TIntObjectHashMap deleted = new TIntObjectHashMap<>(); + for (HabboItem item : items) { + gameClient.getHabbo().getInventory().getItemsComponent().removeHabboItem(item); + deleted.put(item.getId(), item); + } + + Emulator.getThreading().run(new QueryDeleteHabboItems(deleted)); + + gameClient.sendResponse(new InventoryRefreshComposer()); + gameClient.getHabbo().giveCredits(credits); + gameClient.getHabbo().givePixels(pixels); + + final String[] message = {Emulator.getTexts().getValue("generic.redeemed")}; + + message[0] += Emulator.getTexts().getValue("generic.credits"); + message[0] += ": " + credits; + + if (pixels > 0) { + message[0] += ", " + Emulator.getTexts().getValue("generic.pixels"); + message[0] += ": " + pixels + ""; + } + + if (!points.isEmpty()) { + points.forEachEntry(new TIntIntProcedure() { + @Override + public boolean execute(int a, int b) { + gameClient.getHabbo().givePoints(a, b); + message[0] += " ," + Emulator.getTexts().getValue("seasonal.name." + a) + ": " + b; + return true; + } + }); + } + + gameClient.getHabbo().whisper(message[0], RoomChatMessageBubbles.ALERT); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ReloadRoomCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ReloadRoomCommand.java new file mode 100644 index 0000000..1ccd20d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ReloadRoomCommand.java @@ -0,0 +1,35 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.ForwardToRoomComposer; + +import java.util.ArrayList; +import java.util.Collection; + +public class ReloadRoomCommand extends Command { + public ReloadRoomCommand() { + super("cmd_reload_room", Emulator.getTexts().getValue("commands.keys.cmd_reload_room").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Emulator.getThreading().run(() -> { + Room room = gameClient.getHabbo().getHabboInfo().getCurrentRoom(); + if (room != null) { + Collection habbos = new ArrayList<>(room.getHabbos()); + Emulator.getGameEnvironment().getRoomManager().unloadRoom(room); + room = Emulator.getGameEnvironment().getRoomManager().loadRoom(room.getId()); + ServerMessage message = new ForwardToRoomComposer(room.getId()).compose(); + for (Habbo habbo : habbos) { + habbo.getClient().sendResponse(message); + } + } + }, 100); + + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomAlertCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomAlertCommand.java new file mode 100644 index 0000000..e71b6ab --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomAlertCommand.java @@ -0,0 +1,38 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.messages.outgoing.modtool.ModToolIssueHandledComposer; + +public class RoomAlertCommand extends Command { + public RoomAlertCommand() { + super("cmd_roomalert", Emulator.getTexts().getValue("commands.keys.cmd_roomalert").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + StringBuilder message = new StringBuilder(); + + if (params.length >= 2) { + for (int i = 1; i < params.length; i++) { + message.append(params[i]).append(" "); + } + + if (message.length() == 0) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_roomalert.empty"), RoomChatMessageBubbles.ALERT); + return true; + } + + Room room = gameClient.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + room.sendComposer(new ModToolIssueHandledComposer(message.toString()).compose()); + return true; + } + } + + return false; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomBadgeCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomBadgeCommand.java new file mode 100644 index 0000000..a269321 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomBadgeCommand.java @@ -0,0 +1,54 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.habbohotel.users.inventory.BadgesComponent; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.users.AddUserBadgeComposer; +import gnu.trove.map.hash.THashMap; + +public class RoomBadgeCommand extends Command { + public RoomBadgeCommand() { + super("cmd_roombadge", Emulator.getTexts().getValue("commands.keys.cmd_roombadge").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient == null) + return true; + + if (params.length == 2) { + String badge; + + badge = params[1]; + + if (!badge.isEmpty()) { + THashMap keys = new THashMap<>(); + keys.put("display", "BUBBLE"); + keys.put("image", "${image.library.url}album1584/" + badge + ".gif"); + keys.put("message", Emulator.getTexts().getValue("commands.generic.cmd_badge.received")); + ServerMessage message = new BubbleAlertComposer(BubbleAlertKeys.RECEIVED_BADGE.key, keys).compose(); + + for (Habbo habbo : gameClient.getHabbo().getRoomUnit().getRoom().getHabbos()) { + if (habbo.isOnline()) { + if (habbo.getInventory() != null && habbo.getInventory().getBadgesComponent() != null && !habbo.getInventory().getBadgesComponent().hasBadge(badge)) { + HabboBadge b = BadgesComponent.createBadge(badge, habbo); + + habbo.getClient().sendResponse(new AddUserBadgeComposer(b)); + habbo.getClient().sendResponse(message); + } + } + } + } + return true; + } + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_roombadge.no_badge"), RoomChatMessageBubbles.ALERT); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomBundleCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomBundleCommand.java new file mode 100644 index 0000000..346a1e3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomBundleCommand.java @@ -0,0 +1,77 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.habbohotel.catalog.CatalogPageLayouts; +import com.eu.habbo.habbohotel.catalog.layouts.RoomBundleLayout; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import lombok.extern.slf4j.Slf4j; + +import java.sql.*; + +@Slf4j +public class RoomBundleCommand extends Command { + + public RoomBundleCommand() { + super("cmd_bundle", Emulator.getTexts().getValue("commands.keys.cmd_bundle").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + int parentId; + int credits; + int points; + int pointsType; + + if (params.length < 5) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_bundle.missing_params"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (Emulator.getGameEnvironment().getCatalogManager().getCatalogPage("room_bundle_" + gameClient.getHabbo().getHabboInfo().getCurrentRoom().getId()) != null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_bundle.duplicate"), RoomChatMessageBubbles.ALERT); + return true; + } + + parentId = Integer.valueOf(params[1]); + credits = Integer.valueOf(params[2]); + points = Integer.valueOf(params[3]); + pointsType = Integer.valueOf(params[4]); + + CatalogPage page = Emulator.getGameEnvironment().getCatalogManager().createCatalogPage("Room Bundle: " + gameClient.getHabbo().getHabboInfo().getCurrentRoom().getName(), "room_bundle_" + gameClient.getHabbo().getHabboInfo().getCurrentRoom().getId(), gameClient.getHabbo().getHabboInfo().getCurrentRoom().getId(), 0, CatalogPageLayouts.room_bundle, gameClient.getHabbo().getHabboInfo().getRank().getId(), parentId); + + if (page instanceof RoomBundleLayout) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO catalog_items (page_id, item_ids, catalog_name, cost_credits, cost_points, points_type ) VALUES (?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, page.getId()); + statement.setString(2, ""); + statement.setString(3, "room_bundle"); + statement.setInt(4, credits); + statement.setInt(5, points); + statement.setInt(6, pointsType); + statement.execute(); + + try (ResultSet set = statement.getGeneratedKeys()) { + if (set.next()) { + try (PreparedStatement stmt = connection.prepareStatement("SELECT * FROM catalog_items WHERE id = ?")) { + stmt.setInt(1, set.getInt(1)); + try (ResultSet st = stmt.executeQuery()) { + if (st.next()) { + page.addItem(new CatalogItem(st)); + } + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + ((RoomBundleLayout) page).loadItems(gameClient.getHabbo().getHabboInfo().getCurrentRoom()); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_bundle").replace("%id%", page.getId() + ""), RoomChatMessageBubbles.ALERT); + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomCreditsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomCreditsCommand.java new file mode 100644 index 0000000..1c72b7a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomCreditsCommand.java @@ -0,0 +1,37 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +public class RoomCreditsCommand extends Command { + public RoomCreditsCommand() { + super("cmd_roomcredits", Emulator.getTexts().getValue("commands.keys.cmd_roomcredits").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 2) { + int amount; + + try { + amount = Integer.valueOf(params[1]); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_masscredits.invalid_amount"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (amount != 0) { + final String message = Emulator.getTexts().getValue("commands.generic.cmd_credits.received").replace("%amount%", amount + ""); + for (Habbo habbo : gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbos()) { + habbo.giveCredits(amount); + habbo.whisper(message, RoomChatMessageBubbles.ALERT); + } + } + return true; + } + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_masscredits.invalid_amount"), RoomChatMessageBubbles.ALERT); + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomDanceCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomDanceCommand.java new file mode 100644 index 0000000..0fcfa7b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomDanceCommand.java @@ -0,0 +1,42 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.DanceType; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDanceComposer; + +public class RoomDanceCommand extends Command { + public RoomDanceCommand() { + super("cmd_danceall", Emulator.getTexts().getValue("commands.keys.cmd_danceall").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 2) { + int danceId; + + try { + danceId = Integer.valueOf(params[1]); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_danceall.invalid_dance"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (danceId < 0 || danceId > 4) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_danceall.outside_bounds"), RoomChatMessageBubbles.ALERT); + return true; + } + + for (Habbo habbo : gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbos()) { + habbo.getRoomUnit().setDanceType(DanceType.values()[danceId]); + habbo.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserDanceComposer(habbo.getRoomUnit()).compose()); + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_danceall.no_dance"), RoomChatMessageBubbles.ALERT); + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomEffectCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomEffectCommand.java new file mode 100644 index 0000000..111b388 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomEffectCommand.java @@ -0,0 +1,40 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +public class RoomEffectCommand extends Command { + public RoomEffectCommand() { + super("cmd_roomeffect", Emulator.getTexts().getValue("commands.keys.cmd_roomeffect").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length < 2) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_roomeffect.no_effect"), RoomChatMessageBubbles.ALERT); + return true; + } + + try { + int effectId = Integer.valueOf(params[1]); + + if (effectId >= 0) { + Room room = gameClient.getHabbo().getHabboInfo().getCurrentRoom(); + for (Habbo habbo : room.getHabbos()) { + room.giveEffect(habbo, effectId, -1); + } + + return true; + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_roomeffect.positive"), RoomChatMessageBubbles.ALERT); + return true; + } + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_roomeffect.numbers_only"), RoomChatMessageBubbles.ALERT); + return true; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomGiftCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomGiftCommand.java new file mode 100644 index 0000000..f1914b5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomGiftCommand.java @@ -0,0 +1,71 @@ +package com.eu.habbo.habbohotel.commands; + +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.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.wired.WiredRewardAlertComposer; + +public class RoomGiftCommand extends Command { + public RoomGiftCommand() { + super("cmd_roomgift", Emulator.getTexts().getValue("commands.keys.cmd_roomgift").split(";")); + } + + @Override + public boolean handle(final GameClient gameClient, String[] params) throws Exception { + if (params.length >= 2) { + int itemId; + + try { + itemId = Integer.valueOf(params[1]); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_gift.not_a_number"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (itemId <= 0) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_gift.not_a_number"), RoomChatMessageBubbles.ALERT); + return true; + } + + final Item baseItem = Emulator.getGameEnvironment().getItemManager().getItem(itemId); + + if (baseItem == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_gift.not_found").replace("%itemid%", itemId + ""), RoomChatMessageBubbles.ALERT); + return true; + } + + StringBuilder message = new StringBuilder(); + + if (params.length > 2) { + for (int i = 2; i < params.length; i++) { + message.append(params[i]).append(" "); + } + } + + final String finalMessage = message.toString(); + + for (Habbo habbo : gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbos()) { + HabboItem item = Emulator.getGameEnvironment().getItemManager().createItem(0, baseItem, 0, 0, ""); + + Item giftItem = Emulator.getGameEnvironment().getItemManager().getItem((Integer) Emulator.getGameEnvironment().getCatalogManager().giftFurnis.values().toArray()[Emulator.getRandom().nextInt(Emulator.getGameEnvironment().getCatalogManager().giftFurnis.size())]); + + String extraData = "1\t" + item.getId(); + extraData += "\t0\t0\t0\t" + finalMessage + "\t0\t0"; + + Emulator.getGameEnvironment().getItemManager().createGift(habbo.getHabboInfo().getUsername(), giftItem, extraData, 0, 0); + + habbo.getClient().sendResponse(new InventoryRefreshComposer()); + + habbo.getClient().sendResponse(new WiredRewardAlertComposer(WiredRewardAlertComposer.REWARD_RECEIVED_ITEM)); + } + + return true; + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomItemCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomItemCommand.java new file mode 100644 index 0000000..d0bfbae --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomItemCommand.java @@ -0,0 +1,45 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserHandItemComposer; + +public class RoomItemCommand extends Command { + public RoomItemCommand() { + super("cmd_roomitem", Emulator.getTexts().getValue("commands.keys.cmd_roomitem").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + int itemId = 0; + + if (params.length >= 2) { + try { + itemId = Integer.valueOf(params[1]); + + if (itemId < 0) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_roomitem.positive"), RoomChatMessageBubbles.ALERT); + return true; + } + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_roomitem.no_item"), RoomChatMessageBubbles.ALERT); + return true; + } + } + + for (Habbo habbo : gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbos()) { + habbo.getRoomUnit().setHandItem(itemId); + habbo.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserHandItemComposer(habbo.getRoomUnit()).compose()); + } + + if (itemId > 0) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_roomitem.given").replace("%item%", itemId + ""), RoomChatMessageBubbles.ALERT); + return true; + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_roomitem.removed"), RoomChatMessageBubbles.ALERT); + return true; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomKickCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomKickCommand.java new file mode 100644 index 0000000..3610e06 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomKickCommand.java @@ -0,0 +1,35 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.generic.alerts.GenericAlertComposer; + +public class RoomKickCommand extends Command { + public RoomKickCommand() { + super("cmd_kickall", Emulator.getTexts().getValue("commands.keys.cmd_kickall").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + final Room room = gameClient.getHabbo().getHabboInfo().getCurrentRoom(); + if (room != null) { + if (params.length > 1) { + StringBuilder message = new StringBuilder(); + for (int i = 1; i < params.length; i++) { + message.append(params[i]).append(" "); + } + room.sendComposer(new GenericAlertComposer(message + "\r\n-" + gameClient.getHabbo().getHabboInfo().getUsername()).compose()); + } + + for (Habbo habbo : room.getHabbos()) { + if (!(habbo.hasPermission(Permission.ACC_UNKICKABLE) || habbo.hasPermission(Permission.ACC_SUPPORTTOOL) || room.isOwner(habbo))) { + room.kickHabbo(habbo, true); + } + } + } + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomMuteCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomMuteCommand.java new file mode 100644 index 0000000..5ee1bd4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomMuteCommand.java @@ -0,0 +1,24 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class RoomMuteCommand extends Command { + public RoomMuteCommand() { + super("cmd_roommute", Emulator.getTexts().getValue("commands.keys.cmd_roommute").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Room room = gameClient.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + room.setMuted(!room.isMuted()); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_roommute." + (room.isMuted() ? "muted" : "unmuted")), RoomChatMessageBubbles.ALERT); + } + + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomPixelsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomPixelsCommand.java new file mode 100644 index 0000000..567400f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomPixelsCommand.java @@ -0,0 +1,37 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +public class RoomPixelsCommand extends Command { + public RoomPixelsCommand() { + super("cmd_roompixels", Emulator.getTexts().getValue("commands.keys.cmd_roompixels").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 2) { + int amount; + + try { + amount = Integer.valueOf(params[1]); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_massduckets.invalid_amount"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (amount != 0) { + final String message = Emulator.getTexts().getValue("commands.generic.cmd_duckets.received").replace("%amount%", amount + ""); + for (Habbo habbo : gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbos()) { + habbo.givePixels(amount); + habbo.whisper(message, RoomChatMessageBubbles.ALERT); + } + } + return true; + } + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_massduckets.invalid_amount"), RoomChatMessageBubbles.ALERT); + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomPointsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomPointsCommand.java new file mode 100644 index 0000000..32ebe50 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/RoomPointsCommand.java @@ -0,0 +1,65 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +public class RoomPointsCommand extends Command { + public RoomPointsCommand() { + super("cmd_roompoints", Emulator.getTexts().getValue("commands.keys.cmd_roompoints").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + int type = Emulator.getConfig().getInt("seasonal.primary.type"); + String amountString; + if (params.length == 3) { + try { + amountString = params[1]; + + type = Integer.valueOf(params[2]); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_masspoints.invalid_type").replace("%types%", Emulator.getConfig().getValue("seasonal.types").replace(";", ", ")), RoomChatMessageBubbles.ALERT); + return true; + } + } else if (params.length == 2) { + amountString = params[1]; + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_masspoints.invalid_amount"), RoomChatMessageBubbles.ALERT); + return true; + } + + boolean found = false; + for (String s : Emulator.getConfig().getValue("seasonal.types").split(";")) { + if (s.equalsIgnoreCase(type + "")) { + found = true; + break; + } + } + + if (!found) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_masspoints.invalid_type").replace("%types%", Emulator.getConfig().getValue("seasonal.types").replace(";", ", ")), RoomChatMessageBubbles.ALERT); + return true; + } + + int amount; + + try { + amount = Integer.valueOf(amountString); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_masspoints.invalid_amount"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (amount != 0) { + final String message = Emulator.getTexts().getValue("commands.generic.cmd_points.received").replace("%amount%", amount + "").replace("%type%", Emulator.getTexts().getValue("seasonal.name." + type)); + + for (Habbo habbo : gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbos()) { + habbo.givePoints(type, amount); + habbo.whisper(message, RoomChatMessageBubbles.ALERT); + } + } + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SayAllCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SayAllCommand.java new file mode 100644 index 0000000..17cf15a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SayAllCommand.java @@ -0,0 +1,31 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +public class SayAllCommand extends Command { + public SayAllCommand() { + super("cmd_say_all", Emulator.getTexts().getValue("commands.keys.cmd_say_all").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length < 2) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_say_all.forgot_message"), RoomChatMessageBubbles.ALERT); + return true; + } + + StringBuilder message = new StringBuilder(); + for (int i = 1; i < params.length; i++) { + message.append(params[i]).append(" "); + } + + for (Habbo habbo : gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbos()) { + habbo.talk(message.toString()); + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SayCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SayCommand.java new file mode 100644 index 0000000..64addc3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SayCommand.java @@ -0,0 +1,45 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserTalkComposer; + +public class SayCommand extends Command { + public SayCommand() { + super("cmd_say", Emulator.getTexts().getValue("commands.keys.cmd_say").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length < 2) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_say.forgot_username"), RoomChatMessageBubbles.ALERT); + return true; + } + + Habbo target = Emulator.getGameEnvironment().getHabboManager().getHabbo(params[1]); + + if (target == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_say.user_not_found"), RoomChatMessageBubbles.ALERT); + return true; + } else { + if (target.getHabboInfo().getCurrentRoom() == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_say.hotel_view").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + } + + StringBuilder message = new StringBuilder(); + if (params.length > 2) { + for (int i = 2; i < params.length; i++) { + message.append(params[i]).append(" "); + } + } + + target.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserTalkComposer(new RoomChatMessage(message.toString(), target, RoomChatMessageBubbles.NORMAL)).compose()); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_say").replace("%user%", params[1]).replace("%message%", message.toString()), RoomChatMessageBubbles.ALERT); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SetMaxCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SetMaxCommand.java new file mode 100644 index 0000000..b6bdfd8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SetMaxCommand.java @@ -0,0 +1,35 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class SetMaxCommand extends Command { + public SetMaxCommand() { + super("cmd_setmax", Emulator.getTexts().getValue("commands.keys.cmd_setmax").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length >= 2) { + int max; + try { + max = Integer.valueOf(params[1]); + } catch (Exception e) { + return false; + } + + if (max > 0 && max < 9999) { + gameClient.getHabbo().getHabboInfo().getCurrentRoom().setUsersMax(max); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.success.cmd_setmax").replace("%value%", max + ""), RoomChatMessageBubbles.ALERT); + return true; + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_setmax.invalid_number"), RoomChatMessageBubbles.ALERT); + return true; + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_setmax.forgot_number"), RoomChatMessageBubbles.ALERT); + return true; + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SetPollCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SetPollCommand.java new file mode 100644 index 0000000..b9c0072 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SetPollCommand.java @@ -0,0 +1,40 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class SetPollCommand extends Command { + public SetPollCommand() { + super("cmd_set_poll", Emulator.getTexts().getValue("commands.keys.cmd_set_poll").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length >= 2) { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + int pollId = -1; + try { + pollId = Integer.valueOf(params[1]); + } catch (Exception e) { + + } + + if (pollId >= 0) { + if (Emulator.getGameEnvironment().getPollManager().getPoll(pollId) != null) { + gameClient.getHabbo().getHabboInfo().getCurrentRoom().setPollId(pollId); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_set_poll"), RoomChatMessageBubbles.ALERT); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_set_poll.not_found"), RoomChatMessageBubbles.ALERT); + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_set_poll.invalid_number"), RoomChatMessageBubbles.ALERT); + } + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_set_poll.missing_arg"), RoomChatMessageBubbles.ALERT); + } + + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SetSpeedCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SetSpeedCommand.java new file mode 100644 index 0000000..bdce54d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SetSpeedCommand.java @@ -0,0 +1,42 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class SetSpeedCommand extends Command { + public SetSpeedCommand() { + super("cmd_setspeed", Emulator.getTexts().getValue("commands.keys.cmd_setspeed").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() != null) { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom().hasRights(gameClient.getHabbo())) { + Room room = gameClient.getHabbo().getHabboInfo().getCurrentRoom(); + + int oldSpeed = room.getRollerSpeed(); + int newSpeed; + + try { + newSpeed = Integer.valueOf(params[1]); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_setspeed.invalid_amount"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (newSpeed < -1 || newSpeed > Emulator.getConfig().getInt("hotel.rollers.speed.maximum")) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_setspeed.bounds"), RoomChatMessageBubbles.ALERT); + return true; + } + + room.setRollerSpeed(newSpeed); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_setspeed").replace("%oldspeed%", oldSpeed + "").replace("%newspeed%", newSpeed + ""), RoomChatMessageBubbles.ALERT); + return true; + } + } + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ShoutAllCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ShoutAllCommand.java new file mode 100644 index 0000000..156a4da --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ShoutAllCommand.java @@ -0,0 +1,31 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ShoutAllCommand extends Command { + public ShoutAllCommand() { + super("cmd_shout_all", Emulator.getTexts().getValue("commands.keys.cmd_shout_all").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length < 2) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_shout_all.forgot_message"), RoomChatMessageBubbles.ALERT); + return true; + } + + StringBuilder message = new StringBuilder(); + for (int i = 1; i < params.length; i++) { + message.append(params[i]).append(" "); + } + + for (Habbo habbo : gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbos()) { + habbo.shout(message.toString()); + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ShoutCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ShoutCommand.java new file mode 100644 index 0000000..bb12158 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ShoutCommand.java @@ -0,0 +1,47 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserShoutComposer; + +public class ShoutCommand extends Command { + private static String idea = "Kudo's To Droppy for this idea!"; + + public ShoutCommand() { + super("cmd_shout", Emulator.getTexts().getValue("commands.keys.cmd_shout").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length < 2) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_shout.forgot_username"), RoomChatMessageBubbles.ALERT); + return true; + } + + Habbo target = Emulator.getGameEnvironment().getHabboManager().getHabbo(params[1]); + + if (target == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_shout.user_not_found"), RoomChatMessageBubbles.ALERT); + return true; + } else { + if (target.getHabboInfo().getCurrentRoom() == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_shout.hotel_view").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + } + + StringBuilder message = new StringBuilder(); + if (params.length > 2) { + for (int i = 2; i < params.length; i++) { + message.append(params[i]).append(" "); + } + } + + target.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserShoutComposer(new RoomChatMessage(message.toString(), target, RoomChatMessageBubbles.NORMAL)).compose()); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_shout").replace("%user%", params[1]).replace("%message%", message.toString()), RoomChatMessageBubbles.ALERT); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ShutdownCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ShutdownCommand.java new file mode 100644 index 0000000..7abeea6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/ShutdownCommand.java @@ -0,0 +1,50 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomTrade; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.generic.alerts.GenericAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.HotelWillCloseInMinutesComposer; +import com.eu.habbo.threading.runnables.ShutdownEmulator; + +public class ShutdownCommand extends Command { + public ShutdownCommand() { + super("cmd_shutdown", Emulator.getTexts().getValue("commands.keys.cmd_shutdown").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + StringBuilder reason = new StringBuilder("-"); + int minutes = 0; + if (params.length > 2) { + reason = new StringBuilder(); + for (int i = 1; i < params.length; i++) { + reason.append(params[i]).append(" "); + } + } else { + if (params.length == 2) { + try { + minutes = Integer.valueOf(params[1]); + } catch (Exception e) { + reason = new StringBuilder(params[1]); + } + } + } + + ServerMessage message; + if (!reason.toString().equals("-")) { + message = new GenericAlertComposer("" + Emulator.getTexts().getValue("generic.warning") + " \r\n" + + Emulator.getTexts().getValue("generic.shutdown").replace("%minutes%", minutes + "") + "\r\n" + + Emulator.getTexts().getValue("generic.reason.specified") + ": " + reason + "\r" + + "\r" + + "- " + gameClient.getHabbo().getHabboInfo().getUsername()).compose(); + } else { + message = new HotelWillCloseInMinutesComposer(minutes).compose(); + } + RoomTrade.TRADING_ENABLED = false; + ShutdownEmulator.timestamp = Emulator.getIntUnixTimestamp() + (60 * minutes); + Emulator.getThreading().run(new ShutdownEmulator(message), minutes * 60 * 1000); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SitCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SitCommand.java new file mode 100644 index 0000000..dd8199c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SitCommand.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; + +public class SitCommand extends Command { + public SitCommand() { + super(null, Emulator.getTexts().getValue("commands.keys.cmd_sit").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getRiding() == null) //TODO Make this an event plugin which fires that can be cancelled + gameClient.getHabbo().getHabboInfo().getCurrentRoom().makeSit(gameClient.getHabbo()); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SitDownCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SitDownCommand.java new file mode 100644 index 0000000..afb37a3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SitDownCommand.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; + +public class SitDownCommand extends Command { + public SitDownCommand() { + super("cmd_sitdown", Emulator.getTexts().getValue("commands.keys.cmd_sitdown").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + for (Habbo habbo : gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbos()) { + if (habbo.getRoomUnit().isWalking()) { + habbo.getRoomUnit().stopWalking(); + } else if (habbo.getRoomUnit().hasStatus(RoomUnitStatus.SIT)) { + continue; + } + + gameClient.getHabbo().getHabboInfo().getCurrentRoom().makeSit(habbo); + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SoftKickCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SoftKickCommand.java new file mode 100644 index 0000000..b841b94 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SoftKickCommand.java @@ -0,0 +1,41 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +public class SoftKickCommand extends Command { + public SoftKickCommand() { + super("cmd_softkick", Emulator.getTexts().getValue("commands.keys.cmd_softkick").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 2) { + final String username = params[1]; + final Habbo habbo = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbo(username); + + if (habbo == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.keys.cmd_softkick_error").replace("%user%", username), RoomChatMessageBubbles.ALERT); + return true; + } + + if (habbo == gameClient.getHabbo()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.keys.cmd_softkick_error_self"), RoomChatMessageBubbles.ALERT); + return true; + } + + final Room room = gameClient.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + if (!(habbo.hasPermission(Permission.ACC_UNKICKABLE) || habbo.hasPermission(Permission.ACC_SUPPORTTOOL) || room.isOwner(habbo))) { + room.kickHabbo(habbo, false); + } + } + } + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/StaffAlertCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/StaffAlertCommand.java new file mode 100644 index 0000000..ef4afe9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/StaffAlertCommand.java @@ -0,0 +1,30 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.messenger.Message; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.messages.outgoing.friends.FriendChatMessageComposer; + +public class StaffAlertCommand extends Command { + public StaffAlertCommand() { + super("cmd_staffalert", Emulator.getTexts().getValue("commands.keys.cmd_staffalert").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length > 1) { + StringBuilder message = new StringBuilder(); + for (int i = 1; i < params.length; i++) { + message.append(params[i]).append(" "); + } + + Emulator.getGameEnvironment().getHabboManager().staffAlert(message + "\r\n\r\nVan:" + gameClient.getHabbo().getHabboInfo().getUsername()); + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new FriendChatMessageComposer(new Message(gameClient.getHabbo().getHabboInfo().getId(), -1, message.toString())).compose(), "acc_staff_chat", gameClient); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_staffalert.forgot_message"), RoomChatMessageBubbles.ALERT); + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/StaffOnlineCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/StaffOnlineCommand.java new file mode 100644 index 0000000..19eabca --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/StaffOnlineCommand.java @@ -0,0 +1,68 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Map; + +public class StaffOnlineCommand extends Command { + public StaffOnlineCommand() { + super("cmd_staffonline", Emulator.getTexts().getValue("commands.keys.cmd_staffonline").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + int minRank = Emulator.getConfig().getInt("commands.cmd_staffonline.min_rank"); + + if (params.length >= 2) { + try { + int i = Integer.valueOf(params[1]); + + if (i < 1) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_staffonline.positive_only"), RoomChatMessageBubbles.ALERT); + return true; + } else { + minRank = i; + } + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_staffonline.numbers_only"), RoomChatMessageBubbles.ALERT); + return true; + } + } + + synchronized (Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos()) { + ArrayList staffs = new ArrayList<>(); + + for (Map.Entry set : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + if (set.getValue().getHabboInfo().getRank().getId() >= minRank) { + staffs.add(set.getValue()); + } + } + + staffs.sort(new Comparator() { + @Override + public int compare(Habbo o1, Habbo o2) { + return o1.getHabboInfo().getId() - o2.getHabboInfo().getId(); + } + }); + + StringBuilder message = new StringBuilder(Emulator.getTexts().getValue("commands.generic.cmd_staffonline.staffs")); + message.append("\r\n"); + + for (Habbo habbo : staffs) { + message.append(habbo.getHabboInfo().getUsername()); + message.append(": "); + message.append(habbo.getHabboInfo().getRank().getName()); + message.append("\r"); + } + + gameClient.getHabbo().alert(message.toString()); + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/StalkCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/StalkCommand.java new file mode 100644 index 0000000..ac87441 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/StalkCommand.java @@ -0,0 +1,55 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.RoomDataComposer; + +public class StalkCommand extends Command { + public StalkCommand() { + super("cmd_stalk", Emulator.getTexts().getValue("commands.keys.cmd_stalk").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() == null) + return true; + + if (params.length >= 2) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(params[1]); + + if (habbo == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_stalk.not_found").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + + if (habbo.getHabboInfo().isInvisibleInRooms()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_stalk.not_room").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + + if (habbo.getHabboInfo().getCurrentRoom() == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_stalk.not_room").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + + if (gameClient.getHabbo().getHabboInfo().getUsername().equals(habbo.getHabboInfo().getUsername())) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.generic.cmd_stalk.self").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() == habbo.getHabboInfo().getCurrentRoom()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.generic.cmd_stalk.same_room").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + + gameClient.sendResponse(new RoomDataComposer(habbo.getHabboInfo().getCurrentRoom(), gameClient.getHabbo(), true, false)); + //gameClient.sendResponse(new ForwardToRoomComposer(habbo.getHabboInfo().getCurrentRoom().getId())); + return true; + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_stalk.forgot_username"), RoomChatMessageBubbles.ALERT); + return true; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/StandCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/StandCommand.java new file mode 100644 index 0000000..82bf092 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/StandCommand.java @@ -0,0 +1,18 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; + +public class StandCommand extends Command { + public StandCommand() { + super(null, Emulator.getTexts().getValue("commands.keys.cmd_stand").split(";")); + } + + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getRiding() == null) + gameClient.getHabbo().getHabboInfo().getCurrentRoom().makeStand(gameClient.getHabbo()); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SubscriptionCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SubscriptionCommand.java new file mode 100644 index 0000000..96350ae --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SubscriptionCommand.java @@ -0,0 +1,109 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.eu.habbo.habbohotel.users.HabboStats; +import com.eu.habbo.habbohotel.users.subscriptions.Subscription; + +/** + * @author Beny + */ +public class SubscriptionCommand extends Command { + public SubscriptionCommand() { + super("cmd_subscription", Emulator.getTexts().getValue("commands.keys.cmd_subscription").split(";")); + } + + /** + * Allows you to give/extend/remove subscription on a given user. + * + * Parameters: + * [username] = Username of user to execute command on + * [type] = Subscription type (e.g. HABBO_CLUB) + * [add|remove] = Use add or remove to increase/decrease sub duration + * [time] = Time string e.g. "1 week", "18 days", "4 minutes". Can be complex e.g. "1 month 5 days 2 minutes" + * + * Examples: + * :sub Beny habbo_club add 1 month - adds 1 month of HABBO_CLUB subscription duration on the user Beny + * :sub Beny builders_club add 1 month - adds 1 month of BUILDERS_CLUB subscription duration on the user Beny + * :sub Beny habbo_club remove 3 days - removes 3 days of HABBO_CLUB subscription duration on the user Beny + * :sub Beny habbo_club remove - removes all remaining time from the HABBO_CLUB subscription (expires it) on the user Beny + * + * @param gameClient Client that executed the command + * @param params Command parameters + * @return Boolean indicating success + * @throws Exception Exception + */ + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length >= 4) { + HabboInfo info = HabboManager.getOfflineHabboInfo(params[1]); + + if (info != null) { + HabboStats stats = info.getHabboStats(); + String subscription = params[2].toUpperCase(); + String action = params[3]; + + StringBuilder message = new StringBuilder(); + if (params.length > 4) { + for (int i = 4; i < params.length; i++) { + message.append(params[i]).append(" "); + } + } + + if(!Emulator.getGameEnvironment().getSubscriptionManager().types.containsKey(subscription)) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.type_not_found", "%subscription% is not a valid subscription type").replace("%subscription%", subscription), RoomChatMessageBubbles.ALERT); + return true; + } + + if(action.equalsIgnoreCase("add") || action.equalsIgnoreCase("+") || action.equalsIgnoreCase("a")) { + int timeToAdd = Emulator.timeStringToSeconds(message.toString()); + + if(timeToAdd < 1) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.invalid_params_time", "Invalid time span, try: x minutes/days/weeks/months"), RoomChatMessageBubbles.ALERT); + return true; + } + + stats.createSubscription(subscription, timeToAdd); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.success_add_time", "Successfully added %time% seconds to %subscription% on %user%").replace("%time%", timeToAdd + "").replace("%user%", params[1]).replace("%subscription%", subscription), RoomChatMessageBubbles.ALERT); + } + else if(action.equalsIgnoreCase("remove") || action.equalsIgnoreCase("-") || action.equalsIgnoreCase("r")) { + Subscription s = stats.getSubscription(subscription); + + if (s == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.user_not_have", "%user% does not have the %subscription% subscription").replace("%user%", params[1]).replace("%subscription%", subscription), RoomChatMessageBubbles.ALERT); + return true; + } + + if(message.length() != 0) { + int timeToRemove = Emulator.timeStringToSeconds(message.toString()); + + if (timeToRemove < 1) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.invalid_params_time", "Invalid time span, try: x minutes/days/weeks/months"), RoomChatMessageBubbles.ALERT); + return true; + } + + s.addDuration(-timeToRemove); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.success_remove_time", "Successfully removed %time% seconds from %subscription% on %user%").replace("%time%", timeToRemove + "").replace("%user%", params[1]).replace("%subscription%", subscription), RoomChatMessageBubbles.ALERT); + } + else { + s.addDuration(-s.getRemaining()); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.success_remove_sub", "Successfully removed %subscription% sub from %user%").replace("%user%", params[1]).replace("%subscription%", subscription), RoomChatMessageBubbles.ALERT); + } + } + else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.invalid_action", "Invalid action specified. Must be add, +, remove or -"), RoomChatMessageBubbles.ALERT); + } + + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.user_not_found", "%user% was not found").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + } + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.invalid_params", "Invalid command format"), RoomChatMessageBubbles.ALERT); + } + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SummonCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SummonCommand.java new file mode 100644 index 0000000..b362f5a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SummonCommand.java @@ -0,0 +1,61 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.ForwardToRoomComposer; + +public class SummonCommand extends Command { + public SummonCommand() { + super("cmd_summon", Emulator.getTexts().getValue("commands.keys.cmd_summon").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() == null) + return true; + + if (params.length >= 2) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(params[1]); + + if (habbo == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_summon.not_found").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + + if (gameClient.getHabbo().getHabboInfo().getUsername().equals(habbo.getHabboInfo().getUsername())) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.generic.cmd_summon.self").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom() == habbo.getHabboInfo().getCurrentRoom()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.generic.cmd_summon.same_room").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + + Room room = habbo.getHabboInfo().getCurrentRoom(); + if (room != null) { + Emulator.getGameEnvironment().getRoomManager().logExit(habbo); + + room.removeHabbo(habbo, true); + + habbo.getHabboInfo().setCurrentRoom(null); + } + + Emulator.getGameEnvironment().getRoomManager().enterRoom(habbo, gameClient.getHabbo().getHabboInfo().getCurrentRoom().getId(), "", true); + + habbo.getClient().sendResponse(new ForwardToRoomComposer(gameClient.getHabbo().getHabboInfo().getCurrentRoom().getId())); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_summon.summoned").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + + habbo.alert(Emulator.getTexts().getValue("commands.generic.cmd_summon.been_summoned").replace("%user%", gameClient.getHabbo().getHabboInfo().getUsername())); + + return true; + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_summon.forgot_username"), RoomChatMessageBubbles.ALERT); + return true; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SummonRankCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SummonRankCommand.java new file mode 100644 index 0000000..16312bd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SummonRankCommand.java @@ -0,0 +1,56 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.ForwardToRoomComposer; + +import java.util.Map; + +public class SummonRankCommand extends Command { + public SummonRankCommand() { + super("cmd_summonrank", Emulator.getTexts().getValue("commands.keys.cmd_summonrank").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + int minRank; + + if (params.length >= 2) { + try { + minRank = Integer.parseInt(params[1]); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.generic.cmd_summonrank.error"), RoomChatMessageBubbles.ALERT); + return true; + } + + for (Map.Entry set : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + if (set.getValue().getHabboInfo().getRank().getId() >= minRank) { + if (set.getValue() == gameClient.getHabbo()) + continue; + + if (set.getValue().getHabboInfo().getCurrentRoom() == gameClient.getHabbo().getHabboInfo().getCurrentRoom()) + continue; + + Room room = set.getValue().getHabboInfo().getCurrentRoom(); + if (room != null) { + Emulator.getGameEnvironment().getRoomManager().logExit(set.getValue()); + + room.removeHabbo(set.getValue(), true); + + set.getValue().getHabboInfo().setCurrentRoom(null); + } + + Emulator.getGameEnvironment().getRoomManager().enterRoom(set.getValue(), gameClient.getHabbo().getHabboInfo().getCurrentRoom().getId(), "", true); + + set.getValue().getClient().sendResponse(new ForwardToRoomComposer(gameClient.getHabbo().getHabboInfo().getCurrentRoom().getId())); + + } + } + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SuperPullCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SuperPullCommand.java new file mode 100644 index 0000000..edb29ea --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SuperPullCommand.java @@ -0,0 +1,45 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +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.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserTalkComposer; + +public class SuperPullCommand extends Command { + public SuperPullCommand() { + super("cmd_superpull", Emulator.getTexts().getValue("commands.keys.cmd_superpull").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 2) { + Habbo habbo = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getHabbo(params[1]); + + if (habbo == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_pull.not_found").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } else if (habbo == gameClient.getHabbo()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_pull.pull_self"), RoomChatMessageBubbles.ALERT); + return true; + } else { + RoomTile tile = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getLayout().getTileInFront(gameClient.getHabbo().getRoomUnit().getCurrentLocation(), gameClient.getHabbo().getRoomUnit().getBodyRotation().getValue()); + + if (tile != null && tile.isWalkable()) { + if (tile == gameClient.getHabbo().getHabboInfo().getCurrentRoom().getLayout().getDoorTile()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_pull.invalid").replace("%username%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + habbo.getRoomUnit().setGoalLocation(tile); + gameClient.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserTalkComposer(new RoomChatMessage(Emulator.getTexts().getValue("commands.succes.cmd_pull.pull").replace("%user%", params[1]).replace("%gender_name%", (gameClient.getHabbo().getHabboInfo().getGender().equals(HabboGender.M) ? Emulator.getTexts().getValue("gender.him") : Emulator.getTexts().getValue("gender.her"))), gameClient.getHabbo(), gameClient.getHabbo(), RoomChatMessageBubbles.NORMAL)).compose()); + } + } + return true; + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SuperbanCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SuperbanCommand.java new file mode 100644 index 0000000..8f9d896 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/SuperbanCommand.java @@ -0,0 +1,59 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.modtool.ModToolBanType; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboManager; + +public class SuperbanCommand extends Command { + public SuperbanCommand() { + super("cmd_super_ban", Emulator.getTexts().getValue("commands.keys.cmd_super_ban").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + HabboInfo habbo = null; + StringBuilder reason = new StringBuilder(); + if (params.length >= 2) { + Habbo h = Emulator.getGameEnvironment().getHabboManager().getHabbo(params[1]); + + if (h != null) { + habbo = h.getHabboInfo(); + } else { + habbo = HabboManager.getOfflineHabboInfo(params[1]); + } + } + + if (params.length > 2) { + for (int i = 2; i < params.length; i++) { + reason.append(params[i]); + reason.append(" "); + } + } + + int count; + if (habbo != null) { + if (habbo == gameClient.getHabbo().getHabboInfo()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_super_ban.ban_self"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (habbo.getRank().getId() >= gameClient.getHabbo().getHabboInfo().getRank().getId()) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT); + return true; + } + + count = Emulator.getGameEnvironment().getModToolManager().ban(habbo.getId(), gameClient.getHabbo(), reason.toString(), IPBanCommand.TEN_YEARS, ModToolBanType.SUPER, -1).size(); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.user_offline"), RoomChatMessageBubbles.ALERT); + return true; + } + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_super_ban").replace("%count%", count + ""), RoomChatMessageBubbles.ALERT); + + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TakeBadgeCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TakeBadgeCommand.java new file mode 100644 index 0000000..2afe3bb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TakeBadgeCommand.java @@ -0,0 +1,68 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.eu.habbo.habbohotel.users.inventory.BadgesComponent; +import com.eu.habbo.messages.outgoing.inventory.InventoryBadgesComposer; +import com.eu.habbo.messages.outgoing.users.UserBadgesComposer; + +public class TakeBadgeCommand extends Command { + public TakeBadgeCommand() { + super("cmd_take_badge", Emulator.getTexts().getValue("commands.keys.cmd_take_badge").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 2) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_take_badge.forgot_badge"), RoomChatMessageBubbles.ALERT); + return true; + } else if (params.length == 1) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_take_badge.forgot_username"), RoomChatMessageBubbles.ALERT); + return true; + } + + if (params.length == 3) { + String username = params[1]; + String badge = params[2]; + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(username); + + if (habbo != null) { + HabboBadge b = habbo.getInventory().getBadgesComponent().removeBadge(badge); + + if (b == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_take_badge.no_badge").replace("%username%", username).replace("%badge%", badge), RoomChatMessageBubbles.ALERT); + return true; + } + + habbo.getClient().sendResponse(new InventoryBadgesComposer(habbo)); + if (habbo.getHabboInfo().getCurrentRoom() != null) { + habbo.getHabboInfo().getCurrentRoom().sendComposer(new UserBadgesComposer(habbo.getInventory().getBadgesComponent().getWearingBadges(), habbo.getHabboInfo().getId()).compose()); + } + } + + int userId = 0; + + if (habbo != null) + userId = habbo.getHabboInfo().getId(); + else { + HabboInfo habboInfo = HabboManager.getOfflineHabboInfo(username); + if (habboInfo != null) + userId = habboInfo.getId(); + } + + if (userId > 0) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_take_badge"), RoomChatMessageBubbles.ALERT); + + BadgesComponent.deleteBadge(userId, badge); + } + } + + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TeleportCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TeleportCommand.java new file mode 100644 index 0000000..4a79e88 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TeleportCommand.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class TeleportCommand extends Command { + public TeleportCommand() { + super("cmd_teleport", Emulator.getTexts().getValue("commands.keys.cmd_teleport").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getRiding() == null) //TODO Make this an event plugin which fires that can be cancelled + if (gameClient.getHabbo().getRoomUnit().cmdTeleport) { + gameClient.getHabbo().getRoomUnit().cmdTeleport = false; + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_teleport.disabled"), RoomChatMessageBubbles.ALERT); + return true; + } else { + gameClient.getHabbo().getRoomUnit().cmdTeleport = true; + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_teleport.enabled"), RoomChatMessageBubbles.ALERT); + return true; + } + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TestCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TestCommand.java new file mode 100644 index 0000000..243dec7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TestCommand.java @@ -0,0 +1,46 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.messages.ServerMessage; + +public class TestCommand extends Command { + public TestCommand() { + super("acc_debug", new String[]{"test"}); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo() != null || !gameClient.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL) || !Emulator.debugging) + return false; + + int header = Integer.valueOf(params[1]); + + ServerMessage message = new ServerMessage(header); + + for (int i = 1; i < params.length; i++) { + String[] data = params[i].split(":"); + + if (data[0].equalsIgnoreCase("b")) { + message.appendBoolean(data[1].equalsIgnoreCase("1")); + } else if (data[0].equalsIgnoreCase("s")) { + if (data.length > 1) { + message.appendString(data[1]); + } else { + message.appendString(""); + } + } else if (data[0].equals("i")) { + message.appendInt(Integer.valueOf(data[1])); + } else if (data[0].equalsIgnoreCase("by")) { + message.appendByte(Integer.valueOf(data[1])); + } else if (data[0].equalsIgnoreCase("sh")) { + message.appendShort(Integer.valueOf(data[1])); + } + } + + gameClient.sendResponse(message); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TransformCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TransformCommand.java new file mode 100644 index 0000000..39feb7c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TransformCommand.java @@ -0,0 +1,69 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.core.RoomUserPetComposer; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.pets.PetData; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUnitType; +import com.eu.habbo.messages.outgoing.generic.alerts.MessagesForYouComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserRemoveComposer; + +import java.util.ArrayList; +import java.util.Collections; + +public class TransformCommand extends Command { + protected TransformCommand() { + super("cmd_transform", new String[]{"transform"}); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 1) { + StringBuilder petNames = new StringBuilder(); + petNames.append(Emulator.getTexts().getValue("commands.generic.cmd_transform.title")); + petNames.append("\r------------------------------------------------------------------------------\r"); + ArrayList petData = new ArrayList<>(Emulator.getGameEnvironment().getPetManager().getPetData()); + Collections.sort(petData); + String line = Emulator.getTexts().getValue("commands.generic.cmd_transform.line"); + for (PetData p : petData) { + petNames.append(line.replace("%id%", p.getType() + "").replace("%name%", p.getName())).append("\r"); + } + + gameClient.sendResponse(new MessagesForYouComposer(new String[]{petNames.toString()})); + return true; + } else { + String petName = params[1]; + PetData petData = Emulator.getGameEnvironment().getPetManager().getPetData(petName); + + int race = 0; + + if (params.length >= 3) { + try { + race = Integer.valueOf(params[2]); + } catch (Exception e) { + return true; + } + } + + String color = "FFFFFF"; + if (params.length >= 4) { + color = params[3]; + } + + if (petData != null) { + RoomUnit roomUnit = gameClient.getHabbo().getRoomUnit(); + roomUnit.setRoomUnitType(RoomUnitType.PET); + gameClient.getHabbo().getHabboStats().cache.put("pet_type", petData); + gameClient.getHabbo().getHabboStats().cache.put("pet_race", race); + gameClient.getHabbo().getHabboStats().cache.put("pet_color", color); + gameClient.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserRemoveComposer(gameClient.getHabbo().getRoomUnit()).compose()); + gameClient.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserPetComposer(petData.getType(), race, color, gameClient.getHabbo()).compose()); + } else { + //Pet Not Found + return true; + } + return true; + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TrashCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TrashCommand.java new file mode 100644 index 0000000..196fecc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/TrashCommand.java @@ -0,0 +1,16 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; + +public class TrashCommand extends Command { + public TrashCommand() { + super("cmd_trash", Emulator.getTexts().getValue("commands.keys.cmd_trash").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + gameClient.getHabbo().whisper("Sorry. Lulz mode removed |"); + return false; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UnbanCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UnbanCommand.java new file mode 100644 index 0000000..dea44bd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UnbanCommand.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class UnbanCommand extends Command { + public UnbanCommand() { + super("cmd_unban", Emulator.getTexts().getValue("commands.keys.cmd_unban").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 1) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_unban.not_specified"), RoomChatMessageBubbles.ALERT); + } else { + if (Emulator.getGameEnvironment().getModToolManager().unban(params[1])) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_unban.success").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_unban.not_found").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + } + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UnloadRoomCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UnloadRoomCommand.java new file mode 100644 index 0000000..8082401 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UnloadRoomCommand.java @@ -0,0 +1,23 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; + +public class UnloadRoomCommand extends Command { + + public UnloadRoomCommand() { + super("cmd_unload", Emulator.getTexts().getValue("commands.keys.cmd_unload").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (gameClient.getHabbo().getHabboInfo().getCurrentRoom().getOwnerId() == gameClient.getHabbo().getHabboInfo().getId() || gameClient.getHabbo().getHabboInfo().getRank().getId() > 4) { + Room room = gameClient.getHabbo().getHabboInfo().getCurrentRoom(); + + room.dispose(); + return true; + } + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UnmuteCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UnmuteCommand.java new file mode 100644 index 0000000..376f8b9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UnmuteCommand.java @@ -0,0 +1,44 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; + +public class UnmuteCommand extends Command { + public UnmuteCommand() { + super("cmd_unmute", Emulator.getTexts().getValue("commands.keys.cmd_unmute").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length == 1) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_unmute.not_specified"), RoomChatMessageBubbles.ALERT); + return true; + } + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(params[1]); + + if (habbo == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_unmute.not_found").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } else { + if (!habbo.getHabboStats().allowTalk() || (habbo.getHabboInfo().getCurrentRoom() != null && habbo.getHabboInfo().getCurrentRoom().isMuted(habbo))) { + if (!habbo.getHabboStats().allowTalk()) { + habbo.unMute(); + } + + if (habbo.getHabboInfo().getCurrentRoom() != null && habbo.getHabboInfo().getCurrentRoom().isMuted(habbo)) { + habbo.getHabboInfo().getCurrentRoom().muteHabbo(habbo, 1); + } + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_unmute").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + } else { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_unmute.not_muted").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + } + + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateAchievements.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateAchievements.java new file mode 100644 index 0000000..70dc56f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateAchievements.java @@ -0,0 +1,18 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class UpdateAchievements extends Command { + public UpdateAchievements() { + super("cmd_update_achievements", Emulator.getTexts().getValue("commands.keys.cmd_update_achievements").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Emulator.getGameEnvironment().getAchievementManager().reload(); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_update_achievements.updated"), RoomChatMessageBubbles.ALERT); + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateBotsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateBotsCommand.java new file mode 100644 index 0000000..eaf57e9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateBotsCommand.java @@ -0,0 +1,15 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; + +public class UpdateBotsCommand extends Command { + public UpdateBotsCommand() { + super("cmd_update_bots", Emulator.getTexts().getValue("commands.keys.cmd_update_bots").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + return Emulator.getGameEnvironment().getBotManager().reload(); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateCalendarCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateCalendarCommand.java new file mode 100644 index 0000000..a110c20 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateCalendarCommand.java @@ -0,0 +1,21 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.messages.outgoing.catalog.*; +import com.eu.habbo.messages.outgoing.catalog.marketplace.MarketplaceConfigComposer; + +public class UpdateCalendarCommand extends Command { + + public UpdateCalendarCommand() { + super("cmd_update_calendar", Emulator.getTexts().getValue("commands.keys.cmd_update_calendar").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) { + Emulator.getGameEnvironment().getCalendarManager().reload(); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.success.cmd_update_calendar"), RoomChatMessageBubbles.ALERT); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateCatalogCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateCatalogCommand.java new file mode 100644 index 0000000..730fd4a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateCatalogCommand.java @@ -0,0 +1,28 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.messages.outgoing.catalog.*; +import com.eu.habbo.messages.outgoing.catalog.marketplace.MarketplaceConfigComposer; + +public class UpdateCatalogCommand extends Command { + + public UpdateCatalogCommand() { + super("cmd_update_catalogue", Emulator.getTexts().getValue("commands.keys.cmd_update_catalogue").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) { + Emulator.getGameEnvironment().getCatalogManager().initialize(); + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new CatalogUpdatedComposer()); + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new CatalogModeComposer(0)); + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new DiscountComposer()); + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new MarketplaceConfigComposer()); + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new GiftConfigurationComposer()); + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new RecyclerLogicComposer()); + Emulator.getGameEnvironment().getCraftingManager().reload(); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_update_catalog"), RoomChatMessageBubbles.ALERT); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateConfigCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateConfigCommand.java new file mode 100644 index 0000000..7b859cd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateConfigCommand.java @@ -0,0 +1,20 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class UpdateConfigCommand extends Command { + public UpdateConfigCommand() { + super("cmd_update_config", Emulator.getTexts().getValue("commands.keys.cmd_update_config").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Emulator.getConfig().reload(); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_update_config"), RoomChatMessageBubbles.ALERT); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateGuildPartsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateGuildPartsCommand.java new file mode 100644 index 0000000..b7b47a9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateGuildPartsCommand.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; + +public class UpdateGuildPartsCommand extends Command { + public UpdateGuildPartsCommand() { + super("cmd_update_guildparts", Emulator.getTexts().getValue("commands.keys.cmd_update_guildparts").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Emulator.getGameEnvironment().getGuildManager().loadGuildParts(); + Emulator.getBadgeImager().reload(); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateHotelViewCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateHotelViewCommand.java new file mode 100644 index 0000000..88f9c60 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateHotelViewCommand.java @@ -0,0 +1,20 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; + +public class UpdateHotelViewCommand extends Command { + protected UpdateHotelViewCommand() { + super("cmd_update_hotel_view", Emulator.getTexts().getValue("commands.keys.cmd_update_hotel_view").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Emulator.getGameEnvironment().getHotelViewManager().getNewsList().reload(); + Emulator.getGameEnvironment().getHotelViewManager().getHallOfFame().reload(); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_update_hotel_view")); + + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateItemsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateItemsCommand.java new file mode 100644 index 0000000..073b251 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateItemsCommand.java @@ -0,0 +1,32 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.messages.outgoing.rooms.RoomRelativeMapComposer; + +public class UpdateItemsCommand extends Command { + public UpdateItemsCommand() { + super("cmd_update_items", Emulator.getTexts().getValue("commands.keys.cmd_update_items").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Emulator.getGameEnvironment().getItemManager().loadItems(); + Emulator.getGameEnvironment().getItemManager().loadCrackable(); + Emulator.getGameEnvironment().getItemManager().loadSoundTracks(); + + synchronized (Emulator.getGameEnvironment().getRoomManager().getActiveRooms()) { + for (Room room : Emulator.getGameEnvironment().getRoomManager().getActiveRooms()) { + if (room.isLoaded() && room.getUserCount() > 0 && room.getLayout() != null) { + room.sendComposer(new RoomRelativeMapComposer(room).compose()); + } + } + } + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_update_items"), RoomChatMessageBubbles.ALERT); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateNavigatorCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateNavigatorCommand.java new file mode 100644 index 0000000..ee3b5f9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateNavigatorCommand.java @@ -0,0 +1,21 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class UpdateNavigatorCommand extends Command { + public UpdateNavigatorCommand() { + super("cmd_update_navigator", Emulator.getTexts().getValue("commands.keys.cmd_update_navigator").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Emulator.getGameEnvironment().getNavigatorManager().loadNavigator(); + Emulator.getGameEnvironment().getRoomManager().loadRoomModels(); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_update_navigator"), RoomChatMessageBubbles.ALERT); + + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdatePermissionsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdatePermissionsCommand.java new file mode 100644 index 0000000..9f257bd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdatePermissionsCommand.java @@ -0,0 +1,20 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class UpdatePermissionsCommand extends Command { + public UpdatePermissionsCommand() { + super("cmd_update_permissions", Emulator.getTexts().getValue("commands.keys.cmd_update_permissions").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Emulator.getGameEnvironment().getPermissionsManager().reload(); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_update_permissions"), RoomChatMessageBubbles.ALERT); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdatePetDataCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdatePetDataCommand.java new file mode 100644 index 0000000..5d07e2d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdatePetDataCommand.java @@ -0,0 +1,20 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class UpdatePetDataCommand extends Command { + public UpdatePetDataCommand() { + super("cmd_update_pet_data", Emulator.getTexts().getValue("commands.keys.cmd_update_pet_data").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Emulator.getGameEnvironment().getPetManager().reloadPetData(); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_update_pet_data"), RoomChatMessageBubbles.ALERT); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdatePluginsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdatePluginsCommand.java new file mode 100644 index 0000000..285d98d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdatePluginsCommand.java @@ -0,0 +1,20 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class UpdatePluginsCommand extends Command { + public UpdatePluginsCommand() { + super("cmd_update_plugins", Emulator.getTexts().getValue("commands.keys.cmd_update_plugins").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Emulator.getPluginManager().reload(); + + gameClient.getHabbo().whisper("This is an unsafe command and could possibly lead to memory leaks.\rIt is recommended to restart the emulator in order to reload plugins."); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_update_plugins").replace("%count%", Emulator.getPluginManager().getPlugins().size() + ""), RoomChatMessageBubbles.ALERT); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdatePollsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdatePollsCommand.java new file mode 100644 index 0000000..c82e2d5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdatePollsCommand.java @@ -0,0 +1,18 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class UpdatePollsCommand extends Command { + public UpdatePollsCommand() { + super("cmd_update_polls", Emulator.getTexts().getValue("commands.keys.cmd_update_polls").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Emulator.getGameEnvironment().getPollManager().loadPolls(); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_update_polls"), RoomChatMessageBubbles.ALERT); + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateTextsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateTextsCommand.java new file mode 100644 index 0000000..a8a68b9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateTextsCommand.java @@ -0,0 +1,24 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class UpdateTextsCommand extends Command { + public UpdateTextsCommand() { + super("cmd_update_texts", Emulator.getTexts().getValue("commands.keys.cmd_update_texts").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + try { + Emulator.getTexts().reload(); + Emulator.getGameEnvironment().getCommandHandler().reloadCommands(); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_update_texts"), RoomChatMessageBubbles.ALERT); + } catch (Exception e) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_update_texts.failed"), RoomChatMessageBubbles.ALERT); + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateWordFilterCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateWordFilterCommand.java new file mode 100644 index 0000000..ad70f80 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateWordFilterCommand.java @@ -0,0 +1,20 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +public class UpdateWordFilterCommand extends Command { + public UpdateWordFilterCommand() { + super("cmd_update_wordfilter", Emulator.getTexts().getValue("commands.keys.update_wordfilter").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Emulator.getGameEnvironment().getWordFilter().reload(); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_update_wordfilter"), RoomChatMessageBubbles.ALERT); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateYoutubePlaylistsCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateYoutubePlaylistsCommand.java new file mode 100644 index 0000000..94dcf7b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UpdateYoutubePlaylistsCommand.java @@ -0,0 +1,22 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.messages.outgoing.rooms.RoomRelativeMapComposer; + +public class UpdateYoutubePlaylistsCommand extends Command { + public UpdateYoutubePlaylistsCommand() { + super("cmd_update_youtube_playlists", Emulator.getTexts().getValue("commands.keys.cmd_update_youtube_playlists").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + Emulator.getGameEnvironment().getItemManager().getYoutubeManager().load(); + + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_update_youtube_playlists"), RoomChatMessageBubbles.ALERT); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UserInfoCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UserInfoCommand.java new file mode 100644 index 0000000..9299a86 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/UserInfoCommand.java @@ -0,0 +1,108 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.modtool.ModToolBan; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboManager; +import gnu.trove.iterator.TIntIntIterator; + +import java.text.SimpleDateFormat; +import java.util.*; + +public class UserInfoCommand extends Command { + public UserInfoCommand() { + super("cmd_userinfo", Emulator.getTexts().getValue("commands.keys.cmd_userinfo").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (params.length < 2) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_userinfo.forgot_username"), RoomChatMessageBubbles.ALERT); + return true; + } + + Habbo onlineHabbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(params[1]); + HabboInfo habbo = (onlineHabbo != null ? onlineHabbo.getHabboInfo() : null); + + if (habbo == null) { + habbo = HabboManager.getOfflineHabboInfo(params[1]); + } + + if (habbo == null) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_userinfo.not_found").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT); + return true; + } + + StringBuilder message = new StringBuilder(Emulator.getTexts().getValue("command.cmd_userinfo.userinfo") + ": " + " " + habbo.getUsername() + " (" + habbo.getId() + ")\r" + + Emulator.getTexts().getValue("command.cmd_userinfo.user_id") + ": " + habbo.getId() + "\r" + + Emulator.getTexts().getValue("command.cmd_userinfo.user_name") + ": " + habbo.getUsername() + "\r" + + Emulator.getTexts().getValue("command.cmd_userinfo.motto") + ": " + habbo.getMotto().replace("<", "[").replace(">", "]") + "\r" + + Emulator.getTexts().getValue("command.cmd_userinfo.rank") + ": " + habbo.getRank().getName() + " (" + habbo.getRank().getId() + ") \r" + + Emulator.getTexts().getValue("command.cmd_userinfo.online") + ": " + (onlineHabbo == null ? Emulator.getTexts().getValue("generic.no") : Emulator.getTexts().getValue("generic.yes")) + "\r" + + ((habbo.getRank().hasPermission(Permission.ACC_HIDE_MAIL, true)) ? "" : Emulator.getTexts().getValue("command.cmd_userinfo.email") + ": " + habbo.getMail() + "\r") + + ((habbo.getRank().hasPermission(Permission.ACC_HIDE_IP, true)) ? "" : Emulator.getTexts().getValue("command.cmd_userinfo.ip_register") + ": " + habbo.getIpRegister() + "\r") + + ((habbo.getRank().hasPermission(Permission.ACC_HIDE_IP, true)) || onlineHabbo == null ? "" : Emulator.getTexts().getValue("command.cmd_userinfo.ip_current") + ": " + onlineHabbo.getHabboInfo().getIpLogin() + "\r") + + (onlineHabbo != null ? Emulator.getTexts().getValue("command.cmd_userinfo.achievement_score") + ": " + onlineHabbo.getHabboStats().achievementScore + "\r" : "")); + + ModToolBan ban = Emulator.getGameEnvironment().getModToolManager().checkForBan(habbo.getId()); + + message.append(Emulator.getTexts().getValue("command.cmd_userinfo.total_bans")).append(": ").append(Emulator.getGameEnvironment().getModToolManager().totalBans(habbo.getId())).append("\r"); + message.append(Emulator.getTexts().getValue("command.cmd_userinfo.banned")).append(": ").append(Emulator.getTexts().getValue(ban != null ? "generic.yes" : "generic.no")).append("\r\r"); + if (ban != null) { + message.append("").append(Emulator.getTexts().getValue("command.cmd_userinfo.ban_info")).append("\r"); + message.append(ban.listInfo()).append("\r"); + } + + message.append("").append(Emulator.getTexts().getValue("command.cmd_userinfo.currencies")).append("\r"); + message.append(Emulator.getTexts().getValue("command.cmd_userinfo.credits")).append(": ").append(habbo.getCredits()).append("\r"); + TIntIntIterator iterator = habbo.getCurrencies().iterator(); + + for (int i = habbo.getCurrencies().size(); i-- > 0; ) { + try { + iterator.advance(); + } catch (Exception e) { + break; + } + + message.append(Emulator.getTexts().getValue("seasonal.name." + iterator.key())).append(": ").append(iterator.value()).append("\r"); + } + message.append("\r").append(onlineHabbo != null ? "" + Emulator.getTexts().getValue("command.cmd_userinfo.current_activity") + "\r" : "").append(onlineHabbo != null ? Emulator.getTexts().getValue("command.cmd_userinfo.room") + ": " + ((onlineHabbo.getHabboInfo().getCurrentRoom() != null && !onlineHabbo.getHabboInfo().isInvisibleInRooms()) ? onlineHabbo.getHabboInfo().getCurrentRoom().getName() + "(" + onlineHabbo.getHabboInfo().getCurrentRoom().getId() + ")\r" : "-") : "").append(onlineHabbo != null ? Emulator.getTexts().getValue("command.cmd_userinfo.respect_left") + ": " + onlineHabbo.getHabboStats().respectPointsToGive + "\r" : "").append(onlineHabbo != null ? Emulator.getTexts().getValue("command.cmd_userinfo.pet_respect_left") + ": " + onlineHabbo.getHabboStats().petRespectPointsToGive + "\r" : "").append(onlineHabbo != null ? Emulator.getTexts().getValue("command.cmd_userinfo.allow_trade") + ": " + ((onlineHabbo.getHabboStats().allowTrade()) ? Emulator.getTexts().getValue("generic.yes") : Emulator.getTexts().getValue("generic.no")) + "\r" : "").append(onlineHabbo != null ? Emulator.getTexts().getValue("command.cmd_userinfo.allow_follow") + ": " + ((onlineHabbo.getHabboStats().blockFollowing) ? Emulator.getTexts().getValue("generic.no") : Emulator.getTexts().getValue("generic.yes")) + "\r" : "").append(onlineHabbo != null ? Emulator.getTexts().getValue("command.cmd_userinfo.allow_friend_request") + ": " + ((onlineHabbo.getHabboStats().blockFriendRequests) ? Emulator.getTexts().getValue("generic.no") : Emulator.getTexts().getValue("generic.yes")) + "\r" : ""); + + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + List> nameChanges = Emulator.getGameEnvironment().getHabboManager().getNameChanges(habbo.getId(), 3); + if (!nameChanges.isEmpty()) { + message.append("\rLatest name changes:
"); + for (Map.Entry entry : nameChanges) { + message.append(format.format(new Date((long) entry.getKey() * 1000L))).append(" : ").append(entry.getValue()).append("
"); + } + } + + if (onlineHabbo != null) { + message.append("\r" + "Other accounts ("); + + ArrayList users = Emulator.getGameEnvironment().getHabboManager().getCloneAccounts(onlineHabbo, 10); + users.sort(new Comparator() { + @Override + public int compare(HabboInfo o1, HabboInfo o2) { + return o1.getId() - o2.getId(); + } + }); + + message.append(users.size()).append("):\r"); + + + message.append("Username,\tID,\tDate register,\tDate last online\r"); + + for (HabboInfo info : users) { + message.append(info.getUsername()).append(",\t").append(info.getId()).append(",\t").append(format.format(new Date((long) info.getAccountCreated() * 1000L))).append(",\t").append(format.format(new Date((long) info.getLastOnline() * 1000L))).append("\r"); + } + } + gameClient.getHabbo().alert(message.toString()); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/WordQuizCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/WordQuizCommand.java new file mode 100644 index 0000000..ba74d5d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/commands/WordQuizCommand.java @@ -0,0 +1,38 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; + +import java.util.Arrays; + +public class WordQuizCommand extends Command { + public WordQuizCommand() { + super("cmd_word_quiz", Emulator.getTexts().getValue("commands.keys.cmd_word_quiz").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) throws Exception { + if (!gameClient.getHabbo().getHabboInfo().getCurrentRoom().hasActiveWordQuiz()) { + if(params.length == 1) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.description.cmd_word_quiz"), RoomChatMessageBubbles.ALERT); + return true; + } + StringBuilder question = new StringBuilder(); + int duration = 60; + + try { + duration = Integer.parseInt(params[params.length-1]); + params = Arrays.copyOf(params, params.length-1); + } + catch (Exception e) {} + + for (int i = 1; i < params.length; i++) { + question.append(" ").append(params[i]); + } + + gameClient.getHabbo().getHabboInfo().getCurrentRoom().startWordQuiz(question.toString(), duration * 1000); + } + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/crafting/CraftingAltar.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/crafting/CraftingAltar.java new file mode 100644 index 0000000..dc7dcda --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/crafting/CraftingAltar.java @@ -0,0 +1,133 @@ +package com.eu.habbo.habbohotel.crafting; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.users.Habbo; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +public class CraftingAltar { + private final Item baseItem; + private final THashSet ingredients; + private final THashMap recipes; + + public CraftingAltar(Item baseItem) { + this.baseItem = baseItem; + + this.ingredients = new THashSet<>(1); + this.recipes = new THashMap<>(1); + } + + public void addIngredient(Item item) { + this.ingredients.add(item); + } + + public boolean hasIngredient(Item item) { + return this.ingredients.contains(item); + } + + public Map matchRecipes(Map amountMap) { + THashMap foundRecepies = new THashMap<>(Math.max(1, this.recipes.size() / 3)); + + for (Map.Entry set : this.recipes.entrySet()) { + boolean contains = true; + boolean equals; + + if (set.getValue().isLimited() && !set.getValue().canBeCrafted()) { + continue; + } + + equals = amountMap.size() == set.getValue().getIngredients().size(); + + for (Map.Entry entry : amountMap.entrySet()) { + if (contains) { + if (set.getValue().getIngredients().containsKey(entry.getKey())) { + if (set.getValue().getIngredients().get(entry.getKey()).equals(entry.getValue())) { + continue; + } + + equals = false; + + if (set.getValue().getIngredients().get(entry.getKey()) > entry.getValue()) { + continue; + } + } + + contains = false; + } + } + + if (contains) { + foundRecepies.put(set.getValue(), equals); + } + } + + return foundRecepies; + } + + + public void addRecipe(CraftingRecipe recipe) { + this.recipes.put(recipe.getId(), recipe); + } + + public CraftingRecipe getRecipe(int id) { + return this.recipes.get(id); + } + + public CraftingRecipe getRecipe(String name) { + for (Map.Entry set : this.recipes.entrySet()) { + if (set.getValue().getName().equals(name)) { + return set.getValue(); + } + } + + return null; + } + + public CraftingRecipe getRecipe(Map items) { + for (Map.Entry set : this.recipes.entrySet()) { + CraftingRecipe recipe = set.getValue(); + + for (Map.Entry entry : recipe.getIngredients().entrySet()) { + if (!(items.containsKey(entry.getKey()) && items.get(entry.getKey()).equals(entry.getValue()))) { + recipe = null; + break; + } + } + + if (recipe != null) { + return recipe; + } + } + + return null; + } + + public List getRecipesForHabbo(Habbo habbo) { + List recipeList = new ArrayList<>(); + + for (Map.Entry set : this.recipes.entrySet()) { + if (!set.getValue().isSecret() || habbo.getHabboStats().hasRecipe(set.getValue().getId())) { + recipeList.add(set.getValue()); + } + } + + return recipeList; + } + + public Item getBaseItem() { + return this.baseItem; + } + + public Collection getIngredients() { + return this.ingredients; + } + + public Collection getRecipes() { + return this.recipes.values(); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/crafting/CraftingManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/crafting/CraftingManager.java new file mode 100644 index 0000000..079f31f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/crafting/CraftingManager.java @@ -0,0 +1,122 @@ +package com.eu.habbo.habbohotel.crafting; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectProcedure; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class CraftingManager { + private final THashMap altars; + + public CraftingManager() { + this.altars = new THashMap<>(); + + this.reload(); + } + + public void reload() { + this.dispose(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM crafting_altars_recipes " + + "INNER JOIN crafting_recipes ON crafting_altars_recipes.recipe_id = crafting_recipes.id " + + "INNER JOIN crafting_recipes_ingredients ON crafting_recipes.id = crafting_recipes_ingredients.recipe_id " + + "WHERE crafting_recipes.enabled = ? ORDER BY altar_id ASC")) { + statement.setString(1, "1"); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + Item item = Emulator.getGameEnvironment().getItemManager().getItem(set.getInt("altar_id")); + + if (item != null) { + if (!this.altars.containsKey(item)) { + this.altars.put(item, new CraftingAltar(item)); + } + + CraftingAltar altar = this.altars.get(item); + + if (altar != null) { + CraftingRecipe recipe = altar.getRecipe(set.getInt("crafting_recipes_ingredients.recipe_id")); + + if (recipe == null) { + recipe = new CraftingRecipe(set); + altar.addRecipe(recipe); + } + + Item ingredientItem = Emulator.getGameEnvironment().getItemManager().getItem(set.getInt("crafting_recipes_ingredients.item_id")); + + if (ingredientItem != null) { + recipe.addIngredient(ingredientItem, set.getInt("crafting_recipes_ingredients.amount")); + altar.addIngredient(ingredientItem); + } else { + log.error("Unknown ingredient item " + set.getInt("crafting_recipes_ingredients.item_id")); + } + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public int getRecipesWithItemCount(final Item item) { + final int[] i = {0}; + + synchronized (this.altars) { + this.altars.forEachValue(new TObjectProcedure() { + @Override + public boolean execute(CraftingAltar altar) { + if (altar.hasIngredient(item)) { + i[0]++; + } + + return true; + } + }); + } + + return i[0]; + } + + public CraftingRecipe getRecipe(String recipeName) { + CraftingRecipe recipe; + for (CraftingAltar altar : this.altars.values()) { + recipe = altar.getRecipe(recipeName); + + if (recipe != null) { + return recipe; + } + } + + return null; + } + + public CraftingAltar getAltar(Item item) { + return this.altars.get(item); + } + + public void dispose() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE crafting_recipes SET remaining = ? WHERE id = ? LIMIT 1")) { + for (CraftingAltar altar : this.altars.values()) { + for (CraftingRecipe recipe : altar.getRecipes()) { + if (recipe.isLimited()) { + statement.setInt(1, recipe.getRemaining()); + statement.setInt(2, recipe.getId()); + + statement.addBatch(); + } + } + } + statement.executeBatch(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.altars.clear(); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/crafting/CraftingRecipe.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/crafting/CraftingRecipe.java new file mode 100644 index 0000000..286dfb6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/crafting/CraftingRecipe.java @@ -0,0 +1,88 @@ +package com.eu.habbo.habbohotel.crafting; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import gnu.trove.map.hash.THashMap; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class CraftingRecipe { + private final int id; + private final String name; + private final Item reward; + private final boolean secret; + private final String achievement; + private final boolean limited; + private final THashMap ingredients; + private int remaining; + + public CraftingRecipe(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.name = set.getString("product_name"); + this.reward = Emulator.getGameEnvironment().getItemManager().getItem(set.getInt("reward")); + this.secret = set.getString("secret").equals("1"); + this.achievement = set.getString("achievement"); + this.limited = set.getString("limited").equals("1"); + this.remaining = set.getInt("remaining"); + + this.ingredients = new THashMap<>(); + } + + public boolean canBeCrafted() { + return !this.limited || this.remaining > 0; + } + + public synchronized boolean decrease() { + if (this.remaining > 0) { + this.remaining--; + return true; + } + + return false; + } + + public void addIngredient(Item item, int amount) { + this.ingredients.put(item, amount); + } + + public int getAmountNeeded(Item item) { + return this.ingredients.get(item); + } + + public boolean hasIngredient(Item item) { + return this.ingredients.containsKey(item); + } + + public int getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public Item getReward() { + return this.reward; + } + + public boolean isSecret() { + return this.secret; + } + + public String getAchievement() { + return this.achievement; + } + + public boolean isLimited() { + return this.limited; + } + + public THashMap getIngredients() { + return this.ingredients; + } + + public int getRemaining() { + return this.remaining; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/gameclients/GameClient.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/gameclients/GameClient.java new file mode 100644 index 0000000..ea122b4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/gameclients/GameClient.java @@ -0,0 +1,135 @@ +package com.eu.habbo.habbohotel.gameclients; + +import com.eu.habbo.Emulator; +import com.eu.habbo.crypto.HabboEncryption; +import com.eu.habbo.habbohotel.LatencyTracker; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.MessageComposer; +import io.netty.channel.Channel; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; +import java.util.concurrent.ConcurrentHashMap; + +@Slf4j +public class GameClient { + private final Channel channel; + private final HabboEncryption encryption; + private final LatencyTracker latencyTracker; + + private Habbo habbo; + private boolean handshakeFinished; + private String machineId = ""; + + private boolean finishedReleaseEvent = false; + + public void finishedReleaseEvent() { + this.finishedReleaseEvent = true; + } + + public boolean didFinishReleaseEvent() { + return this.finishedReleaseEvent; + } + + public final ConcurrentHashMap incomingPacketCounter = new ConcurrentHashMap<>(25); + public final ConcurrentHashMap, Long> messageTimestamps = new ConcurrentHashMap<>(); + public long lastPacketCounterCleared = Emulator.getIntUnixTimestamp(); + + public GameClient(Channel channel) { + this.channel = channel; + this.encryption = Emulator.getCrypto().isEnabled() + ? new HabboEncryption( + Emulator.getCrypto().getExponent(), + Emulator.getCrypto().getModulus(), + Emulator.getCrypto().getPrivateExponent()) + : null; + this.latencyTracker = new LatencyTracker(); + } + + public Channel getChannel() { + return this.channel; + } + + public HabboEncryption getEncryption() { + return encryption; + } + + public LatencyTracker getLatencyTracker() { + return latencyTracker; + } + + public Habbo getHabbo() { + return this.habbo; + } + + public void setHabbo(Habbo habbo) { + this.habbo = habbo; + } + + public boolean isHandshakeFinished() { + return handshakeFinished; + } + + public void setHandshakeFinished(boolean handshakeFinished) { + this.handshakeFinished = handshakeFinished; + } + + public String getMachineId() { + return this.machineId; + } + + public void setMachineId(String machineId) { + if (machineId == null) { + throw new RuntimeException("Cannot set machineID to NULL"); + } + + this.machineId = machineId; + } + + public void sendResponse(MessageComposer composer) { + this.sendResponse(composer.compose()); + } + + public void sendResponse(ServerMessage response) { + if (this.channel.isOpen()) { + if (response == null || response.getHeader() <= 0) { + return; + } + + this.channel.write(response, this.channel.voidPromise()); + this.channel.flush(); + } + } + + public void sendResponses(ArrayList responses) { + if (this.channel.isOpen()) { + for (ServerMessage response : responses) { + if (response == null || response.getHeader() <= 0) { + return; + } + + this.channel.write(response); + } + + this.channel.flush(); + } + } + + public void dispose() { + try { + this.channel.close(); + + if (this.habbo != null) { + if (this.habbo.isOnline()) { + this.habbo.getHabboInfo().setOnline(false); + this.habbo.disconnect(); + } + + this.habbo = null; + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/gameclients/GameClientManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/gameclients/GameClientManager.java new file mode 100644 index 0000000..ad9b28f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/gameclients/GameClientManager.java @@ -0,0 +1,165 @@ +package com.eu.habbo.habbohotel.gameclients; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.networking.gameserver.GameServerAttributes; +import io.netty.channel.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +public class GameClientManager { + + private final ConcurrentMap clients; + + public GameClientManager() { + this.clients = new ConcurrentHashMap<>(); + } + + + public ConcurrentMap getSessions() { + return this.clients; + } + + + public boolean addClient(ChannelHandlerContext ctx) { + GameClient client = new GameClient(ctx.channel()); + ctx.channel().closeFuture().addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + GameClientManager.this.disposeClient(ctx.channel()); + } + }); + + ctx.channel().attr(GameServerAttributes.CLIENT).set(client); + ctx.fireChannelRegistered(); + + return this.clients.putIfAbsent(ctx.channel().id(), client) == null; + } + + + public void disposeClient(GameClient client) { + this.disposeClient(client.getChannel()); + } + + private void disposeClient(Channel channel) { + GameClient client = channel.attr(GameServerAttributes.CLIENT).get(); + + if (client != null) { + client.dispose(); + } + channel.deregister(); + channel.attr(GameServerAttributes.CLIENT).set(null); + channel.closeFuture(); + channel.close(); + this.clients.remove(channel.id()); + } + + + public boolean containsHabbo(Integer id) { + if (!this.clients.isEmpty()) { + for (GameClient client : this.clients.values()) { + if (client.getHabbo() != null) { + if (client.getHabbo().getHabboInfo() != null) { + if (client.getHabbo().getHabboInfo().getId() == id) + return true; + } + } + } + } + return false; + } + + + public Habbo getHabbo(int id) { + for (GameClient client : this.clients.values()) { + if (client.getHabbo() == null) + continue; + + if (client.getHabbo().getHabboInfo().getId() == id) + return client.getHabbo(); + } + + return null; + } + + + public Habbo getHabbo(String username) { + for (GameClient client : this.clients.values()) { + if (client.getHabbo() == null) + continue; + + if (client.getHabbo().getHabboInfo().getUsername().equalsIgnoreCase(username)) + return client.getHabbo(); + } + + return null; + } + + + public List getHabbosWithIP(String ip) { + List habbos = new ArrayList<>(); + + for (GameClient client : this.clients.values()) { + if (client.getHabbo() != null && client.getHabbo().getHabboInfo() != null) { + if (client.getHabbo().getHabboInfo().getIpLogin().equalsIgnoreCase(ip)) { + habbos.add(client.getHabbo()); + } + } + } + + return habbos; + } + + + public List getHabbosWithMachineId(String machineId) { + List habbos = new ArrayList<>(); + + for (GameClient client : this.clients.values()) { + if (client.getHabbo() != null && client.getHabbo().getHabboInfo() != null && client.getMachineId().equalsIgnoreCase(machineId)) { + habbos.add(client.getHabbo()); + } + } + + return habbos; + } + + + public void sendBroadcastResponse(MessageComposer composer) { + this.sendBroadcastResponse(composer.compose()); + } + + + public void sendBroadcastResponse(ServerMessage message) { + for (GameClient client : this.clients.values()) { + client.sendResponse(message); + } + } + + + public void sendBroadcastResponse(ServerMessage message, GameClient exclude) { + for (GameClient client : this.clients.values()) { + if (client.equals(exclude)) + continue; + + client.sendResponse(message); + } + } + + + public void sendBroadcastResponse(ServerMessage message, String minPermission, GameClient exclude) { + for (GameClient client : this.clients.values()) { + if (client.equals(exclude)) + continue; + + if (client.getHabbo() != null) { + if (client.getHabbo().hasPermission(minPermission)) { + client.sendResponse(message); + } + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/Game.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/Game.java new file mode 100644 index 0000000..b0cb883 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/Game.java @@ -0,0 +1,304 @@ +package com.eu.habbo.habbohotel.games; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredHighscore; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTimer; +import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredBlob; +import com.eu.habbo.habbohotel.wired.highscores.WiredHighscoreDataEntry; +import com.eu.habbo.habbohotel.items.interactions.wired.triggers.WiredTriggerTeamLoses; +import com.eu.habbo.habbohotel.items.interactions.wired.triggers.WiredTriggerTeamWins; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.outgoing.guides.GuideSessionPartnerIsPlayingComposer; +import com.eu.habbo.plugin.Event; +import com.eu.habbo.plugin.events.games.GameHabboJoinEvent; +import com.eu.habbo.plugin.events.games.GameHabboLeaveEvent; +import com.eu.habbo.plugin.events.games.GameStartedEvent; +import com.eu.habbo.plugin.events.games.GameStoppedEvent; +import com.eu.habbo.threading.runnables.SaveScoreForTeam; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; +import java.util.Map; +import java.util.stream.Collectors; +@Slf4j +public abstract class Game implements Runnable { + protected final THashMap teams = new THashMap<>(); + protected final Room room; + private final Class gameTeamClazz; + private final Class gamePlayerClazz; + private final boolean countsAchievements; + public boolean isRunning; + public GameState state = GameState.IDLE; + private int startTime; + private int endTime; + + public Game(Class gameTeamClazz, Class gamePlayerClazz, Room room, boolean countsAchievements) { + this.gameTeamClazz = gameTeamClazz; + this.gamePlayerClazz = gamePlayerClazz; + this.room = room; + this.countsAchievements = countsAchievements; + } + + + public abstract void initialise(); + + + public boolean addHabbo(Habbo habbo, GameTeamColors teamColor) { + try { + if (habbo != null) { + if (Emulator.getPluginManager().isRegistered(GameHabboJoinEvent.class, true)) { + Event gameHabboJoinEvent = new GameHabboJoinEvent(this, habbo); + Emulator.getPluginManager().fireEvent(gameHabboJoinEvent); + if (gameHabboJoinEvent.isCancelled()) + return false; + } + + synchronized (this.teams) { + GameTeam team = this.getTeam(teamColor); + if (team == null) { + team = this.gameTeamClazz.getDeclaredConstructor(GameTeamColors.class).newInstance(teamColor); + this.addTeam(team); + } + + GamePlayer player = this.gamePlayerClazz.getDeclaredConstructor(Habbo.class, GameTeamColors.class).newInstance(habbo, teamColor); + team.addMember(player); + habbo.getHabboInfo().setCurrentGame(this.getClass()); + habbo.getHabboInfo().setGamePlayer(player); + } + habbo.getClient().sendResponse(new GuideSessionPartnerIsPlayingComposer(true)); + return true; + } + } catch (Exception e) { + log.error("Caught exception", e); + } + + return false; + } + + + public void removeHabbo(Habbo habbo) { + if (habbo != null) { + if (Emulator.getPluginManager().isRegistered(GameHabboLeaveEvent.class, true)) { + Event gameHabboLeaveEvent = new GameHabboLeaveEvent(this, habbo); + Emulator.getPluginManager().fireEvent(gameHabboLeaveEvent); + if (gameHabboLeaveEvent.isCancelled()) + return; + } + + GameTeam team = this.getTeamForHabbo(habbo); + if (team != null && team.isMember(habbo)) { + if (habbo.getHabboInfo().getGamePlayer() != null) { + team.removeMember(habbo.getHabboInfo().getGamePlayer()); + if (habbo.getHabboInfo().getGamePlayer() != null) { + habbo.getHabboInfo().getGamePlayer().reset(); + } + } + + habbo.getHabboInfo().setCurrentGame(null); + habbo.getHabboInfo().setGamePlayer(null); + habbo.getClient().sendResponse(new GuideSessionPartnerIsPlayingComposer(false)); + if (this.countsAchievements && this.endTime > this.startTime) { + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("GamePlayed")); + } + } + } + } + + + public void start() { + this.isRunning = false; + this.state = GameState.RUNNING; + this.startTime = Emulator.getIntUnixTimestamp(); + + if (Emulator.getPluginManager().isRegistered(GameStartedEvent.class, true)) { + Event gameStartedEvent = new GameStartedEvent(this); + Emulator.getPluginManager().fireEvent(gameStartedEvent); + } + + for (HabboItem item : this.room.getRoomSpecialTypes().getItemsOfType(WiredBlob.class)) { + ((WiredBlob) item).onGameStart(this.room); + } + + for (GameTeam team : this.teams.values()) { + team.resetScores(); + } + } + + public void onEnd() { + this.endTime = Emulator.getIntUnixTimestamp(); + + this.saveScores(); + + int totalPointsGained = this.teams.values().stream().mapToInt(GameTeam::getTotalScore).sum(); + + Habbo roomOwner = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.room.getOwnerId()); + if (roomOwner != null) { + AchievementManager.progressAchievement(roomOwner, Emulator.getGameEnvironment().getAchievementManager().getAchievement("GameAuthorExperience"), totalPointsGained); + } + + GameTeam winningTeam = null; + if(totalPointsGained > 0) { + for (GameTeam team : this.teams.values()) { + if (winningTeam == null || team.getTotalScore() > winningTeam.getTotalScore()) { + winningTeam = team; + } + } + } + + if (winningTeam != null) { + for (GamePlayer player : winningTeam.getMembers()) { + WiredHandler.handleCustomTrigger(WiredTriggerTeamWins.class, player.getHabbo().getRoomUnit(), this.room, new Object[]{this}); + + Habbo winner = player.getHabbo(); + if (winner != null) { + AchievementManager.progressAchievement(roomOwner, Emulator.getGameEnvironment().getAchievementManager().getAchievement("GamePlayerExperience")); + } + } + + if (winningTeam.getMembers().size() > 0) { + for (HabboItem item : this.room.getRoomSpecialTypes().getItemsOfType(InteractionWiredHighscore.class)) { + Emulator.getGameEnvironment().getItemManager().getHighscoreManager().addHighscoreData(new WiredHighscoreDataEntry(item.getId(), winningTeam.getMembers().stream().map(m -> m.getHabbo().getHabboInfo().getId()).collect(Collectors.toList()), winningTeam.getTotalScore(), true, Emulator.getIntUnixTimestamp())); + } + } + + for (GameTeam team : this.teams.values()) { + if (team == winningTeam) continue; + + for (GamePlayer player : team.getMembers()) { + WiredHandler.handleCustomTrigger(WiredTriggerTeamLoses.class, player.getHabbo().getRoomUnit(), this.room, new Object[]{this}); + } + + if (team.getMembers().size() > 0 && team.getTotalScore() > 0) { + for (HabboItem item : this.room.getRoomSpecialTypes().getItemsOfType(InteractionWiredHighscore.class)) { + Emulator.getGameEnvironment().getItemManager().getHighscoreManager().addHighscoreData(new WiredHighscoreDataEntry(item.getId(), team.getMembers().stream().map(m -> m.getHabbo().getHabboInfo().getId()).collect(Collectors.toList()), team.getTotalScore(), false, Emulator.getIntUnixTimestamp())); + } + } + } + } + + for (HabboItem item : this.room.getRoomSpecialTypes().getItemsOfType(InteractionWiredHighscore.class)) { + ((InteractionWiredHighscore) item).reloadData(); + this.room.updateItem(item); + } + + for (HabboItem item : this.room.getRoomSpecialTypes().getItemsOfType(WiredBlob.class)) { + ((WiredBlob) item).onGameEnd(this.room); + } + } + + public abstract void run(); + + public void pause() { + if (this.state.equals(GameState.RUNNING)) { + this.state = GameState.PAUSED; + } + } + + public void unpause() { + if (this.state.equals(GameState.PAUSED)) { + this.state = GameState.RUNNING; + } + } + + public void stop() { + this.state = GameState.IDLE; + + boolean gamesActive = false; + for (HabboItem timer : room.getFloorItems()) { + if (timer instanceof InteractionGameTimer) { + if (((InteractionGameTimer) timer).isRunning()) + gamesActive = true; + } + } + + if (gamesActive) { + return; + } + + if (Emulator.getPluginManager().isRegistered(GameStoppedEvent.class, true)) { + Event gameStoppedEvent = new GameStoppedEvent(this); + Emulator.getPluginManager().fireEvent(gameStoppedEvent); + } + } + + public void dispose() { + for (GameTeam team : this.teams.values()) { + team.clearMembers(); + } + this.teams.clear(); + + this.stop(); + } + + private void saveScores() { + if (this.room == null) + return; + + THashMap teamsCopy = new THashMap<>(); + teamsCopy.putAll(this.teams); + + for (Map.Entry teamEntry : teamsCopy.entrySet()) { + Emulator.getThreading().run(new SaveScoreForTeam(teamEntry.getValue(), this)); + } + } + + + public GameTeam getTeamForHabbo(Habbo habbo) { + if (habbo != null) { + synchronized (this.teams) { + for (GameTeam team : this.teams.values()) { + if (team.isMember(habbo)) { + return team; + } + } + } + } + + return null; + } + + + public GameTeam getTeam(GameTeamColors teamColor) { + synchronized (this.teams) { + return this.teams.get(teamColor); + } + } + + + public void addTeam(GameTeam team) { + synchronized (this.teams) { + this.teams.put(team.teamColor, team); + } + } + + public Room getRoom() { + return this.room; + } + + public int getStartTime() { + return this.startTime; + } + + public Class getGameTeamClass() { + return gameTeamClazz; + } + + public Class getGamePlayerClass() { + return gamePlayerClazz; + } + + public THashMap getTeams() { + return teams; + } + + public boolean isCountsAchievements() { + return countsAchievements; + } + + public GameState getState() { + return state; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/GamePlayer.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/GamePlayer.java new file mode 100644 index 0000000..bfd82a5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/GamePlayer.java @@ -0,0 +1,65 @@ +package com.eu.habbo.habbohotel.games; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; + +public class GamePlayer { + + private final Habbo habbo; + + + private GameTeamColors teamColor; + + + private int score; + private int wiredScore; + + + public GamePlayer(Habbo habbo, GameTeamColors teamColor) { + this.habbo = habbo; + this.teamColor = teamColor; + } + + + public void reset() { + this.score = 0; + this.wiredScore = 0; + } + + public synchronized void addScore(int amount) { + addScore(amount, false); + } + + public synchronized void addScore(int amount, boolean isWired) { + if (habbo.getHabboInfo().getGamePlayer() != null && this.habbo.getHabboInfo().getCurrentGame() != null && this.habbo.getHabboInfo().getCurrentRoom().getGame(this.habbo.getHabboInfo().getCurrentGame()).getTeamForHabbo(this.habbo) != null) { + this.score += amount; + + if (this.score < 0) this.score = 0; + + if(isWired && this.score > 0) { + this.wiredScore += amount; + } + + WiredHandler.handle(WiredTriggerType.SCORE_ACHIEVED, this.habbo.getRoomUnit(), this.habbo.getHabboInfo().getCurrentRoom(), new Object[]{this.habbo.getHabboInfo().getCurrentRoom().getGame(this.habbo.getHabboInfo().getCurrentGame()).getTeamForHabbo(this.habbo).getTotalScore(), amount}); + } + } + + public Habbo getHabbo() { + return this.habbo; + } + + + public GameTeamColors getTeamColor() { + return this.teamColor; + } + + + public int getScore() { + return this.score; + } + + public int getScoreAchievementValue() { + return this.score - this.wiredScore; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/GameState.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/GameState.java new file mode 100644 index 0000000..2aa7158 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/GameState.java @@ -0,0 +1,7 @@ +package com.eu.habbo.habbohotel.games; + +public enum GameState { + IDLE, + RUNNING, + PAUSED +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/GameTeam.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/GameTeam.java new file mode 100644 index 0000000..143974d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/GameTeam.java @@ -0,0 +1,120 @@ +package com.eu.habbo.habbohotel.games; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.Event; +import com.eu.habbo.plugin.events.games.GameHabboLeaveEvent; +import gnu.trove.set.hash.THashSet; + +public class GameTeam { + + public final GameTeamColors teamColor; + private final THashSet members; + private int teamScore; + + + public GameTeam(GameTeamColors teamColor) { + this.teamColor = teamColor; + + this.members = new THashSet<>(); + } + + + public void initialise() { + for (GamePlayer player : this.members) { + player.reset(); + } + + this.teamScore = 0; + } + + + public void reset() { + this.members.clear(); + } + + + public void addTeamScore(int teamScore) { + this.teamScore += teamScore; + } + + + public int getTeamScore() { + return this.teamScore; + } + + + public synchronized int getTotalScore() { + int score = this.teamScore; + + for (GamePlayer player : this.members) { + score += player.getScore(); + } + + return score; + } + + + public void addMember(GamePlayer gamePlayer) { + synchronized (this.members) { + this.members.add(gamePlayer); + } + } + + + public void removeMember(GamePlayer gamePlayer) { + synchronized (this.members) { + this.members.remove(gamePlayer); + } + } + + public void clearMembers() { + for (GamePlayer player : this.members) { + if (player == null || player.getHabbo() == null) continue; + + if (player.getHabbo().getHabboInfo().getGamePlayer() != null) player.getHabbo().getHabboInfo().getGamePlayer().reset(); + player.getHabbo().getHabboInfo().setCurrentGame(null); + player.getHabbo().getHabboInfo().setGamePlayer(null); + } + + this.members.clear(); + } + + public void resetScores() { + for (GamePlayer player : this.members) { + if (player == null) continue; + + player.reset(); + } + + this.teamScore = 0; + } + + + public THashSet getMembers() { + return this.members; + } + + + public boolean isMember(Habbo habbo) { + for (GamePlayer p : this.members) { + if (p.getHabbo().equals(habbo)) { + return true; + } + } + + return false; + } + + + @Deprecated + public GamePlayer getPlayerForHabbo(Habbo habbo) { + for (GamePlayer p : this.members) { + if (p.getHabbo().equals(habbo)) { + return p; + } + } + + return null; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/GameTeamColors.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/GameTeamColors.java new file mode 100644 index 0000000..1f22eb5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/GameTeamColors.java @@ -0,0 +1,39 @@ +package com.eu.habbo.habbohotel.games; + +public enum GameTeamColors { + + NONE(0), + + RED(1), + GREEN(2), + BLUE(3), + YELLOW(4), + + ONE(5), + TWO(6), + THREE(7), + FOUR(8), + FIVE(9), + SIX(10), + SEVEN(11), + EIGHT(12), + NINE(13), + TEN(14); + + + public final int type; + + GameTeamColors(int type) { + this.type = type; + } + + public static GameTeamColors fromType(int type) { + for (GameTeamColors teamColors : values()) { + if (teamColors.type == type) { + return teamColors; + } + } + + return NONE; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGame.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGame.java new file mode 100644 index 0000000..fbd7995 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGame.java @@ -0,0 +1,413 @@ +package com.eu.habbo.habbohotel.games.battlebanzai; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.games.*; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTimer; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiSphere; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiTile; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.gates.InteractionBattleBanzaiGate; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.scoreboards.InteractionBattleBanzaiScoreboard; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUserAction; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserActionComposer; +import com.eu.habbo.threading.runnables.BattleBanzaiTilesFlicker; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; + +import java.util.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadPoolExecutor; + +@Slf4j +public class BattleBanzaiGame extends Game { + + public static final int effectId = 32; + public static final int POINTS_HIJACK_TILE = Emulator.getConfig().getInt("hotel.banzai.points.tile.steal", 0); + public static final int POINTS_FILL_TILE = Emulator.getConfig().getInt("hotel.banzai.points.tile.fill", 0); + public static final int POINTS_LOCK_TILE = Emulator.getConfig().getInt("hotel.banzai.points.tile.lock", 1); + + private static final ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(Emulator.getConfig().getInt("hotel.banzai.fill.threads", 2)); + private final THashMap> lockedTiles; + private final THashMap gameTiles; + private int tileCount; + private int countDown; + private int countDown2; + + public BattleBanzaiGame(Room room) { + super(BattleBanzaiGameTeam.class, BattleBanzaiGamePlayer.class, room, true); + + this.lockedTiles = new THashMap<>(); + this.gameTiles = new THashMap<>(); + + room.setAllowEffects(true); + } + + @Override + public void initialise() { + if (!this.state.equals(GameState.IDLE)) + return; + + /* The first countdown is activated for the first two seconds emitting only the blue light (second interaction), + the second, after another two seconds, completely activates the sphere (third interaction). + */ + this.countDown = 3; + this.countDown2 = 2; + + this.resetMap(); + + synchronized (this.teams) { + for (GameTeam t : this.teams.values()) { + t.initialise(); + } + } + + for (HabboItem item : this.room.getRoomSpecialTypes().getItemsOfType(InteractionBattleBanzaiSphere.class)) { + item.setExtradata("1"); + this.room.updateItemState(item); + } + + this.start(); + } + + @Override + public boolean addHabbo(Habbo habbo, GameTeamColors teamColor) { + return super.addHabbo(habbo, teamColor); + } + + @Override + public void start() { + if (!this.state.equals(GameState.IDLE)) + return; + + super.start(); + + this.refreshGates(); + + Emulator.getThreading().run(this, 0); + } + + @Override + public void run() { + try { + if (this.state.equals(GameState.IDLE)) + return; + + if (this.countDown > 0) { + this.countDown--; + + if (this.countDown == 0) { + for (HabboItem item : this.room.getRoomSpecialTypes().getItemsOfType(InteractionBattleBanzaiSphere.class)) { + item.setExtradata("1"); + this.room.updateItemState(item); + if(this.countDown2 > 0) { + this.countDown2--; + if(this.countDown2 == 0) { + item.setExtradata("2"); + this.room.updateItemState(item); + } + } + } + } + + if (this.countDown > 1) { + Emulator.getThreading().run(this, 500); + + return; + } + } + + Emulator.getThreading().run(this, 1000); + + if (this.state.equals(GameState.PAUSED)) return; + + int total = 0; + synchronized (this.lockedTiles) { + for (Map.Entry> set : this.lockedTiles.entrySet()) { + total += set.getValue().size(); + } + } + + GameTeam highestScore = null; + + synchronized (this.teams) { + for (Map.Entry set : this.teams.entrySet()) { + if (highestScore == null || highestScore.getTotalScore() < set.getValue().getTotalScore()) { + highestScore = set.getValue(); + } + } + } + + if (highestScore != null) { + for (HabboItem item : this.room.getRoomSpecialTypes().getItemsOfType(InteractionBattleBanzaiSphere.class)) { + item.setExtradata((highestScore.teamColor.type + 2) + ""); + this.room.updateItemState(item); + } + } + + if (total >= this.tileCount && this.tileCount != 0) { + for (InteractionGameTimer timer : room.getRoomSpecialTypes().getGameTimers().values()) { + if (timer.isRunning()) { + timer.endGame(room); + } + } + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + @Override + public void onEnd() { + GameTeam winningTeam = null; + + boolean singleTeamGame = this.teams.values().stream().filter(t -> t.getMembers().size() > 0).count() == 1; + + for (GameTeam team : this.teams.values()) { + if (!singleTeamGame) { + for (GamePlayer player : team.getMembers()) { + if (player.getScoreAchievementValue() > 0) { + AchievementManager.progressAchievement(player.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("BattleBallPlayer")); + } + } + } + + if (winningTeam == null || team.getTotalScore() > winningTeam.getTotalScore()) { + winningTeam = team; + } + } + + if (winningTeam != null) { + if (!singleTeamGame) { + for (GamePlayer player : winningTeam.getMembers()) { + if (player.getScoreAchievementValue() > 0) { + this.room.sendComposer(new RoomUserActionComposer(player.getHabbo().getRoomUnit(), RoomUserAction.WAVE).compose()); + AchievementManager.progressAchievement(player.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("BattleBallWinner")); + } + } + } + + for (HabboItem item : this.room.getRoomSpecialTypes().getItemsOfType(InteractionBattleBanzaiSphere.class)) { + item.setExtradata((6 + winningTeam.teamColor.type) + ""); + this.room.updateItemState(item); + } + synchronized (this.lockedTiles) { + Emulator.getThreading().run(new BattleBanzaiTilesFlicker(this.lockedTiles.get(winningTeam.teamColor), winningTeam.teamColor, this.room)); + } + } + + super.onEnd(); + } + + @Override + public void stop() { + super.stop(); + + this.refreshGates(); + + for (HabboItem tile : this.gameTiles.values()) { + if (tile.getExtradata().equals("1")) { + tile.setExtradata("0"); + this.room.updateItem(tile); + } + } + synchronized (this.lockedTiles) { + this.lockedTiles.clear(); + } + } + + + private synchronized void resetMap() { + this.tileCount = 0; + for (HabboItem item : this.room.getFloorItems()) { + if (item instanceof InteractionBattleBanzaiTile) { + item.setExtradata("1"); + this.room.updateItemState(item); + this.tileCount++; + this.gameTiles.put(item.getId(), item); + } + + if (item instanceof InteractionBattleBanzaiScoreboard) { + item.setExtradata("0"); + this.room.updateItemState(item); + } + } + } + + + public void tileLocked(GameTeamColors teamColor, HabboItem item, Habbo habbo) { + this.tileLocked(teamColor, item, habbo, false); + } + + public void tileLocked(GameTeamColors teamColor, HabboItem item, Habbo habbo, boolean doNotCheckFill) { + synchronized (this.lockedTiles) { + if (item instanceof InteractionBattleBanzaiTile) { + if (!this.lockedTiles.containsKey(teamColor)) { + this.lockedTiles.put(teamColor, new THashSet<>()); + } + + this.lockedTiles.get(teamColor).add(item); + } + + if (habbo != null) { + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("BattleBallTilesLocked")); + } + + if (doNotCheckFill) return; + + final int x = item.getX(); + final int y = item.getY(); + + final List> filledAreas = new ArrayList<>(); + final THashSet lockedTiles = new THashSet<>(this.lockedTiles.get(teamColor)); + + executor.execute(() -> { + filledAreas.add(this.floodFill(x, y - 1, lockedTiles, new ArrayList<>(), teamColor)); + filledAreas.add(this.floodFill(x, y + 1, lockedTiles, new ArrayList<>(), teamColor)); + filledAreas.add(this.floodFill(x - 1, y, lockedTiles, new ArrayList<>(), teamColor)); + filledAreas.add(this.floodFill(x + 1, y, lockedTiles, new ArrayList<>(), teamColor)); + + Optional> largestAreaOfAll = filledAreas.stream().filter(Objects::nonNull).max(Comparator.comparing(List::size)); + + if (largestAreaOfAll.isPresent()) { + for (RoomTile tile : largestAreaOfAll.get()) { + Optional tileItem = this.gameTiles.values().stream().filter(i -> i.getX() == tile.x && i.getY() == tile.y && i instanceof InteractionBattleBanzaiTile).findAny(); + + tileItem.ifPresent(habboItem -> { + this.tileLocked(teamColor, habboItem, habbo, true); + + habboItem.setExtradata((2 + (teamColor.type * 3)) + ""); + this.room.updateItem(habboItem); + }); + } + + this.refreshCounters(teamColor); + if (habbo != null) { + habbo.getHabboInfo().getGamePlayer().addScore(BattleBanzaiGame.POINTS_LOCK_TILE * largestAreaOfAll.get().size()); + } + } + }); + } + } + + private List floodFill(int x, int y, THashSet lockedTiles, List stack, GameTeamColors color) { + if (this.isOutOfBounds(x, y) || this.isForeignLockedTile(x, y, color)) return null; + + RoomTile tile = this.room.getLayout().getTile((short) x, (short) y); + + if (this.hasLockedTileAtCoordinates(x, y, lockedTiles) || stack.contains(tile)) return stack; + + stack.add(tile); + + List> result = new ArrayList<>(); + result.add(this.floodFill(x, y - 1, lockedTiles, stack, color)); + result.add(this.floodFill(x, y + 1, lockedTiles, stack, color)); + result.add(this.floodFill(x - 1, y, lockedTiles, stack, color)); + result.add(this.floodFill(x + 1, y, lockedTiles, stack, color)); + + if (result.contains(null)) return null; + + Optional> biggestArea = result.stream().max(Comparator.comparing(List::size)); + + return biggestArea.orElse(null); + + } + + private boolean hasLockedTileAtCoordinates(int x, int y, THashSet lockedTiles) { + for (HabboItem item : lockedTiles) { + if (item.getX() == x && item.getY() == y) return true; + } + + return false; + } + + private boolean isOutOfBounds(int x, int y) { + for (HabboItem item : this.gameTiles.values()) { + if (item.getX() == x && item.getY() == y) return false; + } + + return true; + } + + private boolean isForeignLockedTile(int x, int y, GameTeamColors color) { + for (HashMap.Entry> lockedTilesForColor : this.lockedTiles.entrySet()) { + if (lockedTilesForColor.getKey() == color) continue; + + for (HabboItem item : lockedTilesForColor.getValue()) { + if (item.getX() == x && item.getY() == y) return true; + } + } + + return false; + } + + public void refreshCounters() { + for (GameTeam team : this.teams.values()) { + if (team.getMembers().isEmpty()) + continue; + + this.refreshCounters(team.teamColor); + } + } + + + public void refreshCounters(GameTeamColors teamColors) { + if (!this.teams.containsKey(teamColors)) return; + + int totalScore = this.teams.get(teamColors).getTotalScore(); + + THashMap scoreBoards = this.room.getRoomSpecialTypes().getBattleBanzaiScoreboards(teamColors); + + for (InteractionBattleBanzaiScoreboard scoreboard : scoreBoards.values()) { + if (scoreboard.getExtradata().isEmpty()) { + scoreboard.setExtradata("0"); + } + + int oldScore = Integer.valueOf(scoreboard.getExtradata()); + + if (oldScore == totalScore) + continue; + + scoreboard.setExtradata(totalScore + ""); + this.room.updateItemState(scoreboard); + } + } + + private void refreshGates() { + Collection gates = this.room.getRoomSpecialTypes().getBattleBanzaiGates().values(); + THashSet tilesToUpdate = new THashSet<>(gates.size()); + for (HabboItem item : gates) { + tilesToUpdate.add(this.room.getLayout().getTile(item.getX(), item.getY())); + } + + this.room.updateTiles(tilesToUpdate); + } + + public void markTile(Habbo habbo, InteractionBattleBanzaiTile tile, int state) { + if (!this.gameTiles.contains(tile.getId())) return; + + int check = state - (habbo.getHabboInfo().getGamePlayer().getTeamColor().type * 3); + if (check == 0 || check == 1) { + state++; + + if (state % 3 == 2) { + habbo.getHabboInfo().getGamePlayer().addScore(BattleBanzaiGame.POINTS_LOCK_TILE); + this.tileLocked(habbo.getHabboInfo().getGamePlayer().getTeamColor(), tile, habbo); + } else { + habbo.getHabboInfo().getGamePlayer().addScore(BattleBanzaiGame.POINTS_FILL_TILE); + } + } else { + state = habbo.getHabboInfo().getGamePlayer().getTeamColor().type * 3; + + habbo.getHabboInfo().getGamePlayer().addScore(BattleBanzaiGame.POINTS_HIJACK_TILE); + } + + this.refreshCounters(habbo.getHabboInfo().getGamePlayer().getTeamColor()); + tile.setExtradata(state + ""); + this.room.updateItem(tile); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGamePlayer.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGamePlayer.java new file mode 100644 index 0000000..05dc979 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGamePlayer.java @@ -0,0 +1,11 @@ +package com.eu.habbo.habbohotel.games.battlebanzai; + +import com.eu.habbo.habbohotel.games.GamePlayer; +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.users.Habbo; + +public class BattleBanzaiGamePlayer extends GamePlayer { + public BattleBanzaiGamePlayer(Habbo habbo, GameTeamColors teamColor) { + super(habbo, teamColor); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGameTeam.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGameTeam.java new file mode 100644 index 0000000..bc3aed4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGameTeam.java @@ -0,0 +1,38 @@ +package com.eu.habbo.habbohotel.games.battlebanzai; + +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.games.GamePlayer; +import com.eu.habbo.habbohotel.games.GameTeam; +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameGate; +import com.eu.habbo.habbohotel.rooms.Room; + +public class BattleBanzaiGameTeam extends GameTeam { + public BattleBanzaiGameTeam(GameTeamColors teamColor) { + super(teamColor); + } + + @Override + public void addMember(GamePlayer gamePlayer) { + super.addMember(gamePlayer); + + gamePlayer.getHabbo().getHabboInfo().getCurrentRoom().giveEffect(gamePlayer.getHabbo(), BattleBanzaiGame.effectId + this.teamColor.type, -1); + } + + @Override + public void removeMember(GamePlayer gamePlayer) { + Game game = gamePlayer.getHabbo().getHabboInfo().getCurrentRoom().getGame(gamePlayer.getHabbo().getHabboInfo().getCurrentGame()); + Room room = gamePlayer.getHabbo().getRoomUnit().getRoom(); + + gamePlayer.getHabbo().getHabboInfo().getCurrentRoom().giveEffect(gamePlayer.getHabbo(), 0, -1); + gamePlayer.getHabbo().getRoomUnit().setCanWalk(true); + + super.removeMember(gamePlayer); + + if (room != null && room.getRoomSpecialTypes() != null) { + for (InteractionGameGate gate : room.getRoomSpecialTypes().getBattleBanzaiGates().values()) { + gate.updateState(game, 5); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/football/FootballGame.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/football/FootballGame.java new file mode 100644 index 0000000..addadf8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/football/FootballGame.java @@ -0,0 +1,52 @@ +package com.eu.habbo.habbohotel.games.football; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.interactions.games.football.scoreboards.InteractionFootballScoreboard; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUserAction; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserActionComposer; + +import java.util.Map; + + +public class FootballGame extends Game { + private Room room; + + public FootballGame(Room room) { + super(null, null, room, true); + + this.room = room; + } + + @Override + public void initialise() { + } + + @Override + public void run() { + } + + public void onScore(RoomUnit kicker, GameTeamColors team) { + if (this.room == null || !this.room.isLoaded()) + return; + + Habbo habbo = this.room.getHabbo(kicker); + if (habbo != null) { + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("FootballGoalScored")); + if (habbo.getHabboInfo().getId() != this.room.getOwnerId()) { + AchievementManager.progressAchievement(this.room.getOwnerId(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("FootballGoalScoredInRoom")); + } + } + + this.room.sendComposer(new RoomUserActionComposer(kicker, RoomUserAction.WAVE).compose()); + + for (Map.Entry scoreBoard : this.room.getRoomSpecialTypes().getFootballScoreboards(team).entrySet()) { + scoreBoard.getValue().changeScore(1); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/freeze/FreezeGame.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/freeze/FreezeGame.java new file mode 100644 index 0000000..ef8cb6d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/freeze/FreezeGame.java @@ -0,0 +1,336 @@ +package com.eu.habbo.habbohotel.games.freeze; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.games.*; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeBlock; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeExitTile; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeTile; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.gates.InteractionFreezeGate; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.scoreboards.InteractionFreezeScoreboard; +import com.eu.habbo.habbohotel.items.interactions.wired.effects.WiredEffectTeleport; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomLayout; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUserAction; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserActionComposer; +import com.eu.habbo.plugin.EventHandler; +import com.eu.habbo.plugin.events.emulator.EmulatorConfigUpdatedEvent; +import com.eu.habbo.threading.runnables.freeze.FreezeClearEffects; +import com.eu.habbo.threading.runnables.freeze.FreezeThrowSnowball; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +public class FreezeGame extends Game { + public static final int effectId = 39; + public static int POWER_UP_POINTS; + public static int POWER_UP_CHANCE; + public static int POWER_UP_PROTECT_TIME; + public static int DESTROY_BLOCK_POINTS; + public static int FREEZE_TIME; + public static int FREEZE_LOOSE_SNOWBALL; + public static int FREEZE_LOOSE_BOOST; + public static int MAX_LIVES; + public static int MAX_SNOWBALLS; + public static int FREEZE_LOOSE_POINTS; + public static boolean POWERUP_STACK; + + public FreezeGame(Room room) { + super(FreezeGameTeam.class, FreezeGamePlayer.class, room, true); + room.setAllowEffects(true); + } + + @EventHandler + public static void onConfigurationUpdated(EmulatorConfigUpdatedEvent event) { + POWER_UP_POINTS = Emulator.getConfig().getInt("hotel.freeze.points.effect"); + POWER_UP_CHANCE = Emulator.getConfig().getInt("hotel.freeze.powerup.chance"); + POWER_UP_PROTECT_TIME = Emulator.getConfig().getInt("hotel.freeze.powerup.protection.time"); + DESTROY_BLOCK_POINTS = Emulator.getConfig().getInt("hotel.freeze.points.block"); + FREEZE_TIME = Emulator.getConfig().getInt("hotel.freeze.onfreeze.time.frozen"); + FREEZE_LOOSE_SNOWBALL = Emulator.getConfig().getInt("hotel.freeze.onfreeze.loose.snowballs"); + FREEZE_LOOSE_BOOST = Emulator.getConfig().getInt("hotel.freeze.onfreeze.loose.explosionboost"); + MAX_LIVES = Emulator.getConfig().getInt("hotel.freeze.powerup.max.lives"); + MAX_SNOWBALLS = Emulator.getConfig().getInt("hotel.freeze.powerup.max.snowballs"); + FREEZE_LOOSE_POINTS = Emulator.getConfig().getInt("hotel.freeze.points.freeze"); + POWERUP_STACK = Emulator.getConfig().getBoolean("hotel.freeze.powerup.protection.stack"); + } + + @Override + public synchronized void initialise() { + if (this.state == GameState.RUNNING) + return; + + this.resetMap(); + + for (GameTeam t : this.teams.values()) { + t.initialise(); + } + + this.start(); + } + + synchronized void resetMap() { + for (HabboItem item : this.room.getFloorItems()) { + if (item instanceof InteractionFreezeBlock || item instanceof InteractionFreezeScoreboard) { + item.setExtradata("0"); + this.room.updateItemState(item); + } + } + } + + public void throwBall(Habbo habbo, InteractionFreezeTile item) { + if (!this.state.equals(GameState.RUNNING) || !habbo.getHabboInfo().isInGame() || habbo.getHabboInfo().getCurrentGame() != this.getClass()) + return; + + if (!item.getExtradata().equalsIgnoreCase("0") && !item.getExtradata().isEmpty()) + return; + + if (RoomLayout.tilesAdjecent(habbo.getRoomUnit().getCurrentLocation(), this.room.getLayout().getTile(item.getX(), item.getY()))) { + if (((FreezeGamePlayer) habbo.getHabboInfo().getGamePlayer()).canThrowSnowball()) { + Emulator.getThreading().run(new FreezeThrowSnowball(habbo, item, this.room)); + } + } + } + + public THashSet affectedTilesByExplosion(short x, short y, int radius) { + THashSet tiles = new THashSet<>(); + + RoomTile t = this.room.getLayout().getTile(x, y); + + tiles.add(t); + for (int rotatation = 0; rotatation < 8; rotatation += 2) { + for (int j = 0; j < radius; j++) { + t = this.room.getLayout().getTileInFront(this.room.getLayout().getTile(x, y), rotatation, j); + + if (t == null || t.x < 0 || t.y < 0 || t.x >= this.room.getLayout().getMapSizeX() || t.y >= this.room.getLayout().getMapSizeY()) + continue; + + tiles.add(t); + } + } + + return tiles; + } + + public THashSet affectedTilesByExplosionDiagonal(short x, short y, int radius) { + THashSet tiles = new THashSet<>(); + + for (int rotation = 1; rotation < 9; rotation += 2) { + RoomTile t = this.room.getLayout().getTile(x, y); + + for (int j = 0; j < radius; j++) { + t = this.room.getLayout().getTileInFront(this.room.getLayout().getTile(x, y), rotation, j); + + if (t != null) { + if (t.x < 0 || t.y < 0 || t.x >= this.room.getLayout().getMapSizeX() || t.y >= this.room.getLayout().getMapSizeY()) + continue; + + tiles.add(t); + } + } + } + + return tiles; + } + + public synchronized void explodeBox(InteractionFreezeBlock block, int delay) { + int powerUp = 0; + if (Emulator.getRandom().nextInt(100) + 1 <= FreezeGame.POWER_UP_CHANCE) { + powerUp += Emulator.getRandom().nextInt(6) + 1; + } + + block.setExtradata((powerUp + 1) + String.format("%3d", delay)); + + this.room.updateItemState(block); + } + + public synchronized void givePowerUp(FreezeGamePlayer player, int powerUpId) { + player.addScore(FreezeGame.POWER_UP_POINTS); + + switch (powerUpId) { + case 2: { + player.increaseExplosion(); + break; + } + + case 3: { + player.addSnowball(); + break; + } + + case 4: { + player.nextDiagonal = true; + break; + } + + case 5: { + player.nextHorizontal = true; + player.nextDiagonal = true; + player.tempMassiveExplosion = true; + break; + } + + case 6: { + player.addLife(); + break; + } + + case 7: { + player.addProtection(); + break; + } + } + } + + public synchronized void playerDies(GamePlayer player) { + Emulator.getThreading().run(new FreezeClearEffects(player.getHabbo()), 1000); + if (this.room.getRoomSpecialTypes().hasFreezeExitTile()) { + InteractionFreezeExitTile tile = this.room.getRoomSpecialTypes().getRandomFreezeExitTile(); + tile.setExtradata("1"); + this.room.updateItemState(tile); + this.room.teleportHabboToItem(player.getHabbo(), tile); + } + this.removeHabbo(player.getHabbo()); + } + + @Override + public void start() { + if (this.state != GameState.IDLE) { + return; + } + + super.start(); + + if (this.room.getRoomSpecialTypes().hasFreezeExitTile()) { + for (Habbo habbo : this.room.getHabbos()) { + if (this.getTeamForHabbo(habbo) == null) { + for (HabboItem item : this.room.getItemsAt(habbo.getRoomUnit().getCurrentLocation())) { + if (item instanceof InteractionFreezeTile) { + HabboItem exitTile = this.room.getRoomSpecialTypes().getRandomFreezeExitTile(); + WiredEffectTeleport.teleportUnitToTile(habbo.getRoomUnit(), this.room.getLayout().getTile(exitTile.getX(), exitTile.getY())); + } + } + } + } + } + + this.refreshGates(); + + this.setFreezeTileState("1"); + this.run(); + } + + @Override + public synchronized void run() { + try { + if (this.state.equals(GameState.IDLE)) + return; + + Emulator.getThreading().run(this, 1000); + + if (this.state.equals(GameState.PAUSED)) return; + + for (GameTeam team : this.teams.values()) { + for (GamePlayer player : team.getMembers()) { + ((FreezeGamePlayer) player).cycle(); + } + + int totalScore = team.getTotalScore(); + + THashMap scoreBoards = this.room.getRoomSpecialTypes().getFreezeScoreboards(team.teamColor); + + for (InteractionFreezeScoreboard scoreboard : scoreBoards.values()) { + if (scoreboard.getExtradata().isEmpty()) { + scoreboard.setExtradata("0"); + } + + int oldScore = Integer.valueOf(scoreboard.getExtradata()); + + if (oldScore == totalScore) + continue; + + scoreboard.setExtradata(totalScore + ""); + this.room.updateItemState(scoreboard); + } + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + @Override + public void stop() { + super.stop(); + + GameTeam winningTeam = null; + + for (GameTeam team : this.teams.values()) { + if (winningTeam == null || team.getTotalScore() > winningTeam.getTotalScore()) { + winningTeam = team; + } + } + + for (GameTeam team : this.teams.values()) { + THashSet players = new THashSet<>(); + + players.addAll(team.getMembers()); + + for (GamePlayer p : players) { + if (p.getScoreAchievementValue() > 0) { + if (team.equals(winningTeam)) { + AchievementManager.progressAchievement(p.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("FreezeWinner"), p.getScoreAchievementValue()); + this.room.sendComposer(new RoomUserActionComposer(p.getHabbo().getRoomUnit(), RoomUserAction.WAVE).compose()); + } + + AchievementManager.progressAchievement(p.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("FreezePlayer")); + } + } + } + + Map teamMemberCount = new HashMap<>(); + for (Map.Entry teamEntry : this.teams.entrySet()) { + teamMemberCount.put(teamEntry.getKey(), teamEntry.getValue().getMembers().size()); + } + + for (Map.Entry set : this.room.getRoomSpecialTypes().getFreezeGates().entrySet()) { + if (teamMemberCount.containsKey(set.getValue().teamColor)) { + int amount = Math.min(teamMemberCount.get(set.getValue().teamColor), 5); + set.getValue().setExtradata(amount + ""); + teamMemberCount.put(set.getValue().teamColor, teamMemberCount.get(set.getValue().teamColor) - amount); + this.room.updateItemState(set.getValue()); + } + } + + this.refreshGates(); + + this.setFreezeTileState("0"); + } + + public void setFreezeTileState(String state) { + this.room.getRoomSpecialTypes().getFreezeExitTiles().forEachValue(new TObjectProcedure() { + @Override + public boolean execute(InteractionFreezeExitTile object) { + object.setExtradata(state); + FreezeGame.this.room.updateItemState(object); + return true; + } + }); + + } + + private void refreshGates() { + THashSet tilesToUpdate = new THashSet<>(); + for (HabboItem item : this.room.getRoomSpecialTypes().getFreezeGates().values()) { + tilesToUpdate.add(this.room.getLayout().getTile(item.getX(), item.getY())); + } + + this.room.updateTiles(tilesToUpdate); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/freeze/FreezeGamePlayer.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/freeze/FreezeGamePlayer.java new file mode 100644 index 0000000..d425a61 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/freeze/FreezeGamePlayer.java @@ -0,0 +1,218 @@ +package com.eu.habbo.habbohotel.games.freeze; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.games.GamePlayer; +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.FreezeLivesComposer; + +public class FreezeGamePlayer extends GamePlayer { + public boolean nextDiagonal; + public boolean nextHorizontal; + public boolean tempMassiveExplosion; + public boolean dead; + private int lives; + private int snowBalls; + private int explosionBoost; + private int protectionTime; + private int frozenTime; + + public FreezeGamePlayer(Habbo habbo, GameTeamColors teamColor) { + super(habbo, teamColor); + } + + @Override + public void reset() { + this.lives = 3; + this.snowBalls = 1; + this.explosionBoost = 0; + this.protectionTime = 0; + this.frozenTime = 0; + this.nextDiagonal = false; + this.nextHorizontal = true; + this.tempMassiveExplosion = false; + this.dead = false; + + super.reset(); + } + + @Override + public void addScore(int amount) { + super.addScore(amount); + + if (amount > 0) { + AchievementManager.progressAchievement(this.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("FreezePlayer"), amount); + } + } + + + public void addLife() { + if (this.lives < FreezeGame.MAX_LIVES) { + this.lives++; + super.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new FreezeLivesComposer(this).compose()); + } + } + + public void takeLife() { + this.lives--; + if (this.lives == 0) { + this.dead = true; + + FreezeGame game = (FreezeGame) super.getHabbo().getHabboInfo().getCurrentRoom().getGame(FreezeGame.class); + + if (game != null) { + game.playerDies(this); + } + } else { + super.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new FreezeLivesComposer(this).compose()); + } + } + + public int getLives() { + return this.lives; + } + + public boolean canPickupLife() { + return this.lives < 3; + } + + public void addSnowball() { + if (this.snowBalls < FreezeGame.MAX_SNOWBALLS) + this.snowBalls++; + } + + public void addSnowball(int amount) { + this.snowBalls += amount; + + if (this.snowBalls < 1) + this.snowBalls = 1; + } + + public void takeSnowball() { + if (this.snowBalls > 0) + this.snowBalls--; + } + + public boolean canThrowSnowball() { + return this.snowBalls > 0 && !this.isFrozen(); + } + + public void freeze() { + if (this.protectionTime > 0 || this.frozenTime > 0) + return; + + this.takeLife(); + + this.frozenTime = FreezeGame.FREEZE_TIME; + this.addSnowball(-FreezeGame.FREEZE_LOOSE_SNOWBALL); + this.addExplosion(-FreezeGame.FREEZE_LOOSE_BOOST); + super.getHabbo().getRoomUnit().setCanWalk(false); + this.updateEffect(); + } + + public void unfreeze() { + super.getHabbo().getRoomUnit().setCanWalk(true); + this.frozenTime = 0; + this.addProtection(); + } + + public boolean isFrozen() { + return this.frozenTime > 0; + } + + public boolean canGetFrozen() { + if (this.isFrozen() || this.isProtected()) + return false; + + return true; + } + + public void addProtection() { + this.updateEffect(); + + if (this.isProtected() && !FreezeGame.POWERUP_STACK) + return; + + this.protectionTime += FreezeGame.POWER_UP_PROTECT_TIME; + } + + public boolean isProtected() { + return this.protectionTime > 0; + } + + public int getExplosionBoost() { + if (this.tempMassiveExplosion) { + this.tempMassiveExplosion = false; + return 5; + } + + return this.explosionBoost; + } + + public void increaseExplosion() { + if (this.explosionBoost < 5) + this.explosionBoost++; + } + + public void addExplosion(int radius) { + this.explosionBoost += radius; + + if (this.explosionBoost < 0) { + this.explosionBoost = 0; + } + + if (this.explosionBoost > 5) { + this.explosionBoost = 5; + } + } + + public void cycle() { + boolean needsEffectUpdate = false; + + if (this.isProtected()) { + this.protectionTime--; + + if (!this.isProtected()) + needsEffectUpdate = true; + } + + if (this.frozenTime > 0) { + this.frozenTime--; + + if (this.frozenTime <= 0) { + super.getHabbo().getRoomUnit().setCanWalk(true); + needsEffectUpdate = true; + } + } + + if (needsEffectUpdate) + this.updateEffect(); + } + + public int correctEffectId() { + if (this.dead) + return 0; + + if (!this.isFrozen()) { + int effectId = FreezeGame.effectId; + + effectId += super.getTeamColor().type; + + if (this.isProtected()) { + effectId += 9; + } + + return effectId; + } else { + return 12; + } + } + + public void updateEffect() { + if (this.dead) + return; + + super.getHabbo().getHabboInfo().getCurrentRoom().giveEffect(super.getHabbo(), this.correctEffectId(), -1); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/freeze/FreezeGameTeam.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/freeze/FreezeGameTeam.java new file mode 100644 index 0000000..cb3bd3c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/freeze/FreezeGameTeam.java @@ -0,0 +1,40 @@ +package com.eu.habbo.habbohotel.games.freeze; + +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.games.GamePlayer; +import com.eu.habbo.habbohotel.games.GameTeam; +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameGate; +import com.eu.habbo.habbohotel.rooms.Room; + +public class FreezeGameTeam extends GameTeam { + public FreezeGameTeam(GameTeamColors teamColor) { + super(teamColor); + } + + @Override + public void removeMember(GamePlayer gamePlayer) { + if (gamePlayer == null || gamePlayer.getHabbo() == null || gamePlayer.getHabbo().getHabboInfo().getCurrentRoom() == null) return; + + Game game = gamePlayer.getHabbo().getHabboInfo().getCurrentRoom().getGame(FreezeGame.class); + Room room = gamePlayer.getHabbo().getRoomUnit().getRoom(); + + gamePlayer.getHabbo().getHabboInfo().getCurrentRoom().giveEffect(gamePlayer.getHabbo(), 0, -1); + gamePlayer.getHabbo().getRoomUnit().setCanWalk(true); + + super.removeMember(gamePlayer); + + if (room != null && room.getRoomSpecialTypes() != null) { + for (InteractionGameGate gate : room.getRoomSpecialTypes().getFreezeGates().values()) { + gate.updateState(game, 5); + } + } + } + + @Override + public void addMember(GamePlayer gamePlayer) { + super.addMember(gamePlayer); + + gamePlayer.getHabbo().getHabboInfo().getCurrentRoom().giveEffect(gamePlayer.getHabbo(), FreezeGame.effectId + this.teamColor.type, -1); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/BunnyrunGame.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/BunnyrunGame.java new file mode 100644 index 0000000..3b74413 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/BunnyrunGame.java @@ -0,0 +1,37 @@ +package com.eu.habbo.habbohotel.games.tag; + +import com.eu.habbo.habbohotel.games.GameTeam; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagPole; +import com.eu.habbo.habbohotel.items.interactions.games.tag.bunnyrun.InteractionBunnyrunPole; +import com.eu.habbo.habbohotel.rooms.Room; + +public class BunnyrunGame extends TagGame { + public BunnyrunGame(Room room) { + super(GameTeam.class, TagGamePlayer.class, room); + } + + @Override + public Class getTagPole() { + return InteractionBunnyrunPole.class; + } + + @Override + public int getMaleEffect() { + return 0; + } + + @Override + public int getMaleTaggerEffect() { + return 68; + } + + @Override + public int getFemaleEffect() { + return 0; + } + + @Override + public int getFemaleTaggerEffect() { + return 68; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/IceTagGame.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/IceTagGame.java new file mode 100644 index 0000000..397f596 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/IceTagGame.java @@ -0,0 +1,41 @@ +package com.eu.habbo.habbohotel.games.tag; + +import com.eu.habbo.habbohotel.games.GameTeam; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagPole; +import com.eu.habbo.habbohotel.items.interactions.games.tag.icetag.InteractionIceTagPole; +import com.eu.habbo.habbohotel.rooms.Room; + + +public class IceTagGame extends TagGame { + private static final int MALE_SKATES = 38; + private static final int FEMALE_SKATES = 39; + + public IceTagGame(Room room) { + super(GameTeam.class, TagGamePlayer.class, room); + } + + @Override + public Class getTagPole() { + return InteractionIceTagPole.class; + } + + @Override + public int getMaleEffect() { + return MALE_SKATES; + } + + @Override + public int getMaleTaggerEffect() { + return MALE_SKATES + 7; + } + + @Override + public int getFemaleEffect() { + return FEMALE_SKATES; + } + + @Override + public int getFemaleTaggerEffect() { + return FEMALE_SKATES + 7; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/RollerskateGame.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/RollerskateGame.java new file mode 100644 index 0000000..d277aa5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/RollerskateGame.java @@ -0,0 +1,36 @@ +package com.eu.habbo.habbohotel.games.tag; + +import com.eu.habbo.habbohotel.games.GameTeam; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagPole; +import com.eu.habbo.habbohotel.rooms.Room; + +public class RollerskateGame extends TagGame { + public RollerskateGame(Room room) { + super(GameTeam.class, TagGamePlayer.class, room); + } + + @Override + public Class getTagPole() { + return null; + } + + @Override + public int getMaleEffect() { + return 55; + } + + @Override + public int getMaleTaggerEffect() { + return 57; + } + + @Override + public int getFemaleEffect() { + return 56; + } + + @Override + public int getFemaleTaggerEffect() { + return 58; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/TagGame.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/TagGame.java new file mode 100644 index 0000000..f256cce --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/TagGame.java @@ -0,0 +1,199 @@ +package com.eu.habbo.habbohotel.games.tag; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.games.GamePlayer; +import com.eu.habbo.habbohotel.games.GameTeam; +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagField; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagPole; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomLayout; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.plugin.EventHandler; +import com.eu.habbo.plugin.events.roomunit.RoomUnitLookAtPointEvent; +import com.eu.habbo.plugin.events.users.UserTakeStepEvent; +import com.eu.habbo.threading.runnables.HabboItemNewState; +import gnu.trove.iterator.hash.TObjectHashIterator; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + +import java.util.Map; + +public abstract class TagGame extends Game { + public THashMap taggers = new THashMap<>(); + + public TagGame(Class gameTeamClazz, Class gamePlayerClazz, Room room) { + super(gameTeamClazz, gamePlayerClazz, room, false); + } + + @EventHandler + public static void onUserLookAtPoint(RoomUnitLookAtPointEvent event) { + if (event.room == null || event.roomUnit == null || event.location == null) return; + + if (RoomLayout.tilesAdjecent(event.roomUnit.getCurrentLocation(), event.location)) { + Habbo habbo = event.room.getHabbo(event.roomUnit); + + if (habbo != null) { + if (habbo.getHabboInfo().getCurrentGame() != null) { + if (TagGame.class.isAssignableFrom(habbo.getHabboInfo().getCurrentGame())) { + TagGame game = (TagGame) event.room.getGame(habbo.getHabboInfo().getCurrentGame()); + + if (game != null) { + if (game.isTagger(habbo)) { + for (Habbo tagged : event.room.getHabbosAt(event.location)) { + if (tagged == habbo || tagged.getHabboInfo().getCurrentGame() == null || tagged.getHabboInfo().getCurrentGame() != habbo.getHabboInfo().getCurrentGame()) { + continue; + } + + game.tagged(event.room, habbo, tagged); + break; + } + } + } + } + } + } + } + } + + @EventHandler + public static void onUserWalkEvent(UserTakeStepEvent event) { + if (event.habbo.getHabboInfo().getCurrentGame() != null && TagGame.class.isAssignableFrom(event.habbo.getHabboInfo().getCurrentGame())) { + THashSet items = event.habbo.getHabboInfo().getCurrentRoom().getItemsAt(event.toLocation); + + TagGame game = (TagGame) event.habbo.getHabboInfo().getCurrentRoom().getGame(event.habbo.getHabboInfo().getCurrentGame()); + + if (game != null) { + for (HabboItem item : items) { + if (item instanceof InteractionTagField && ((InteractionTagField) item).gameClazz == event.habbo.getHabboInfo().getCurrentGame()) { + if (game.taggers.isEmpty()) { + game.tagged(event.habbo.getHabboInfo().getCurrentRoom(), null, event.habbo); + } + return; + } + } + + game.removeHabbo(event.habbo); + } + } + } + + public abstract Class getTagPole(); + + public abstract int getMaleEffect(); + + public abstract int getMaleTaggerEffect(); + + public abstract int getFemaleEffect(); + + public abstract int getFemaleTaggerEffect(); + + public void tagged(Room room, Habbo tagger, Habbo tagged) { + if (this.taggers.containsKey(tagged)) { + return; + } + + THashSet poles = room.getRoomSpecialTypes().getItemsOfType(this.getTagPole()); + InteractionTagPole pole = this.taggers.get(tagger); + room.giveEffect(tagged, this.getTaggedEffect(tagged), -1); + + if (poles.size() > this.taggers.size()) { + for (Map.Entry set : this.taggers.entrySet()) { + poles.remove(set.getValue()); + } + + for (HabboItem item : poles) { + tagged.getHabboInfo().getCurrentRoom().giveEffect(tagged, this.getTaggedEffect(tagged), -1); + this.taggers.put(tagged, (InteractionTagPole) item); + } + } else { + if (tagger != null) { + room.giveEffect(tagger, this.getEffect(tagger), -1); + this.taggers.remove(tagger); + } + + this.taggers.put(tagged, pole); + } + + if (pole != null) { + pole.setExtradata("1"); + room.updateItemState(pole); + Emulator.getThreading().run(new HabboItemNewState(pole, room, "0"), 1000); + } + } + + @Override + public synchronized boolean addHabbo(Habbo habbo, GameTeamColors teamColor) { + super.addHabbo(habbo, GameTeamColors.RED); + + if (this.getTagPole() != null) { + THashSet poles = habbo.getHabboInfo().getCurrentRoom().getRoomSpecialTypes().getItemsOfType(this.getTagPole()); + + if (poles.size() > this.taggers.size()) { + for (Map.Entry set : this.taggers.entrySet()) { + poles.remove(set.getValue()); + } + + TObjectHashIterator iterator = poles.iterator(); + if ((iterator.hasNext())) { + HabboItem item = iterator.next(); + habbo.getHabboInfo().getCurrentRoom().giveEffect(habbo, this.getEffect(habbo), -1); + this.room.scheduledTasks.add(() -> habbo.getHabboInfo().getCurrentRoom().giveEffect(habbo, this.getTaggedEffect(habbo), -1)); + this.taggers.put(habbo, (InteractionTagPole) item); + return true; + } + } + } else { + if (this.taggers.isEmpty()) { + habbo.getHabboInfo().getCurrentRoom().giveEffect(habbo, this.getEffect(habbo), -1); + this.room.scheduledTasks.add(() -> habbo.getHabboInfo().getCurrentRoom().giveEffect(habbo, this.getTaggedEffect(habbo), -1)); + this.taggers.put(habbo, null); + return true; + } + } + + habbo.getHabboInfo().getCurrentRoom().giveEffect(habbo, this.getEffect(habbo), -1); + + return true; + } + + @Override + public synchronized void removeHabbo(Habbo habbo) { + super.removeHabbo(habbo); + this.taggers.remove(habbo); + habbo.getHabboInfo().getCurrentRoom().giveEffect(habbo, 0, -1); + } + + @Override + public void initialise() { + + } + + @Override + public void run() { + + } + + public int getEffect(Habbo habbo) { + if (habbo.getHabboInfo().getGender().equals(HabboGender.M)) { + return this.getMaleEffect(); + } + + return this.getFemaleEffect(); + } + + public int getTaggedEffect(Habbo habbo) { + if (habbo.getHabboInfo().getGender().equals(HabboGender.M)) { + return this.getMaleTaggerEffect(); + } + + return this.getFemaleTaggerEffect(); + } + + public boolean isTagger(Habbo habbo) { + return this.taggers.containsKey(habbo); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/TagGamePlayer.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/TagGamePlayer.java new file mode 100644 index 0000000..2751396 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/tag/TagGamePlayer.java @@ -0,0 +1,12 @@ +package com.eu.habbo.habbohotel.games.tag; + +import com.eu.habbo.habbohotel.games.GamePlayer; +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.users.Habbo; + +public class TagGamePlayer extends GamePlayer { + + public TagGamePlayer(Habbo habbo, GameTeamColors teamColor) { + super(habbo, teamColor); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/games/wired/WiredGame.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/wired/WiredGame.java new file mode 100644 index 0000000..80fe874 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/games/wired/WiredGame.java @@ -0,0 +1,50 @@ +package com.eu.habbo.habbohotel.games.wired; + +import com.eu.habbo.habbohotel.games.*; +import com.eu.habbo.habbohotel.games.freeze.FreezeGame; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; + +public class WiredGame extends Game { + public GameState state = GameState.RUNNING; + + public WiredGame(Room room) { + super(GameTeam.class, GamePlayer.class, room, false); + } + + @Override + public void initialise() { + this.state = GameState.RUNNING; + + for (GameTeam team : this.teams.values()) { + team.resetScores(); + } + } + + @Override + public void run() { + this.state = GameState.RUNNING; + } + + @Override + public boolean addHabbo(Habbo habbo, GameTeamColors teamColor) { + this.room.giveEffect(habbo, FreezeGame.effectId + teamColor.type, -1); + return super.addHabbo(habbo, teamColor); + } + + @Override + public void removeHabbo(Habbo habbo) { + super.removeHabbo(habbo); + this.room.giveEffect(habbo, 0, -1); + } + + @Override + public void stop() { + this.state = GameState.RUNNING; + } + + @Override + public GameState getState() { + return GameState.RUNNING; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuardianTicket.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuardianTicket.java new file mode 100644 index 0000000..75d4cc5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuardianTicket.java @@ -0,0 +1,261 @@ +package com.eu.habbo.habbohotel.guides; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.modtool.ModToolChatLog; +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.habbohotel.modtool.ModToolTicketType; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.guardians.*; +import com.eu.habbo.messages.outgoing.guides.BullyReportClosedComposer; +import com.eu.habbo.threading.runnables.GuardianNotAccepted; +import com.eu.habbo.threading.runnables.GuardianVotingFinish; +import gnu.trove.map.hash.THashMap; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.Map; + +public class GuardianTicket { + private final THashMap votes = new THashMap<>(); + private final Habbo reporter; + private final Habbo reported; + private final Date date; + private ArrayList chatLogs; + private GuardianVoteType verdict; + private int timeLeft = 120; + private int resendCount = 0; + private int checkSum = 0; + private int guardianCount = 0; //TODO: Figure out what this was supposed to do. + + public GuardianTicket(Habbo reporter, Habbo reported, ArrayList chatLogs) { + this.chatLogs = chatLogs; + Collections.sort(chatLogs); + Emulator.getThreading().run(new GuardianVotingFinish(this), 120000); + + this.reported = reported; + this.reporter = reporter; + this.date = new Date(); + } + + + public void requestToVote(Habbo guardian) { + guardian.getClient().sendResponse(new GuardianNewReportReceivedComposer()); + + this.votes.put(guardian, new GuardianVote(this.guardianCount, guardian)); + + Emulator.getThreading().run(new GuardianNotAccepted(this, guardian), Emulator.getConfig().getInt("guardians.accept.timer") * 1000); + } + + + public void addGuardian(Habbo guardian) { + GuardianVote vote = this.votes.get(guardian); + + if (vote != null && vote.type == GuardianVoteType.SEARCHING) { + guardian.getClient().sendResponse(new GuardianVotingRequestedComposer(this)); + vote.type = GuardianVoteType.WAITING; + this.updateVotes(); + } + } + + + public void removeGuardian(Habbo guardian) { + GuardianVote vote = this.getVoteForGuardian(guardian); + + if (vote == null) + return; + + if (vote.type == GuardianVoteType.SEARCHING || vote.type == GuardianVoteType.WAITING) { + this.getVoteForGuardian(guardian).type = GuardianVoteType.NOT_VOTED; + } + + this.getVoteForGuardian(guardian).ignore = true; + + guardian.getClient().sendResponse(new GuardianVotingTimeEnded()); + + this.updateVotes(); + } + + + public void vote(Habbo guardian, GuardianVoteType vote) { + this.votes.get(guardian).type = vote; + + this.updateVotes(); + + AchievementManager.progressAchievement(guardian, Emulator.getGameEnvironment().getAchievementManager().getAchievement("GuideChatReviewer")); + + this.finish(); + } + + + public void updateVotes() { + synchronized (this.votes) { + for (Map.Entry set : this.votes.entrySet()) { + if (set.getValue().type == GuardianVoteType.WAITING || set.getValue().type == GuardianVoteType.NOT_VOTED || set.getValue().ignore || set.getValue().type == GuardianVoteType.SEARCHING) + continue; + + set.getKey().getClient().sendResponse(new GuardianVotingVotesComposer(this, set.getKey())); + } + } + } + + + public void finish() { + int votedCount = this.getVotedCount(); + if (votedCount < Emulator.getConfig().getInt("guardians.minimum.votes")) { + if (this.votes.size() >= Emulator.getConfig().getInt("guardians.maximum.guardians.total") || this.resendCount == Emulator.getConfig().getInt("guardians.maximum.resends")) { + this.verdict = GuardianVoteType.FORWARDED; + + Emulator.getGameEnvironment().getGuideManager().closeTicket(this); + + ModToolIssue issue = new ModToolIssue(this.reporter.getHabboInfo().getId(), + this.reporter.getHabboInfo().getUsername(), + this.reported.getHabboInfo().getId(), + this.reported.getHabboInfo().getUsername(), + 0, + "", + ModToolTicketType.GUARDIAN); + + Emulator.getGameEnvironment().getModToolManager().addTicket(issue); + Emulator.getGameEnvironment().getModToolManager().updateTicketToMods(issue); + + this.reporter.getClient().sendResponse(new BullyReportClosedComposer(BullyReportClosedComposer.CLOSED)); + } else { + this.timeLeft = 30; + Emulator.getThreading().run(new GuardianVotingFinish(this), 10000); + this.resendCount++; + + Emulator.getGameEnvironment().getGuideManager().findGuardians(this); + } + } else { + this.verdict = this.calculateVerdict(); + + for (Map.Entry set : this.votes.entrySet()) { + if (set.getValue().type == GuardianVoteType.ACCEPTABLY || + set.getValue().type == GuardianVoteType.BADLY || + set.getValue().type == GuardianVoteType.AWFULLY) { + set.getKey().getClient().sendResponse(new GuardianVotingResultComposer(this, set.getValue())); + } + } + + Emulator.getGameEnvironment().getGuideManager().closeTicket(this); + + if (this.verdict == GuardianVoteType.ACCEPTABLY) + this.reporter.getClient().sendResponse(new BullyReportClosedComposer(BullyReportClosedComposer.MISUSE)); + else + this.reporter.getClient().sendResponse(new BullyReportClosedComposer(BullyReportClosedComposer.CLOSED)); + } + } + + + public boolean inProgress() { + return this.verdict == null; + } + + + public GuardianVoteType calculateVerdict() { + int countAcceptably = 0; + int countBadly = 0; + int countAwfully = 0; + int total = 0; + + synchronized (this.votes) { + for (Map.Entry set : this.votes.entrySet()) { + GuardianVote vote = set.getValue(); + + if (vote.type == GuardianVoteType.ACCEPTABLY) { + countAcceptably++; + } else if (vote.type == GuardianVoteType.BADLY) { + countBadly++; + } else if (vote.type == GuardianVoteType.AWFULLY) { + countAwfully++; + } + } + } + + total += countAcceptably; + total += countBadly; + + + return GuardianVoteType.BADLY; + } + + public GuardianVote getVoteForGuardian(Habbo guardian) { + return this.votes.get(guardian); + } + + public THashMap getVotes() { + return this.votes; + } + + public int getTimeLeft() { + return this.timeLeft; + } + + public GuardianVoteType getVerdict() { + return this.verdict; + } + + public ArrayList getChatLogs() { + return this.chatLogs; + } + + public int getResendCount() { + return this.resendCount; + } + + public int getCheckSum() { + return this.checkSum; + } + + public Habbo getReporter() { + return this.reporter; + } + + public Habbo getReported() { + return this.reported; + } + + public Date getDate() { + return this.date; + } + + public int getGuardianCount() { + return this.guardianCount; + } + + + public ArrayList getSortedVotes(Habbo guardian) { + synchronized (this.votes) { + ArrayList votes = new ArrayList<>(this.votes.values()); + Collections.sort(votes); + + GuardianVote v = null; + for (GuardianVote vote : votes) { + if (vote.guardian == guardian) { + v = vote; + break; + } + } + votes.remove(v); + + return votes; + } + } + + + public int getVotedCount() { + int count = 0; + synchronized (this.votes) { + for (Map.Entry set : this.votes.entrySet()) { + if (set.getValue().type == GuardianVoteType.ACCEPTABLY || + set.getValue().type == GuardianVoteType.BADLY || + set.getValue().type == GuardianVoteType.AWFULLY) + count++; + } + } + + return count; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuardianVote.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuardianVote.java new file mode 100644 index 0000000..0066bc3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuardianVote.java @@ -0,0 +1,35 @@ +package com.eu.habbo.habbohotel.guides; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class GuardianVote implements Comparable { + public final int id; + final Habbo guardian; + public GuardianVoteType type; + boolean ignore; + + public GuardianVote(int id, Habbo guardian) { + this.id = id; + this.guardian = guardian; + this.type = GuardianVoteType.SEARCHING; + this.ignore = false; + } + + @Override + public int compareTo(GuardianVote o) { + return this.id - o.id; + } + + @Override + public boolean equals(Object o) { + if (o instanceof GuardianVote) { + return ((GuardianVote) o).id == this.id && ((GuardianVote) o).guardian == this.guardian && ((GuardianVote) o).type == this.type; + } + + return false; + } + + public void ignore() { + this.ignore = true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuardianVoteType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuardianVoteType.java new file mode 100644 index 0000000..68d93ae --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuardianVoteType.java @@ -0,0 +1,22 @@ +package com.eu.habbo.habbohotel.guides; + +public enum GuardianVoteType { + FORWARDED(-1), + WAITING(0), + ACCEPTABLY(1), + BADLY(2), + AWFULLY(3), + NOT_VOTED(4), + SEARCHING(5); + + private final int type; + + GuardianVoteType(int type) { + this.type = type; + } + + public int getType() { + return this.type; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuideChatMessage.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuideChatMessage.java new file mode 100644 index 0000000..8011fdc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuideChatMessage.java @@ -0,0 +1,13 @@ +package com.eu.habbo.habbohotel.guides; + +public class GuideChatMessage { + public final int userId; + public final String message; + public final int timestamp; + + public GuideChatMessage(int userId, String message, int timestamp) { + this.userId = userId; + this.message = message; + this.timestamp = timestamp; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuideManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuideManager.java new file mode 100644 index 0000000..4407f81 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuideManager.java @@ -0,0 +1,388 @@ +package com.eu.habbo.habbohotel.guides; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.guides.*; +import com.eu.habbo.threading.runnables.GuardianTicketFindMoreSlaves; +import com.eu.habbo.threading.runnables.GuideFindNewHelper; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + +import java.util.Map; + +public class GuideManager { + private final THashSet activeTours; + private final THashSet activeTickets; + private final THashSet closedTickets; + private final THashMap activeHelpers; + private final THashMap activeGuardians; + private final THashMap tourRequestTiming; + + public GuideManager() { + this.activeTours = new THashSet<>(); + this.activeTickets = new THashSet<>(); + this.closedTickets = new THashSet<>(); + this.activeHelpers = new THashMap<>(); + this.activeGuardians = new THashMap<>(); + this.tourRequestTiming = new THashMap<>(); + } + + public void userLogsOut(Habbo habbo) { + GuideTour tour = this.getGuideTourByHabbo(habbo); + + if (tour != null) { + this.endSession(tour); + } + + this.activeHelpers.remove(habbo); + + GuardianTicket ticket = this.getTicketForGuardian(habbo); + + if (ticket != null) { + ticket.removeGuardian(habbo); + } + + this.activeGuardians.remove(habbo); + } + + + public void setOnGuide(Habbo habbo, boolean onDuty) { + if (onDuty) { + this.activeHelpers.put(habbo, false); + } else { + GuideTour tour = this.getGuideTourByHabbo(habbo); + + if (tour != null) + return; + + this.activeHelpers.remove(habbo); + } + } + + + public boolean findHelper(GuideTour tour) { + synchronized (this.activeHelpers) { + for (Map.Entry set : this.activeHelpers.entrySet()) { + if (!set.getValue()) { + if (!tour.hasDeclined(set.getKey().getHabboInfo().getId())) { + tour.checkSum++; + tour.setHelper(set.getKey()); + set.getKey().getClient().sendResponse(new GuideSessionAttachedComposer(tour, true)); + tour.getNoob().getClient().sendResponse(new GuideSessionAttachedComposer(tour, false)); + Emulator.getThreading().run(new GuideFindNewHelper(tour, set.getKey()), 60000); + this.activeTours.add(tour); + return true; + } + } + } + } + this.endSession(tour); + tour.getNoob().getClient().sendResponse(new GuideSessionErrorComposer(GuideSessionErrorComposer.NO_HELPERS_AVAILABLE)); + + return false; + } + + + public void declineTour(GuideTour tour) { + Habbo helper = tour.getHelper(); + tour.addDeclinedHelper(tour.getHelper().getHabboInfo().getId()); + tour.setHelper(null); + helper.getClient().sendResponse(new GuideSessionEndedComposer(GuideSessionEndedComposer.HELP_CASE_CLOSED)); + helper.getClient().sendResponse(new GuideSessionDetachedComposer()); + if (!this.findHelper(tour)) { + this.endSession(tour); + tour.getNoob().getClient().sendResponse(new GuideSessionErrorComposer(GuideSessionErrorComposer.NO_HELPERS_AVAILABLE)); + } + } + + + public void startSession(GuideTour tour, Habbo helper) { + synchronized (this.activeTours) { + synchronized (this.activeHelpers) { + this.activeHelpers.put(helper, true); + + ServerMessage message = new GuideSessionStartedComposer(tour).compose(); + tour.getNoob().getClient().sendResponse(message); + tour.getHelper().getClient().sendResponse(message); + tour.checkSum++; + this.tourRequestTiming.put(tour.getStartTime(), Emulator.getIntUnixTimestamp()); + } + } + } + + + public void endSession(GuideTour tour) { + synchronized (this.activeTours) { + synchronized (this.activeHelpers) { + tour.getNoob().getClient().sendResponse(new GuideSessionEndedComposer(GuideSessionEndedComposer.HELP_CASE_CLOSED)); + tour.end(); + + if (tour.getHelper() != null) { + this.activeHelpers.put(tour.getHelper(), false); + tour.getHelper().getClient().sendResponse(new GuideSessionEndedComposer(GuideSessionEndedComposer.HELP_CASE_CLOSED)); + tour.getHelper().getClient().sendResponse(new GuideSessionDetachedComposer()); + tour.getHelper().getClient().sendResponse(new GuideToolsComposer(true)); + } + } + } + } + + + public void recommend(GuideTour tour, boolean recommend) { + synchronized (this.activeTours) { + tour.setWouldRecommend(recommend ? GuideRecommendStatus.YES : GuideRecommendStatus.NO); + tour.getNoob().getClient().sendResponse(new GuideSessionDetachedComposer()); + AchievementManager.progressAchievement(tour.getNoob(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("GuideFeedbackGiver")); + + this.activeTours.remove(tour); + } + } + + + public GuideTour getGuideTourByHelper(Habbo helper) { + synchronized (this.activeTours) { + for (GuideTour tour : this.activeTours) { + if (!tour.isEnded() && tour.getHelper() == helper) { + return tour; + } + } + } + + return null; + } + + + public GuideTour getGuideTourByNoob(Habbo noob) { + synchronized (this.activeTours) { + for (GuideTour tour : this.activeTours) { + if (tour.getNoob() == noob) { + return tour; + } + } + } + + return null; + } + + + public GuideTour getGuideTourByHabbo(Habbo habbo) { + synchronized (this.activeTours) { + for (GuideTour tour : this.activeTours) { + if (tour.getHelper() == habbo || tour.getNoob() == habbo) { + return tour; + } + } + } + + return null; + } + + + public int getGuidesCount() { + return this.activeHelpers.size(); + } + + + public int getGuardiansCount() { + return this.activeGuardians.size(); + } + + + public boolean activeGuardians() { + return this.activeGuardians.size() > 0; + } + + + public int getAverageWaitingTime() { + synchronized (this.tourRequestTiming) { + int total = 0; + + if (this.tourRequestTiming.isEmpty()) + return 5; + + for (Map.Entry set : this.tourRequestTiming.entrySet()) { + total += (set.getValue() - set.getKey()); + } + + return total / this.tourRequestTiming.size(); + } + } + + + public void addGuardianTicket(GuardianTicket ticket) { + synchronized (this.activeTickets) { + this.activeTickets.add(ticket); + + this.findGuardians(ticket); + } + } + + + public void findGuardians(GuardianTicket ticket) { + synchronized (this.activeGuardians) { + int count = ticket.getVotedCount(); + + THashSet selectedGuardians = new THashSet<>(); + + for (Map.Entry set : this.activeGuardians.entrySet()) { + if (count == 5) + break; + + if (set.getKey() == ticket.getReporter() || + set.getKey() == ticket.getReported()) + continue; + + if (set.getValue() == null) { + if (ticket.getVoteForGuardian(set.getKey()) == null) { + ticket.requestToVote(set.getKey()); + + selectedGuardians.add(set.getKey()); + } + } + + count++; + } + + for (Habbo habbo : selectedGuardians) { + this.activeGuardians.put(habbo, ticket); + } + + if (count < 5) { + Emulator.getThreading().run(new GuardianTicketFindMoreSlaves(ticket), 3000); + } + } + } + + + public void acceptTicket(Habbo guardian, boolean accepted) { + GuardianTicket ticket = this.getTicketForGuardian(guardian); + + if (ticket != null) { + if (!accepted) { + ticket.removeGuardian(guardian); + this.findGuardians(ticket); + this.activeGuardians.put(guardian, null); + } else { + ticket.addGuardian(guardian); + this.activeGuardians.put(guardian, ticket); + } + } + } + + + public GuardianTicket getTicketForGuardian(Habbo guardian) { + synchronized (this.activeGuardians) { + return this.activeGuardians.get(guardian); + } + } + + + public GuardianTicket getRecentTicket(Habbo reporter) { + GuardianTicket ticket = null; + + synchronized (this.activeTickets) { + for (GuardianTicket t : this.activeTickets) { + if (t.getReporter() == reporter) { + return t; + } + } + } + + synchronized (this.closedTickets) { + for (GuardianTicket t : this.closedTickets) { + if (t.getReporter() != reporter) + continue; + + if (ticket == null || Emulator.getIntUnixTimestamp() - (t.getDate().getTime() / 1000) < Emulator.getIntUnixTimestamp() - (ticket.getDate().getTime() / 1000)) { + ticket = t; + } + } + } + + return ticket; + } + + public GuardianTicket getOpenReportedHabboTicket(Habbo reported) { + synchronized (this.activeTickets) { + for (GuardianTicket t : this.activeTickets) { + if (t.getReported() == reported) { + return t; + } + } + } + + return null; + } + + + public void closeTicket(GuardianTicket ticket) { + synchronized (this.activeTickets) { + this.activeTickets.remove(ticket); + } + + synchronized (this.closedTickets) { + this.closedTickets.add(ticket); + } + + THashSet toUpdate = new THashSet<>(); + + synchronized (this.activeGuardians) { + for (Map.Entry set : this.activeGuardians.entrySet()) { + if (set.getValue() == ticket) { + toUpdate.add(set.getKey()); + } + } + + for (Habbo habbo : toUpdate) { + this.activeGuardians.put(habbo, null); + } + } + } + + + public void setOnGuardian(Habbo habbo, boolean onDuty) { + if (onDuty) { + this.activeGuardians.put(habbo, null); + } else { + GuardianTicket ticket = this.getTicketForGuardian(habbo); + + if (ticket != null) { + ticket.removeGuardian(habbo); + } + + this.activeGuardians.remove(habbo); + } + } + + + public void cleanup() { + synchronized (this.activeTours) { + THashSet tours = new THashSet<>(); + for (GuideTour tour : this.activeTours) { + if (tour.isEnded() && (Emulator.getIntUnixTimestamp() - tour.getEndTime() > 300)) { + tours.add(tour); + } + } + + for (GuideTour tour : tours) { + this.activeTours.remove(tour); + } + } + + synchronized (this.activeTickets) { + THashSet tickets = new THashSet<>(); + + for (GuardianTicket ticket : this.closedTickets) { + if (Emulator.getIntUnixTimestamp() - (ticket.getDate().getTime() / 1000) > 15 * 60) { + tickets.add(ticket); + } + } + + for (GuardianTicket ticket : tickets) { + this.closedTickets.remove(ticket); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuideRecommendStatus.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuideRecommendStatus.java new file mode 100644 index 0000000..169dfee --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuideRecommendStatus.java @@ -0,0 +1,7 @@ +package com.eu.habbo.habbohotel.guides; + +public enum GuideRecommendStatus { + UNKNOWN, + YES, + NO +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuideTour.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuideTour.java new file mode 100644 index 0000000..8e52be2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guides/GuideTour.java @@ -0,0 +1,96 @@ +package com.eu.habbo.habbohotel.guides; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.users.Habbo; +import gnu.trove.set.hash.THashSet; + +public class GuideTour { + private final Habbo noob; + private final String helpRequest; + private final THashSet sendMessages = new THashSet<>(); + private final THashSet declinedHelpers = new THashSet<>(); + public int checkSum = 0; + private Habbo helper; + private int startTime; + private int endTime; + private boolean ended; + private GuideRecommendStatus wouldRecommend = GuideRecommendStatus.UNKNOWN; + + public GuideTour(Habbo noob, String helpRequest) { + this.noob = noob; + this.helpRequest = helpRequest; + + AchievementManager.progressAchievement(this.noob, Emulator.getGameEnvironment().getAchievementManager().getAchievement("GuideAdvertisementReader")); + } + + public void finish() { + //TODO Insert recommendation. + //TODO Query messages. + } + + public Habbo getNoob() { + return this.noob; + } + + public String getHelpRequest() { + return this.helpRequest; + } + + public Habbo getHelper() { + return this.helper; + } + + public void setHelper(Habbo helper) { + this.helper = helper; + } + + public void addMessage(GuideChatMessage message) { + this.sendMessages.add(message); + } + + public GuideRecommendStatus getWouldRecommend() { + return this.wouldRecommend; + } + + public void setWouldRecommend(GuideRecommendStatus wouldRecommend) { + this.wouldRecommend = wouldRecommend; + + if (this.wouldRecommend == GuideRecommendStatus.YES) { + AchievementManager.progressAchievement(this.getHelper(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("GuideRecommendation")); + } + } + + public void addDeclinedHelper(int userId) { + this.declinedHelpers.add(userId); + } + + public boolean hasDeclined(int userId) { + return this.declinedHelpers.contains(userId); + } + + public void end() { + this.ended = true; + this.endTime = Emulator.getIntUnixTimestamp(); + + AchievementManager.progressAchievement(this.helper, Emulator.getGameEnvironment().getAchievementManager().getAchievement("GuideEnrollmentLifetime")); + AchievementManager.progressAchievement(this.helper, Emulator.getGameEnvironment().getAchievementManager().getAchievement("GuideRequestHandler")); + AchievementManager.progressAchievement(this.noob, Emulator.getGameEnvironment().getAchievementManager().getAchievement("GuideRequester")); + } + + public boolean isEnded() { + return this.ended; + } + + public int getStartTime() { + return this.startTime; + } + + public void setStartTime(int startTime) { + this.startTime = startTime; + } + + public int getEndTime() { + return this.endTime; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/Guild.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/Guild.java new file mode 100644 index 0000000..e778c20 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/Guild.java @@ -0,0 +1,276 @@ +package com.eu.habbo.habbohotel.guilds; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class Guild implements Runnable { + public boolean needsUpdate; + public int lastRequested = Emulator.getIntUnixTimestamp(); + private int id; + private int ownerId; + private String ownerName; + private String name; + private String description; + private int roomId; + private String roomName; + private GuildState state; + private boolean rights; + private int colorOne; + private int colorTwo; + private String badge; + private int dateCreated; + private int memberCount; + private int requestCount; + private boolean forum = false; + private SettingsState readForum = SettingsState.ADMINS; + private SettingsState postMessages = SettingsState.ADMINS; + private SettingsState postThreads = SettingsState.ADMINS; + private SettingsState modForum = SettingsState.ADMINS; + + public Guild(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.ownerId = set.getInt("user_id"); + this.ownerName = set.getString("username"); + this.name = set.getString("name"); + this.description = set.getString("description"); + this.state = GuildState.values()[set.getInt("state")]; + this.roomId = set.getInt("room_id"); + this.roomName = set.getString("room_name"); + this.rights = set.getString("rights").equalsIgnoreCase("1"); + this.colorOne = set.getInt("color_one"); + this.colorTwo = set.getInt("color_two"); + this.badge = set.getString("badge"); + this.dateCreated = set.getInt("date_created"); + this.forum = set.getString("forum").equalsIgnoreCase("1"); + this.readForum = SettingsState.valueOf(set.getString("read_forum")); + this.postMessages = SettingsState.valueOf(set.getString("post_messages")); + this.postThreads = SettingsState.valueOf(set.getString("post_threads")); + this.modForum = SettingsState.valueOf(set.getString("mod_forum")); + this.memberCount = 0; + this.requestCount = 0; + } + + public Guild(int ownerId, String ownerName, int roomId, String roomName, String name, String description, int colorOne, int colorTwo, String badge) { + this.id = 0; + this.ownerId = ownerId; + this.ownerName = ownerName; + this.roomId = roomId; + this.roomName = roomName; + this.name = name; + this.description = description; + this.state = GuildState.OPEN; + this.rights = false; + this.colorOne = colorOne; + this.colorTwo = colorTwo; + this.badge = badge; + this.memberCount = 0; + this.dateCreated = Emulator.getIntUnixTimestamp(); + } + + public void loadMemberCount() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT COUNT(id) as count FROM guilds_members WHERE level_id < 3 AND guild_id = ?")) { + statement.setInt(1, this.id); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + this.memberCount = set.getInt(1); + } + } + } + + try (PreparedStatement statement = connection.prepareStatement("SELECT COUNT(id) as count FROM guilds_members WHERE level_id = 3 AND guild_id = ?")) { + statement.setInt(1, this.id); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + this.requestCount = set.getInt(1); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + @Override + public void run() { + if (this.needsUpdate) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE guilds SET name = ?, description = ?, state = ?, rights = ?, color_one = ?, color_two = ?, badge = ?, read_forum = ?, post_messages = ?, post_threads = ?, mod_forum = ?, forum = ? WHERE id = ?")) { + statement.setString(1, this.name); + statement.setString(2, this.description); + statement.setInt(3, this.state.state); + statement.setString(4, this.rights ? "1" : "0"); + statement.setInt(5, this.colorOne); + statement.setInt(6, this.colorTwo); + statement.setString(7, this.badge); + statement.setString(8, this.readForum.name()); + statement.setString(9, this.postMessages.name()); + statement.setString(10, this.postThreads.name()); + statement.setString(11, this.modForum.name()); + statement.setString(12, this.forum ? "1" : "0"); + statement.setInt(13, this.id); + statement.execute(); + + this.needsUpdate = false; + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public String getOwnerName() { + return this.ownerName; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return this.description; + } + + public void setDescription(String description) { + this.description = description; + } + + public int getRoomId() { + return this.roomId; + } + + public String getRoomName() { + return this.roomName; + } + + public void setRoomName(String roomName) { + this.roomName = roomName; + } + + public GuildState getState() { + return this.state; + } + + public void setState(GuildState state) { + this.state = state; + } + + public boolean getRights() { + return this.rights; + } + + public void setRights(boolean rights) { + this.rights = rights; + } + + public int getColorOne() { + return this.colorOne; + } + + public void setColorOne(int colorOne) { + this.colorOne = colorOne; + } + + public int getColorTwo() { + return this.colorTwo; + } + + public void setColorTwo(int colorTwo) { + this.colorTwo = colorTwo; + } + + public String getBadge() { + return this.badge; + } + + public void setBadge(String badge) { + this.badge = badge; + } + + public int getOwnerId() { + return this.ownerId; + } + + public int getDateCreated() { + return dateCreated; + } + + public int getMemberCount() { + return this.memberCount; + } + + public void increaseMemberCount() { + this.memberCount++; + } + + public void decreaseMemberCount() { + this.memberCount--; + } + + public int getRequestCount() { + return this.requestCount; + } + + public void increaseRequestCount() { + this.requestCount++; + } + + public void decreaseRequestCount() { + this.requestCount--; + } + + public boolean hasForum() { + return this.forum; + } + + public void setForum(boolean forum) { + this.forum = forum; + } + + public SettingsState canReadForum() { + return this.readForum; + } + + public void setReadForum(SettingsState readForum) { + this.readForum = readForum; + } + + public SettingsState canPostMessages() { + return this.postMessages; + } + + public void setPostMessages(SettingsState postMessages) { + this.postMessages = postMessages; + } + + public SettingsState canPostThreads() { + return this.postThreads; + } + + public void setPostThreads(SettingsState postThreads) { + this.postThreads = postThreads; + } + + public SettingsState canModForum() { + return this.modForum; + } + + public void setModForum(SettingsState modForum) { + this.modForum = modForum; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildManager.java new file mode 100644 index 0000000..65c6903 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildManager.java @@ -0,0 +1,645 @@ +package com.eu.habbo.habbohotel.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.guilds.forums.ForumView; +import com.eu.habbo.habbohotel.items.interactions.InteractionGuildFurni; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.guilds.GuildJoinErrorComposer; +import gnu.trove.TCollections; +import gnu.trove.iterator.TIntObjectIterator; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; +import java.sql.*; +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +public class GuildManager { + private final THashMap> guildParts; + private final TIntObjectMap guilds; + private final THashSet views = new THashSet<>(); + + public GuildManager() { + long millis = System.currentTimeMillis(); + this.guildParts = new THashMap>(); + this.guilds = TCollections.synchronizedMap(new TIntObjectHashMap()); + + this.loadGuildParts(); + this.loadGuildViews(); + + log.info("Guild Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)"); + } + + + public void loadGuildParts() { + this.guildParts.clear(); + + for (GuildPartType t : GuildPartType.values()) { + this.guildParts.put(t, new THashMap<>()); + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + Statement statement = connection.createStatement(); + ResultSet set = statement.executeQuery("SELECT * FROM guilds_elements")) { + while (set.next()) { + this.guildParts.get(GuildPartType.valueOf(set.getString("type").toUpperCase())).put(set.getInt("id"), new GuildPart(set)); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void loadGuildViews() { + this.views.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + Statement statement = connection.createStatement(); + ResultSet set = statement.executeQuery("SELECT * FROM guild_forum_views")) { + while (set.next()) { + this.views.add(new ForumView(set)); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public Guild createGuild(Habbo habbo, int roomId, String roomName, String name, String description, String badge, int colorOne, int colorTwo) { + Guild guild = new Guild(habbo.getHabboInfo().getId(), habbo.getHabboInfo().getUsername(), roomId, roomName, name, description, colorOne, colorTwo, badge); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO guilds (name, description, room_id, user_id, color_one, color_two, badge, date_created) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setString(1, name); + statement.setString(2, description); + statement.setInt(3, roomId); + statement.setInt(4, guild.getOwnerId()); + statement.setInt(5, colorOne); + statement.setInt(6, colorTwo); + statement.setString(7, badge); + statement.setInt(8, Emulator.getIntUnixTimestamp()); + statement.execute(); + + try (ResultSet set = statement.getGeneratedKeys()) { + if (set.next()) { + guild.setId(set.getInt(1)); + } + } + } + + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO guilds_members (guild_id, user_id, level_id, member_since) VALUES (?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, guild.getId()); + statement.setInt(2, habbo.getHabboInfo().getId()); + statement.setInt(3, 0); + statement.setInt(4, Emulator.getIntUnixTimestamp()); + statement.execute(); + + try (ResultSet set = statement.getGeneratedKeys()) { + if (set.next()) { + guild.increaseMemberCount(); + //guild.addMember(new GuildMember(habbo.getHabboInfo().getId(), habbo.getHabboInfo().getUsername(), habbo.getHabboInfo().getLook(), Emulator.getIntUnixTimestamp(), 2)); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + habbo.getHabboStats().addGuild(guild.getId()); + + return guild; + } + + + public void deleteGuild(Guild guild) { + THashSet members = this.getGuildMembers(guild); + + for (GuildMember member : members) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(member.getUserId()); + + if (habbo != null) { + habbo.getHabboStats().removeGuild(guild.getId()); + + if (habbo.getHabboStats().guild == guild.getId()) { + habbo.getHabboStats().guild = 0; + } + } + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement deleteFavourite = connection.prepareStatement("UPDATE users_settings SET guild_id = ? WHERE guild_id = ?")) { + deleteFavourite.setInt(1, 0); + deleteFavourite.setInt(2, guild.getId()); + deleteFavourite.execute(); + } + + + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM guilds_members WHERE guild_id = ?")) { + statement.setInt(1, guild.getId()); + statement.execute(); + } + + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM guilds WHERE id = ?")) { + statement.setInt(1, guild.getId()); + statement.execute(); + } + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(guild.getRoomId()); + + if (room != null) { + room.setGuildId(0); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + + public void clearInactiveGuilds() { + List toRemove = new ArrayList(); + TIntObjectIterator guilds = this.guilds.iterator(); + for (int i = this.guilds.size(); i-- > 0; ) { + try { + guilds.advance(); + } catch (NoSuchElementException e) { + break; + } + + if (guilds.value().lastRequested < Emulator.getIntUnixTimestamp() - 300) { + toRemove.add(guilds.value().getId()); + } + } + + for (Integer i : toRemove) { + this.guilds.remove(i); + } + } + + + public void joinGuild(Guild guild, GameClient client, int userId, boolean acceptRequest) { + boolean error = false; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT COUNT(id) as total FROM guilds_members WHERE user_id = ?")) { + if (userId == 0) + statement.setInt(1, client.getHabbo().getHabboInfo().getId()); + else + statement.setInt(1, userId); + + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + if (set.getInt(1) >= 100) { + //TODO Add non acceptRequest errors. See Outgoing.GroupEditFailComposer + if (userId == 0) + client.sendResponse(new GuildJoinErrorComposer(GuildJoinErrorComposer.GROUP_LIMIT_EXCEED)); + else + client.sendResponse(new GuildJoinErrorComposer(GuildJoinErrorComposer.MEMBER_FAIL_JOIN_LIMIT_EXCEED_NON_HC)); + + error = true; + } + } + } + } + + if (!error) { + try (PreparedStatement statement = connection.prepareStatement("SELECT COUNT(id) as total FROM guilds_members WHERE guild_id = ? AND level_id < 3")) { + statement.setInt(1, guild.getId()); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + if (set.getInt(1) >= 50000) { + client.sendResponse(new GuildJoinErrorComposer(GuildJoinErrorComposer.GROUP_FULL)); + error = true; + } + } + } + } + + if (userId == 0 && !error) { + if (guild.getState() == GuildState.EXCLUSIVE) { + try (PreparedStatement statement = connection.prepareStatement("SELECT COUNT(id) as total FROM guilds_members WHERE guild_id = ? AND level_id = 3")) { + statement.setInt(1, guild.getId()); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + if (set.getInt(1) >= 100) { + client.sendResponse(new GuildJoinErrorComposer(GuildJoinErrorComposer.GROUP_NOT_ACCEPT_REQUESTS)); + error = true; + } + } + } + } + + if (!error) { + try (PreparedStatement statement = connection.prepareStatement("SELECT COUNT(id) as total FROM guilds_members WHERE guild_id = ? AND user_id = ? LIMIT 1")) { + statement.setInt(1, guild.getId()); + statement.setInt(2, client.getHabbo().getHabboInfo().getId()); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + if (set.getInt(1) >= 1) { + error = true; + } + } + } + } + } + } + + if (!error) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO guilds_members (guild_id, user_id, member_since, level_id) VALUES (?, ?, ?, ?)")) { + statement.setInt(1, guild.getId()); + statement.setInt(2, client.getHabbo().getHabboInfo().getId()); + statement.setInt(3, Emulator.getIntUnixTimestamp()); + statement.setInt(4, guild.getState() == GuildState.EXCLUSIVE ? GuildRank.REQUESTED.type : GuildRank.MEMBER.type); + statement.execute(); + } + } + } else if (!error) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE guilds_members SET level_id = ?, member_since = ? WHERE user_id = ? AND guild_id = ?")) { + statement.setInt(1, GuildRank.MEMBER.type); + statement.setInt(2, Emulator.getIntUnixTimestamp()); + statement.setInt(3, userId); + statement.setInt(4, guild.getId()); + statement.execute(); + } + } + + if (userId == 0 && !error) { + if (guild.getState() == GuildState.EXCLUSIVE) + guild.increaseRequestCount(); + else { + guild.increaseMemberCount(); + client.getHabbo().getHabboStats().addGuild(guild.getId()); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + + public void setAdmin(Guild guild, int userId) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE guilds_members SET level_id = ? WHERE user_id = ? AND guild_id = ? LIMIT 1")) { + statement.setInt(1, 1); + statement.setInt(2, userId); + statement.setInt(3, guild.getId()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + + public void removeAdmin(Guild guild, int userId) { + if (guild.getOwnerId() == userId) + return; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE guilds_members SET level_id = ? WHERE user_id = ? AND guild_id = ? LIMIT 1")) { + statement.setInt(1, 2); + statement.setInt(2, userId); + statement.setInt(3, guild.getId()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + + public void removeMember(Guild guild, int userId) { + if (guild.getOwnerId() == userId) + return; + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + + if (habbo != null && habbo.getHabboStats().guild == guild.getId()) { + habbo.getHabboStats().removeGuild(guild.getId()); + habbo.getHabboStats().guild = 0; + habbo.getHabboStats().run(); + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM guilds_members WHERE user_id = ? AND guild_id = ? LIMIT 1")) { + statement.setInt(1, userId); + statement.setInt(2, guild.getId()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + + public void addGuild(Guild guild) { + guild.lastRequested = Emulator.getIntUnixTimestamp(); + this.guilds.put(guild.getId(), guild); + } + + + public GuildMember getGuildMember(Guild guild, Habbo habbo) { + return getGuildMember(guild.getId(), habbo.getHabboInfo().getId()); + } + + + public GuildMember getGuildMember(int guildId, int habboId) { + GuildMember member = null; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.username, users.look, guilds_members.* FROM guilds_members INNER JOIN users ON guilds_members.user_id = users.id WHERE guilds_members.guild_id = ? AND guilds_members.user_id = ? LIMIT 1")) { + statement.setInt(1, guildId); + statement.setInt(2, habboId); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + member = new GuildMember(set); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return member; + } + + + public THashSet getGuildMembers(int guildId) { + return this.getGuildMembers(this.getGuild(guildId)); + } + + + THashSet getGuildMembers(Guild guild) { + THashSet guildMembers = new THashSet(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.username, users.look, guilds_members.* FROM guilds_members INNER JOIN users ON guilds_members.user_id = users.id WHERE guilds_members.guild_id = ?")) { + statement.setInt(1, guild.getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + guildMembers.add(new GuildMember(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return guildMembers; + } + + + public ArrayList getGuildMembers(Guild guild, int page, int levelId, String query) { + ArrayList guildMembers = new ArrayList(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.username, users.look, guilds_members.* FROM guilds_members INNER JOIN users ON guilds_members.user_id = users.id WHERE guilds_members.guild_id = ? " + (rankQuery(levelId)) + " AND users.username LIKE ? ORDER BY level_id, member_since ASC LIMIT ?, ?")) { + statement.setInt(1, guild.getId()); + statement.setString(2, "%" + query + "%"); + statement.setInt(3, page * 14); + statement.setInt(4, (page * 14) + 14); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + guildMembers.add(new GuildMember(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return guildMembers; + } + + public int getGuildMembersCount(Guild guild, int page, int levelId, String query) { + ArrayList guildMembers = new ArrayList(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT COUNT(*) FROM guilds_members INNER JOIN users ON guilds_members.user_id = users.id WHERE guilds_members.guild_id = ? " + (rankQuery(levelId)) + " AND users.username LIKE ? ORDER BY level_id, member_since ASC")) { + statement.setInt(1, guild.getId()); + statement.setString(2, "%" + query + "%"); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + return set.getInt(1); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return 0; + } + + + public THashMap getOnlyAdmins(Guild guild) { + THashMap guildAdmins = new THashMap(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.username, users.look, guilds_members.* FROM guilds_members INNER JOIN users ON guilds_members.user_id = users.id WHERE guilds_members.guild_id = ? " + (rankQuery(1)))) { + statement.setInt(1, guild.getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + guildAdmins.put(set.getInt("user_id"), new GuildMember(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return guildAdmins; + } + + private String rankQuery(int level) { + switch (level) { + case 2: + return "AND guilds_members.level_id = 3"; + case 1: + return "AND (guilds_members.level_id = 0 OR guilds_members.level_id = 1)"; + default: + return "AND guilds_members.level_id >= 0 AND guilds_members.level_id <= 2"; + } + } + + + public Guild getGuild(int guildId) { + Guild g = this.guilds.get(guildId); + + if (g == null) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.username, rooms.name as room_name, guilds.* FROM guilds INNER JOIN users ON guilds.user_id = users.id INNER JOIN rooms ON rooms.id = guilds.room_id WHERE guilds.id = ? LIMIT 1")) { + statement.setInt(1, guildId); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + g = new Guild(set); + } + } + if (g != null) + g.loadMemberCount(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + if (g != null) { + g.lastRequested = Emulator.getIntUnixTimestamp(); + if (!this.guilds.containsKey(guildId)) + this.guilds.put(guildId, g); + } + + return g; + } + + public List getGuilds(int userId) { + List guilds = new ArrayList(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT guild_id FROM guilds_members WHERE user_id = ? AND level_id <= 2 ORDER BY member_since ASC")) { + statement.setInt(1, userId); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + Guild guild = getGuild(set.getInt("guild_id")); + + if (guild != null) { + guilds.add(guild); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return guilds; + } + + public List getAllGuilds() { + List guilds = new ArrayList(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT id FROM guilds ORDER BY id DESC LIMIT 20")) { + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + Guild guild = getGuild(set.getInt("id")); + + if (guild != null) { + guilds.add(guild); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return guilds; + } + + public boolean symbolColor(int colorId) { + for (GuildPart part : this.getSymbolColors()) { + if (part.id == colorId) + return true; + } + + return false; + } + + public boolean backgroundColor(int colorId) { + for (GuildPart part : this.getBackgroundColors()) { + if (part.id == colorId) + return true; + } + return false; + } + + public THashMap> getGuildParts() { + return this.guildParts; + } + + public Collection getBases() { + return this.guildParts.get(GuildPartType.BASE).values(); + } + + public GuildPart getBase(int id) { + return this.guildParts.get(GuildPartType.BASE).get(id); + } + + public Collection getSymbols() { + return this.guildParts.get(GuildPartType.SYMBOL).values(); + } + + public GuildPart getSymbol(int id) { + return this.guildParts.get(GuildPartType.SYMBOL).get(id); + } + + public Collection getBaseColors() { + return this.guildParts.get(GuildPartType.BASE_COLOR).values(); + } + + public GuildPart getBaseColor(int id) { + return this.guildParts.get(GuildPartType.BASE_COLOR).get(id); + } + + public Collection getSymbolColors() { + return this.guildParts.get(GuildPartType.SYMBOL_COLOR).values(); + } + + public GuildPart getSymbolColor(int id) { + return this.guildParts.get(GuildPartType.SYMBOL_COLOR).get(id); + } + + public Collection getBackgroundColors() { + return this.guildParts.get(GuildPartType.BACKGROUND_COLOR).values(); + } + + public GuildPart getBackgroundColor(int id) { + return this.guildParts.get(GuildPartType.BACKGROUND_COLOR).get(id); + } + + public GuildPart getPart(GuildPartType type, int id) { + return this.guildParts.get(type).get(id); + } + + + public void setGuild(InteractionGuildFurni furni, int guildId) { + furni.setGuildId(guildId); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE items SET guild_id = ? WHERE id = ?")) { + statement.setInt(1, guildId); + statement.setInt(2, furni.getId()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + + public void dispose() { + TIntObjectIterator guildIterator = this.guilds.iterator(); + + for (int i = this.guilds.size(); i-- > 0; ) { + guildIterator.advance(); + if (guildIterator.value().needsUpdate) + guildIterator.value().run(); + + guildIterator.remove(); + } + log.info("Guild Manager -> Disposed!"); + } + + public boolean hasViewedForum(int userId, int guildId) { + return this.views.stream() + .anyMatch(v -> v.getUserId() == userId && v.getGuildId() == guildId && v.getTimestamp() > (Emulator.getIntUnixTimestamp() - 7 * 24 * 60 * 60)); + } + + public void addView(int userId, int guildId) { + ForumView view = new ForumView(userId, guildId, Emulator.getIntUnixTimestamp()); + + this.views.add(view); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO `guild_forum_views`(`user_id`, `guild_id`, `timestamp`) VALUES (?, ?, ?)")) { + statement.setInt(1, view.getUserId()); + statement.setInt(2, view.getGuildId()); + statement.setInt(3, view.getTimestamp()); + + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public Set getMostViewed() { + return this.views.stream() + .filter(v -> v.getTimestamp() > (Emulator.getIntUnixTimestamp() - 7 * 24 * 60 * 60)) + .collect(Collectors.groupingBy(ForumView::getGuildId)) + .entrySet() + .stream() + .sorted(Comparator.comparingInt((Map.Entry> a) -> a.getValue().size())) + .map(k -> this.getGuild(k.getKey())) + .filter(g -> g != null && g.canReadForum() == SettingsState.EVERYONE) + .limit(100) + .collect(Collectors.toSet()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildMember.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildMember.java new file mode 100644 index 0000000..173bed2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildMember.java @@ -0,0 +1,73 @@ +package com.eu.habbo.habbohotel.guilds; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class GuildMember implements Comparable { + private int userId; + private String username; + private String look; + private int joinDate; + private GuildRank rank; + + public GuildMember(ResultSet set) throws SQLException { + this.userId = set.getInt("user_id"); + this.username = set.getString("username"); + this.look = set.getString("look"); + this.joinDate = set.getInt("member_since"); + this.rank = GuildRank.getRank(set.getInt("level_id")); + } + + public GuildMember(int user_id, String username, String look, int joinDate, int guildRank) { + this.userId = user_id; + this.username = username; + this.look = look; + this.joinDate = joinDate; + this.rank = GuildRank.values()[guildRank]; + } + + public int getUserId() { + return userId; + } + + public String getUsername() { + return username; + } + + public String getLook() { + return look; + } + + public void setLook(String look) { + this.look = look; + } + + public int getJoinDate() { + return joinDate; + } + + public void setJoinDate(int joinDate) { + this.joinDate = joinDate; + } + + public GuildRank getRank() { + return rank; + } + + public void setRank(GuildRank rank) { + this.rank = rank; + } + + @Override + public int compareTo(Object o) { + return 0; + } + + public GuildMembershipStatus getMembershipStatus() { + if (this.rank == GuildRank.DELETED) return GuildMembershipStatus.NOT_MEMBER; + if (this.rank == GuildRank.OWNER || this.rank == GuildRank.ADMIN || this.rank == GuildRank.MEMBER) return GuildMembershipStatus.MEMBER; + if (this.rank == GuildRank.REQUESTED) return GuildMembershipStatus.PENDING; + + return GuildMembershipStatus.NOT_MEMBER; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildMembershipStatus.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildMembershipStatus.java new file mode 100644 index 0000000..e6cb38f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildMembershipStatus.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.guilds; + +public enum GuildMembershipStatus { + NOT_MEMBER(0), + MEMBER(1), + PENDING(2); + + private int status; + + GuildMembershipStatus(int status) { + this.status = status; + } + + public int getStatus() { + return status; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildPart.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildPart.java new file mode 100644 index 0000000..2595c37 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildPart.java @@ -0,0 +1,21 @@ +package com.eu.habbo.habbohotel.guilds; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class GuildPart { + + public final int id; + + + public final String valueA; + + + public final String valueB; + + public GuildPart(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.valueA = set.getString("firstvalue"); + this.valueB = set.getString("secondvalue"); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildPartType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildPartType.java new file mode 100644 index 0000000..5881b53 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildPartType.java @@ -0,0 +1,14 @@ +package com.eu.habbo.habbohotel.guilds; + +public enum GuildPartType { + + BASE, + + + SYMBOL, + + + BASE_COLOR, + SYMBOL_COLOR, + BACKGROUND_COLOR +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildRank.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildRank.java new file mode 100644 index 0000000..a7afa1b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildRank.java @@ -0,0 +1,23 @@ +package com.eu.habbo.habbohotel.guilds; + +public enum GuildRank { + OWNER(0), + ADMIN(1), + MEMBER(2), + REQUESTED(3), + DELETED(4); + + public final int type; + + GuildRank(int type) { + this.type = type; + } + + public static GuildRank getRank(int type) { + try { + return values()[type]; + } catch (Exception e) { + return MEMBER; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildState.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildState.java new file mode 100644 index 0000000..7fcd74e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/GuildState.java @@ -0,0 +1,23 @@ +package com.eu.habbo.habbohotel.guilds; + +public enum GuildState { + OPEN(0), + EXCLUSIVE(1), + CLOSED(2), + LARGE(3), + LARGE_CLOSED(4); + + public final int state; + + GuildState(int state) { + this.state = state; + } + + public static GuildState valueOf(int state) { + try { + return values()[state]; + } catch (Exception e) { + return OPEN; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/SettingsState.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/SettingsState.java new file mode 100644 index 0000000..146606d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/SettingsState.java @@ -0,0 +1,32 @@ +package com.eu.habbo.habbohotel.guilds; + +public enum SettingsState { + EVERYONE(0), + MEMBERS(1), + ADMINS(2), + OWNER(3); + + public final int state; + + SettingsState(int state) { + this.state = state; + } + + public static SettingsState fromValue(int state) { + try { + switch (state) { + case 0: + return EVERYONE; + case 1: + return MEMBERS; + case 2: + return ADMINS; + case 3: + return OWNER; + } + } catch (Exception e) { + } + + return EVERYONE; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumThread.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumThread.java new file mode 100644 index 0000000..444f34b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumThread.java @@ -0,0 +1,468 @@ +package com.eu.habbo.habbohotel.guilds.forums; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.plugin.events.guilds.forums.GuildForumThreadBeforeCreated; +import com.eu.habbo.plugin.events.guilds.forums.GuildForumThreadCreated; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; +import java.sql.*; +import java.util.*; + +@Slf4j +public class ForumThread implements Runnable, ISerialize { + private final static THashMap> guildThreadsCache = new THashMap<>(); + private final static THashMap forumThreadsCache = new THashMap<>(); + private final int threadId; + private final int guildId; + private final int openerId; + private final String subject; + private final int createdAt; + private final THashMap comments; + private int postsCount; + private int updatedAt; + private ForumThreadState state; + private boolean pinned; + private boolean locked; + private int adminId; + private boolean needsUpdate; + private boolean hasCommentsLoaded; + private int commentIndex; + private ForumThreadComment lastComment; + + public ForumThread(int threadId, int guildId, int openerId, String subject, int postsCount, int createdAt, int updatedAt, ForumThreadState state, boolean pinned, boolean locked, int adminId, ForumThreadComment lastComment) { + this.threadId = threadId; + this.guildId = guildId; + this.openerId = openerId; + this.subject = subject; + this.postsCount = postsCount; + this.createdAt = createdAt; + this.updatedAt = updatedAt; + this.state = state; + this.pinned = pinned; + this.locked = locked; + this.adminId = adminId; + this.lastComment = lastComment; + this.comments = new THashMap<>(); + this.needsUpdate = false; + this.hasCommentsLoaded = false; + this.commentIndex = 0; + } + + public ForumThread(ResultSet set) throws SQLException { + this.threadId = set.getInt("id"); + this.guildId = set.getInt("guild_id"); + this.openerId = set.getInt("opener_id"); + this.subject = set.getString("subject"); + this.postsCount = set.getInt("posts_count"); + this.createdAt = set.getInt("created_at"); + this.updatedAt = set.getInt("updated_at"); + this.state = ForumThreadState.fromValue(set.getInt("state")); + this.pinned = set.getInt("pinned") > 0; + this.locked = set.getInt("locked") > 0; + this.adminId = set.getInt("admin_id"); + this.lastComment = null; + + try { + this.lastComment = ForumThreadComment.getById(set.getInt("last_comment_id")); + } catch (SQLException e) { + log.error("ForumThread last_comment_id exception", e); + } + + this.comments = new THashMap<>(); + this.needsUpdate = false; + this.hasCommentsLoaded = false; + this.commentIndex = 0; + } + + public static ForumThread create(Guild guild, Habbo opener, String subject, String message) throws Exception { + ForumThread createdThread = null; + + if (Emulator.getPluginManager().fireEvent(new GuildForumThreadBeforeCreated(guild, opener, subject, message)).isCancelled()) + return null; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO `guilds_forums_threads`(`guild_id`, `opener_id`, `subject`, `created_at`, `updated_at`) VALUES (?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + int timestamp = Emulator.getIntUnixTimestamp(); + + statement.setInt(1, guild.getId()); + statement.setInt(2, opener.getHabboInfo().getId()); + statement.setString(3, subject); + statement.setInt(4, timestamp); + statement.setInt(5, timestamp); + + if (statement.executeUpdate() < 1) + return null; + + ResultSet set = statement.getGeneratedKeys(); + if (set.next()) { + int threadId = set.getInt(1); + createdThread = new ForumThread(threadId, guild.getId(), opener.getHabboInfo().getId(), subject, 0, timestamp, timestamp, ForumThreadState.OPEN, false, false, 0, null); + cacheThread(createdThread); + + ForumThreadComment comment = ForumThreadComment.create(createdThread, opener, message); + createdThread.addComment(comment); + + Emulator.getPluginManager().fireEvent(new GuildForumThreadCreated(createdThread)); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return createdThread; + } + + public static THashSet getByGuildId(int guildId) { + THashSet threads = null; + + if (guildThreadsCache.containsKey(guildId)) { + guildThreadsCache.get(guildId); + } + + if (threads != null) + return threads; + + threads = new THashSet(); + + guildThreadsCache.put(guildId, threads); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT A.*, B.`id` AS `last_comment_id` " + + "FROM guilds_forums_threads A " + + "JOIN (" + + "SELECT * " + + "FROM `guilds_forums_comments` " + + "WHERE `id` IN (" + + "SELECT MAX(id) " + + "FROM `guilds_forums_comments` B " + + "GROUP BY `thread_id` " + + "ORDER BY B.`id` ASC " + + ") " + + "ORDER BY `id` DESC " + + ") B ON A.`id` = B.`thread_id` " + + "WHERE A.`guild_id` = ? " + + "ORDER BY A.`pinned` DESC, B.`created_at` DESC " + )) { + statement.setInt(1, guildId); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + ForumThread thread = new ForumThread(set); + synchronized (threads) { + threads.add(thread); + } + cacheThread(thread); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return threads; + } + + public static ForumThread getById(int threadId) throws SQLException { + ForumThread foundThread = forumThreadsCache.get(threadId); + + if (foundThread != null) + return foundThread; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement( + "SELECT A.*, B.`id` AS `last_comment_id` " + + "FROM guilds_forums_threads A " + + "JOIN (" + + "SELECT * " + + "FROM `guilds_forums_comments` " + + "WHERE `id` IN (" + + "SELECT MAX(id) " + + "FROM `guilds_forums_comments` B " + + "GROUP BY `thread_id` " + + "ORDER BY B.`id` ASC " + + ") " + + "ORDER BY `id` DESC " + + ") B ON A.`id` = B.`thread_id` " + + "WHERE A.`id` = ? " + + "ORDER BY A.`pinned` DESC, B.`created_at` DESC " + + "LIMIT 1" + )) { + statement.setInt(1, threadId); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + foundThread = new ForumThread(set); + cacheThread(foundThread); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return foundThread; + } + + private static void cacheThread(ForumThread thread) { + synchronized (forumThreadsCache) { + forumThreadsCache.put(thread.threadId, thread); + } + + THashSet guildThreads = guildThreadsCache.get(thread.guildId); + + if (guildThreads == null) { + guildThreads = new THashSet<>(); + synchronized (forumThreadsCache) { + guildThreadsCache.put(thread.guildId, guildThreads); + } + } + + synchronized (guildThreads) { + guildThreads.add(thread); + } + } + + public static void clearCache() { + for (THashSet threads : guildThreadsCache.values()) { + for (ForumThread thread : threads) { + thread.run(); + } + } + + synchronized (forumThreadsCache) { + forumThreadsCache.clear(); + } + + synchronized (guildThreadsCache) { + guildThreadsCache.clear(); + } + } + + public int getThreadId() { + return threadId; + } + + public int getGuildId() { + return guildId; + } + + public int getOpenerId() { + return openerId; + } + + public String getSubject() { + return subject; + } + + public int getCreatedAt() { + return createdAt; + } + + public int getPostsCount() { + return postsCount; + } + + public void setPostsCount(int postsCount) { + this.postsCount = postsCount; + this.needsUpdate = true; + } + + public int getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(int updatedAt) { + this.updatedAt = updatedAt; + this.needsUpdate = true; + } + + public ForumThreadState getState() { + return state; + } + + public void setState(ForumThreadState state) { + this.state = state; + this.needsUpdate = true; + } + + public boolean isPinned() { + return pinned; + } + + public void setPinned(boolean pinned) { + this.pinned = pinned; + this.needsUpdate = true; + } + + public boolean isLocked() { + return locked; + } + + public void setLocked(boolean locked) { + this.locked = locked; + this.needsUpdate = true; + } + + public int getAdminId() { + return adminId; + } + + public void setAdminId(int adminId) { + this.adminId = adminId; + this.needsUpdate = true; + } + + public ForumThreadComment getLastComment() { + return lastComment; + } + + public void setLastComment(ForumThreadComment lastComment) { + this.lastComment = lastComment; + } + + private void loadComments() { + if (this.hasCommentsLoaded) + return; + + synchronized (this.comments) { + this.hasCommentsLoaded = true; + + commentIndex = 0; + this.comments.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM `guilds_forums_comments` WHERE `thread_id` = ? ORDER BY `id`")) { + statement.setInt(1, this.threadId); + ResultSet set = statement.executeQuery(); + + while (set.next()) { + ForumThreadComment comment = new ForumThreadComment(set); + addComment(comment); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public void addComment(ForumThreadComment comment) { + this.comments.put(comment.getCommentId(), comment); + comment.setIndex(this.commentIndex); + this.commentIndex++; + this.lastComment = comment; + } + + public Collection getComments() { + if (!this.hasCommentsLoaded) { + loadComments(); + } + + return this.comments.values(); + } + + public Collection getComments(int limit, int offset) { + if (!this.hasCommentsLoaded) { + loadComments(); + } + + synchronized (this.comments) { + ArrayList limitedComments = new ArrayList<>(); + + List comments = new ArrayList<>(this.comments.values()); + comments.sort(Comparator.comparingInt(ForumThreadComment::getIndex)); + + Iterator iterator = comments.iterator(); + + for (; offset > 0; --offset) { + if (!iterator.hasNext()) + break; + + iterator.next(); + } + + for (; limit > 0; --limit) { + if (!iterator.hasNext()) + break; + + limitedComments.add(iterator.next()); + } + + return limitedComments; + } + } + + public ForumThreadComment getCommentById(int commentId) { + if (!this.hasCommentsLoaded) { + loadComments(); + } + + synchronized (this.comments) { + return this.comments.get(commentId); + } + } + + @Override + public void serialize(ServerMessage message) { + Habbo opener = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.openerId); + Habbo admin = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.adminId); + + Collection comments = this.getComments(); + int lastSeenAt = 0; + int totalComments = comments.size(); + int newComments = 0; + ForumThreadComment lastComment = this.lastComment; + + if (lastComment == null) { + for (ForumThreadComment comment : comments) { + if (comment.getCreatedAt() > lastSeenAt) { + newComments++; + } + if (lastComment == null || lastComment.getCreatedAt() < comment.getCreatedAt()) { + lastComment = comment; + } + } + this.lastComment = lastComment; + } + + Habbo lastAuthor = lastComment != null ? lastComment.getHabbo() : null; + + int nowTimestamp = Emulator.getIntUnixTimestamp(); + message.appendInt(this.threadId); + message.appendInt(this.openerId); + message.appendString(opener != null ? opener.getHabboInfo().getUsername() : ""); + message.appendString(this.subject); + message.appendBoolean(this.pinned); + message.appendBoolean(this.locked); + message.appendInt(nowTimestamp - this.createdAt); + message.appendInt(totalComments); // total comments + message.appendInt(newComments); // unread comments + message.appendInt(1); + + message.appendInt(lastAuthor != null ? lastAuthor.getHabboInfo().getId() : -1); + message.appendString(lastAuthor != null ? lastAuthor.getHabboInfo().getUsername() : ""); + message.appendInt(nowTimestamp - (lastComment != null ? lastComment.getCreatedAt() : this.updatedAt)); + message.appendByte(this.state.getStateId()); + message.appendInt(this.adminId); + message.appendString(admin != null ? admin.getHabboInfo().getUsername() : ""); + message.appendInt(this.threadId); + } + + @Override + public void run() { + if (!this.needsUpdate) + return; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE `guilds_forums_threads` SET `posts_count` = ?, `updated_at` = ?, `state` = ?, `pinned` = ?, `locked` = ?, `admin_id` = ? WHERE `id` = ?")) { + statement.setInt(1, this.postsCount); + statement.setInt(2, this.updatedAt); + statement.setInt(3, this.state.getStateId()); + statement.setInt(4, this.pinned ? 1 : 0); + statement.setInt(5, this.locked ? 1 : 0); + statement.setInt(6, this.adminId); + statement.setInt(7, this.threadId); + statement.execute(); + + this.needsUpdate = false; + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumThreadComment.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumThreadComment.java new file mode 100644 index 0000000..7819064 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumThreadComment.java @@ -0,0 +1,206 @@ +package com.eu.habbo.habbohotel.guilds.forums; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.plugin.events.guilds.forums.GuildForumThreadCommentBeforeCreated; +import com.eu.habbo.plugin.events.guilds.forums.GuildForumThreadCommentCreated; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; +import java.sql.*; + +@Slf4j +public class ForumThreadComment implements Runnable, ISerialize { + private static THashMap forumCommentsCache = new THashMap<>(); + private final int commentId; + private final int threadId; + private final int userId; + private final String message; + private final int createdAt; + private ForumThreadState state; + private int adminId; + private int index; + private boolean needsUpdate; + + public ForumThreadComment(int commentId, int threadId, int userId, String message, int createdAt, ForumThreadState state, int adminId) { + this.commentId = commentId; + this.threadId = threadId; + this.userId = userId; + this.message = message; + this.createdAt = createdAt; + this.state = state; + this.adminId = adminId; + this.index = -1; + this.needsUpdate = false; + } + + public ForumThreadComment(ResultSet set) throws SQLException { + this.commentId = set.getInt("id"); + this.threadId = set.getInt("thread_id"); + this.userId = set.getInt("user_id"); + this.message = set.getString("message"); + this.createdAt = set.getInt("created_at"); + this.state = ForumThreadState.fromValue(set.getInt("state")); + this.adminId = set.getInt("admin_id"); + this.index = -1; + this.needsUpdate = false; + } + + public static ForumThreadComment getById(int id) { + ForumThreadComment foundComment = forumCommentsCache.get(id); + + if (foundComment != null) + return foundComment; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM `guilds_forums_comments` WHERE `id` = ? LIMIT 1")) { + statement.setInt(1, id); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + foundComment = new ForumThreadComment(set); + cacheComment(foundComment); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return foundComment; + } + + public static void cacheComment(ForumThreadComment foundComment) { + forumCommentsCache.put(foundComment.commentId, foundComment); + } + + public static void clearCache() { + forumCommentsCache.clear(); + } + + public static ForumThreadComment create(ForumThread thread, Habbo poster, String message) throws Exception { + ForumThreadComment createdComment = null; + + if (Emulator.getPluginManager().fireEvent(new GuildForumThreadCommentBeforeCreated(thread, poster, message)).isCancelled()) + return null; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO `guilds_forums_comments`(`thread_id`, `user_id`, `message`, `created_at`) VALUES (?, ?, ?, ?);", Statement.RETURN_GENERATED_KEYS)) { + int timestamp = Emulator.getIntUnixTimestamp(); + + statement.setInt(1, thread.getThreadId()); + statement.setInt(2, poster.getHabboInfo().getId()); + statement.setString(3, message); + statement.setInt(4, timestamp); + + if (statement.executeUpdate() < 1) + return null; + + ResultSet set = statement.getGeneratedKeys(); + if (set.next()) { + int commentId = set.getInt(1); + createdComment = new ForumThreadComment(commentId, thread.getThreadId(), poster.getHabboInfo().getId(), message, timestamp, ForumThreadState.OPEN, 0); + + Emulator.getPluginManager().fireEvent(new GuildForumThreadCommentCreated(createdComment)); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return createdComment; + } + + public int getCommentId() { + return commentId; + } + + public int getThreadId() { + return threadId; + } + + public int getUserId() { + return userId; + } + + public String getMessage() { + return message; + } + + public int getCreatedAt() { + return createdAt; + } + + public ForumThreadState getState() { + return state; + } + + public void setState(ForumThreadState state) { + this.state = state; + this.needsUpdate = true; + } + + public int getAdminId() { + return adminId; + } + + public void setAdminId(int adminId) { + this.adminId = adminId; + this.needsUpdate = true; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public Habbo getHabbo() { + return Emulator.getGameEnvironment().getHabboManager().getHabbo(this.userId); + } + + public ForumThread getThread() { + try { + return ForumThread.getById(this.threadId); + } catch (SQLException e) { + return null; + } + } + + @Override + public void serialize(ServerMessage message) { + + HabboInfo habbo = Emulator.getGameEnvironment().getHabboManager().getHabboInfo(this.userId); + HabboInfo admin = Emulator.getGameEnvironment().getHabboManager().getHabboInfo(this.adminId); + + message.appendInt(this.commentId); + message.appendInt(this.index); + message.appendInt(this.userId); + message.appendString(habbo != null ? habbo.getUsername() : ""); + message.appendString(habbo != null ? habbo.getLook() : ""); + message.appendInt(Emulator.getIntUnixTimestamp() - this.createdAt); + message.appendString(this.message); + message.appendByte(this.state.getStateId()); + message.appendInt(this.adminId); + message.appendString(admin != null ? admin.getUsername() : ""); + message.appendInt(0); // admin action time ago? + message.appendInt(habbo != null ? habbo.getHabboStats().forumPostsCount : 0); + } + + @Override + public void run() { + if (!this.needsUpdate) + return; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE guilds_forums_comments SET `state` = ?, `admin_id` = ? WHERE `id` = ?")) { + statement.setInt(1, this.state.getStateId()); + statement.setInt(2, this.adminId); + statement.setInt(3, this.commentId); + statement.execute(); + + this.needsUpdate = false; + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumThreadState.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumThreadState.java new file mode 100644 index 0000000..2e57039 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumThreadState.java @@ -0,0 +1,28 @@ +package com.eu.habbo.habbohotel.guilds.forums; + +public enum ForumThreadState { + OPEN(0), + CLOSED(1), + HIDDEN_BY_STAFF_MEMBER(10), + HIDDEN_BY_GUILD_ADMIN(20); + + private int stateId; + + ForumThreadState(int stateId) { + this.stateId = stateId; + } + + public static ForumThreadState fromValue(int value) { + for (ForumThreadState state : ForumThreadState.values()) { + if (state.stateId == value) { + return state; + } + } + + return CLOSED; + } + + public int getStateId() { + return this.stateId; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumView.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumView.java new file mode 100644 index 0000000..c1b2569 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumView.java @@ -0,0 +1,34 @@ +package com.eu.habbo.habbohotel.guilds.forums; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class ForumView { + private final int userId; + private final int guildId; + private final int timestamp; + + public ForumView(int userId, int guildId, int timestamp) { + this.userId = userId; + this.guildId = guildId; + this.timestamp = timestamp; + } + + public ForumView(ResultSet set) throws SQLException { + this.userId = set.getInt("user_id"); + this.guildId = set.getInt("guild_id"); + this.timestamp = set.getInt("timestamp"); + } + + public int getUserId() { + return userId; + } + + public int getGuildId() { + return guildId; + } + + public int getTimestamp() { + return timestamp; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/HallOfFame.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/HallOfFame.java new file mode 100644 index 0000000..a6d8cd1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/HallOfFame.java @@ -0,0 +1,47 @@ +package com.eu.habbo.habbohotel.hotelview; + +import com.eu.habbo.Emulator; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +@Slf4j +public class HallOfFame { + private final THashMap winners = new THashMap<>(); + private String competitionName; + public HallOfFame() { + this.setCompetitionName("xmasRoomComp"); + + this.reload(); + } + + public void reload() { + this.winners.clear(); + + synchronized (this.winners) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery(Emulator.getConfig().getValue("hotelview.halloffame.query"))) { + while (set.next()) { + HallOfFameWinner winner = new HallOfFameWinner(set); + this.winners.put(winner.getId(), winner); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public THashMap getWinners() { + return this.winners; + } + + public String getCompetitionName() { + return this.competitionName; + } + + void setCompetitionName(String name) { + this.competitionName = name; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/HallOfFameWinner.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/HallOfFameWinner.java new file mode 100644 index 0000000..d8a03d8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/HallOfFameWinner.java @@ -0,0 +1,50 @@ +package com.eu.habbo.habbohotel.hotelview; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class HallOfFameWinner implements Comparable { + + private int id; + + + private String username; + + + private String look; + + + private int points; + + public HallOfFameWinner(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.username = set.getString("username"); + this.look = set.getString("look"); + this.points = set.getInt("achievement_score"); + } + + + public int getId() { + return this.id; + } + + + public String getUsername() { + return this.username; + } + + + public String getLook() { + return this.look; + } + + + public int getPoints() { + return this.points; + } + + @Override + public int compareTo(HallOfFameWinner o) { + return o.getPoints() - this.points; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/HotelViewManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/HotelViewManager.java new file mode 100644 index 0000000..d85eaf8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/HotelViewManager.java @@ -0,0 +1,30 @@ +package com.eu.habbo.habbohotel.hotelview; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class HotelViewManager { + private final HallOfFame hallOfFame; + private final NewsList newsList; + + public HotelViewManager() { + long millis = System.currentTimeMillis(); + this.hallOfFame = new HallOfFame(); + this.newsList = new NewsList(); + + log.info("Hotelview Manager -> Loaded! ({} MS)", System.currentTimeMillis() - millis); + } + + public HallOfFame getHallOfFame() { + return this.hallOfFame; + } + + public NewsList getNewsList() { + return this.newsList; + } + + public void dispose() { + log.info("HotelView Manager -> Disposed!"); + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/NewsList.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/NewsList.java new file mode 100644 index 0000000..3eed86d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/NewsList.java @@ -0,0 +1,38 @@ +package com.eu.habbo.habbohotel.hotelview; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; + +@Slf4j +public class NewsList { + private final ArrayList newsWidgets; + + public NewsList() { + this.newsWidgets = new ArrayList<>(); + this.reload(); + } + + + public void reload() { + synchronized (this.newsWidgets) { + this.newsWidgets.clear(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM hotelview_news ORDER BY id DESC LIMIT 10")) { + while (set.next()) { + this.newsWidgets.add(new NewsWidget(set)); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + + public ArrayList getNewsWidgets() { + return this.newsWidgets; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/NewsWidget.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/NewsWidget.java new file mode 100644 index 0000000..bb30976 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/hotelview/NewsWidget.java @@ -0,0 +1,72 @@ +package com.eu.habbo.habbohotel.hotelview; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class NewsWidget { + + private int id; + + + private String title; + + + private String message; + + + private String buttonMessage; + + + private int type; + + + private String link; + + + private String image; + + public NewsWidget(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.title = set.getString("title"); + this.message = set.getString("text"); + this.buttonMessage = set.getString("button_text"); + this.type = set.getString("button_type").equals("client") ? 1 : 0; + this.link = set.getString("button_link"); + this.image = set.getString("image"); + } + + + public int getId() { + return this.id; + } + + + public String getTitle() { + return this.title; + } + + + public String getMessage() { + return this.message; + } + + + public String getButtonMessage() { + return this.buttonMessage; + } + + + public int getType() { + return this.type; + } + + + public String getLink() { + return this.link; + } + + + public String getImage() { + return this.image; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/CrackableReward.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/CrackableReward.java new file mode 100644 index 0000000..af7cd65 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/CrackableReward.java @@ -0,0 +1,77 @@ +package com.eu.habbo.habbohotel.items; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.AbstractMap; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +public class CrackableReward { + + public final int itemId; + public final int count; + public final Map> prizes; + public final String achievementTick; + public final String achievementCracked; + public final int requiredEffect; + public final int subscriptionDuration; + public final RedeemableSubscriptionType subscriptionType; + public int totalChance; + + public CrackableReward(ResultSet set) throws SQLException { + this.itemId = set.getInt("item_id"); + this.count = set.getInt("count"); + this.achievementTick = set.getString("achievement_tick"); + this.achievementCracked = set.getString("achievement_cracked"); + this.requiredEffect = set.getInt("required_effect"); + this.subscriptionDuration = set.getInt("subscription_duration"); + this.subscriptionType = RedeemableSubscriptionType.fromString(set.getString("subscription_type")); + + + String[] prizes = set.getString("prizes").split(";"); + this.prizes = new HashMap<>(); + + if (set.getString("prizes").isEmpty()) return; + + this.totalChance = 0; + for (String prize : prizes) { + try { + int itemId = 0; + int chance = 100; + + if (prize.contains(":") && prize.split(":").length == 2) { + itemId = Integer.valueOf(prize.split(":")[0]); + chance = Integer.valueOf(prize.split(":")[1]); + } else if (prize.contains(":")) { + log.error("Invalid configuration of crackable prizes (item id: " + this.itemId + "). '" + prize + "' format should be itemId:chance."); + } else { + itemId = Integer.valueOf(prize.replace(":", "")); + } + + this.prizes.put(itemId, new AbstractMap.SimpleEntry<>(this.totalChance, this.totalChance + chance)); + this.totalChance += chance; + } catch (Exception e) { + log.error("Caught exception", e); + } + } + } + + public int getRandomReward() { + if (this.prizes.size() == 0) return 0; + + int random = Emulator.getRandom().nextInt(this.totalChance); + + int notFound = 0; + for (Map.Entry> set : this.prizes.entrySet()) { + notFound = set.getKey(); + if (random >= set.getValue().getKey() && random < set.getValue().getValue()) { + return set.getKey(); + } + } + + return notFound; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/FurnitureType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/FurnitureType.java new file mode 100644 index 0000000..f22fc5b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/FurnitureType.java @@ -0,0 +1,39 @@ +package com.eu.habbo.habbohotel.items; + +public enum FurnitureType { + FLOOR("S"), + WALL("I"), + EFFECT("E"), + BADGE("B"), + ROBOT("R"), + HABBO_CLUB("H"), + PET("P"); + + public final String code; + + FurnitureType(String code) { + this.code = code; + } + + public static FurnitureType fromString(String code) { + switch (code.toUpperCase()) { + case "S": + return FLOOR; + case "I": + return WALL; + case "E": + return EFFECT; + case "B": + return BADGE; + case "R": + return ROBOT; + case "H": + return HABBO_CLUB; + case "P": + return PET; + default: + return FLOOR; + } + + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/ICycleable.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/ICycleable.java new file mode 100644 index 0000000..223c09e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/ICycleable.java @@ -0,0 +1,7 @@ +package com.eu.habbo.habbohotel.items; + +import com.eu.habbo.habbohotel.rooms.Room; + +public interface ICycleable { + void cycle(Room room); +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/IEventTriggers.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/IEventTriggers.java new file mode 100644 index 0000000..788f92d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/IEventTriggers.java @@ -0,0 +1,13 @@ +package com.eu.habbo.habbohotel.items; + +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; + +public interface IEventTriggers { + void onClick(GameClient client, Room room, Object[] objects) throws Exception; + + void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception; + + void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception; +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/Item.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/Item.java new file mode 100644 index 0000000..11d1929 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/Item.java @@ -0,0 +1,263 @@ +package com.eu.habbo.habbohotel.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionMultiHeight; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.list.array.TIntArrayList; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class Item implements ISerialize { + + private int id; + private int spriteId; + private String name; + private String fullName; + private FurnitureType type; + private short width; + private short length; + private double height; + private boolean allowStack; + private boolean allowWalk; + private boolean allowSit; + private boolean allowLay; + private boolean allowRecyle; + private boolean allowTrade; + private boolean allowMarketplace; + private boolean allowGift; + private boolean allowInventoryStack; + private short stateCount; + private short effectM; + private short effectF; + private TIntArrayList vendingItems; + private double[] multiHeights; + private String customParams; + private String clothingOnWalk; + + private ItemInteraction interactionType; + private int rotations; + + public Item(ResultSet set) throws SQLException { + this.load(set); + } + + public static boolean isPet(Item item) { + return item.getName().toLowerCase().startsWith("a0 pet"); + } + + public static double getCurrentHeight(HabboItem item) { + if (item instanceof InteractionMultiHeight && item.getBaseItem().getMultiHeights().length > 0) { + if (item.getExtradata().isEmpty()) { + item.setExtradata("0"); + } + + try { + int index = Integer.valueOf(item.getExtradata()) % (item.getBaseItem().getMultiHeights().length); + return item.getBaseItem().getMultiHeights()[(item.getExtradata().isEmpty() ? 0 : index)]; + } catch (NumberFormatException e) { + + } + } + + return item.getBaseItem().getHeight(); + } + + public void update(ResultSet set) throws SQLException { + this.load(set); + } + + private void load(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.spriteId = set.getInt("sprite_id"); + this.name = set.getString("item_name"); + this.fullName = set.getString("public_name"); + this.type = FurnitureType.fromString(set.getString("type")); + this.width = set.getShort("width"); + this.length = set.getShort("length"); + this.height = set.getDouble("stack_height"); + if (this.height == 0) { + this.height = 1e-6; + } + this.allowStack = set.getBoolean("allow_stack"); + this.allowWalk = set.getBoolean("allow_walk"); + this.allowSit = set.getBoolean("allow_sit"); + this.allowLay = set.getBoolean("allow_lay"); + this.allowRecyle = set.getBoolean("allow_recycle"); + this.allowTrade = set.getBoolean("allow_trade"); + this.allowMarketplace = set.getBoolean("allow_marketplace_sell"); + this.allowGift = set.getBoolean("allow_gift"); + this.allowInventoryStack = set.getBoolean("allow_inventory_stack"); + + this.interactionType = Emulator.getGameEnvironment().getItemManager().getItemInteraction(set.getString("interaction_type").toLowerCase()); + + this.stateCount = set.getShort("interaction_modes_count"); + this.effectM = set.getShort("effect_id_male"); + this.effectF = set.getShort("effect_id_female"); + this.customParams = set.getString("customparams"); + this.clothingOnWalk = set.getString("clothing_on_walk"); + + if (!set.getString("vending_ids").isEmpty()) { + this.vendingItems = new TIntArrayList(); + String[] vendingIds = set.getString("vending_ids").replace(";", ",").split(","); + for (String s : vendingIds) { + this.vendingItems.add(Integer.valueOf(s.replace(" ", ""))); + } + } + + //if(this.interactionType.getType() == InteractionMultiHeight.class || this.interactionType.getType().isAssignableFrom(InteractionMultiHeight.class)) + { + if (set.getString("multiheight").contains(";")) { + String[] s = set.getString("multiheight").split(";"); + this.multiHeights = new double[s.length]; + + for (int i = 0; i < s.length; i++) { + this.multiHeights[i] = Double.parseDouble(s[i]); + } + } else { + this.multiHeights = new double[0]; + } + } + + this.rotations = 4; + + try { + this.rotations = set.getInt("rotations"); + } + catch (SQLException ignored) { } + } + + public int getId() { + return this.id; + } + + public int getSpriteId() { + return this.spriteId; + } + + public String getName() { + return this.name; + } + + public String getFullName() { + return this.fullName; + } + + public FurnitureType getType() { + return this.type; + } + + public int getWidth() { + return this.width; + } + + public int getLength() { + return this.length; + } + + public double getHeight() { + return this.height; + } + + public boolean allowStack() { + return this.allowStack; + } + + public boolean allowWalk() { + return this.allowWalk; + } + + public boolean allowSit() { + return this.allowSit; + } + + public boolean allowLay() { + return this.allowLay; + } + + public boolean allowRecyle() { + return this.allowRecyle; + } + + public boolean allowTrade() { + return this.allowTrade; + } + + public boolean allowMarketplace() { + return this.allowMarketplace; + } + + public boolean allowGift() { + return this.allowGift; + } + + public boolean allowInventoryStack() { + return this.allowInventoryStack; + } + + public int getStateCount() { + return this.stateCount; + } + + public int getEffectM() { + return this.effectM; + } + + public int getEffectF() { + return this.effectF; + } + + public ItemInteraction getInteractionType() { + return this.interactionType; + } + + public TIntArrayList getVendingItems() { + return this.vendingItems; + } + + public int getRandomVendingItem() { + return this.vendingItems.get(Emulator.getRandom().nextInt(this.vendingItems.size())); + } + + public double[] getMultiHeights() { + return this.multiHeights; + } + + public String getCustomParams() { + return customParams; + } + + public String getClothingOnWalk() { return clothingOnWalk; } + + public int getRotations() { + return rotations; + } + + @Override + public void serialize(ServerMessage message) { + message.appendString(this.type.code.toLowerCase()); + + if (type == FurnitureType.BADGE) { + message.appendString(this.customParams); + } else { + message.appendInt(this.spriteId); + + if (this.getName().contains("wallpaper_single") || this.getName().contains("floor_single") || this.getName().contains("landscape_single")) { + message.appendString(this.name.split("_")[2]); + } else if (type == FurnitureType.ROBOT) { + message.appendString(this.customParams); + } else if (name.equalsIgnoreCase("poster")) { + message.appendString(this.customParams); + } else if (name.startsWith("SONG ")) { + message.appendString(this.customParams); + } else { + message.appendString(""); + } + + message.appendInt(1); // productCount + message.appendBoolean(false); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/ItemInteraction.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/ItemInteraction.java new file mode 100644 index 0000000..2e07ba2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/ItemInteraction.java @@ -0,0 +1,24 @@ +package com.eu.habbo.habbohotel.items; + +import com.eu.habbo.habbohotel.users.HabboItem; + +public class ItemInteraction { + private final String name; + private final Class type; + + + public ItemInteraction(String name, Class type) { + this.name = name; + this.type = type; + } + + + public Class getType() { + return this.type; + } + + + public String getName() { + return this.name; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/ItemManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/ItemManager.java new file mode 100644 index 0000000..344c066 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/ItemManager.java @@ -0,0 +1,787 @@ +package com.eu.habbo.habbohotel.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.*; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTimer; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.*; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.gates.InteractionBattleBanzaiGateBlue; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.gates.InteractionBattleBanzaiGateGreen; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.gates.InteractionBattleBanzaiGateRed; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.gates.InteractionBattleBanzaiGateYellow; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.scoreboards.InteractionBattleBanzaiScoreboardBlue; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.scoreboards.InteractionBattleBanzaiScoreboardGreen; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.scoreboards.InteractionBattleBanzaiScoreboardRed; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.scoreboards.InteractionBattleBanzaiScoreboardYellow; +import com.eu.habbo.habbohotel.items.interactions.games.football.InteractionFootball; +import com.eu.habbo.habbohotel.items.interactions.games.football.InteractionFootballGate; +import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoalBlue; +import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoalGreen; +import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoalRed; +import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoalYellow; +import com.eu.habbo.habbohotel.items.interactions.games.football.scoreboards.InteractionFootballScoreboardBlue; +import com.eu.habbo.habbohotel.items.interactions.games.football.scoreboards.InteractionFootballScoreboardGreen; +import com.eu.habbo.habbohotel.items.interactions.games.football.scoreboards.InteractionFootballScoreboardRed; +import com.eu.habbo.habbohotel.items.interactions.games.football.scoreboards.InteractionFootballScoreboardYellow; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeBlock; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeExitTile; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeTile; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.gates.InteractionFreezeGateBlue; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.gates.InteractionFreezeGateGreen; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.gates.InteractionFreezeGateRed; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.gates.InteractionFreezeGateYellow; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.scoreboards.InteractionFreezeScoreboardBlue; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.scoreboards.InteractionFreezeScoreboardGreen; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.scoreboards.InteractionFreezeScoreboardRed; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.scoreboards.InteractionFreezeScoreboardYellow; +import com.eu.habbo.habbohotel.items.interactions.games.tag.bunnyrun.InteractionBunnyrunField; +import com.eu.habbo.habbohotel.items.interactions.games.tag.bunnyrun.InteractionBunnyrunPole; +import com.eu.habbo.habbohotel.items.interactions.games.tag.icetag.InteractionIceTagField; +import com.eu.habbo.habbohotel.items.interactions.games.tag.icetag.InteractionIceTagPole; +import com.eu.habbo.habbohotel.items.interactions.games.tag.rollerskate.InteractionRollerskateField; +import com.eu.habbo.habbohotel.items.interactions.pets.*; +import com.eu.habbo.habbohotel.items.interactions.totems.InteractionTotemHead; +import com.eu.habbo.habbohotel.items.interactions.totems.InteractionTotemLegs; +import com.eu.habbo.habbohotel.items.interactions.totems.InteractionTotemPlanet; +import com.eu.habbo.habbohotel.items.interactions.wired.conditions.*; +import com.eu.habbo.habbohotel.items.interactions.wired.effects.*; +import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredBlob; +import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraRandom; +import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraUnseen; +import com.eu.habbo.habbohotel.wired.highscores.WiredHighscoreManager; +import com.eu.habbo.habbohotel.items.interactions.wired.triggers.*; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.plugin.events.emulator.EmulatorLoadItemsManagerEvent; +import com.eu.habbo.threading.runnables.QueryDeleteHabboItem; +import gnu.trove.TCollections; +import gnu.trove.iterator.TIntObjectIterator; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; +import java.lang.reflect.Constructor; +import java.sql.*; +import java.util.*; + +@Slf4j +public class ItemManager { + //Configuration. Loaded from database & updated accordingly. + public static boolean RECYCLER_ENABLED = true; + + private final TIntObjectMap items; + private final TIntObjectHashMap crackableRewards; + private final THashSet interactionsList; + private final THashMap soundTracks; + private final YoutubeManager youtubeManager; + private final WiredHighscoreManager highscoreManager; + private final TreeMap newuserGifts; + + public ItemManager() { + this.items = TCollections.synchronizedMap(new TIntObjectHashMap<>()); + this.crackableRewards = new TIntObjectHashMap<>(); + this.interactionsList = new THashSet<>(); + this.soundTracks = new THashMap<>(); + this.youtubeManager = new YoutubeManager(); + this.highscoreManager = new WiredHighscoreManager(); + this.newuserGifts = new TreeMap<>(); + } + + public void load() { + Emulator.getPluginManager().fireEvent(new EmulatorLoadItemsManagerEvent()); + + long millis = System.currentTimeMillis(); + + this.loadItemInteractions(); + this.loadItems(); + this.loadCrackable(); + this.loadSoundTracks(); + this.youtubeManager.load(); + this.highscoreManager.load(); + this.loadNewUserGifts(); + + log.info("Item Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)"); + } + + protected void loadItemInteractions() { + this.interactionsList.add(new ItemInteraction("default", InteractionDefault.class)); + this.interactionsList.add(new ItemInteraction("gate", InteractionGate.class)); + this.interactionsList.add(new ItemInteraction("guild_furni", InteractionGuildFurni.class)); + this.interactionsList.add(new ItemInteraction("guild_gate", InteractionGuildGate.class)); + this.interactionsList.add(new ItemInteraction("background_toner", InteractionBackgroundToner.class)); + this.interactionsList.add(new ItemInteraction("badge_display", InteractionBadgeDisplay.class)); + this.interactionsList.add(new ItemInteraction("mannequin", InteractionMannequin.class)); + this.interactionsList.add(new ItemInteraction("ads_bg", InteractionRoomAds.class)); + this.interactionsList.add(new ItemInteraction("trophy", InteractionTrophy.class)); + this.interactionsList.add(new ItemInteraction("vendingmachine", InteractionVendingMachine.class)); + this.interactionsList.add(new ItemInteraction("pressureplate", InteractionPressurePlate.class)); + this.interactionsList.add(new ItemInteraction("colorplate", InteractionColorPlate.class)); + this.interactionsList.add(new ItemInteraction("multiheight", InteractionMultiHeight.class)); + this.interactionsList.add(new ItemInteraction("dice", InteractionDice.class)); + this.interactionsList.add(new ItemInteraction("colorwheel", InteractionColorWheel.class)); + this.interactionsList.add(new ItemInteraction("cannon", InteractionCannon.class)); + this.interactionsList.add(new ItemInteraction("teleport", InteractionTeleport.class)); + this.interactionsList.add(new ItemInteraction("teleporttile", InteractionTeleportTile.class)); + this.interactionsList.add(new ItemInteraction("crackable", InteractionCrackable.class)); + this.interactionsList.add(new ItemInteraction("crackable_master", InteractionCrackableMaster.class)); + this.interactionsList.add(new ItemInteraction("nest", InteractionNest.class)); + this.interactionsList.add(new ItemInteraction("pet_drink", InteractionPetDrink.class)); + this.interactionsList.add(new ItemInteraction("pet_food", InteractionPetFood.class)); + this.interactionsList.add(new ItemInteraction("pet_toy", InteractionPetToy.class)); + this.interactionsList.add(new ItemInteraction("breeding_nest", InteractionPetBreedingNest.class)); + this.interactionsList.add(new ItemInteraction("obstacle", InteractionObstacle.class)); + this.interactionsList.add(new ItemInteraction("monsterplant_seed", InteractionMonsterPlantSeed.class)); + this.interactionsList.add(new ItemInteraction("gift", InteractionGift.class)); + this.interactionsList.add(new ItemInteraction("stack_helper", InteractionStackHelper.class)); + this.interactionsList.add(new ItemInteraction("puzzle_box", InteractionPuzzleBox.class)); + this.interactionsList.add(new ItemInteraction("hopper", InteractionHopper.class)); + this.interactionsList.add(new ItemInteraction("costume_hopper", InteractionCostumeHopper.class)); + this.interactionsList.add(new ItemInteraction("effect_gate", InteractionEffectGate.class)); + this.interactionsList.add(new ItemInteraction("club_hopper", InteractionHabboClubHopper.class)); + this.interactionsList.add(new ItemInteraction("club_gate", InteractionHabboClubGate.class)); + this.interactionsList.add(new ItemInteraction("club_teleporttile", InteractionHabboClubTeleportTile.class)); + this.interactionsList.add(new ItemInteraction("onewaygate", InteractionOneWayGate.class)); + this.interactionsList.add(new ItemInteraction("love_lock", InteractionLoveLock.class)); + this.interactionsList.add(new ItemInteraction("clothing", InteractionClothing.class)); + this.interactionsList.add(new ItemInteraction("roller", InteractionRoller.class)); + this.interactionsList.add(new ItemInteraction("postit", InteractionPostIt.class)); + this.interactionsList.add(new ItemInteraction("dimmer", InteractionMoodLight.class)); + this.interactionsList.add(new ItemInteraction("rentable_space", InteractionRentableSpace.class)); + this.interactionsList.add(new ItemInteraction("pyramid", InteractionPyramid.class)); + this.interactionsList.add(new ItemInteraction("musicdisc", InteractionMusicDisc.class)); + this.interactionsList.add(new ItemInteraction("fireworks", InteractionFireworks.class)); + this.interactionsList.add(new ItemInteraction("talking_furni", InteractionTalkingFurniture.class)); + this.interactionsList.add(new ItemInteraction("water_item", InteractionWaterItem.class)); + this.interactionsList.add(new ItemInteraction("water", InteractionWater.class)); + this.interactionsList.add(new ItemInteraction("viking_cotie", InteractionVikingCotie.class)); + this.interactionsList.add(new ItemInteraction("tile_fxprovider_nfs", InteractionTileEffectProvider.class)); + this.interactionsList.add(new ItemInteraction("mutearea", InteractionMuteArea.class)); + this.interactionsList.add(new ItemInteraction("buildarea", InteractionBuildArea.class)); + this.interactionsList.add(new ItemInteraction("information_terminal", InteractionInformationTerminal.class)); + this.interactionsList.add(new ItemInteraction("external_image", InteractionExternalImage.class)); + this.interactionsList.add(new ItemInteraction("youtube", InteractionYoutubeTV.class)); + this.interactionsList.add(new ItemInteraction("jukebox", InteractionJukeBox.class)); + this.interactionsList.add(new ItemInteraction("switch", InteractionSwitch.class)); + this.interactionsList.add(new ItemInteraction("fx_box", InteractionFXBox.class)); + this.interactionsList.add(new ItemInteraction("blackhole", InteractionBlackHole.class)); + this.interactionsList.add(new ItemInteraction("effect_toggle", InteractionEffectToggle.class)); + this.interactionsList.add(new ItemInteraction("room_o_matic", InteractionRoomOMatic.class)); + this.interactionsList.add(new ItemInteraction("effect_tile", InteractionEffectTile.class)); + this.interactionsList.add(new ItemInteraction("sticky_pole", InteractionStickyPole.class)); + this.interactionsList.add(new ItemInteraction("trap", InteractionTrap.class)); + this.interactionsList.add(new ItemInteraction("tent", InteractionTent.class)); + this.interactionsList.add(new ItemInteraction("gym_equipment", InteractionGymEquipment.class)); + this.interactionsList.add(new ItemInteraction("handitem", InteractionHanditem.class)); + this.interactionsList.add(new ItemInteraction("handitem_tile", InteractionHanditemTile.class)); + this.interactionsList.add(new ItemInteraction("effect_giver", InteractionEffectGiver.class)); + this.interactionsList.add(new ItemInteraction("effect_vendingmachine", InteractionEffectVendingMachine.class)); + this.interactionsList.add(new ItemInteraction("effect_vendingmachine_no_sides", InteractionEffectVendingMachineNoSides.class)); + this.interactionsList.add(new ItemInteraction("crackable_monster", InteractionMonsterCrackable.class)); + this.interactionsList.add(new ItemInteraction("snowboard_slope", InteractionSnowboardSlope.class)); + this.interactionsList.add(new ItemInteraction("pressureplate_group", InteractionGroupPressurePlate.class)); + this.interactionsList.add(new ItemInteraction("effect_tile_group", InteractionEffectTile.class)); + this.interactionsList.add(new ItemInteraction("crackable_subscription_box", InteractionRedeemableSubscriptionBox.class)); + this.interactionsList.add(new ItemInteraction("random_state", InteractionRandomState.class)); + this.interactionsList.add(new ItemInteraction("vendingmachine_no_sides", InteractionNoSidesVendingMachine.class)); + + this.interactionsList.add(new ItemInteraction("game_timer", InteractionGameTimer.class)); + + this.interactionsList.add(new ItemInteraction("wf_trg_walks_on_furni", WiredTriggerHabboWalkOnFurni.class)); + this.interactionsList.add(new ItemInteraction("wf_trg_walks_off_furni", WiredTriggerHabboWalkOffFurni.class)); + this.interactionsList.add(new ItemInteraction("wf_trg_enter_room", WiredTriggerHabboEntersRoom.class)); + this.interactionsList.add(new ItemInteraction("wf_trg_says_something", WiredTriggerHabboSaysKeyword.class)); + this.interactionsList.add(new ItemInteraction("wf_trg_periodically", WiredTriggerRepeater.class)); + this.interactionsList.add(new ItemInteraction("wf_trg_period_long", WiredTriggerRepeaterLong.class)); + this.interactionsList.add(new ItemInteraction("wf_trg_state_changed", WiredTriggerFurniStateToggled.class)); + this.interactionsList.add(new ItemInteraction("wf_trg_at_given_time", WiredTriggerAtSetTime.class)); + this.interactionsList.add(new ItemInteraction("wf_trg_at_time_long", WiredTriggerAtTimeLong.class)); + this.interactionsList.add(new ItemInteraction("wf_trg_collision", WiredTriggerCollision.class)); + this.interactionsList.add(new ItemInteraction("wf_trg_game_starts", WiredTriggerGameStarts.class)); + this.interactionsList.add(new ItemInteraction("wf_trg_game_ends", WiredTriggerGameEnds.class)); + this.interactionsList.add(new ItemInteraction("wf_trg_bot_reached_stf", WiredTriggerBotReachedFurni.class)); + this.interactionsList.add(new ItemInteraction("wf_trg_bot_reached_avtr", WiredTriggerBotReachedHabbo.class)); + this.interactionsList.add(new ItemInteraction("wf_trg_score_achieved", WiredTriggerScoreAchieved.class)); + this.interactionsList.add(new ItemInteraction("wf_trg_game_team_win", WiredTriggerTeamWins.class)); + this.interactionsList.add(new ItemInteraction("wf_trg_game_team_lose", WiredTriggerTeamLoses.class)); + + + this.interactionsList.add(new ItemInteraction("wf_act_toggle_state", WiredEffectToggleFurni.class)); + this.interactionsList.add(new ItemInteraction("wf_act_reset_timers", WiredEffectResetTimers.class)); + this.interactionsList.add(new ItemInteraction("wf_act_match_to_sshot", WiredEffectMatchFurni.class)); + this.interactionsList.add(new ItemInteraction("wf_act_move_rotate", WiredEffectMoveRotateFurni.class)); + this.interactionsList.add(new ItemInteraction("wf_act_give_score", WiredEffectGiveScore.class)); + this.interactionsList.add(new ItemInteraction("wf_act_show_message", WiredEffectWhisper.class)); + this.interactionsList.add(new ItemInteraction("wf_act_teleport_to", WiredEffectTeleport.class)); + this.interactionsList.add(new ItemInteraction("wf_act_join_team", WiredEffectJoinTeam.class)); + this.interactionsList.add(new ItemInteraction("wf_act_leave_team", WiredEffectLeaveTeam.class)); + this.interactionsList.add(new ItemInteraction("wf_act_chase", WiredEffectMoveFurniTowards.class)); + this.interactionsList.add(new ItemInteraction("wf_act_flee", WiredEffectMoveFurniAway.class)); + this.interactionsList.add(new ItemInteraction("wf_act_move_to_dir", WiredEffectChangeFurniDirection.class)); + this.interactionsList.add(new ItemInteraction("wf_act_give_score_tm", WiredEffectGiveScoreToTeam.class)); + this.interactionsList.add(new ItemInteraction("wf_act_toggle_to_rnd", WiredEffectToggleRandom.class)); + this.interactionsList.add(new ItemInteraction("wf_act_move_furni_to", WiredEffectMoveFurniTo.class)); + this.interactionsList.add(new ItemInteraction("wf_act_give_reward", WiredEffectGiveReward.class)); + this.interactionsList.add(new ItemInteraction("wf_act_call_stacks", WiredEffectTriggerStacks.class)); + this.interactionsList.add(new ItemInteraction("wf_act_kick_user", WiredEffectKickHabbo.class)); + this.interactionsList.add(new ItemInteraction("wf_act_mute_triggerer", WiredEffectMuteHabbo.class)); + this.interactionsList.add(new ItemInteraction("wf_act_bot_teleport", WiredEffectBotTeleport.class)); + this.interactionsList.add(new ItemInteraction("wf_act_bot_move", WiredEffectBotWalkToFurni.class)); + this.interactionsList.add(new ItemInteraction("wf_act_bot_talk", WiredEffectBotTalk.class)); + this.interactionsList.add(new ItemInteraction("wf_act_bot_give_handitem", WiredEffectBotGiveHandItem.class)); + this.interactionsList.add(new ItemInteraction("wf_act_bot_follow_avatar", WiredEffectBotFollowHabbo.class)); + this.interactionsList.add(new ItemInteraction("wf_act_bot_clothes", WiredEffectBotClothes.class)); + this.interactionsList.add(new ItemInteraction("wf_act_bot_talk_to_avatar", WiredEffectBotTalkToHabbo.class)); + this.interactionsList.add(new ItemInteraction("wf_act_give_respect", WiredEffectGiveRespect.class)); + this.interactionsList.add(new ItemInteraction("wf_act_alert", WiredEffectAlert.class)); + this.interactionsList.add(new ItemInteraction("wf_act_give_handitem", WiredEffectGiveHandItem.class)); + this.interactionsList.add(new ItemInteraction("wf_act_give_effect", WiredEffectGiveEffect.class)); + + this.interactionsList.add(new ItemInteraction("wf_cnd_has_furni_on", WiredConditionFurniHaveFurni.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_furnis_hv_avtrs", WiredConditionFurniHaveHabbo.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_stuff_is", WiredConditionFurniTypeMatch.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_actor_in_group", WiredConditionGroupMember.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_user_count_in", WiredConditionHabboCount.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_wearing_effect", WiredConditionHabboHasEffect.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_wearing_badge", WiredConditionHabboWearsBadge.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_time_less_than", WiredConditionLessTimeElapsed.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_match_snapshot", WiredConditionMatchStatePosition.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_time_more_than", WiredConditionMoreTimeElapsed.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_not_furni_on", WiredConditionNotFurniHaveFurni.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_not_hv_avtrs", WiredConditionNotFurniHaveHabbo.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_not_stuff_is", WiredConditionNotFurniTypeMatch.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_not_user_count", WiredConditionNotHabboCount.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_not_wearing_fx", WiredConditionNotHabboHasEffect.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_not_wearing_b", WiredConditionNotHabboWearsBadge.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_not_in_group", WiredConditionNotInGroup.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_not_in_team", WiredConditionNotInTeam.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_not_match_snap", WiredConditionNotMatchStatePosition.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_not_trggrer_on", WiredConditionNotTriggerOnFurni.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_actor_in_team", WiredConditionTeamMember.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_trggrer_on_frn", WiredConditionTriggerOnFurni.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_has_handitem", WiredConditionHabboHasHandItem.class)); + this.interactionsList.add(new ItemInteraction("wf_cnd_date_rng_active", WiredConditionDateRangeActive.class)); + + this.interactionsList.add(new ItemInteraction("wf_xtra_random", WiredExtraRandom.class)); + this.interactionsList.add(new ItemInteraction("wf_xtra_unseen", WiredExtraUnseen.class)); + this.interactionsList.add(new ItemInteraction("wf_blob", WiredBlob.class)); + + + this.interactionsList.add(new ItemInteraction("wf_highscore", InteractionWiredHighscore.class)); + + + this.interactionsList.add(new ItemInteraction("battlebanzai_tile", InteractionBattleBanzaiTile.class)); + this.interactionsList.add(new ItemInteraction("battlebanzai_random_teleport", InteractionBattleBanzaiTeleporter.class)); + this.interactionsList.add(new ItemInteraction("battlebanzai_sphere", InteractionBattleBanzaiSphere.class)); + this.interactionsList.add(new ItemInteraction("battlebanzai_puck", InteractionBattleBanzaiPuck.class)); + + + this.interactionsList.add(new ItemInteraction("battlebanzai_gate_blue", InteractionBattleBanzaiGateBlue.class)); + this.interactionsList.add(new ItemInteraction("battlebanzai_gate_green", InteractionBattleBanzaiGateGreen.class)); + this.interactionsList.add(new ItemInteraction("battlebanzai_gate_red", InteractionBattleBanzaiGateRed.class)); + this.interactionsList.add(new ItemInteraction("battlebanzai_gate_yellow", InteractionBattleBanzaiGateYellow.class)); + + + this.interactionsList.add(new ItemInteraction("battlebanzai_counter_blue", InteractionBattleBanzaiScoreboardBlue.class)); + this.interactionsList.add(new ItemInteraction("battlebanzai_counter_green", InteractionBattleBanzaiScoreboardGreen.class)); + this.interactionsList.add(new ItemInteraction("battlebanzai_counter_red", InteractionBattleBanzaiScoreboardRed.class)); + this.interactionsList.add(new ItemInteraction("battlebanzai_counter_yellow", InteractionBattleBanzaiScoreboardYellow.class)); + + + this.interactionsList.add(new ItemInteraction("freeze_block", InteractionFreezeBlock.class)); + this.interactionsList.add(new ItemInteraction("freeze_tile", InteractionFreezeTile.class)); + this.interactionsList.add(new ItemInteraction("freeze_exit", InteractionFreezeExitTile.class)); + + + this.interactionsList.add(new ItemInteraction("freeze_gate_blue", InteractionFreezeGateBlue.class)); + this.interactionsList.add(new ItemInteraction("freeze_gate_green", InteractionFreezeGateGreen.class)); + this.interactionsList.add(new ItemInteraction("freeze_gate_red", InteractionFreezeGateRed.class)); + this.interactionsList.add(new ItemInteraction("freeze_gate_yellow", InteractionFreezeGateYellow.class)); + + + this.interactionsList.add(new ItemInteraction("freeze_counter_blue", InteractionFreezeScoreboardBlue.class)); + this.interactionsList.add(new ItemInteraction("freeze_counter_green", InteractionFreezeScoreboardGreen.class)); + this.interactionsList.add(new ItemInteraction("freeze_counter_red", InteractionFreezeScoreboardRed.class)); + this.interactionsList.add(new ItemInteraction("freeze_counter_yellow", InteractionFreezeScoreboardYellow.class)); + + + this.interactionsList.add(new ItemInteraction("icetag_pole", InteractionIceTagPole.class)); + this.interactionsList.add(new ItemInteraction("icetag_field", InteractionIceTagField.class)); + + + this.interactionsList.add(new ItemInteraction("bunnyrun_pole", InteractionBunnyrunPole.class)); + this.interactionsList.add(new ItemInteraction("bunnyrun_field", InteractionBunnyrunField.class)); + + + this.interactionsList.add(new ItemInteraction("rollerskate_field", InteractionRollerskateField.class)); + + + this.interactionsList.add(new ItemInteraction("football", InteractionFootball.class)); + this.interactionsList.add(new ItemInteraction("football_gate", InteractionFootballGate.class)); + this.interactionsList.add(new ItemInteraction("football_counter_blue", InteractionFootballScoreboardBlue.class)); + this.interactionsList.add(new ItemInteraction("football_counter_green", InteractionFootballScoreboardGreen.class)); + this.interactionsList.add(new ItemInteraction("football_counter_red", InteractionFootballScoreboardRed.class)); + this.interactionsList.add(new ItemInteraction("football_counter_yellow", InteractionFootballScoreboardYellow.class)); + this.interactionsList.add(new ItemInteraction("football_goal_blue", InteractionFootballGoalBlue.class)); + this.interactionsList.add(new ItemInteraction("football_goal_green", InteractionFootballGoalGreen.class)); + this.interactionsList.add(new ItemInteraction("football_goal_red", InteractionFootballGoalRed.class)); + this.interactionsList.add(new ItemInteraction("football_goal_yellow", InteractionFootballGoalYellow.class)); + + this.interactionsList.add(new ItemInteraction("snowstorm_tree", null)); + this.interactionsList.add(new ItemInteraction("snowstorm_machine", null)); + this.interactionsList.add(new ItemInteraction("snowstorm_pile", null)); + + this.interactionsList.add(new ItemInteraction("vote_counter", InteractionVoteCounter.class)); + + this.interactionsList.add(new ItemInteraction("totem_leg", InteractionTotemLegs.class)); + this.interactionsList.add(new ItemInteraction("totem_head", InteractionTotemHead.class)); + this.interactionsList.add(new ItemInteraction("totem_planet", InteractionTotemPlanet.class)); + } + + + public void addItemInteraction(ItemInteraction itemInteraction) { + for (ItemInteraction interaction : this.interactionsList) { + if (interaction.getType() == itemInteraction.getType() || + interaction.getName().equalsIgnoreCase(itemInteraction.getName())) + + throw new RuntimeException("Interaction Types must be unique. An class with type: " + interaction.getClass().getName() + " was already added OR the key: " + interaction.getName() + " is already in use."); + } + + this.interactionsList.add(itemInteraction); + } + + + public ItemInteraction getItemInteraction(Class type) { + for (ItemInteraction interaction : this.interactionsList) { + if (interaction.getType() == type) + return interaction; + } + + log.debug("Can't find interaction class: {}", type.getName()); + return this.getItemInteraction(InteractionDefault.class); + } + + + public ItemInteraction getItemInteraction(String type) { + for (ItemInteraction interaction : this.interactionsList) { + if (interaction.getName().equalsIgnoreCase(type)) + return interaction; + } + + return this.getItemInteraction(InteractionDefault.class); + } + + + public void loadItems() { + try ( + Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + Statement statement = connection.createStatement(); + ResultSet set = statement.executeQuery(("SELECT * FROM items_base ORDER BY id DESC")) + ) { + while (set.next()) { + try { + //Item proxyItem = + int id = set.getInt("id"); + if (!this.items.containsKey(id)) + this.items.put(id, new Item(set)); + else + this.items.get(id).update(set); + } catch (Exception e) { + log.error("Failed to load Item ({})", set.getInt("id")); + log.error("Caught exception", e); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + + public void loadCrackable() { + this.crackableRewards.clear(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM items_crackable"); ResultSet set = statement.executeQuery()) { + while (set.next()) { + CrackableReward reward; + try { + reward = new CrackableReward(set); + } catch (Exception e) { + log.error("Failed to load items_crackable item_id = {}", set.getInt("item_id")); + log.error("Caught exception", e); + continue; + } + this.crackableRewards.put(set.getInt("item_id"), reward); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + + public int getCrackableCount(int itemId) { + if (this.crackableRewards.containsKey(itemId)) + return this.crackableRewards.get(itemId).count; + else + return 0; + } + + + public int calculateCrackState(int count, int max, Item baseItem) { + return (int) Math.floor((1.0D / ((double) max / (double) count) * baseItem.getStateCount())); + } + + public CrackableReward getCrackableData(int itemId) { + return this.crackableRewards.get(itemId); + } + + public Item getCrackableReward(int itemId) { + return this.getItem(this.crackableRewards.get(itemId).getRandomReward()); + } + + + public void loadSoundTracks() { + this.soundTracks.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM soundtracks"); ResultSet set = statement.executeQuery()) { + while (set.next()) { + this.soundTracks.put(set.getString("code"), new SoundTrack(set)); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public SoundTrack getSoundTrack(String code) { + return this.soundTracks.get(code); + } + + public SoundTrack getSoundTrack(int id) { + for (Map.Entry entry : this.soundTracks.entrySet()) { + if (entry.getValue().getId() == id) + return entry.getValue(); + } + + return null; + } + + public HabboItem createItem(int habboId, Item item, int limitedStack, int limitedSells, String extraData) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO items (user_id, item_id, extra_data, limited_data) VALUES (?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, habboId); + statement.setInt(2, item.getId()); + statement.setString(3, extraData); + statement.setString(4, limitedStack + ":" + limitedSells); + statement.execute(); + + try (ResultSet set = statement.getGeneratedKeys()) { + if (set.next()) { + Class itemClass = item.getInteractionType().getType(); + + if (itemClass != null) { + try { + return itemClass.getDeclaredConstructor(int.class, int.class, Item.class, String.class, int.class, int.class).newInstance(set.getInt(1), habboId, item, extraData, limitedStack, limitedSells); + } catch (Exception e) { + log.error("Caught exception", e); + return new InteractionDefault(set.getInt(1), habboId, item, extraData, limitedStack, limitedSells); + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } catch (Exception e) { + log.error("Caught exception", e); + } + return null; + } + + public void loadNewUserGifts() { + this.newuserGifts.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM nux_gifts")) { + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + this.newuserGifts.put(set.getInt("id"), new NewUserGift(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void addNewUserGift(NewUserGift gift) { + this.newuserGifts.put(gift.getId(), gift); + } + + public void removeNewUserGift(NewUserGift gift) { + this.newuserGifts.remove(gift.getId()); + } + + public NewUserGift getNewUserGift(int id) { + return this.newuserGifts.get(id); + } + + public List getNewUserGifts() { + return new ArrayList<>(this.newuserGifts.values()); + } + + public void deleteItem(HabboItem item) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM items WHERE id = ?")) { + statement.setInt(1, item.getId()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public HabboItem handleRecycle(Habbo habbo, String itemId) { + String extradata = Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + "-" + (Calendar.getInstance().get(Calendar.MONTH) + 1) + "-" + Calendar.getInstance().get(Calendar.YEAR); + + HabboItem item = null; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO items (user_id, item_id, extra_data) VALUES (?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, habbo.getHabboInfo().getId()); + statement.setInt(2, Emulator.getGameEnvironment().getCatalogManager().ecotronItem.getId()); + statement.setString(3, extradata); + statement.execute(); + + try (ResultSet set = statement.getGeneratedKeys()) { + try (PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO items_presents VALUES (?, ?)")) { + while (set.next() && item == null) { + preparedStatement.setInt(1, set.getInt(1)); + preparedStatement.setInt(2, Integer.valueOf(itemId)); + preparedStatement.addBatch(); + item = new InteractionDefault(set.getInt(1), habbo.getHabboInfo().getId(), Emulator.getGameEnvironment().getCatalogManager().ecotronItem, extradata, 0, 0); + } + + preparedStatement.executeBatch(); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return item; + } + + public HabboItem handleOpenRecycleBox(Habbo habbo, HabboItem box) { + Emulator.getThreading().run(new QueryDeleteHabboItem(box.getId())); + HabboItem item = null; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM items_presents WHERE item_id = ? LIMIT 1")) { + statement.setInt(1, box.getId()); + try (ResultSet rewardSet = statement.executeQuery()) { + if (rewardSet.next()) { + try (PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO items (user_id, item_id) VALUES(?, ?)", Statement.RETURN_GENERATED_KEYS)) { + preparedStatement.setInt(1, habbo.getHabboInfo().getId()); + preparedStatement.setInt(2, rewardSet.getInt("base_item_reward")); + preparedStatement.execute(); + + try (ResultSet set = preparedStatement.getGeneratedKeys()) { + if (set.next()) { + try (PreparedStatement request = connection.prepareStatement("SELECT * FROM items WHERE id = ? LIMIT 1")) { + request.setInt(1, set.getInt(1)); + + try (ResultSet resultSet = request.executeQuery()) { + if (resultSet.next()) { + try (PreparedStatement deleteStatement = connection.prepareStatement("DELETE FROM items_presents WHERE item_id = ? LIMIT 1")) { + deleteStatement.setInt(1, box.getId()); + deleteStatement.execute(); + + item = this.loadHabboItem(resultSet); + } + } + } + } + } + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } catch (Exception e) { + log.error("Caught exception", e); + } + + return item; + } + + public void insertTeleportPair(int itemOneId, int itemTwoId) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO items_teleports VALUES (?, ?)")) { + statement.setInt(1, itemOneId); + statement.setInt(2, itemTwoId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void insertHopper(HabboItem hopper) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO items_hoppers VALUES (?, ?)")) { + statement.setInt(1, hopper.getId()); + statement.setInt(2, hopper.getBaseItem().getId()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public int[] getTargetTeleportRoomId(HabboItem item) { + int[] a = new int[]{}; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT items.id, items.room_id FROM items_teleports INNER JOIN items ON items_teleports.teleport_one_id = items.id OR items_teleports.teleport_two_id = items.id WHERE items.id != ? AND items.room_id > 0 LIMIT 1")) { + statement.setInt(1, item.getId()); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + a = new int[]{set.getInt("room_id"), set.getInt("id")}; + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return a; + } + + public HabboItem loadHabboItem(int itemId) { + HabboItem item = null; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM items WHERE id = ? LIMIT 1")) { + statement.setInt(1, itemId); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + item = this.loadHabboItem(set); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } catch (Exception e) { + log.error("Caught exception", e); + } + + return item; + } + + public HabboItem loadHabboItem(ResultSet set) throws SQLException { + Item baseItem = this.getItem(set.getInt("item_id")); + + if (baseItem == null) + return null; + + Class itemClass = baseItem.getInteractionType().getType(); + + if (itemClass != null) { + try { + Constructor c = itemClass.getConstructor(ResultSet.class, Item.class); + c.setAccessible(true); + + return (HabboItem) c.newInstance(set, baseItem); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + return null; + } + + public HabboItem createGift(String username, Item item, String extraData, int limitedStack, int limitedSells) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(username); + + int userId = 0; + + if (habbo != null) { + userId = habbo.getHabboInfo().getId(); + } + else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT id FROM users WHERE username = ?")) { + statement.setString(1, username); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + userId = set.getInt(1); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + if(userId > 0) { + return createGift(userId, item, extraData, limitedStack, limitedSells); + } + + return null; + } + + public HabboItem createGift(int userId, Item item, String extraData, int limitedStack, int limitedSells) { + if (userId == 0) + return null; + + if (extraData.length() > 1000) { + log.error("Extradata exceeds maximum length of 1000 characters: {}", extraData); + extraData = extraData.substring(0, 1000); + } + + HabboItem gift = this.createItem(userId, item, limitedStack, limitedSells, extraData); + + if (gift != null) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + if (habbo != null) { + habbo.getInventory().getItemsComponent().addItem(gift); + habbo.getClient().sendResponse(new AddHabboItemComposer(gift)); + } + } + + return gift; + } + + public Item getItem(int itemId) { + if (itemId < 0) + return null; + + return this.items.get(itemId); + } + + public TIntObjectMap getItems() { + return this.items; + } + + public Item getItem(String itemName) { + TIntObjectIterator item = this.items.iterator(); + + for (int i = this.items.size(); i-- > 0; ) { + try { + item.advance(); + if (item.value().getName().toLowerCase().equals(itemName.toLowerCase())) { + return item.value(); + } + } catch (NoSuchElementException e) { + break; + } + } + + return null; + } + + public YoutubeManager getYoutubeManager() { + return this.youtubeManager; + } + + public WiredHighscoreManager getHighscoreManager() { + return highscoreManager; + } + + public void dispose() { + this.items.clear(); + + log.info("Item Manager -> Disposed!"); + } + + public List getInteractionList() { + List interactions = new ArrayList<>(); + + for (ItemInteraction interaction : this.interactionsList) { + interactions.add(interaction.getName()); + } + + Collections.sort(interactions); + return interactions; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/NewUserGift.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/NewUserGift.java new file mode 100644 index 0000000..90aff43 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/NewUserGift.java @@ -0,0 +1,82 @@ +package com.eu.habbo.habbohotel.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; + +public class NewUserGift implements ISerialize { + private final int id; + private final Type type; + private final String imageUrl; + private Map items = new HashMap<>(); + + public NewUserGift(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.type = Type.valueOf(set.getString("type").toUpperCase()); + this.imageUrl = set.getString("image"); + this.items.put(this.type == Type.ROOM ? "" : set.getString("value"), this.type == Type.ROOM ? set.getString("value") : ""); + } + + public NewUserGift(int id, Type type, String imageUrl, Map items) { + this.id = id; + this.imageUrl = imageUrl; + this.type = type; + this.items = items; + } + + @Override + public void serialize(ServerMessage message) { + message.appendString(this.imageUrl); + message.appendInt(this.items.size()); + for (Map.Entry entry : this.items.entrySet()) { + message.appendString(entry.getKey()); //Item Name + message.appendString(entry.getValue()); //Extra Info + } + } + + public void give(Habbo habbo) { + if (this.type == Type.ITEM) { + for (Map.Entry set : this.items.entrySet()) { + Item item = Emulator.getGameEnvironment().getItemManager().getItem(set.getKey()); + + if (item != null) { + HabboItem createdItem = Emulator.getGameEnvironment().getItemManager().createItem(habbo.getHabboInfo().getId(), item, 0, 0, ""); + + if (createdItem != null) { + habbo.addFurniture(createdItem); + } + } + } + } else if (this.type == Type.ROOM) { + //TODO Give room + } + } + + public int getId() { + return this.id; + } + + public Type getType() { + return this.type; + } + + public String getImageUrl() { + return this.imageUrl; + } + + public Map getItems() { + return this.items; + } + + public enum Type { + ITEM, + ROOM + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/PostItColor.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/PostItColor.java new file mode 100644 index 0000000..f046227 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/PostItColor.java @@ -0,0 +1,55 @@ +package com.eu.habbo.habbohotel.items; + +import com.eu.habbo.Emulator; + +public enum PostItColor { + + BLUE("9CCEFF"), + + + GREEN("9CFF9C"), + + + PINK("FF9CFF"), + + + YELLOW("FFFF33"), + + + RED("FF9C9D"), + + + ORANGE("FFCD9C"), + + + PURPLE("C3B1E1"), + + + LIGHTBLUE("DBDEFB"), + + + WHITE("FFFFFF"), + + + BLACK("282828"); + + public final String hexColor; + + PostItColor(String hexColor) { + this.hexColor = hexColor; + } + + + public static boolean isCustomColor(String color) { + for (PostItColor postItColor : PostItColor.values()) { + if (postItColor.hexColor.equalsIgnoreCase(color)) + return false; + } + + return true; + } + + public static PostItColor randomColorNotYellow() { + return PostItColor.values()[Emulator.getRandom().nextInt(3)]; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/RandomStateParams.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/RandomStateParams.java new file mode 100644 index 0000000..ff3babe --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/RandomStateParams.java @@ -0,0 +1,41 @@ +package com.eu.habbo.habbohotel.items; + +import lombok.extern.slf4j.Slf4j; +import java.util.Arrays; + +@Slf4j +public class RandomStateParams { + private int states = -1; + private int delay = -1; + + public RandomStateParams(String customparams) throws Exception { + Arrays.stream(customparams.split(",")).forEach(pair -> { + String[] keyValue = pair.split("="); + + if (keyValue.length != 2) return; + + switch (keyValue[0]) { + case "states": + this.states = Integer.parseInt(keyValue[1]); + break; + case "delay": + this.delay = Integer.parseInt(keyValue[1]); + break; + default: + log.warn("RandomStateParams: unknown key: " + keyValue[0]); + break; + } + }); + + if (this.states < 0) throw new Exception("RandomStateParams: states not defined"); + if (this.delay < 0) throw new Exception("RandomStateParams: states not defined"); + } + + public int getStates() { + return states; + } + + public int getDelay() { + return delay; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/RedeemableSubscriptionType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/RedeemableSubscriptionType.java new file mode 100644 index 0000000..6747e7b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/RedeemableSubscriptionType.java @@ -0,0 +1,25 @@ +package com.eu.habbo.habbohotel.items; + +public enum RedeemableSubscriptionType { + HABBO_CLUB("hc"), + BUILDERS_CLUB("bc"); + + public final String subscriptionType; + + RedeemableSubscriptionType(String subscriptionType) { + this.subscriptionType = subscriptionType; + } + + public static RedeemableSubscriptionType fromString(String subscriptionType) { + if (subscriptionType == null) return null; + + switch (subscriptionType) { + case "hc": + return HABBO_CLUB; + case "bc": + return BUILDERS_CLUB; + } + + return null; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/SoundTrack.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/SoundTrack.java new file mode 100644 index 0000000..53430c1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/SoundTrack.java @@ -0,0 +1,46 @@ +package com.eu.habbo.habbohotel.items; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class SoundTrack { + private int id; + private String name; + private String author; + private String code; + private String data; + private int length; + + public SoundTrack(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.name = set.getString("name"); + this.author = set.getString("author"); + this.code = set.getString("code"); + this.data = set.getString("track"); + this.length = set.getInt("length"); + } + + public int getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public String getAuthor() { + return this.author; + } + + public String getCode() { + return this.code; + } + + public String getData() { + return this.data; + } + + public int getLength() { + return this.length; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/YoutubeManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/YoutubeManager.java new file mode 100644 index 0000000..9ac2b61 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/YoutubeManager.java @@ -0,0 +1,230 @@ +package com.eu.habbo.habbohotel.items; + +import com.eu.habbo.Emulator; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; +import javax.net.ssl.HttpsURLConnection; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.sql.*; +import java.time.Duration; +import java.util.ArrayList; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +@Slf4j +public class YoutubeManager { + + public static class YoutubeVideo { + private final String id; + private final int duration; + + YoutubeVideo(String id, int duration) { + this.id = id; + this.duration = duration; + } + + public String getId() { + return id; + } + + public int getDuration() { + return duration; + } + } + + public static class YoutubePlaylist { + private final String id; + private final String name; + private final String description; + private final ArrayList videos; + + YoutubePlaylist(String id, String name, String description, ArrayList videos) { + this.id = id; + this.name = name; + this.description = description; + this.videos = videos; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public ArrayList getVideos() { + return videos; + } + } + + private final THashMap> playlists = new THashMap<>(); + private final THashMap playlistCache = new THashMap<>(); + private final String apiKey = Emulator.getConfig().getValue("youtube.apikey"); + + public void load() { + this.playlists.clear(); + this.playlistCache.clear(); + + long millis = System.currentTimeMillis(); + + Emulator.getThreading().run(() -> { + ExecutorService youtubeDataLoaderPool = Executors.newFixedThreadPool(10); + + log.info("YouTube Manager -> Loading..."); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM youtube_playlists")) { + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + final int itemId = set.getInt("item_id"); + final String playlistId = set.getString("playlist_id"); + + + youtubeDataLoaderPool.submit(() -> { + YoutubePlaylist playlist; + try { + playlist = this.getPlaylistDataById(playlistId); + if (playlist != null) { + this.addPlaylistToItem(itemId, playlist); + } + } catch (IOException e) { + log.error("Failed to load YouTube playlist {} ERROR: {}", playlistId, e); + } + }); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + youtubeDataLoaderPool.shutdown(); + try { + youtubeDataLoaderPool.awaitTermination(60, TimeUnit.SECONDS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + log.info("YouTube Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)"); + }); + } + + public YoutubePlaylist getPlaylistDataById(String playlistId) throws IOException { + if (this.playlistCache.containsKey(playlistId)) return this.playlistCache.get(playlistId); + if(apiKey.isEmpty()) return null; + + YoutubePlaylist playlist; + URL playlistInfo = new URL("https://youtube.googleapis.com/youtube/v3/playlists?part=snippet&id=" + playlistId + "&maxResults=1&key=" + apiKey); + HttpsURLConnection playlistCon = (HttpsURLConnection) playlistInfo.openConnection(); + if (playlistCon.getResponseCode() != 200) { + InputStream errorInputStream = playlistCon.getErrorStream(); + InputStreamReader playlistISR = new InputStreamReader(errorInputStream); + BufferedReader playlistBR = new BufferedReader(playlistISR); + JsonObject errorObj = JsonParser.parseReader(playlistBR).getAsJsonObject(); + String message = errorObj.get("error").getAsJsonObject().get("message").getAsString(); + log.error("Failed to load YouTube playlist {} ERROR: {}", playlistId, message); + return null; + } + InputStream playlistInputStream = playlistCon.getInputStream(); + InputStreamReader playlistISR = new InputStreamReader(playlistInputStream); + BufferedReader playlistBR = new BufferedReader(playlistISR); + + JsonObject playlistData = JsonParser.parseReader(playlistBR).getAsJsonObject(); + + JsonArray playlists = playlistData.get("items").getAsJsonArray(); + if (playlists.size() == 0) { + log.error("Playlist {} not found!", playlistId); + return null; + } + JsonObject playlistItem = playlists.get(0).getAsJsonObject().get("snippet").getAsJsonObject(); + + String name = playlistItem.get("title").getAsString(); + String description = playlistItem.get("description").getAsString(); + + ArrayList < YoutubeVideo > videos = new ArrayList < > (); + String nextPageToken = ""; + do { + ArrayList < String > videoIds = new ArrayList < > (); + URL playlistItems; + + if (nextPageToken.isEmpty()) { + playlistItems = new URL("https://youtube.googleapis.com/youtube/v3/playlistItems?part=snippet%2Cstatus&playlistId=" + playlistId + "&maxResults=50&key=" + apiKey); + } else { + playlistItems = new URL("https://youtube.googleapis.com/youtube/v3/playlistItems?part=snippet%2Cstatus&playlistId=" + playlistId + "&pageToken=" + nextPageToken + "&maxResults=50&key=" + apiKey); + } + + HttpsURLConnection con = (HttpsURLConnection) playlistItems.openConnection(); + + InputStream is = con.getInputStream(); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + JsonObject object = JsonParser.parseReader(br).getAsJsonObject(); + + JsonArray rawV = object.get("items").getAsJsonArray(); + for (JsonElement rawVideo: rawV) { + JsonObject videoData = rawVideo.getAsJsonObject().get("snippet").getAsJsonObject(); + JsonObject videoStatus = rawVideo.getAsJsonObject().get("status").getAsJsonObject(); + if (!videoStatus.get("privacyStatus").getAsString().equals("public")) + continue; // removed videos + videoIds.add(videoData.get("resourceId").getAsJsonObject().get("videoId").getAsString()); + } + + if (!videoIds.isEmpty()) { + URL VideoItems; + + String commaSeparatedVideos = String.join(",", videoIds); + + VideoItems = new URL("https://youtube.googleapis.com/youtube/v3/videos?part=contentDetails&id=" + commaSeparatedVideos + "&maxResults=50&key=" + apiKey); + HttpsURLConnection con1 = (HttpsURLConnection) VideoItems.openConnection(); + InputStream is1 = con1.getInputStream(); + InputStreamReader isr1 = new InputStreamReader(is1); + BufferedReader br1 = new BufferedReader(isr1); + JsonObject object1 = JsonParser.parseReader(br1).getAsJsonObject(); + JsonArray Vds = object1.get("items").getAsJsonArray(); + for (JsonElement rawVideo: Vds) { + JsonObject contentDetails = rawVideo.getAsJsonObject().get("contentDetails").getAsJsonObject(); + int duration = (int) Duration.parse(contentDetails.get("duration").getAsString()).getSeconds(); + if (duration < 1) continue; + videos.add(new YoutubeVideo(rawVideo.getAsJsonObject().get("id").getAsString(), duration)); + } + } + if (object.has("nextPageToken")) { + nextPageToken = object.get("nextPageToken").getAsString(); + } else { + nextPageToken = null; + } + } while (nextPageToken != null); + + if (videos.isEmpty()) { + log.warn("Playlist {} has no videos!", playlistId); + return null; + } + playlist = new YoutubePlaylist(playlistId, name, description, videos); + + this.playlistCache.put(playlistId, playlist); + log.info("Loaded youtube playList into cache:" + playlistId); + + return playlist; + + } + + public ArrayList getPlaylistsForItemId(int itemId) { + return this.playlists.get(itemId); + } + + public void addPlaylistToItem(int itemId, YoutubePlaylist playlist) { + this.playlists.computeIfAbsent(itemId, k -> new ArrayList<>()).add(playlist); + log.info("Loaded youtube playList into FurniID:" + itemId); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBackgroundToner.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBackgroundToner.java new file mode 100644 index 0000000..ab6bf36 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBackgroundToner.java @@ -0,0 +1,111 @@ +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.modtool.ScripterManager; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.threading.runnables.BackgroundAnimation; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBackgroundToner extends HabboItem { + public InteractionBackgroundToner(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionBackgroundToner(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt(5 + (this.isLimited() ? 256 : 0)); + serverMessage.appendInt(4); + if (this.getExtradata().split(":").length == 4) { + String[] colorData = this.getExtradata().split(":"); + serverMessage.appendInt(Integer.valueOf(colorData[0])); + serverMessage.appendInt(Integer.valueOf(colorData[1])); + serverMessage.appendInt(Integer.valueOf(colorData[2])); + serverMessage.appendInt(Integer.valueOf(colorData[3])); + } else { + serverMessage.appendInt(0); + serverMessage.appendInt(126); + serverMessage.appendInt(126); + serverMessage.appendInt(126); + this.setExtradata("0:126:126:126"); + this.needsUpdate(true); + Emulator.getThreading().run(this); + } + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return this.getBaseItem().allowWalk(); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + + if(client != null) + { + if (!client.getHabbo().getRoomUnit().getRoom().hasRights(client.getHabbo())) { + ScripterManager.scripterDetected( + client, + Emulator.getTexts().getValue("scripter.warning.item.bgtoner.permission").replace("%username%", client.getHabbo().getHabboInfo().getUsername()) + .replace("%room%", room.getName()) + .replace("%owner%", room.getOwnerName()) + ); + return; + } + + if (client.getHabbo().getRoomUnit().cmdSit && client.getHabbo().getRoomUnit().getEffectId() == 1337) { + new BackgroundAnimation(this, room).run(); + return; + } + } + + if (this.getExtradata().split(":").length == 4) { + String[] data = this.getExtradata().split(":"); + this.setExtradata((data[0].equals("0") ? "1" : "0") + ":" + data[1] + ":" + data[2] + ":" + data[3]); + room.updateItem(this); + } else { + this.setExtradata("0:126:126:126"); + room.updateItem(this); + } + this.needsUpdate(true); + Emulator.getThreading().run(this); + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + } + + @Override + public boolean isUsable() { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBadgeDisplay.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBadgeDisplay.java new file mode 100644 index 0000000..01b552f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBadgeDisplay.java @@ -0,0 +1,70 @@ +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; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBadgeDisplay extends HabboItem { + public InteractionBadgeDisplay(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionBadgeDisplay(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt(2 + (this.isLimited() ? 256 : 0)); + serverMessage.appendInt(4); + serverMessage.appendString("0"); + String[] data = this.getExtradata().split((char) 9 + ""); + if (data.length == 3) { + serverMessage.appendString(data[2]); + serverMessage.appendString(data[1]); + serverMessage.appendString(data[0]); + } else { + serverMessage.appendString(this.getExtradata()); + serverMessage.appendString("Unknown User"); + serverMessage.appendString("Unknown Date"); + } + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBlackHole.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBlackHole.java new file mode 100644 index 0000000..f669479 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBlackHole.java @@ -0,0 +1,46 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBlackHole extends InteractionGate { + public InteractionBlackHole(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionBlackHole(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onPlace(Room room) { + Achievement holeCountAchievement = Emulator.getGameEnvironment().getAchievementManager().getAchievement("RoomDecoHoleFurniCount"); + + int holesCountProgress = 0; + Habbo owner = room.getHabbo(this.getUserId()); + + if (owner == null) { + holesCountProgress = AchievementManager.getAchievementProgressForHabbo(this.getUserId(), holeCountAchievement); + } else { + holesCountProgress = owner.getHabboStats().getAchievementProgress(holeCountAchievement); + } + int holeDifference = room.getRoomSpecialTypes().getItemsOfType(InteractionBlackHole.class).size() - holesCountProgress; + + if (holeDifference > 0) { + if (owner != null) { + AchievementManager.progressAchievement(owner, holeCountAchievement, holeDifference); + } else { + AchievementManager.progressAchievement(this.getUserId(), holeCountAchievement, holeDifference); + } + } + + super.onPlace(room); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBuildArea.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBuildArea.java new file mode 100644 index 0000000..015ab45 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBuildArea.java @@ -0,0 +1,253 @@ +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.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.users.HabboManager; +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.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; + +public class InteractionBuildArea extends InteractionCustomValues { + public static THashMap defaultValues = new THashMap() { + { + this.put("tilesLeft", "0"); + } + + { + this.put("tilesRight", "0"); + } + + { + this.put("tilesFront", "0"); + } + + { + this.put("tilesBack", "0"); + } + + { + this.put("builders", ""); + } + }; + + private THashSet tiles; + + public InteractionBuildArea(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, defaultValues); + tiles = new THashSet<>(); + } + + public InteractionBuildArea(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 onPlace(Room room) { + super.onPlace(room); + this.regenAffectedTiles(room); + } + + @Override + public void onPickUp(Room room) { + super.onPickUp(room); + + ArrayList builderNames = new ArrayList<>(Arrays.asList(this.values.get("builders").split(";"))); + THashSet canBuild = new THashSet<>(); + + for (String builderName : builderNames) { + Habbo builder = Emulator.getGameEnvironment().getHabboManager().getHabbo(builderName); + HabboInfo builderInfo; + if (builder != null) { + builderInfo = builder.getHabboInfo(); + } else { + builderInfo = HabboManager.getOfflineHabboInfo(builderName); + } + if (builderInfo != null) { + canBuild.add(builderInfo.getId()); + } + } + + if (!canBuild.isEmpty()) { + for (RoomTile tile : this.tiles) { + THashSet tileItems = room.getItemsAt(tile); + for (HabboItem tileItem : tileItems) { + if (canBuild.contains(tileItem.getUserId()) && tileItem != this) { + room.pickUpItem(tileItem, null); + } + } + } + } + + this.tiles.clear(); + } + + @Override + public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + super.onMove(room, oldLocation, newLocation); + + ArrayList builderNames = new ArrayList<>(Arrays.asList(this.values.get("builders").split(";"))); + THashSet canBuild = new THashSet<>(); + + for (String builderName : builderNames) { + Habbo builder = Emulator.getGameEnvironment().getHabboManager().getHabbo(builderName); + HabboInfo builderInfo; + if (builder != null) { + builderInfo = builder.getHabboInfo(); + } else { + builderInfo = HabboManager.getOfflineHabboInfo(builderName); + } + if (builderInfo != null) { + canBuild.add(builderInfo.getId()); + } + } + + THashSet oldTiles = this.tiles; + THashSet newTiles = new THashSet<>(); + + int minX = Math.max(0, newLocation.x - Integer.parseInt(this.values.get("tilesBack"))); + int minY = Math.max(0, newLocation.y - Integer.parseInt(this.values.get("tilesRight"))); + int maxX = Math.min(room.getLayout().getMapSizeX(), newLocation.x + Integer.parseInt(this.values.get("tilesFront"))); + int maxY = Math.min(room.getLayout().getMapSizeY(), newLocation.y + Integer.parseInt(this.values.get("tilesLeft"))); + + 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) + newTiles.add(tile); + } + } + + if (!canBuild.isEmpty()) { + for (RoomTile tile : oldTiles) { + THashSet tileItems = room.getItemsAt(tile); + if(newTiles.contains(tile)) continue; + for (HabboItem tileItem : tileItems) { + if (canBuild.contains(tileItem.getUserId()) && tileItem != this) { + room.pickUpItem(tileItem, null); + } + } + } + } + this.regenAffectedTiles(room); + } + + public boolean inSquare(RoomTile location) { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room != null && this.tiles.size() == 0) { + regenAffectedTiles(room); + } + + return this.tiles.contains(location); + + } + + 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, THashMap oldValues) { + regenAffectedTiles(room); + ArrayList builderNames = new ArrayList<>(Arrays.asList(this.values.get("builders").split(";"))); + THashSet canBuild = new THashSet<>(); + + for (String builderName : builderNames) { + Habbo builder = Emulator.getGameEnvironment().getHabboManager().getHabbo(builderName); + HabboInfo builderInfo; + if (builder != null) { + builderInfo = builder.getHabboInfo(); + } else { + builderInfo = HabboManager.getOfflineHabboInfo(builderName); + } + if (builderInfo != null) { + canBuild.add(builderInfo.getId()); + } + } + + THashSet oldTiles = new THashSet<>(); + + int minX = Math.max(0, this.getX() - Integer.parseInt(oldValues.get("tilesBack"))); + int minY = Math.max(0, this.getY() - Integer.parseInt(oldValues.get("tilesRight"))); + int maxX = Math.min(room.getLayout().getMapSizeX(), this.getX() + Integer.parseInt(oldValues.get("tilesFront"))); + int maxY = Math.min(room.getLayout().getMapSizeY(), this.getY() + Integer.parseInt(oldValues.get("tilesLeft"))); + + 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.contains(tile)) + oldTiles.add(tile); + } + } + if (!canBuild.isEmpty()) { + for (RoomTile tile : oldTiles) { + THashSet tileItems = room.getItemsAt(tile); + for (HabboItem tileItem : tileItems) { + if (canBuild.contains(tileItem.getUserId()) && tileItem != this) { + room.pickUpItem(tileItem, null); + } + } + } + } + + // 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); + } + } + + public boolean isBuilder(String Username){ + return Arrays.asList(this.values.get("builders").split(";")).contains(Username); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCannon.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCannon.java new file mode 100644 index 0000000..00ea3d9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCannon.java @@ -0,0 +1,105 @@ +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.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.threading.runnables.CannonKickAction; +import com.eu.habbo.threading.runnables.CannonResetCooldownAction; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class InteractionCannon extends HabboItem { + public boolean cooldown = false; + + public InteractionCannon(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionCannon(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (client != null) { + super.onClick(client, room, objects); + } + + if (room == null) + return; + + RoomTile tile = room.getLayout().getTile(this.getX(), this.getY()); + RoomTile fuseTile = this.getRotation() >= 4 ? tile : room.getLayout().getTileInFront(tile, ((this.getRotation() % 2) + 2) % 8); + List tiles = room.getLayout().getTilesAround(fuseTile); + tiles.remove(room.getLayout().getTileInFront(tile, (this.getRotation() + (this.getRotation() >= 4 ? -1 : 0)) % 8)); + tiles.remove(room.getLayout().getTileInFront(tile, (this.getRotation() + (this.getRotation() >= 4 ? 5 : 4)) % 8)); + + if ((client == null || (tiles.contains(client.getHabbo().getRoomUnit().getCurrentLocation())) && client.getHabbo().getRoomUnit().canWalk()) && !this.cooldown) { + if (client != null) { + client.getHabbo().getRoomUnit().setCanWalk(false); + client.getHabbo().getRoomUnit().setGoalLocation(client.getHabbo().getRoomUnit().getCurrentLocation()); + client.getHabbo().getRoomUnit().lookAtPoint(fuseTile); + client.getHabbo().getRoomUnit().statusUpdate(true); + } + + this.cooldown = true; + this.setExtradata(this.getExtradata().equals("1") ? "0" : "1"); + room.updateItemState(this); + Emulator.getThreading().run(new CannonKickAction(this, room, client), 750); + Emulator.getThreading().run(new CannonResetCooldownAction(this), 2000); + } + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + } + + @Override + public void onPickUp(Room room) { + this.setExtradata("0"); + } + + + @Override + public boolean isUsable() { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionClothing.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionClothing.java new file mode 100644 index 0000000..d9aaf6f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionClothing.java @@ -0,0 +1,44 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionClothing extends HabboItem { + public InteractionClothing(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionClothing(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt(2 + (this.isLimited() ? 256 : 0)); + serverMessage.appendInt(1); + serverMessage.appendString(""); + + super.serializeExtradata(serverMessage); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionColorPlate.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionColorPlate.java new file mode 100644 index 0000000..d045698 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionColorPlate.java @@ -0,0 +1,60 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import lombok.extern.slf4j.Slf4j; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class InteractionColorPlate extends InteractionDefault { + public InteractionColorPlate(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionColorPlate(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + this.change(room, 1); + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + + this.change(room, -1); + } + + private void change(Room room, int amount) { + int state = 0; + + if (this.getExtradata() == null || this.getExtradata().isEmpty()) { + this.setExtradata("0"); + } + + try { + state = Integer.valueOf(this.getExtradata()); + } catch (Exception e) { + log.error("Caught exception", e); + } + + state += amount; + if (state > this.getBaseItem().getStateCount()) { + state = this.getBaseItem().getStateCount(); + } + + if (state < 0) { + state = 0; + } + + this.setExtradata(state + ""); + this.needsUpdate(true); + room.updateItemState(this); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionColorWheel.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionColorWheel.java new file mode 100644 index 0000000..8105464 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionColorWheel.java @@ -0,0 +1,78 @@ +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.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.items.WallItemUpdateComposer; +import com.eu.habbo.threading.runnables.RandomDiceNumber; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionColorWheel extends HabboItem { + private Runnable rollTaks; + + public InteractionColorWheel(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionColorWheel(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + + if (!room.hasRights(client.getHabbo())) + return; + + if (this.rollTaks == null && !this.getExtradata().equalsIgnoreCase("-1")) { + this.setExtradata("-1"); + room.sendComposer(new WallItemUpdateComposer(this).compose()); + Emulator.getThreading().run(this); + Emulator.getThreading().run(new RandomDiceNumber(this, room, this.getBaseItem().getStateCount()), 3000); + } + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOn(RoomUnit client, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + } + + public void clearRunnable() { + this.rollTaks = null; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCostumeHopper.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCostumeHopper.java new file mode 100644 index 0000000..a73106f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCostumeHopper.java @@ -0,0 +1,28 @@ +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.messages.outgoing.generic.alerts.CustomNotificationComposer; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionCostumeHopper extends InteractionHopper { + public InteractionCostumeHopper(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionCostumeHopper(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (client.getHabbo().getRoomUnit().getEffectId() > 0) { + super.onClick(client, room, objects); + } else { + client.sendResponse(new CustomNotificationComposer(CustomNotificationComposer.HOPPER_NO_COSTUME)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCrackable.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCrackable.java new file mode 100644 index 0000000..1cc34bf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCrackable.java @@ -0,0 +1,183 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.CrackableReward; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionHabboClub; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.users.UserClubComposer; +import com.eu.habbo.messages.outgoing.users.UserPermissionsComposer; +import com.eu.habbo.threading.runnables.CrackableExplode; +import com.eu.habbo.util.pathfinding.Rotation; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionCrackable extends HabboItem { + private final Object lock = new Object(); + public boolean cracked = false; + protected int ticks = 0; + + public InteractionCrackable(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionCrackable(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + if (this.getExtradata().length() == 0) + this.setExtradata("0"); + + serverMessage.appendInt(7 + (this.isLimited() ? 256 : 0)); + + serverMessage.appendString(Emulator.getGameEnvironment().getItemManager().calculateCrackState(Integer.valueOf(this.getExtradata()), Emulator.getGameEnvironment().getItemManager().getCrackableCount(this.getBaseItem().getId()), this.getBaseItem()) + ""); + serverMessage.appendInt(Integer.valueOf(this.getExtradata())); + serverMessage.appendInt(Emulator.getGameEnvironment().getItemManager().getCrackableCount(this.getBaseItem().getId())); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (client == null) { + return; + } + + super.onClick(client, room, objects); + synchronized (this.lock) { + if (this.getRoomId() == 0) + return; + + if (this.cracked) + return; + + if (this.userRequiredToBeAdjacent() && client.getHabbo().getRoomUnit().getCurrentLocation().distance(room.getLayout().getTile(this.getX(), this.getY())) > 1.5) { + client.getHabbo().getRoomUnit().setGoalLocation(room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), Rotation.Calculate(client.getHabbo().getRoomUnit().getX(), client.getHabbo().getRoomUnit().getY(), this.getX(), this.getY()))); + return; + } + + if (this.getExtradata().length() == 0) + this.setExtradata("0"); + + if (this.getBaseItem().getEffectF() > 0) + if (client.getHabbo().getHabboInfo().getGender().equals(HabboGender.F) && this.getBaseItem().getEffectF() == client.getHabbo().getRoomUnit().getEffectId()) + return; + + if (this.getBaseItem().getEffectM() > 0) + if (client.getHabbo().getHabboInfo().getGender().equals(HabboGender.M) && this.getBaseItem().getEffectM() == client.getHabbo().getRoomUnit().getEffectId()) + return; + + this.onTick(client.getHabbo(), room); + } + } + + public void onTick(Habbo habbo, Room room) { + if (this.cracked) return; + + if (this.allowAnyone() || this.getUserId() == habbo.getHabboInfo().getId()) { + CrackableReward rewardData = Emulator.getGameEnvironment().getItemManager().getCrackableData(this.getBaseItem().getId()); + + if (rewardData != null) { + if (rewardData.requiredEffect > 0 && habbo.getRoomUnit().getEffectId() != rewardData.requiredEffect) + return; + + if(this.ticks < 1) + { + // If there are no ticks (for example because the room has been reloaded), check the current extradata of the item and update the ticks. + this.ticks = Integer.parseInt(this.getExtradata()); + } + this.ticks++; + this.setExtradata("" + (this.ticks)); + this.needsUpdate(true); + room.updateItem(this); + + if (!rewardData.achievementTick.isEmpty()) { + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement(rewardData.achievementTick)); + } + if (!this.cracked && this.ticks == Emulator.getGameEnvironment().getItemManager().getCrackableCount(this.getBaseItem().getId())) { + this.cracked = true; + Emulator.getThreading().run(new CrackableExplode(room, this, habbo, !this.placeInRoom(), this.getX(), this.getY()), 1500); + + if (!rewardData.achievementCracked.isEmpty()) { + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement(rewardData.achievementCracked)); + } + + if (rewardData.subscriptionType != null && rewardData.subscriptionDuration > 0) { + // subscriptions are given immediately upon cracking + switch (rewardData.subscriptionType) { + case HABBO_CLUB: + habbo.getHabboStats().createSubscription(SubscriptionHabboClub.HABBO_CLUB, rewardData.subscriptionDuration * 86400); + break; + case BUILDERS_CLUB: + habbo.getHabboStats().createSubscription("BUILDERS_CLUB", rewardData.subscriptionDuration * 86400); + break; + } + } + } + } + } + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOn(RoomUnit client, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOff(RoomUnit client, Room room, Object[] objects) throws Exception { + + } + + public boolean allowAnyone() { + return false; + } + + protected boolean placeInRoom() { + return true; + } + + public boolean resetable() { + return false; + } + + public boolean userRequiredToBeAdjacent() { + return true; + } + + public void reset(Room room) { + this.cracked = false; + this.ticks = 0; + this.setExtradata("0"); + room.updateItem(this); + } + + @Override + public boolean isUsable() { + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCrackableMaster.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCrackableMaster.java new file mode 100644 index 0000000..6024493 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCrackableMaster.java @@ -0,0 +1,31 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionCrackableMaster extends InteractionCrackable { + public InteractionCrackableMaster(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionCrackableMaster(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + protected boolean placeInRoom() { + return false; + } + + @Override + public boolean resetable() { + return true; + } + + @Override + public boolean allowAnyone() { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCustomValues.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCustomValues.java new file mode 100644 index 0000000..5a275c2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCustomValues.java @@ -0,0 +1,86 @@ +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; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.map.hash.THashMap; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Map; + +public abstract class InteractionCustomValues extends HabboItem { + public final THashMap values = new THashMap<>(); + + public InteractionCustomValues(ResultSet set, Item baseItem, THashMap defaultValues) throws SQLException { + super(set, baseItem); + + this.values.putAll(defaultValues); + + for (String s : set.getString("extra_data").split(";")) { + String[] data = s.split("="); + + if (data.length == 2) { + this.values.put(data[0], data[1]); + } + } + } + + public InteractionCustomValues(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells, THashMap defaultValues) { + super(id, userId, item, extradata, limitedStack, limitedSells); + + this.values.putAll(defaultValues); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void run() { + this.setExtradata(this.toExtraData()); + + super.run(); + } + + public String toExtraData() { + StringBuilder data = new StringBuilder(); + synchronized (this.values) { + for (Map.Entry set : this.values.entrySet()) { + data.append(set.getKey()).append("=").append(set.getValue()).append(";"); + } + } + + return data.toString(); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt(1 + (this.isLimited() ? 256 : 0)); + serverMessage.appendInt(this.values.size()); + for (Map.Entry set : this.values.entrySet()) { + serverMessage.appendString(set.getKey()); + serverMessage.appendString(set.getValue()); + } + + super.serializeExtradata(serverMessage); + } + + public void onCustomValuesSaved(Room room, GameClient client, THashMap oldValues) { + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionDefault.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionDefault.java new file mode 100644 index 0000000..150ae99 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionDefault.java @@ -0,0 +1,212 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.messages.ServerMessage; +import lombok.extern.slf4j.Slf4j; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class InteractionDefault extends HabboItem { + public InteractionDefault(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionDefault(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean isWalkable() { + return this.getBaseItem().allowWalk(); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + super.onMove(room, oldLocation, newLocation); + + if(room.getItemsAt(oldLocation).stream().noneMatch(item -> item.getClass().isAssignableFrom(InteractionRoller.class))) { + for (RoomUnit unit : room.getRoomUnits()) { + if (!oldLocation.unitIsOnFurniOnTile(unit, this.getBaseItem())) + continue; // If the unit was previously on the furni... + if (newLocation.unitIsOnFurniOnTile(unit, this.getBaseItem())) continue; // but is not anymore... + + try { + this.onWalkOff(unit, room, new Object[]{oldLocation, newLocation}); // the unit walked off! + } catch (Exception ignored) { + + } + } + } + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (room != null && (client == null || this.canToggle(client.getHabbo(), room) || (objects.length >= 2 && objects[1] instanceof WiredEffectType && objects[1] == WiredEffectType.TOGGLE_STATE))) { + super.onClick(client, room, objects); + + if (objects != null && objects.length > 0) { + if (objects[0] instanceof Integer) { + if (this.getExtradata().length() == 0) + this.setExtradata("0"); + + if (this.getBaseItem().getStateCount() > 0) { + int currentState = 0; + + try { + currentState = Integer.valueOf(this.getExtradata()); + } catch (NumberFormatException e) { + log.error("Incorrect extradata (" + this.getExtradata() + ") for item ID (" + this.getId() + ") of type (" + this.getBaseItem().getName() + ")"); + } + + this.setExtradata("" + (currentState + 1) % this.getBaseItem().getStateCount()); + this.needsUpdate(true); + + room.updateItemState(this); + } + } + } + } + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null && habbo.getHabboInfo().getRiding() == null) { + super.onWalkOn(roomUnit, room, objects); + if (roomUnit != null) { + if (this.getBaseItem().getEffectF() > 0 || this.getBaseItem().getEffectM() > 0) { + if (roomUnit.getRoomUnitType().equals(RoomUnitType.USER)) { + if (habbo != null) { + if (habbo.getHabboInfo().getGender().equals(HabboGender.M) && this.getBaseItem().getEffectM() > 0 && habbo.getRoomUnit().getEffectId() != this.getBaseItem().getEffectM()) { + room.giveEffect(habbo, this.getBaseItem().getEffectM(), -1); + log.error("newHabbos Effect Male"); + return; + } + + if (habbo.getHabboInfo().getGender().equals(HabboGender.F) && this.getBaseItem().getEffectF() > 0 && habbo.getRoomUnit().getEffectId() != this.getBaseItem().getEffectF()) { + room.giveEffect(habbo, this.getBaseItem().getEffectF(), -1); + log.error("newHabbos Effect Female"); + } + } + } else if (roomUnit.getRoomUnitType().equals(RoomUnitType.BOT)) { + Bot bot = room.getBot(roomUnit); + + if (bot != null) { + if (bot.getGender().equals(HabboGender.M) && this.getBaseItem().getEffectM() > 0 && roomUnit.getEffectId() != this.getBaseItem().getEffectM()) { + room.giveEffect(bot.getRoomUnit(), this.getBaseItem().getEffectM(), -1); + return; + } + if (bot.getGender().equals(HabboGender.F) && this.getBaseItem().getEffectF() > 0 && roomUnit.getEffectId() != this.getBaseItem().getEffectF()) { + room.giveEffect(bot.getRoomUnit(), this.getBaseItem().getEffectF(), -1); + } + } + } + } + } + } + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + Habbo habboride = room.getHabbo(roomUnit); + + if (habboride != null && habboride.getHabboInfo().getRiding() == null) { + super.onWalkOff(roomUnit, room, objects); + + if (roomUnit != null) { + if (this.getBaseItem().getEffectF() > 0 || this.getBaseItem().getEffectM() > 0) { + int nextEffectM = 0; + int nextEffectF = 0; + + if (objects != null && objects.length == 2) { + if (objects[0] instanceof RoomTile && objects[1] instanceof RoomTile) { + RoomTile goalTile = (RoomTile) objects[0]; + HabboItem topItem = room.getTopItemAt(goalTile.x, goalTile.y, (objects[0] != objects[1]) ? this : null); + + if (topItem != null && (topItem.getBaseItem().getEffectM() == this.getBaseItem().getEffectM() || topItem.getBaseItem().getEffectF() == this.getBaseItem().getEffectF())) { + return; + } + + if (topItem != null) { + nextEffectM = topItem.getBaseItem().getEffectM(); + nextEffectF = topItem.getBaseItem().getEffectF(); + } + } + } + + if (roomUnit.getRoomUnitType().equals(RoomUnitType.USER)) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + + if (habbo.getHabboInfo().getGender().equals(HabboGender.M) && this.getBaseItem().getEffectM() > 0) { + room.giveEffect(habbo, nextEffectM, -1); + return; + } + + if (habbo.getHabboInfo().getGender().equals(HabboGender.F) && this.getBaseItem().getEffectF() > 0) { + room.giveEffect(habbo, nextEffectF, -1); + } + } + } else if (roomUnit.getRoomUnitType().equals(RoomUnitType.BOT)) { + Bot bot = room.getBot(roomUnit); + + if (bot != null) { + if (bot.getGender().equals(HabboGender.M) && this.getBaseItem().getEffectM() > 0) { + room.giveEffect(roomUnit, nextEffectM, -1); + return; + } + + if (bot.getGender().equals(HabboGender.F) && this.getBaseItem().getEffectF() > 0) { + room.giveEffect(roomUnit, nextEffectF, -1); + } + } + } + } + } + } + } + + public boolean canToggle(Habbo habbo, Room room) { + if (room.hasRights(habbo)) return true; + + if (!habbo.getHabboStats().isRentingSpace()) return false; + + HabboItem rentSpace = room.getHabboItem(habbo.getHabboStats().rentedItemId); + + return rentSpace != null && RoomLayout.squareInSquare(RoomLayout.getRectangle(rentSpace.getX(), rentSpace.getY(), rentSpace.getBaseItem().getWidth(), rentSpace.getBaseItem().getLength(), rentSpace.getRotation()), RoomLayout.getRectangle(this.getX(), this.getY(), this.getBaseItem().getWidth(), this.getBaseItem().getLength(), this.getRotation())); + + } + + @Override + public boolean allowWiredResetState() { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionDice.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionDice.java new file mode 100644 index 0000000..aa938ee --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionDice.java @@ -0,0 +1,89 @@ +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.RoomLayout; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.plugin.events.furniture.FurnitureDiceRolledEvent; +import com.eu.habbo.threading.runnables.RandomDiceNumber; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionDice extends HabboItem { + public InteractionDice(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + public InteractionDice(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + + if (client != null) { + if (RoomLayout.tilesAdjecent(room.getLayout().getTile(this.getX(), this.getY()), client.getHabbo().getRoomUnit().getCurrentLocation())) { + if (!this.getExtradata().equalsIgnoreCase("-1")) { + FurnitureDiceRolledEvent event = (FurnitureDiceRolledEvent) Emulator.getPluginManager().fireEvent(new FurnitureDiceRolledEvent(this, client.getHabbo(), -1)); + + if (event.isCancelled()) + return; + + this.setExtradata("-1"); + room.updateItemState(this); + Emulator.getThreading().run(this); + + if (event.result > 0) { + Emulator.getThreading().run(new RandomDiceNumber(room, this, event.result), 1500); + } else { + Emulator.getThreading().run(new RandomDiceNumber(this, room, this.getBaseItem().getStateCount()), 1500); + } + } + } + } + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onPickUp(Room room) { + this.setExtradata("0"); + } + + @Override + public boolean allowWiredResetState() { + return false; + } + + @Override + public boolean isUsable() { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectGate.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectGate.java new file mode 100644 index 0000000..0e6ad5d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectGate.java @@ -0,0 +1,85 @@ +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.items.interactions.interfaces.ConditionalGate; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.threading.runnables.CloseGate; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class InteractionEffectGate extends InteractionDefault implements ConditionalGate { + + // List of Habboween costumes according to http://www.habboxwiki.com/Costumes + private static final List defaultAllowedEnables = new ArrayList<>(Arrays.asList( + 114, // Strong Arms + 115, // Ringmaster Costume + 116, // Fly Head + 117, // Executioner Hood + 118, // Evil Clown Paint + 135 // Marionette + )); + + public InteractionEffectGate(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionEffectGate(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + if (roomUnit == null || room == null) + return false; + + String customparams = this.getBaseItem().getCustomParams().trim(); + + if (!customparams.isEmpty()) { + return Arrays.asList(customparams.split(";")) + .contains(Integer.valueOf(roomUnit.getEffectId()).toString()); + } + + return defaultAllowedEnables.contains(roomUnit.getEffectId()); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + if (this.canWalkOn(roomUnit, room, objects)) { + this.setExtradata("1"); + room.updateItemState(this); + } + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + + Emulator.getThreading().run(new CloseGate(this, room), 1000); + } + + @Override + public void onRejected(RoomUnit roomUnit, Room room, Object[] objects) { + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectGiver.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectGiver.java new file mode 100644 index 0000000..99df17f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectGiver.java @@ -0,0 +1,53 @@ +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.RoomLayout; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionEffectGiver extends InteractionDefault { + public InteractionEffectGiver(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionEffectGiver(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + + if (RoomLayout.tilesAdjecent(client.getHabbo().getRoomUnit().getCurrentLocation(), room.getLayout().getTile(this.getX(), this.getY())) || + (client.getHabbo().getRoomUnit().getCurrentLocation().x == this.getX() && client.getHabbo().getRoomUnit().getCurrentLocation().y == this.getY())) { + this.handle(room, client.getHabbo().getRoomUnit()); + } + } + + protected void handle(Room room, RoomUnit roomUnit) { + if (this.getExtradata().isEmpty()) this.setExtradata("0"); + + if (!this.getExtradata().equals("0")) return; + + HabboItem instance = this; + room.giveEffect(roomUnit, this.getBaseItem().getRandomVendingItem(), -1); + + if (this.getBaseItem().getStateCount() > 1) { + this.setExtradata("1"); + room.updateItem(this); + + Emulator.getThreading().run(() -> { + InteractionEffectGiver.this.setExtradata("0"); + room.updateItem(instance); + }, 500); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectTile.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectTile.java new file mode 100644 index 0000000..ac10dcc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectTile.java @@ -0,0 +1,81 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUnitType; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionEffectTile extends InteractionPressurePlate { + public InteractionEffectTile(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionEffectTile(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + Emulator.getThreading().run(() -> updateState(room), 100); + + if(objects != null && objects.length > 0) { + WiredHandler.handle(WiredTriggerType.WALKS_OFF_FURNI, roomUnit, room, new Object[]{this}); + } + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalk(roomUnit, room, objects); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + if (roomUnit.getRoomUnitType() == RoomUnitType.USER) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + this.giveEffect(room, roomUnit, habbo.getHabboInfo().getGender()); + } + } else if (roomUnit.getRoomUnitType() == RoomUnitType.BOT) { + Bot bot = room.getBot(roomUnit); + + if (bot != null) { + this.giveEffect(room, roomUnit, bot.getGender()); + } + } + } + + private void giveEffect(Room room, RoomUnit roomUnit, HabboGender gender) { + if (gender.equals(HabboGender.M)) { + room.giveEffect(roomUnit, this.getBaseItem().getEffectM(), -1); + } else { + room.giveEffect(roomUnit, this.getBaseItem().getEffectF(), -1); + } + } + + @Override + public boolean isUsable() { + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectToggle.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectToggle.java new file mode 100644 index 0000000..feb6399 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectToggle.java @@ -0,0 +1,37 @@ +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.users.HabboGender; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionEffectToggle extends InteractionDefault { + public InteractionEffectToggle(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionEffectToggle(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (this.getExtradata().isEmpty()) { + this.setExtradata("0"); + } + + if (client != null) { + if (room.hasRights(client.getHabbo())) { + if (Integer.valueOf(this.getExtradata()) < this.getBaseItem().getStateCount() - 1) { + if ((client.getHabbo().getHabboInfo().getGender() == HabboGender.M && client.getHabbo().getRoomUnit().getEffectId() == this.getBaseItem().getEffectM()) || + (client.getHabbo().getHabboInfo().getGender() == HabboGender.F && client.getHabbo().getRoomUnit().getEffectId() == this.getBaseItem().getEffectF())) { + super.onClick(client, room, objects); + } + } + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectVendingMachine.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectVendingMachine.java new file mode 100644 index 0000000..c0d4227 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectVendingMachine.java @@ -0,0 +1,35 @@ +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.*; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.rooms.items.FloorItemUpdateComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import com.eu.habbo.threading.runnables.RoomUnitVendingMachineAction; +import com.eu.habbo.threading.runnables.RoomUnitWalkToLocation; +import com.eu.habbo.util.pathfinding.Rotation; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class InteractionEffectVendingMachine extends InteractionVendingMachine { + public InteractionEffectVendingMachine(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionEffectVendingMachine(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public void giveVendingMachineItem(Room room, RoomUnit unit) { + room.giveEffect(unit, this.getBaseItem().getRandomVendingItem(), 30); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectVendingMachineNoSides.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectVendingMachineNoSides.java new file mode 100644 index 0000000..799c211 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectVendingMachineNoSides.java @@ -0,0 +1,43 @@ +package com.eu.habbo.habbohotel.items.interactions; + +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.RoomUnit; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionEffectVendingMachineNoSides extends InteractionVendingMachine { + public InteractionEffectVendingMachineNoSides(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionEffectVendingMachineNoSides(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public void giveVendingMachineItem(Room room, RoomUnit unit) { + room.giveEffect(unit, this.getBaseItem().getRandomVendingItem(), 30); + } + + @Override + public THashSet getActivatorTiles(Room room) { + + THashSet tiles = new THashSet(); + for(int x = -1; x <= 1; x++) { + for(int y = -1; y <= 1; y++) { + RoomTile tile = room.getLayout().getTile((short)(this.getX() + x), (short)(this.getY() + y)); + if(tile != null) { + tiles.add(tile); + } + } + } + + return tiles; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionExternalImage.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionExternalImage.java new file mode 100644 index 0000000..b6a0682 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionExternalImage.java @@ -0,0 +1,50 @@ +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; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionExternalImage extends HabboItem { + public InteractionExternalImage(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionExternalImage(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + } + + //{"t":10000000, "u":"http://arcturus.pw/camera/", "m":"idk", "s":1, "w":"http://arcturus.pw/camera/image.png"} +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionFXBox.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionFXBox.java new file mode 100644 index 0000000..ca92ccf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionFXBox.java @@ -0,0 +1,67 @@ +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.users.HabboGender; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.users.inventory.EffectsComponent; +import com.eu.habbo.messages.outgoing.rooms.items.RemoveFloorItemComposer; +import com.eu.habbo.threading.runnables.QueryDeleteHabboItem; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFXBox extends InteractionDefault { + public InteractionFXBox(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + // this.setExtradata("0"); + } + + public InteractionFXBox(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + // this.setExtradata("0"); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (client != null && this.getUserId() == client.getHabbo().getHabboInfo().getId()) { + if(this.getExtradata().equals("1")) + return; + + int effectId = -1; + + if (client.getHabbo().getHabboInfo().getGender().equals(HabboGender.M)) { + if (this.getBaseItem().getEffectM() > 0) { + effectId = this.getBaseItem().getEffectM(); + } + } + + if (client.getHabbo().getHabboInfo().getGender().equals(HabboGender.F)) { + if (this.getBaseItem().getEffectF() > 0) { + effectId = this.getBaseItem().getEffectF(); + } + } + + if(effectId < 0) + return; + + if(client.getHabbo().getInventory().getEffectsComponent().ownsEffect(effectId)) + return; + + EffectsComponent.HabboEffect effect = client.getHabbo().getInventory().getEffectsComponent().createEffect(effectId, 0); + client.getHabbo().getInventory().getEffectsComponent().enableEffect(effectId); + + this.setExtradata("1"); + room.updateItemState(this); + room.removeHabboItem(this); + HabboItem item = this; + Emulator.getThreading().run(() -> { + new QueryDeleteHabboItem(item.getId()).run(); + room.sendComposer(new RemoveFloorItemComposer(item).compose()); + room.updateTile(room.getLayout().getTile(this.getX(), this.getY())); + }, 500); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionFireworks.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionFireworks.java new file mode 100644 index 0000000..af3f799 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionFireworks.java @@ -0,0 +1,138 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +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.RoomLayout; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.threading.runnables.RoomUnitWalkToLocation; +import lombok.extern.slf4j.Slf4j; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +public class InteractionFireworks extends InteractionDefault { + private static final String STATE_EMPTY = "0"; // Not used since the removal of pixels + private static final String STATE_CHARGED = "1"; + private static final String STATE_EXPLOSION = "2"; + + public InteractionFireworks(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionFireworks(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + /** + * Checked in Habbo on 2021-01-03 + * - Fireworks should be charged to be able to detonate them + * - Habbos with Rights can detonate fireworks from anywhere in a room + * - Habbos without rights have to walk to an adjecent tile to be able to detonate (see Interaction Switch) + * - Wired can always detonate fireworks + */ + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (room == null) + return; + + // Wireds can always detonate fireworks if charged + if (objects.length >= 2 && objects[1] instanceof WiredEffectType && objects[1] == WiredEffectType.TOGGLE_STATE) { + if (this.getExtradata().equalsIgnoreCase(STATE_CHARGED)) { + super.onClick(client, room, objects); + + if (this.getExtradata().equalsIgnoreCase(STATE_EXPLOSION)) { + this.reCharge(room); + } + } + + return; + } + + if (client == null) + return; + + // Habbos without rights have to walk to an adjecent tile to be able to detonate the fireworks + if (!this.canToggle(client.getHabbo(), room)) { + RoomTile closestTile = null; + for (RoomTile tile : room.getLayout().getTilesAround(room.getLayout().getTile(this.getX(), this.getY()))) { + if (tile.isWalkable() && (closestTile == null || closestTile.distance(client.getHabbo().getRoomUnit().getCurrentLocation()) > tile.distance(client.getHabbo().getRoomUnit().getCurrentLocation()))) { + closestTile = tile; + } + } + + if (closestTile != null && !closestTile.equals(client.getHabbo().getRoomUnit().getCurrentLocation())) { + List onSuccess = new ArrayList<>(); + onSuccess.add(() -> { + try { + this.onClick(client, room, objects); + } catch (Exception e) { + e.printStackTrace(); + } + }); + + client.getHabbo().getRoomUnit().setGoalLocation(closestTile); + Emulator.getThreading().run(new RoomUnitWalkToLocation(client.getHabbo().getRoomUnit(), closestTile, room, onSuccess, new ArrayList<>())); + } + } + + if (this.getExtradata().equalsIgnoreCase(STATE_CHARGED)) { + super.onClick(client, room, objects); + + if (this.getExtradata().equalsIgnoreCase(STATE_EXPLOSION)) + { + this.reCharge(room); + AchievementManager.progressAchievement(client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("FireworksCharger")); + } + } + } + + @Override + public boolean allowWiredResetState() { + return false; + } + + @Override + public void onPlace(Room room) { + super.onPlace(room); + this.setExtradata(STATE_CHARGED); + } + + @Override + public boolean canToggle(Habbo habbo, Room room) { + return room.hasRights(habbo) || RoomLayout.tilesAdjecent( + room.getLayout().getTile(this.getX(), this.getY()), + habbo.getRoomUnit().getCurrentLocation() + ); + } + + private void reCharge(Room room) { + // Default = 5000, Nuclear Firework should have 10000 in its custom params according to Habbo + int explodeDuration = 5000; + if (!this.getBaseItem().getCustomParams().isEmpty()) { + try { + explodeDuration = Integer.parseInt(this.getBaseItem().getCustomParams()); + } catch (NumberFormatException e) { + log.error("Incorrect customparams (" + this.getBaseItem().getCustomParams() + ") for base item ID (" + this.getBaseItem().getId() + ") of type (" + this.getBaseItem().getName() + ")"); + } + } + + Emulator.getThreading().run(() -> { + this.setExtradata(STATE_CHARGED); + this.needsUpdate(true); + room.updateItemState(this); + }, explodeDuration); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGate.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGate.java new file mode 100644 index 0000000..f7ceb0e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGate.java @@ -0,0 +1,87 @@ +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.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionGate extends HabboItem { + public InteractionGate(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionGate(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + public boolean isWalkable() { + return this.getExtradata().equals("1"); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + boolean executedByWired = (objects.length >= 2 && objects[1] instanceof WiredEffectType && objects[1] == WiredEffectType.TOGGLE_STATE); + + if (client != null && !room.hasRights(client.getHabbo()) && !executedByWired) + return; + + // If a Habbo is standing on a tile occupied by the gate, the gate shouldn't open/close + for (RoomTile tile : room.getLayout().getTilesAt(room.getLayout().getTile(this.getX(), this.getY()), this.getBaseItem().getWidth(), this.getBaseItem().getLength(), this.getRotation())) + if (room.hasHabbosAt(tile.x, tile.y)) + return; + + // Gate closed = 0, open = 1 + if (this.getExtradata().length() == 0) + this.setExtradata("0"); + + this.setExtradata((Integer.parseInt(this.getExtradata()) + 1) % 2 + ""); + room.updateTile(room.getLayout().getTile(this.getX(), this.getY())); + this.needsUpdate(true); + room.updateItemState(this); + + super.onClick(client, room, new Object[]{"TOGGLE_OVERRIDE"}); + } + + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + } + + @Override + public boolean allowWiredResetState() { + return true; + } + + @Override + public boolean isUsable() { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGift.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGift.java new file mode 100644 index 0000000..5aa15da --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGift.java @@ -0,0 +1,139 @@ +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.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class InteractionGift extends HabboItem { + public boolean explode = false; + private int[] itemId; + private int colorId = 0; + private int ribbonId = 0; + private boolean showSender = false; + private String message = ""; + private String sender = ""; + private String look = ""; + + public InteractionGift(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + + try { + this.loadData(); + } catch (Exception e) { + log.warn("Incorrect extradata for gift with ID " + this.getId()); + } + } + + public InteractionGift(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + + try { + this.loadData(); + } catch (Exception e) { + log.warn("Incorrect extradata for gift with ID " + this.getId()); + } + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + //serverMessage.appendInt(this.colorId * 1000 + this.ribbonId); + serverMessage.appendInt(1); + serverMessage.appendInt(6); + serverMessage.appendString("EXTRA_PARAM"); + serverMessage.appendString(""); + serverMessage.appendString("MESSAGE"); + serverMessage.appendString(this.message); + serverMessage.appendString("PURCHASER_NAME"); + serverMessage.appendString(this.showSender ? this.sender : ""); + serverMessage.appendString("PURCHASER_FIGURE"); + serverMessage.appendString(this.showSender ? this.look : ""); + serverMessage.appendString("PRODUCT_CODE"); + serverMessage.appendString(""); //this.gift.getItemId() + serverMessage.appendString("state"); + serverMessage.appendString(this.explode ? "1" : "0"); + + super.serializeExtradata(serverMessage); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + private void loadData() throws NumberFormatException { + String[] data = null; + + if (this.getExtradata().contains("\t")) + data = this.getExtradata().split("\t"); + + if (data != null && data.length >= 5) { + int count = Integer.valueOf(data[0]); + + this.itemId = new int[count]; + + for (int i = 0; i < count; i++) { + this.itemId[i] = Integer.valueOf(data[i + 1]); + } + + this.colorId = Integer.valueOf(data[count + 1]); + this.ribbonId = Integer.valueOf(data[count + 2]); + this.showSender = data[count + 3].equalsIgnoreCase("1"); + this.message = data[count + 4]; + + if (data.length - count >= 7 && this.showSender) { + this.sender = data[count + 5]; + this.look = data[count + 6]; + } + } else { + this.itemId = new int[0]; + this.colorId = 0; + this.ribbonId = 0; + this.showSender = false; + this.message = "Please delete this present. Thanks!"; + } + } + + public int getColorId() { + return this.colorId; + } + + public int getRibbonId() { + return this.ribbonId; + } + + public THashSet loadItems() { + THashSet items = new THashSet<>(); + for (int anItemId : this.itemId) { + if (anItemId == 0) + continue; + + items.add(Emulator.getGameEnvironment().getItemManager().loadHabboItem(anItemId)); + } + + return items; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGroupEffectTile.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGroupEffectTile.java new file mode 100644 index 0000000..721f252 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGroupEffectTile.java @@ -0,0 +1,21 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionGroupEffectTile extends InteractionEffectTile { + public InteractionGroupEffectTile(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionGroupEffectTile(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean requiresAllTilesOccupied() { + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGroupPressurePlate.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGroupPressurePlate.java new file mode 100644 index 0000000..6aae5d3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGroupPressurePlate.java @@ -0,0 +1,21 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionGroupPressurePlate extends InteractionPressurePlate { + public InteractionGroupPressurePlate(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionGroupPressurePlate(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean requiresAllTilesOccupied() { + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGuildFurni.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGuildFurni.java new file mode 100644 index 0000000..b4374f8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGuildFurni.java @@ -0,0 +1,85 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionGuildFurni extends InteractionDefault { + private int guildId; + private static final THashSet ROTATION_8_ITEMS = new THashSet() { + { + this.add("gld_wall_tall"); + } + }; + + public InteractionGuildFurni(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.guildId = set.getInt("guild_id"); + } + + public InteractionGuildFurni(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.guildId = 0; + } + + @Override + public int getMaximumRotations() { + if(ROTATION_8_ITEMS.stream().anyMatch(x -> x.equalsIgnoreCase(this.getBaseItem().getName()))) { + return 8; + } + return this.getBaseItem().getRotations(); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(this.guildId); + + if (guild != null) { + serverMessage.appendInt(2 + (this.isLimited() ? 256 : 0)); + serverMessage.appendInt(5); + serverMessage.appendString(this.getExtradata()); + serverMessage.appendString(guild.getId() + ""); + serverMessage.appendString(guild.getBadge()); + serverMessage.appendString(Emulator.getGameEnvironment().getGuildManager().getSymbolColor(guild.getColorOne()).valueA); + serverMessage.appendString(Emulator.getGameEnvironment().getGuildManager().getBackgroundColor(guild.getColorTwo()).valueA); + } else { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + } + + if (this.isLimited()) { + serverMessage.appendInt(this.getLimitedSells()); + serverMessage.appendInt(this.getLimitedStack()); + } + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return this.getBaseItem().allowWalk(); + } + + public int getGuildId() { + return this.guildId; + } + + public void setGuildId(int guildId) { + this.guildId = guildId; + } + + @Override + public boolean allowWiredResetState() { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGuildGate.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGuildGate.java new file mode 100644 index 0000000..4129021 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGuildGate.java @@ -0,0 +1,70 @@ +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.items.interactions.interfaces.ConditionalGate; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.threading.runnables.CloseGate; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionGuildGate extends InteractionGuildFurni implements ConditionalGate { + public InteractionGuildGate(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionGuildGate(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + if (roomUnit == null) + return false; + + Habbo habbo = room.getHabbo(roomUnit); + + return habbo != null && (habbo.getHabboStats().hasGuild(super.getGuildId()) || habbo.hasPermission(Permission.ACC_GUILDGATE)); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + if (this.canWalkOn(roomUnit, room, objects)) { + this.setExtradata("1"); + room.updateItemState(this); + } + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + + Emulator.getThreading().run(new CloseGate(this, room), 500); + } + + @Override + public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + this.setExtradata("0"); + room.updateItemState(this); + } + + @Override + public void onRejected(RoomUnit roomUnit, Room room, Object[] objects) { + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGymEquipment.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGymEquipment.java new file mode 100644 index 0000000..a4c1441 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionGymEquipment.java @@ -0,0 +1,158 @@ +package com.eu.habbo.habbohotel.items.interactions; + +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.ICycleable; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionGymEquipment extends InteractionEffectTile implements ICycleable { + private int startTime = 0; + private int roomUnitId = -1; + + public InteractionGymEquipment(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionGymEquipment(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return this.roomUnitId == -1 && super.canWalkOn(roomUnit, room, objects) && (roomUnit.getRoomUnitType().equals(RoomUnitType.USER) || roomUnit.getRoomUnitType().equals(RoomUnitType.BOT)); + } + + @Override + public boolean isWalkable() { + return this.roomUnitId == -1; + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + if (this.forceRotation()) { + roomUnit.setRotation(RoomUserRotation.fromValue(this.getRotation())); + roomUnit.canRotate = false; + } + this.roomUnitId = roomUnit.getId(); + + if (roomUnit.getRoomUnitType() == RoomUnitType.USER) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + this.startTime = Emulator.getIntUnixTimestamp(); + } + } + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + room.giveEffect(roomUnit, 0, -1); + + if (this.forceRotation()) { + roomUnit.canRotate = true; + } + + this.reset(room); + } + + public String achievementName() { + return Emulator.getConfig().getValue("hotel.furni.gym.achievement." + this.getBaseItem().getName(), ""); + } + + public boolean forceRotation() { + return Emulator.getConfig().getBoolean("hotel.furni.gym.forcerot." + this.getBaseItem().getName(), true); + } + + @Override + public void cycle(Room room) { + if (this.roomUnitId != -1) { + Habbo habbo = room.getHabboByRoomUnitId(this.roomUnitId); + + if (habbo != null) { + int timestamp = Emulator.getIntUnixTimestamp(); + if (timestamp - this.startTime >= 120) { + String achievement = this.achievementName(); + + if (!achievement.isEmpty()) { + AchievementManager.progressAchievement(habbo.getHabboInfo().getId(), Emulator.getGameEnvironment().getAchievementManager().getAchievement(achievement)); + } + + this.startTime = timestamp; + } + } + } + } + + @Override + public void setRotation(int rotation) { + super.setRotation(rotation); + + if (this.forceRotation() && this.roomUnitId != -1) { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room != null) { + RoomUnit roomUnit = this.getCurrentRoomUnit(room); + + if (roomUnit != null) { + roomUnit.setRotation(RoomUserRotation.fromValue(rotation)); + room.updateRoomUnit(roomUnit); + } + } + } + } + + @Override + public void onPickUp(Room room) { + super.onPickUp(room); + + if (this.roomUnitId != -1) { + this.setEffect(room, 0); + } + + this.reset(room); + } + + @Override + public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + super.onMove(room, oldLocation, newLocation); + if (!oldLocation.equals(newLocation)) { + this.setEffect(room, 0); + this.reset(room); + } + } + + private void setEffect(Room room, int effectId) { + if (this.roomUnitId == -1) return; + + room.giveEffect(this.getCurrentRoomUnit(room), effectId, -1); + } + + private void reset(Room room) { + this.roomUnitId = -1; + this.startTime = 0; + this.setExtradata("0"); + room.updateItem(this); + } + + private RoomUnit getCurrentRoomUnit(Room room) { + Habbo habbo = room.getHabboByRoomUnitId(this.roomUnitId); + if (habbo != null) { + return habbo.getRoomUnit(); + } else { + Bot bot = room.getBotByRoomUnitId(this.roomUnitId); + if (bot != null) { + return bot.getRoomUnit(); + } + } + + return null; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHabboClubGate.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHabboClubGate.java new file mode 100644 index 0000000..f356d4d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHabboClubGate.java @@ -0,0 +1,76 @@ +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.items.interactions.interfaces.ConditionalGate; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.generic.alerts.CustomNotificationComposer; +import com.eu.habbo.threading.runnables.CloseGate; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionHabboClubGate extends InteractionDefault implements ConditionalGate { + public InteractionHabboClubGate(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionHabboClubGate(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + Habbo habbo = room.getHabbo(roomUnit); + + return habbo != null && habbo.getHabboStats().hasActiveClub(); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + if (this.canWalkOn(roomUnit, room, objects)) { + this.setExtradata("1"); + room.updateItemState(this); + } + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (client != null) { + if (this.canWalkOn(client.getHabbo().getRoomUnit(), room, null)) { + super.onClick(client, room, objects); + } else { + client.sendResponse(new CustomNotificationComposer(CustomNotificationComposer.GATE_NO_HC)); + } + } + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + + Emulator.getThreading().run(new CloseGate(this, room), 1000); + } + + @Override + public void onRejected(RoomUnit roomUnit, Room room, Object[] objects) { + if (roomUnit == null || room == null) + return; + + room.getHabbo(roomUnit).getClient().sendResponse( + new CustomNotificationComposer(CustomNotificationComposer.GATE_NO_HC) + ); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHabboClubHopper.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHabboClubHopper.java new file mode 100644 index 0000000..1fb38ff --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHabboClubHopper.java @@ -0,0 +1,34 @@ +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.RoomTile; +import com.eu.habbo.messages.outgoing.generic.alerts.CustomNotificationComposer; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionHabboClubHopper extends InteractionHopper { + public InteractionHabboClubHopper(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionHabboClubHopper(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (client.getHabbo().getHabboStats().hasActiveClub()) { + super.onClick(client, room, objects); + } else { + client.sendResponse(new CustomNotificationComposer(CustomNotificationComposer.HOPPER_NO_HC)); + } + } + + @Override + protected boolean canUseTeleport(GameClient client, RoomTile front, Room room) { + return super.canUseTeleport(client, front, room) && client.getHabbo().getHabboStats().hasActiveClub(); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHabboClubTeleportTile.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHabboClubTeleportTile.java new file mode 100644 index 0000000..9d1bfb1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHabboClubTeleportTile.java @@ -0,0 +1,36 @@ +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; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionHabboClubTeleportTile extends InteractionTeleportTile { + public InteractionHabboClubTeleportTile(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionHabboClubTeleportTile(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + return habbo.getHabboStats().hasActiveClub(); + } + + return false; + } + + @Override + public boolean canUseTeleport(GameClient client, Room room) { + return super.canUseTeleport(client, room) && client.getHabbo().getHabboStats().hasActiveClub(); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHanditem.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHanditem.java new file mode 100644 index 0000000..7782736 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHanditem.java @@ -0,0 +1,51 @@ +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.RoomLayout; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionHanditem extends InteractionDefault { + public InteractionHanditem(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionHanditem(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + + if (RoomLayout.tilesAdjecent(client.getHabbo().getRoomUnit().getCurrentLocation(), room.getLayout().getTile(this.getX(), this.getY())) || + (client.getHabbo().getRoomUnit().getCurrentLocation().x == this.getX() && client.getHabbo().getRoomUnit().getCurrentLocation().y == this.getY())) { + this.handle(room, client.getHabbo().getRoomUnit()); + } + } + + protected void handle(Room room, RoomUnit roomUnit) { + if (this.getExtradata().isEmpty()) this.setExtradata("0"); + + if (!this.getExtradata().equals("0")) return; + + HabboItem instance = this; + room.giveHandItem(roomUnit, this.getBaseItem().getRandomVendingItem()); + + if (this.getBaseItem().getStateCount() > 1) { + this.setExtradata("1"); + room.updateItem(this); + + Emulator.getThreading().run(() -> { + InteractionHanditem.this.setExtradata("0"); + room.updateItem(instance); + }, 500); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHanditemTile.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHanditemTile.java new file mode 100644 index 0000000..786e369 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHanditemTile.java @@ -0,0 +1,29 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionHanditemTile extends InteractionHanditem { + public InteractionHanditemTile(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionHanditemTile(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + InteractionHanditemTile instance = this; + Emulator.getThreading().run(() -> { + if (roomUnit.getCurrentLocation().x == instance.getX() && roomUnit.getCurrentLocation().y == instance.getY()) { + instance.handle(room, roomUnit); + } + }, 3000); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHopper.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHopper.java new file mode 100644 index 0000000..fa0d257 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionHopper.java @@ -0,0 +1,103 @@ +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.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.threading.runnables.hopper.HopperActionOne; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionHopper extends HabboItem { + public InteractionHopper(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionHopper(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + + if (room != null) { + RoomTile loc = HabboItem.getSquareInFront(room.getLayout(), this); + if (loc != null) { + if (this.canUseTeleport(client, loc, room)) { + client.getHabbo().getRoomUnit().isTeleporting = true; + this.setExtradata("1"); + room.updateItemState(this); + + Emulator.getThreading().run(new HopperActionOne(this, room, client), 500); + } else { + client.getHabbo().getRoomUnit().setGoalLocation(loc); + } + } + } + } + + @Override + public void onPickUp(Room room) { + this.setExtradata("0"); + } + + @Override + public void run() { + if (!this.getExtradata().equals("0")) { + this.setExtradata("0"); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room != null) { + room.updateItemState(this); + } + } + super.run(); + } + + protected boolean canUseTeleport(GameClient client, RoomTile front, Room room) { + if (client.getHabbo().getRoomUnit().getX() != front.x) + return false; + + if (client.getHabbo().getRoomUnit().getY() != front.y) + return false; + + if (client.getHabbo().getRoomUnit().isTeleporting) + return false; + + if (!room.getHabbosAt(this.getX(), this.getY()).isEmpty()) + return false; + + return this.getExtradata().equals("0"); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionInformationTerminal.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionInformationTerminal.java new file mode 100644 index 0000000..e4b3a79 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionInformationTerminal.java @@ -0,0 +1,37 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.habboway.nux.NuxAlertComposer; +import gnu.trove.map.hash.THashMap; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionInformationTerminal extends InteractionCustomValues { + public static final THashMap defaultValues = new THashMap() { + { + this.put("internalLink", "habbopages/chat/commands"); + } + }; + + public InteractionInformationTerminal(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, defaultValues); + } + + public InteractionInformationTerminal(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, defaultValues); + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalk(roomUnit, room, objects); + + Habbo habbo = room.getHabbo(roomUnit); + if (habbo != null && this.values.containsKey("internalLink")) { + habbo.getClient().sendResponse(new NuxAlertComposer(this.values.get("internalLink"))); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionJukeBox.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionJukeBox.java new file mode 100644 index 0000000..bc5744c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionJukeBox.java @@ -0,0 +1,75 @@ +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; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionJukeBox extends HabboItem { + public InteractionJukeBox(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionJukeBox(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + + if (client != null && objects.length == 1) { + if ((Integer) objects[0] == 0) { + if (room.getTraxManager().isPlaying()) { + room.getTraxManager().stop(); + } else { + room.getTraxManager().play(0, client.getHabbo()); + } + } + } + } + + @Override + public void onPickUp(Room room) { + super.onPickUp(room); + this.setExtradata("0"); + room.getTraxManager().removeTraxOnRoom(this); + } + + @Override + public void onPlace(Room room) { + super.onPlace(room); + room.getTraxManager().addTraxOnRoom(this); + if (room.getTraxManager().isPlaying()) { + this.setExtradata("1"); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionLoveLock.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionLoveLock.java new file mode 100644 index 0000000..9b207ca --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionLoveLock.java @@ -0,0 +1,122 @@ +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.RoomLayout; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.items.lovelock.LoveLockFurniStartComposer; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Calendar; + +public class InteractionLoveLock extends HabboItem { + public int userOneId; + public int userTwoId; + + public InteractionLoveLock(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionLoveLock(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt(2 + (this.isLimited() ? 256 : 0)); + serverMessage.appendInt(6); + + String[] data = this.getExtradata().split("\t"); + + if (data.length == 6) { + serverMessage.appendString("1"); + serverMessage.appendString(data[1]); + serverMessage.appendString(data[2]); + serverMessage.appendString(data[3]); + serverMessage.appendString(data[4]); + serverMessage.appendString(data[5]); + } else { + serverMessage.appendString("0"); + serverMessage.appendString(""); + serverMessage.appendString(""); + serverMessage.appendString(""); + serverMessage.appendString(""); + serverMessage.appendString(""); + } + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (this.getExtradata().contains("\t")) + return; + + if (client == null) + return; + + if (RoomLayout.tilesAdjecent(client.getHabbo().getRoomUnit().getCurrentLocation(), room.getLayout().getTile(this.getX(), this.getY()))) { + if (this.userOneId == 0) { + this.userOneId = client.getHabbo().getHabboInfo().getId(); + client.sendResponse(new LoveLockFurniStartComposer(this)); + } else { + if (this.userOneId != client.getHabbo().getHabboInfo().getId()) { + Habbo habbo = room.getHabbo(this.userOneId); + + if (habbo != null) { + this.userTwoId = client.getHabbo().getHabboInfo().getId(); + client.sendResponse(new LoveLockFurniStartComposer(this)); + } + } + } + } + } + + public boolean lock(Habbo userOne, Habbo userTwo, Room room) { + RoomTile tile = room.getLayout().getTile(this.getX(), this.getY()); + if (RoomLayout.tilesAdjecent(userOne.getRoomUnit().getCurrentLocation(), tile) && RoomLayout.tilesAdjecent(userTwo.getRoomUnit().getCurrentLocation(), tile)) { + String data = "1"; + data += "\t"; + data += userOne.getHabboInfo().getUsername(); + data += "\t"; + data += userTwo.getHabboInfo().getUsername(); + data += "\t"; + data += userOne.getHabboInfo().getLook(); + data += "\t"; + data += userTwo.getHabboInfo().getLook(); + data += "\t"; + data += Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + "-" + (Calendar.getInstance().get(Calendar.MONTH) + 1) + "-" + Calendar.getInstance().get(Calendar.YEAR); + + this.setExtradata(data); + this.needsUpdate(true); + Emulator.getThreading().run(this); + room.updateItem(this); + + return true; + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMannequin.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMannequin.java new file mode 100644 index 0000000..f9c304a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMannequin.java @@ -0,0 +1,120 @@ +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.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.users.clothingvalidation.ClothingValidationManager; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer; +import com.eu.habbo.messages.outgoing.users.UserDataComposer; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionMannequin extends HabboItem { + public InteractionMannequin(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionMannequin(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public int getMaximumRotations() { + return 8; + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt(1 + (this.isLimited() ? 256 : 0)); + serverMessage.appendInt(3); + if (this.getExtradata().split(":").length >= 2) { + String[] data = this.getExtradata().split(":"); + serverMessage.appendString("GENDER"); + serverMessage.appendString(data[0].toLowerCase()); + serverMessage.appendString("FIGURE"); + serverMessage.appendString(data[1]); + serverMessage.appendString("OUTFIT_NAME"); + serverMessage.appendString((data.length >= 3 ? data[2] : "")); + } else { + serverMessage.appendString("GENDER"); + serverMessage.appendString("m"); + serverMessage.appendString("FIGURE"); + serverMessage.appendString(""); + serverMessage.appendString("OUTFIT_NAME"); + serverMessage.appendString("My Look"); + this.setExtradata("m: :My look"); + this.needsUpdate(true); + Emulator.getThreading().run(this); + } + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + String[] data = this.getExtradata().split(":"); + + if(data.length < 2) + return; + + String gender = data[0]; + String figure = data[1]; + + if (gender.isEmpty() || figure.isEmpty() || (!gender.equalsIgnoreCase("m") && !gender.equalsIgnoreCase("f")) || !client.getHabbo().getHabboInfo().getGender().name().equalsIgnoreCase(gender)) + return; + + String newFigure = ""; + + for (String playerFigurePart : client.getHabbo().getHabboInfo().getLook().split("\\.")) { + if (!playerFigurePart.startsWith("ch") && !playerFigurePart.startsWith("lg")) + newFigure += playerFigurePart + "."; + } + + String newFigureParts = figure; + + for (String newFigurePart : newFigureParts.split("\\.")) { + if (newFigurePart.startsWith("hd")) + newFigureParts = newFigureParts.replace(newFigurePart, ""); + } + + if (newFigureParts.equals("")) return; + + String newLook = newFigure + newFigureParts; + + if (newLook.length() > 512) + return; + + client.getHabbo().getHabboInfo().setLook(ClothingValidationManager.VALIDATE_ON_MANNEQUIN ? ClothingValidationManager.validateLook(client.getHabbo(), newLook, client.getHabbo().getHabboInfo().getGender().name()) : newLook); + room.sendComposer(new RoomUserDataComposer(client.getHabbo()).compose()); + client.sendResponse(new UserDataComposer(client.getHabbo())); + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMonsterCrackable.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMonsterCrackable.java new file mode 100644 index 0000000..51e47e6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMonsterCrackable.java @@ -0,0 +1,69 @@ +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.ICycleable; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionMonsterCrackable extends InteractionCrackable implements ICycleable { + private int lastHealthChange = 0; + private boolean respawn = false; + + public InteractionMonsterCrackable(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionMonsterCrackable(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void cycle(Room room) { + if (this.ticks > 0 && Emulator.getIntUnixTimestamp() - this.lastHealthChange > 30) { + this.lastHealthChange = Emulator.getIntUnixTimestamp(); + this.ticks--; + room.updateItem(this); + } + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (room.isPublicRoom()) this.respawn = true; + + super.onClick(client, room, objects); + } + + @Override + public boolean resetable() { + return this.respawn; + } + + @Override + public void reset(Room room) { + RoomTile tile = room.getRandomWalkableTile(); + this.setX(tile.x); + this.setY(tile.y); + this.setZ(room.getStackHeight(tile.x, tile.y, false)); + super.reset(room); + } + + @Override + public boolean allowAnyone() { + return this.respawn; + } + + @Override + public boolean isUsable() { + return true; + } + + @Override + protected boolean placeInRoom() { + return this.respawn; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMoodLight.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMoodLight.java new file mode 100644 index 0000000..ee30d1e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMoodLight.java @@ -0,0 +1,66 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomMoodlightData; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionMoodLight extends HabboItem { + public InteractionMoodLight(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionMoodLight(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onPlace(Room room) { + if (room != null) { + for (RoomMoodlightData data : room.getMoodlightData().valueCollection()) { + if (data.isEnabled()) { + this.setExtradata(data.toString()); + this.needsUpdate(true); + room.updateItem(this); + Emulator.getThreading().run(this); + } + } + } + + super.onPlace(room); + } + + @Override + public boolean isUsable() { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMultiHeight.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMultiHeight.java new file mode 100644 index 0000000..47cba01 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMultiHeight.java @@ -0,0 +1,163 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class InteractionMultiHeight extends HabboItem { + public InteractionMultiHeight(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + public InteractionMultiHeight(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return this.getBaseItem().allowWalk(); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + + if (client != null) { + if (!room.hasRights(client.getHabbo()) && !(objects.length >= 2 && objects[1] instanceof WiredEffectType && objects[1] == WiredEffectType.TOGGLE_STATE)) + return; + } + + if (objects.length > 0) { + if (objects[0] instanceof Integer && room != null) { + HabboItem topItem = room.getTopItemAt(this.getX(), this.getY()); + if (topItem != null && !topItem.equals(this)) { // multiheight items cannot change height even if there is a stackable item on top - no items allowed on top + return; + } + + this.needsUpdate(true); + + if (this.getExtradata().length() == 0) + this.setExtradata("0"); + + if (this.getBaseItem().getMultiHeights().length > 0) { + this.setExtradata("" + (Integer.parseInt(this.getExtradata()) + 1) % (this.getBaseItem().getMultiHeights().length)); + this.needsUpdate(true); + room.updateTiles(room.getLayout().getTilesAt(room.getLayout().getTile(this.getX(), this.getY()), this.getBaseItem().getWidth(), this.getBaseItem().getLength(), this.getRotation())); + room.updateItemState(this); + //room.sendComposer(new UpdateStackHeightComposer(this.getX(), this.getY(), this.getBaseItem().getMultiHeights()[Integer.valueOf(this.getExtradata())] * 256.0D).compose()); + } + } + } + } + + public void updateUnitsOnItem(Room room) { + THashSet occupiedTiles = room.getLayout().getTilesAt(room.getLayout().getTile(this.getX(), this.getY()), this.getBaseItem().getWidth(), this.getBaseItem().getLength(), this.getRotation()); + + for(RoomTile tile : occupiedTiles) { + Collection unitsOnItem = room.getRoomUnitsAt(room.getLayout().getTile(tile.x, tile.y)); + + THashSet updatedUnits = new THashSet<>(); + for (RoomUnit unit : unitsOnItem) { + if (unit.hasStatus(RoomUnitStatus.MOVE) && unit.getGoal() != tile) + continue; + + if (this.getBaseItem().allowSit() || unit.hasStatus(RoomUnitStatus.SIT)) { + unit.sitUpdate = true; + unit.statusUpdate(true); + } else { + unit.setZ(unit.getCurrentLocation().getStackHeight()); + unit.setPreviousLocationZ(unit.getZ()); + unit.statusUpdate(true); + } + } + } + + //room.sendComposer(new RoomUserStatusComposer(updatedUnits, true).compose()); + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) { + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + if (roomUnit != null) { + if (this.getBaseItem().getEffectF() > 0 || this.getBaseItem().getEffectM() > 0) { + if (roomUnit.getRoomUnitType().equals(RoomUnitType.USER)) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + if (habbo.getHabboInfo().getGender().equals(HabboGender.M) && this.getBaseItem().getEffectM() > 0 && habbo.getRoomUnit().getEffectId() != this.getBaseItem().getEffectM()) { + room.giveEffect(habbo, this.getBaseItem().getEffectM(), -1); + return; + } + + if (habbo.getHabboInfo().getGender().equals(HabboGender.F) && this.getBaseItem().getEffectF() > 0 && habbo.getRoomUnit().getEffectId() != this.getBaseItem().getEffectF()) { + room.giveEffect(habbo, this.getBaseItem().getEffectF(), -1); + } + } + } + } + } + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + + if (roomUnit != null) { + if (this.getBaseItem().getEffectF() > 0 || this.getBaseItem().getEffectM() > 0) { + if (roomUnit.getRoomUnitType().equals(RoomUnitType.USER)) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + if (habbo.getHabboInfo().getGender().equals(HabboGender.M) && this.getBaseItem().getEffectM() > 0) { + room.giveEffect(habbo, 0, -1); + return; + } + + if (habbo.getHabboInfo().getGender().equals(HabboGender.F) && this.getBaseItem().getEffectF() > 0) { + room.giveEffect(habbo, 0, -1); + } + } + } + } + } + } + + @Override + public boolean allowWiredResetState() { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMusicDisc.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMusicDisc.java new file mode 100644 index 0000000..5009359 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMusicDisc.java @@ -0,0 +1,83 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import lombok.extern.slf4j.Slf4j; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class InteractionMusicDisc extends HabboItem { + private int songId; + public InteractionMusicDisc(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + + String[] stuff = this.getExtradata().split("\n"); + + if (stuff.length >= 7 && !stuff[6].isEmpty()) { + try { + this.songId = Integer.valueOf(stuff[6]); + } catch (Exception e) { + log.error("Warning: Item " + this.getId() + " has an invalid song id set for its music disk!"); + } + } + } + + public InteractionMusicDisc(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + + String[] stuff = this.getExtradata().split("\n"); + + if (stuff.length >= 7 && !stuff[6].isEmpty()) { + try { + this.songId = Integer.valueOf(stuff[6]); + } catch (Exception e) { + log.error("Warning: Item " + this.getId() + " has an invalid song id set for its music disk!"); + } + } + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + public int getSongId() { + return this.songId; + } + + @Override + public void onPlace(Room room) { + super.onPlace(room); + + room.getTraxManager().sendUpdatedSongList(); + } + + @Override + public void onPickUp(Room room) { + super.onPickUp(room); + + room.getTraxManager().sendUpdatedSongList(); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMuteArea.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMuteArea.java new file mode 100644 index 0000000..beed113 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMuteArea.java @@ -0,0 +1,158 @@ +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.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionMuteArea extends InteractionCustomValues { + public static THashMap defaultValues = new THashMap() { + { + this.put("tilesLeft", "0"); + } + + { + this.put("tilesRight", "0"); + } + + { + this.put("tilesFront", "0"); + } + + { + 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) { + 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.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, THashMap oldValues) { + super.onCustomValuesSaved(room, client, oldValues); + + 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/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionNoSidesVendingMachine.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionNoSidesVendingMachine.java new file mode 100644 index 0000000..f246370 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionNoSidesVendingMachine.java @@ -0,0 +1,36 @@ +package com.eu.habbo.habbohotel.items.interactions; + +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.users.Habbo; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionNoSidesVendingMachine extends InteractionVendingMachine { + public InteractionNoSidesVendingMachine(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionNoSidesVendingMachine(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public THashSet getActivatorTiles(Room room) { + + THashSet tiles = new THashSet(); + for(int x = -1; x <= 1; x++) { + for(int y = -1; y <= 1; y++) { + RoomTile tile = room.getLayout().getTile((short)(this.getX() + x), (short)(this.getY() + y)); + if(tile != null) { + tiles.add(tile); + } + } + } + + return tiles; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionObstacle.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionObstacle.java new file mode 100644 index 0000000..4e18542 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionObstacle.java @@ -0,0 +1,143 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.pets.HorsePet; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.threading.runnables.HabboItemNewState; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionObstacle extends HabboItem { + + public InteractionObstacle(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionObstacle(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + final HorsePet horse = room.getHabboHorse(roomUnit); + + if (horse == null) { + return; + } + + if (horse.getRoomUnit().hasStatus(RoomUnitStatus.JUMP)) { + return; + } + + // Random state. + int state = 0; + for (int i = 0; i < 2; i++) { + state = Emulator.getRandom().nextInt(4) + 1; + + if (state == 4) + break; + } + + this.setExtradata(state + ""); + + // Reset state. + Emulator.getThreading().run(new HabboItemNewState(this, room, "0"), 2000); + + // Jump animation. + roomUnit.removeStatus(RoomUnitStatus.MOVE); + roomUnit.removeStatus(RoomUnitStatus.JUMP); + roomUnit.statusUpdate(true); + + horse.getRoomUnit().removeStatus(RoomUnitStatus.JUMP); + horse.getRoomUnit().removeStatus(RoomUnitStatus.MOVE); + horse.getRoomUnit().setStatus(RoomUnitStatus.JUMP, "0"); + room.updateRoomUnit(horse.getRoomUnit()); + + Emulator.getThreading().run(() -> { + horse.getRoomUnit().removeStatus(RoomUnitStatus.JUMP); + room.updateRoomUnit(horse.getRoomUnit()); + }, 1000); + + // Achievement. + final Habbo habbo = horse.getRider(); + + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("HorseConsecutiveJumpsCount")); + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("HorseJumping")); + + room.updateItemState(this); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + final HorsePet horse = room.getHabboHorse(roomUnit); + + if (horse == null) { + return; + } + + if (roomUnit.getBodyRotation().getValue() % 2 != 0) { + return; + } + + if (this.getRotation() == 2) { + if (roomUnit.getBodyRotation() == RoomUserRotation.WEST) { + roomUnit.setGoalLocation(room.getLayout().getTile((short) (roomUnit.getX() - 3), roomUnit.getY())); + } else if (roomUnit.getBodyRotation() == RoomUserRotation.EAST) { + roomUnit.setGoalLocation(room.getLayout().getTile((short) (roomUnit.getX() + 3), roomUnit.getY())); + } + } else if (this.getRotation() == 4) { + if (roomUnit.getBodyRotation() == RoomUserRotation.NORTH) { + roomUnit.setGoalLocation(room.getLayout().getTile(roomUnit.getX(), (short) (roomUnit.getY() - 3))); + } else if (roomUnit.getBodyRotation() == RoomUserRotation.SOUTH) { + roomUnit.setGoalLocation(room.getLayout().getTile(roomUnit.getX(), (short) (roomUnit.getY() + 3))); + } + } + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + + final HorsePet horse = room.getHabboHorse(roomUnit); + + if (horse == null) { + return; + } + + horse.getRoomUnit().removeStatus(RoomUnitStatus.JUMP); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionOneWayGate.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionOneWayGate.java new file mode 100644 index 0000000..6a26e6c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionOneWayGate.java @@ -0,0 +1,165 @@ +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.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.rooms.users.RoomUserWalkEvent; +import com.eu.habbo.messages.outgoing.rooms.items.ItemIntStateComposer; +import com.eu.habbo.threading.runnables.RoomUnitWalkToLocation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class InteractionOneWayGate extends HabboItem { + private static final Logger LOGGER = LoggerFactory.getLogger(InteractionOneWayGate.class); + + private boolean walkable = false; + + public InteractionOneWayGate(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionOneWayGate(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return this.getBaseItem().allowWalk(); + } + + @Override + public boolean isWalkable() { + return walkable; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + if (this.getExtradata().length() == 0) { + this.setExtradata("0"); + this.needsUpdate(true); + } + + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public void onClick(final GameClient client, final Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + + if (client != null) { + RoomTile tileInfront = room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), this.getRotation()); + if (tileInfront == null) + return; + + RoomTile currentLocation = room.getLayout().getTile(this.getX(), this.getY()); + if (currentLocation == null) + return; + + RoomUnit unit = client.getHabbo().getRoomUnit(); + if (unit == null) + return; + + if (tileInfront.x == unit.getX() && tileInfront.y == unit.getY()) { + if (!currentLocation.hasUnits()) { + List onSuccess = new ArrayList(); + List onFail = new ArrayList(); + + onSuccess.add(() -> { + unit.setCanLeaveRoomByDoor(false); + walkable = this.getBaseItem().allowWalk(); + RoomTile tile = room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), this.getRotation() + 4); + unit.setGoalLocation(tile); + Emulator.getThreading().run(new RoomUnitWalkToLocation(unit, tile, room, onFail, onFail)); + + Emulator.getThreading().run(() -> WiredHandler.handle(WiredTriggerType.WALKS_ON_FURNI, unit, room, new Object[]{this}), 500); + }); + + onFail.add(() -> { + unit.setCanLeaveRoomByDoor(true); + walkable = this.getBaseItem().allowWalk(); + room.updateTile(currentLocation); + room.sendComposer(new ItemIntStateComposer(this.getId(), 0).compose()); + unit.removeOverrideTile(currentLocation); + }); + + walkable = true; + room.updateTile(currentLocation); + unit.addOverrideTile(currentLocation); + unit.setGoalLocation(currentLocation); + Emulator.getThreading().run(new RoomUnitWalkToLocation(unit, currentLocation, room, onSuccess, onFail)); + room.sendComposer(new ItemIntStateComposer(this.getId(), 1).compose()); + + /* + room.scheduledTasks.add(new Runnable() + { + @Override + public void run() + { + gate.roomUnitID = client.getHabbo().getRoomUnit().getId(); + room.updateTile(gatePosition); + client.getHabbo().getRoomUnit().setGoalLocation(room.getLayout().getTileInFront(room.getLayout().getTile(InteractionOneWayGate.this.getX(), InteractionOneWayGate.this.getY()), InteractionOneWayGate.this.getRotation() + 4)); + } + }); + */ + } + } + } + } + + private void refresh(Room room) { + this.setExtradata("0"); + room.sendComposer(new ItemIntStateComposer(this.getId(), 0).compose()); + room.updateTile(room.getLayout().getTile(this.getX(), this.getY())); + } + + @Override + public void onPickUp(Room room) { + this.setExtradata("0"); + this.refresh(room); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + this.refresh(room); + } + + @Override + public void onPlace(Room room) { + super.onPlace(room); + this.refresh(room); + } + + @Override + public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + super.onMove(room, oldLocation, newLocation); + this.refresh(room); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPostIt.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPostIt.java new file mode 100644 index 0000000..b703861 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPostIt.java @@ -0,0 +1,45 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionPostIt extends HabboItem { + public static String STICKYPOLE_PREFIX_TEXT = ""; + + public InteractionPostIt(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionPostIt(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata().replace(((char) 9) + "", "")); + + super.serializeExtradata(serverMessage); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPoster.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPoster.java new file mode 100644 index 0000000..d734d3a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPoster.java @@ -0,0 +1,43 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionPoster extends HabboItem { + public InteractionPoster(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + public InteractionPoster(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPressurePlate.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPressurePlate.java new file mode 100644 index 0000000..b446e6f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPressurePlate.java @@ -0,0 +1,112 @@ +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.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.items.ItemStateComposer; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionPressurePlate extends InteractionDefault { + public InteractionPressurePlate(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionPressurePlate(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + Emulator.getThreading().run(() -> updateState(room), 100); + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + + Emulator.getThreading().run(() -> updateState(room), 100); + } + + @Override + public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + super.onMove(room, oldLocation, newLocation); + + updateState(room); + } + + @Override + public void onPickUp(Room room) { + this.setExtradata("0"); + } + + public void updateState(Room room) { + boolean occupied = false; + + if (room == null || room.getLayout() == null || this.getBaseItem() == null) return; + + RoomTile tileAtItem = room.getLayout().getTile(this.getX(), this.getY()); + + if (tileAtItem == null) return; + + THashSet tiles = room.getLayout().getTilesAt(tileAtItem, this.getBaseItem().getWidth(), this.getBaseItem().getLength(), this.getRotation()); + + if (tiles == null) return; + + for (RoomTile tile : tiles) { + boolean hasHabbos = room.hasHabbosAt(tile.x, tile.y); + if (!hasHabbos && this.requiresAllTilesOccupied()) { + occupied = false; + break; + } + + if (hasHabbos) { + occupied = true; + } + } + + this.setExtradata(occupied ? "1" : "0"); + room.updateItemState(this); + } + + @Override + public boolean allowWiredResetState() { + return true; + } + + public boolean requiresAllTilesOccupied() { + return false; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPushable.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPushable.java new file mode 100644 index 0000000..a8d0db0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPushable.java @@ -0,0 +1,162 @@ +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.*; +import com.eu.habbo.threading.runnables.KickBallAction; + +import java.sql.ResultSet; +import java.sql.SQLException; + + +public abstract class InteractionPushable extends InteractionDefault { + + + private KickBallAction currentThread; + + public InteractionPushable(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionPushable(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onWalkOff(RoomUnit roomUnit, final Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + + if (!(this.currentThread == null || this.currentThread.dead)) + return; + + int velocity = this.getWalkOffVelocity(roomUnit, room); + RoomUserRotation direction = this.getWalkOffDirection(roomUnit, room); + this.onKick(room, roomUnit, velocity, direction); + + if (velocity > 0) { + if (this.currentThread != null) + this.currentThread.dead = true; + + this.currentThread = new KickBallAction(this, room, roomUnit, direction, velocity, false); + Emulator.getThreading().run(this.currentThread, 0); + } + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + + if (client == null) return; + if (RoomLayout.tilesAdjecent(client.getHabbo().getRoomUnit().getCurrentLocation(), room.getLayout().getTile(this.getX(), this.getY()))) { + int velocity = this.getTackleVelocity(client.getHabbo().getRoomUnit(), room); + RoomUserRotation direction = this.getWalkOnDirection(client.getHabbo().getRoomUnit(), room); + this.onTackle(room, client.getHabbo().getRoomUnit(), velocity, direction); + + if (velocity > 0) { + if (this.currentThread != null) + this.currentThread.dead = true; + + this.currentThread = new KickBallAction(this, room, client.getHabbo().getRoomUnit(), direction, velocity, false); + Emulator.getThreading().run(this.currentThread, 0); + } + } + } + + @Override + public void onWalkOn(RoomUnit roomUnit, final Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + int velocity; + boolean isDrag = false; + RoomUserRotation direction; + + if (this.getX() == roomUnit.getGoal().x && this.getY() == roomUnit.getGoal().y) //User clicked on the tile the ball is on, they want to kick it + { + velocity = this.getWalkOnVelocity(roomUnit, room); + direction = this.getWalkOnDirection(roomUnit, room); + this.onKick(room, roomUnit, velocity, direction); + } else //User is walking past the ball, they want to drag it with them + { + velocity = this.getDragVelocity(roomUnit, room); + direction = this.getDragDirection(roomUnit, room); + this.onDrag(room, roomUnit, velocity, direction); + isDrag = true; + } + + if (velocity > 0) { + if (this.currentThread != null) + this.currentThread.dead = true; + + this.currentThread = new KickBallAction(this, room, roomUnit, direction, velocity, isDrag); + Emulator.getThreading().run(this.currentThread, 0); + } + } + + + public abstract int getWalkOnVelocity(RoomUnit roomUnit, Room room); + + + public abstract RoomUserRotation getWalkOnDirection(RoomUnit roomUnit, Room room); + + + public abstract int getWalkOffVelocity(RoomUnit roomUnit, Room room); + + + public abstract RoomUserRotation getWalkOffDirection(RoomUnit roomUnit, Room room); + + + public abstract int getDragVelocity(RoomUnit roomUnit, Room room); + + + public abstract RoomUserRotation getDragDirection(RoomUnit roomUnit, Room room); + + + public abstract int getTackleVelocity(RoomUnit roomUnit, Room room); + + + public abstract RoomUserRotation getTackleDirection(RoomUnit roomUnit, Room room); + + + public abstract int getNextRollDelay(int currentStep, int totalSteps); //The length in milliseconds when the ball should next roll + + + public abstract RoomUserRotation getBounceDirection(Room room, RoomUserRotation currentDirection); //Returns the new direction to move the ball when the ball cannot move + + + public abstract boolean validMove(Room room, RoomTile from, RoomTile to); //Checks if the next move is valid + + + public abstract void onDrag(Room room, RoomUnit roomUnit, int velocity, RoomUserRotation direction); + + + public abstract void onKick(Room room, RoomUnit roomUnit, int velocity, RoomUserRotation direction); + + + public abstract void onTackle(Room room, RoomUnit roomUnit, int velocity, RoomUserRotation direction); + + + public abstract void onMove(Room room, RoomTile from, RoomTile to, RoomUserRotation direction, RoomUnit kicker, int nextRoll, int currentStep, int totalSteps); + + + public abstract void onBounce(Room room, RoomUserRotation oldDirection, RoomUserRotation newDirection, RoomUnit kicker); + + + public abstract void onStop(Room room, RoomUnit kicker, int currentStep, int totalSteps); + + + public abstract boolean canStillMove(Room room, RoomTile from, RoomTile to, RoomUserRotation direction, RoomUnit kicker, int nextRoll, int currentStep, int totalSteps); + +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPuzzleBox.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPuzzleBox.java new file mode 100644 index 0000000..a23586b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPuzzleBox.java @@ -0,0 +1,98 @@ +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.*; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionPuzzleBox extends HabboItem { + public InteractionPuzzleBox(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionPuzzleBox(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + RoomTile boxLocation = room.getLayout().getTile(this.getX(), this.getY()); + RoomUserRotation rotation = null; + + if (this.getX() == client.getHabbo().getRoomUnit().getX()) { + if (this.getY() == client.getHabbo().getRoomUnit().getY() + 1) { + rotation = RoomUserRotation.SOUTH; + } else if (this.getY() == client.getHabbo().getRoomUnit().getY() - 1) { + rotation = RoomUserRotation.NORTH; + } + } else if (this.getY() == client.getHabbo().getRoomUnit().getY()) { + if (this.getX() == client.getHabbo().getRoomUnit().getX() + 1) { + rotation = RoomUserRotation.EAST; + } else if (this.getX() == client.getHabbo().getRoomUnit().getX() - 1) { + rotation = RoomUserRotation.WEST; + } + } + + if (rotation == null) { + RoomTile nearestTile = client.getHabbo().getRoomUnit().getClosestAdjacentTile(this.getX(), this.getY(), false); + + if (nearestTile != null) client.getHabbo().getRoomUnit().setGoalLocation(nearestTile); + return; + } + + super.onClick(client, room, new Object[]{"TOGGLE_OVERRIDE"}); + + RoomTile tile = room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), rotation.getValue()); + + if (tile == null || tile.getState() == RoomTileState.INVALID || room.hasHabbosAt(tile.x, tile.y)) { + return; + } + + if (!boxLocation.equals(room.getLayout().getTileInFront(client.getHabbo().getRoomUnit().getCurrentLocation(), rotation.getValue()))) + return; + + HabboItem item = room.getTopItemAt(tile.x, tile.y); + + if (item != null && !room.getTopItemAt(tile.x, tile.y).getBaseItem().allowStack()) return; + + this.setZ(room.getStackHeight(tile.x, tile.y, false)); + this.needsUpdate(true); + room.updateItem(this); + + room.scheduledComposers.add(new FloorItemOnRollerComposer(this, null, tile, 0, room).compose()); + room.scheduledTasks.add(() -> { + client.getHabbo().getRoomUnit().setGoalLocation(boxLocation); + + room.scheduledTasks.add(() -> client.getHabbo().getRoomUnit().setGoalLocation(boxLocation)); + }); + this.needsUpdate(true); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPyramid.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPyramid.java new file mode 100644 index 0000000..1ddc2be --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPyramid.java @@ -0,0 +1,51 @@ +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 java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionPyramid extends InteractionGate { + private int nextChange; + + public InteractionPyramid(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionPyramid(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + public void change(Room room) { + if (!(this.getExtradata().equals("0") || this.getExtradata().equals("1"))) + this.setExtradata("0"); + + if (room != null) { + if (room.getHabbosAt(this.getX(), this.getY()).isEmpty()) { + int state = Integer.valueOf(this.getExtradata()); + state = Math.abs(state - 1); + + this.setExtradata(state + ""); + room.updateItemState(this); + + this.nextChange = Emulator.getIntUnixTimestamp() + 1 + (Emulator.getRandom().nextInt(Emulator.getConfig().getInt("pyramids.max.delay"))); + } + } + } + + public int getNextChange() { + return this.nextChange; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + } + + @Override + public boolean isUsable() { + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRandomState.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRandomState.java new file mode 100644 index 0000000..c28ee16 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRandomState.java @@ -0,0 +1,42 @@ +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.items.RandomStateParams; +import com.eu.habbo.habbohotel.rooms.Room; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionRandomState extends InteractionDefault { + public InteractionRandomState(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionRandomState(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onPlace(Room room) { + super.onPlace(room); + + this.setExtradata(""); + room.updateItemState(this); + } + + public void onRandomStateClick(GameClient client, Room room) throws Exception { + RandomStateParams params = new RandomStateParams(this.getBaseItem().getCustomParams()); + + this.setExtradata(""); + room.updateItemState(this); + + int randomState = Emulator.getRandom().nextInt(params.getStates()) + 1; + + Emulator.getThreading().run(() -> { + this.setExtradata(randomState + ""); + room.updateItemState(this); + }, params.getDelay()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRedeemableSubscriptionBox.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRedeemableSubscriptionBox.java new file mode 100644 index 0000000..250d750 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRedeemableSubscriptionBox.java @@ -0,0 +1,20 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionRedeemableSubscriptionBox extends InteractionCrackable { + public InteractionRedeemableSubscriptionBox(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionRedeemableSubscriptionBox(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + public boolean userRequiredToBeAdjacent() { + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRentableSpace.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRentableSpace.java new file mode 100644 index 0000000..b1c7ba9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRentableSpace.java @@ -0,0 +1,265 @@ +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.RoomLayout; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.items.rentablespaces.RentableSpaceInfoComposer; +import com.eu.habbo.threading.runnables.ClearRentedSpace; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; +import java.awt.*; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class InteractionRentableSpace extends HabboItem { + private int renterId; + private String renterName; + private int endTimestamp; + + public InteractionRentableSpace(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + + String[] data = set.getString("extra_data").split(":"); + + this.renterName = "Unknown"; + + if (data.length == 2) { + this.renterId = Integer.valueOf(data[0]); + this.endTimestamp = Integer.valueOf(data[1]); + + if (this.renterId > 0) { + if (this.isRented()) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.renterId); + + if (habbo != null) { + this.renterName = habbo.getHabboInfo().getUsername(); + } else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT username FROM users WHERE id = ? LIMIT 1")) { + statement.setInt(1, this.renterId); + try (ResultSet row = statement.executeQuery()) { + if (row.next()) { + this.renterName = row.getString("username"); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } else { + if (this.getRoomId() > 0) { + Emulator.getThreading().run(new ClearRentedSpace(this, Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()))); + this.renterId = 0; + } + } + } + } + } + + public InteractionRentableSpace(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + + this.renterName = ""; + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + if (this.getExtradata().isEmpty()) + return false; + + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo == null) + return true; + + if (habbo.getHabboInfo().getId() == room.getId()) + return true; + + if (this.endTimestamp > Emulator.getIntUnixTimestamp()) { + return this.renterId > 0 && this.renterId == habbo.getHabboInfo().getId(); + } + + return false; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + this.sendRentWidget(client.getHabbo()); + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + if (this.getExtradata().isEmpty()) + this.setExtradata("0:0"); + + serverMessage.appendInt(1 + (this.isLimited() ? 256 : 0)); + + if (this.isRented()) { + serverMessage.appendInt(1); + serverMessage.appendString("renterId"); + serverMessage.appendString(this.renterId + ""); + } else { + serverMessage.appendInt(0); + } + + super.serializeExtradata(serverMessage); + } + + public void rent(Habbo habbo) { + if (this.isRented()) + return; + + if (habbo.getHabboStats().isRentingSpace()) + return; + + if (habbo.getHabboInfo().getCredits() < this.rentCost()) + return; + + if (habbo.getHabboStats().getClubExpireTimestamp() < Emulator.getIntUnixTimestamp()) + return; + + this.setRenterId(habbo.getHabboInfo().getId()); + this.setRenterName(habbo.getHabboInfo().getUsername()); + this.setEndTimestamp(Emulator.getIntUnixTimestamp() + (7 * 86400)); + + habbo.getHabboStats().setRentedItemId(this.getId()); + habbo.getHabboStats().setRentedTimeEnd(this.endTimestamp); + this.needsUpdate(true); + this.run(); + } + + public void endRent() { + this.setEndTimestamp(0); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room == null) + return; + + Rectangle rect = RoomLayout.getRectangle(this.getX(), this.getY(), this.getBaseItem().getWidth(), this.getBaseItem().getLength(), this.getRotation()); + + THashSet items = new THashSet<>(); + for (int i = rect.x; i < rect.x + rect.getWidth(); i++) { + for (int j = rect.y; j < rect.y + rect.getHeight(); j++) { + items.addAll(room.getItemsAt(i, j, this.getZ())); + } + } + + for (HabboItem item : items) { + if (item.getUserId() == this.renterId) { + room.pickUpItem(item, null); + } + } + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.renterId); + + if (habbo != null) { + habbo.getHabboStats().setRentedItemId(0); + habbo.getHabboStats().setRentedTimeEnd(0); + } else { + int zero = 0; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users_settings SET rent_space_id = ?, rent_space_endtime = ? WHERE user_id = ? LIMIT 1")) { + statement.setInt(1, zero); + statement.setInt(2, zero); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + //room.ejectUserFurni(this.renterId); + + this.setRenterId(0); + this.setRenterName(""); + this.needsUpdate(true); + this.run(); + } + + @Override + public String getExtradata() { + return this.renterId + ":" + this.endTimestamp; + } + + public int getRenterId() { + return this.renterId; + } + + public void setRenterId(int renterId) { + this.renterId = renterId; + } + + public String getRenterName() { + return this.renterName; + } + + public void setRenterName(String renterName) { + this.renterName = renterName; + } + + public int getEndTimestamp() { + return this.endTimestamp; + } + + public void setEndTimestamp(int endTimestamp) { + this.endTimestamp = endTimestamp; + } + + public boolean isRented() { + return this.endTimestamp > Emulator.getIntUnixTimestamp(); + } + + public int rentCost() { + String[] data = this.getBaseItem().getName().replace("hblooza_spacerent", "").split("x"); + + if (data.length == 2) { + int x = Integer.valueOf(data[0]); + int y = Integer.valueOf(data[1]); + + return 10 * (x * y); + } + + return 1337; + } + + public int getRentErrorCode(Habbo habbo) { + if (this.isRented() && this.renterId != habbo.getHabboInfo().getId()) { + return RentableSpaceInfoComposer.SPACE_ALREADY_RENTED; + } + + if (habbo.getHabboStats().isRentingSpace() && habbo.getHabboStats().getRentedItemId() != this.getId()) { + return RentableSpaceInfoComposer.CAN_RENT_ONLY_ONE_SPACE; + } + + if (habbo.getHabboStats().getClubExpireTimestamp() < Emulator.getIntUnixTimestamp()) { + return RentableSpaceInfoComposer.CANT_RENT_NO_HABBO_CLUB; + } + + if (this.rentCost() > habbo.getHabboInfo().getCredits()) { + return RentableSpaceInfoComposer.NOT_ENOUGH_CREDITS; + } + + return 0; + } + + public void sendRentWidget(Habbo habbo) { + habbo.getClient().sendResponse(new RentableSpaceInfoComposer(habbo, this, this.getRentErrorCode(habbo))); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRoller.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRoller.java new file mode 100644 index 0000000..c2e7ea4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRoller.java @@ -0,0 +1,87 @@ +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.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; +import org.apache.commons.math3.util.Pair; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class InteractionRoller extends HabboItem { + public static boolean NO_RULES = false; + public static final int DELAY = 400; + + public InteractionRoller(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionRoller(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) { + + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + } + + + @Override + public boolean canStackAt(Room room, List>> itemsAtLocation) { + if (NO_RULES) return true; + if (itemsAtLocation.isEmpty()) return false; + + for (Pair> set : itemsAtLocation) { + if (set.getValue() != null && !set.getValue().isEmpty()) { + if (set.getValue().size() > 1) { + return false; + } else if (!set.getValue().contains(this)) { + return false; + } + } + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRoomAds.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRoomAds.java new file mode 100644 index 0000000..d37dea1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRoomAds.java @@ -0,0 +1,51 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import gnu.trove.map.hash.THashMap; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionRoomAds extends InteractionCustomValues { + public final static THashMap defaultValues = new THashMap() { + { + this.put("imageUrl", ""); + } + + { + this.put("clickUrl", ""); + } + + { + this.put("offsetX", "0"); + } + + { + this.put("offsetY", "0"); + } + + { + this.put("offsetZ", "0"); + } + }; + + public InteractionRoomAds(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, defaultValues); + } + + public InteractionRoomAds(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, defaultValues); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRoomOMatic.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRoomOMatic.java new file mode 100644 index 0000000..28fa960 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionRoomOMatic.java @@ -0,0 +1,26 @@ +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.messages.outgoing.navigator.OpenRoomCreationWindowComposer; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionRoomOMatic extends InteractionDefault { + public InteractionRoomOMatic(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionRoomOMatic(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (client != null) { + client.sendResponse(new OpenRoomCreationWindowComposer()); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionSnowboardSlope.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionSnowboardSlope.java new file mode 100644 index 0000000..3a6bf45 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionSnowboardSlope.java @@ -0,0 +1,87 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomLayout; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import gnu.trove.set.hash.THashSet; + +import java.awt.*; +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionSnowboardSlope extends InteractionMultiHeight { + public InteractionSnowboardSlope(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + public InteractionSnowboardSlope(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + room.giveEffect(roomUnit, 97, -1); + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + + if (roomUnit.getEffectId() == 97) { + room.giveEffect(roomUnit, 0, -1); + } + } + + @Override + public void onPlace(Room room) { + super.onPlace(room); + THashSet items = room.getRoomSpecialTypes().getItemsOfType(InteractionSnowboardSlope.class); + + Achievement snowboardBuild = Emulator.getGameEnvironment().getAchievementManager().getAchievement("snowBoardBuild"); + + if (snowboardBuild == null) return; + int progress; + Habbo habbo = room.getHabbo(room.getOwnerId()); + + if (habbo != null) { + progress = habbo.getHabboStats().getAchievementProgress(snowboardBuild); + + + } else { + progress = AchievementManager.getAchievementProgressForHabbo(room.getOwnerId(), snowboardBuild); + } + + progress = Math.max(items.size() - progress, 0); + + if (progress > 0) { + AchievementManager.progressAchievement(room.getOwnerId(), snowboardBuild); + } + } + + @Override + public void onPickUp(Room room) { + for (Habbo habbo : room.getHabbosOnItem(this)) { + if (habbo.getRoomUnit().getEffectId() == 97) { + room.giveEffect(habbo, 0, -1); + } + } + } + + @Override + public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + Rectangle newRect = RoomLayout.getRectangle(newLocation.x, newLocation.y, this.getBaseItem().getWidth(), this.getBaseItem().getLength(), this.getRotation()); + + for (Habbo habbo : room.getHabbosOnItem(this)) { + if (habbo.getRoomUnit().getEffectId() == 97 && !newRect.contains(habbo.getRoomUnit().getCurrentLocation().x, habbo.getRoomUnit().getCurrentLocation().y)) { + room.giveEffect(habbo, 0, -1); + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionStackHelper.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionStackHelper.java new file mode 100644 index 0000000..5955665 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionStackHelper.java @@ -0,0 +1,48 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionStackHelper extends HabboItem { + public InteractionStackHelper(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionStackHelper(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean isUsable() { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionStickyPole.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionStickyPole.java new file mode 100644 index 0000000..cd434e5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionStickyPole.java @@ -0,0 +1,16 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionStickyPole extends InteractionDefault { + public InteractionStickyPole(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionStickyPole(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionSwitch.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionSwitch.java new file mode 100644 index 0000000..e176187 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionSwitch.java @@ -0,0 +1,71 @@ +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.RoomLayout; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.threading.runnables.RoomUnitWalkToLocation; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class InteractionSwitch extends InteractionDefault { + public InteractionSwitch(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionSwitch(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean canToggle(Habbo habbo, Room room) { + return RoomLayout.tilesAdjecent(room.getLayout().getTile(this.getX(), this.getY()), habbo.getRoomUnit().getCurrentLocation()); + } + + @Override + public boolean allowWiredResetState() { + return true; + } + + @Override + public boolean isUsable() { + return true; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (client == null) + return; + + if (!this.canToggle(client.getHabbo(), room)) { + RoomTile closestTile = null; + for (RoomTile tile : room.getLayout().getTilesAround(room.getLayout().getTile(this.getX(), this.getY()))) { + if (tile.isWalkable() && (closestTile == null || closestTile.distance(client.getHabbo().getRoomUnit().getCurrentLocation()) > tile.distance(client.getHabbo().getRoomUnit().getCurrentLocation()))) { + closestTile = tile; + } + } + + if (closestTile != null && !closestTile.equals(client.getHabbo().getRoomUnit().getCurrentLocation())) { + List onSuccess = new ArrayList<>(); + onSuccess.add(() -> { + try { + this.onClick(client, room, objects); + } catch (Exception e) { + e.printStackTrace(); + } + }); + + client.getHabbo().getRoomUnit().setGoalLocation(closestTile); + Emulator.getThreading().run(new RoomUnitWalkToLocation(client.getHabbo().getRoomUnit(), closestTile, room, onSuccess, new ArrayList<>())); + } + } + + super.onClick(client, room, objects); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTalkingFurniture.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTalkingFurniture.java new file mode 100644 index 0000000..c958a9d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTalkingFurniture.java @@ -0,0 +1,16 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionTalkingFurniture extends InteractionDefault { + public InteractionTalkingFurniture(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionTalkingFurniture(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTeleport.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTeleport.java new file mode 100644 index 0000000..4281371 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTeleport.java @@ -0,0 +1,235 @@ +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.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.threading.runnables.RoomUnitWalkToLocation; +import com.eu.habbo.threading.runnables.teleport.TeleportActionOne; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class InteractionTeleport extends HabboItem { + private int targetId; + private int targetRoomId; + private int roomUnitID = -1; + private boolean walkable; + + public InteractionTeleport(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + walkable = baseItem.allowWalk(); + this.setExtradata("0"); + } + + public InteractionTeleport(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + walkable = item.allowWalk(); + this.setExtradata("0"); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return this.getBaseItem().allowWalk() || roomUnit.getId() == this.roomUnitID; + } + + @Override + public boolean isWalkable() { + return walkable; + } + + private void tryTeleport(GameClient client, Room room) { + /* + if user is on item, startTeleport + else if user is on infront, set state 1 and walk on item + else move to infront and interact + */ + + Habbo habbo = client.getHabbo(); + + if (habbo == null) + return; + + RoomUnit unit = habbo.getRoomUnit(); + + if (unit == null) + return; + + RoomTile currentLocation = room.getLayout().getTile(this.getX(), this.getY()); + + if (currentLocation == null) + return; + + RoomTile infrontTile = room.getLayout().getTileInFront(currentLocation, this.getRotation()); + + if (!canUseTeleport(client, room)) + return; + + if (this.roomUnitID == unit.getId() && unit.getCurrentLocation().equals(currentLocation)) { + startTeleport(room, habbo); + walkable = true; + + try { + super.onClick(client, room, new Object[]{"TOGGLE_OVERRIDE"}); + } catch (Exception e) { + e.printStackTrace(); + } + } else if (unit.getCurrentLocation().equals(currentLocation) || unit.getCurrentLocation().equals(infrontTile)) { + // set state 1 and walk on item + this.roomUnitID = unit.getId(); + this.setExtradata("1"); + room.updateItemState(this); + unit.setGoalLocation(infrontTile); + + List onSuccess = new ArrayList(); + List onFail = new ArrayList(); + + onSuccess.add(() -> { + room.updateTile(currentLocation); + tryTeleport(client, room); + unit.removeOverrideTile(currentLocation); + unit.setCanLeaveRoomByDoor(true); + walkable = this.getBaseItem().allowWalk(); + }); + + onFail.add(() -> { + walkable = this.getBaseItem().allowWalk(); + room.updateTile(currentLocation); + this.setExtradata("0"); + room.updateItemState(this); + this.roomUnitID = -1; + unit.removeOverrideTile(currentLocation); + unit.setCanLeaveRoomByDoor(true); + }); + + walkable = true; + room.updateTile(currentLocation); + unit.addOverrideTile(currentLocation); + unit.setGoalLocation(currentLocation); + unit.setCanLeaveRoomByDoor(false); + Emulator.getThreading().run(new RoomUnitWalkToLocation(unit, currentLocation, room, onSuccess, onFail)); + } else { + // walk to teleport and interact + List onSuccess = new ArrayList(); + List onFail = new ArrayList(); + + onSuccess.add(() -> { + tryTeleport(client, room); + }); + + unit.setGoalLocation(infrontTile); + Emulator.getThreading().run(new RoomUnitWalkToLocation(unit, infrontTile, room, onSuccess, onFail)); + } + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (room != null && client != null && objects != null && objects.length <= 1) { + tryTeleport(client, room); + } + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + } + + @Override + public void run() { + if (!this.getExtradata().equals("0")) { + this.setExtradata("0"); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room != null) { + room.updateItem(this); + } + } + super.run(); + } + + @Override + public void onPickUp(Room room) { + this.targetId = 0; + this.targetRoomId = 0; + this.roomUnitID = -1; + this.setExtradata("0"); + } + + public int getTargetId() { + return this.targetId; + } + + public void setTargetId(int targetId) { + this.targetId = targetId; + } + + public int getTargetRoomId() { + return this.targetRoomId; + } + + public void setTargetRoomId(int targetRoomId) { + this.targetRoomId = targetRoomId; + } + + @Override + public boolean allowWiredResetState() { + return false; + } + + public boolean canUseTeleport(GameClient client, Room room) { + + Habbo habbo = client.getHabbo(); + + if (habbo == null) + return false; + + RoomUnit unit = habbo.getRoomUnit(); + + if (unit == null) + return false; + + if (habbo.getHabboInfo().getRiding() != null) + return false; + + return true; + } + + public void startTeleport(Room room, Habbo habbo) { + this.startTeleport(room, habbo, 500); + } + + public void startTeleport(Room room, Habbo habbo, int delay) { + if (habbo.getRoomUnit().isTeleporting) { + walkable = this.getBaseItem().allowWalk(); + return; + } + + this.roomUnitID = -1; + habbo.getRoomUnit().isTeleporting = true; + Emulator.getThreading().run(new TeleportActionOne(this, room, habbo.getClient()), delay); + } + + @Override + public boolean isUsable() { + return true; + } + + @Override + public boolean invalidatesToRoomKick() { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTeleportTile.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTeleportTile.java new file mode 100644 index 0000000..fc8e7b5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTeleportTile.java @@ -0,0 +1,46 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionTeleportTile extends InteractionTeleport { + public InteractionTeleportTile(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionTeleportTile(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + if (roomUnit != null && this.canWalkOn(roomUnit, room, objects)) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + if (!canUseTeleport(habbo.getClient(), room)) + return; + + if (!habbo.getRoomUnit().isTeleporting) { + habbo.getRoomUnit().setGoalLocation(habbo.getRoomUnit().getCurrentLocation()); + this.startTeleport(room, habbo, 1000); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTent.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTent.java new file mode 100644 index 0000000..7ded66c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTent.java @@ -0,0 +1,23 @@ +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 java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionTent extends InteractionDefault { + public InteractionTent(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionTent(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + // do nothing + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTileEffectProvider.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTileEffectProvider.java new file mode 100644 index 0000000..c58f619 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTileEffectProvider.java @@ -0,0 +1,58 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import gnu.trove.map.hash.THashMap; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionTileEffectProvider extends InteractionCustomValues { + public static THashMap defaultValues = new THashMap() { + { + this.put("effectId", "0"); + } + }; + + public InteractionTileEffectProvider(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, defaultValues); + } + + public InteractionTileEffectProvider(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, defaultValues); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onWalkOn(RoomUnit roomUnit, final Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + int effectId = Integer.valueOf(this.values.get("effectId")); + + if (roomUnit.getEffectId() == effectId) { + effectId = 0; + } + + this.values.put("state", "1"); + room.updateItem(this); + + final InteractionTileEffectProvider proxy = this; + Emulator.getThreading().run(() -> { + proxy.values.put("state", "0"); + room.updateItem(proxy); + }, 500); + + room.giveEffect(roomUnit, effectId, -1); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTrap.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTrap.java new file mode 100644 index 0000000..8a0f084 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTrap.java @@ -0,0 +1,71 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUnitType; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionTrap extends InteractionDefault { + public InteractionTrap(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionTrap(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + if (!this.getExtradata().equals("0")) { + Habbo habbo = room.getHabbo(roomUnit); + if(habbo == null) { + return; + } + int effect = habbo.getClient().getHabbo().getRoomUnit().getEffectId(); + roomUnit.stopWalking(); + super.onWalkOn(roomUnit, room, objects); + int delay = Emulator.getConfig().getInt("hotel.item.trap." + this.getBaseItem().getName()); + if (delay == 0) { + Emulator.getConfig().register("hotel.item.trap." + this.getBaseItem().getName(), "3000"); + delay = 3000; + } + + if (roomUnit != null) { + if (this.getBaseItem().getEffectF() > 0 || this.getBaseItem().getEffectM() > 0) { + if (roomUnit.getRoomUnitType().equals(RoomUnitType.USER)) { + + if (habbo != null) { + if (habbo.getHabboInfo().getGender().equals(HabboGender.M) && this.getBaseItem().getEffectM() > 0 && habbo.getRoomUnit().getEffectId() != this.getBaseItem().getEffectM()) { + room.giveEffect(habbo, this.getBaseItem().getEffectM(), -1); + return; + } + + if (habbo.getHabboInfo().getGender().equals(HabboGender.F) && this.getBaseItem().getEffectF() > 0 && habbo.getRoomUnit().getEffectId() != this.getBaseItem().getEffectF()) { + room.giveEffect(habbo, this.getBaseItem().getEffectF(), -1); + return; + } + + + roomUnit.setCanWalk(false); + Emulator.getThreading().run(() -> { + room.giveEffect(roomUnit, 0, -1); + roomUnit.setCanWalk(true); + room.giveEffect(roomUnit, effect, -1); + }, delay); + } + } + } + } + } + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTrophy.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTrophy.java new file mode 100644 index 0000000..80f2c39 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTrophy.java @@ -0,0 +1,21 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionTrophy extends InteractionDefault { + public InteractionTrophy(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionTrophy(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean allowWiredResetState() { + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionVendingMachine.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionVendingMachine.java new file mode 100644 index 0000000..63a32a1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionVendingMachine.java @@ -0,0 +1,193 @@ +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.*; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.items.FloorItemUpdateComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import com.eu.habbo.threading.runnables.RoomUnitGiveHanditem; +import com.eu.habbo.threading.runnables.RoomUnitWalkToLocation; +import com.eu.habbo.util.pathfinding.Rotation; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ScheduledFuture; + +public class InteractionVendingMachine extends HabboItem { + public InteractionVendingMachine(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionVendingMachine(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + public THashSet getActivatorTiles(Room room) { + THashSet tiles = new THashSet<>(); + RoomTile tileInFront = getSquareInFront(room.getLayout(), this); + + if (tileInFront != null) + tiles.add(tileInFront); + + tiles.add(room.getLayout().getTile(this.getX(), this.getY())); + return tiles; + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + private void tryInteract(GameClient client, Room room, RoomUnit unit) { + THashSet activatorTiles = getActivatorTiles(room); + + if(activatorTiles.size() == 0) + return; + + boolean inActivatorSpace = false; + + for(RoomTile tile : activatorTiles) { + if(unit.getCurrentLocation().is(unit.getX(), unit.getY())) { + inActivatorSpace = true; + } + } + + if(inActivatorSpace) { + useVendingMachine(client, room, unit); + } + } + + private void useVendingMachine(GameClient client, Room room, RoomUnit unit) { + this.setExtradata("1"); + room.updateItem(this); + + try { + super.onClick(client, room, new Object[]{"TOGGLE_OVERRIDE"}); + } catch (Exception e) { + e.printStackTrace(); + } + + if(!unit.isWalking() && !unit.hasStatus(RoomUnitStatus.SIT) && !unit.hasStatus(RoomUnitStatus.LAY)) { + this.rotateToMachine(room, unit); + } + + Emulator.getThreading().run(() -> { + + giveVendingMachineItem(room, unit); + + if (this.getBaseItem().getEffectM() > 0 && client.getHabbo().getHabboInfo().getGender() == HabboGender.M) + room.giveEffect(client.getHabbo(), this.getBaseItem().getEffectM(), -1); + if (this.getBaseItem().getEffectF() > 0 && client.getHabbo().getHabboInfo().getGender() == HabboGender.F) + room.giveEffect(client.getHabbo(), this.getBaseItem().getEffectF(), -1); + + Emulator.getThreading().run(this, 500); + }, 1500); + } + + public void giveVendingMachineItem(Room room, RoomUnit unit) { + Emulator.getThreading().run(new RoomUnitGiveHanditem(unit, room, this.getBaseItem().getRandomVendingItem())); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (client == null) { + return; + } + + RoomUnit unit = client.getHabbo().getRoomUnit(); + + THashSet activatorTiles = getActivatorTiles(room); + + if(activatorTiles.size() == 0) + return; + + boolean inActivatorSpace = false; + + for(RoomTile tile : activatorTiles) { + if(unit.getCurrentLocation().is(tile.x, tile.y)) { + inActivatorSpace = true; + } + } + + if(!inActivatorSpace) { + RoomTile tileToWalkTo = null; + for(RoomTile tile : activatorTiles) { + if((tile.state == RoomTileState.OPEN || tile.state == RoomTileState.SIT) && (tileToWalkTo == null || tileToWalkTo.distance(unit.getCurrentLocation()) > tile.distance(unit.getCurrentLocation()))) { + tileToWalkTo = tile; + } + } + + if(tileToWalkTo != null) { + List onSuccess = new ArrayList(); + List onFail = new ArrayList(); + + onSuccess.add(() -> { + tryInteract(client, room, unit); + }); + + unit.setGoalLocation(tileToWalkTo); + Emulator.getThreading().run(new RoomUnitWalkToLocation(unit, tileToWalkTo, room, onSuccess, onFail)); + } + } + else { + useVendingMachine(client, room, unit); + } + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void run() { + super.run(); + if (this.getExtradata().equals("1")) { + this.setExtradata("0"); + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room != null) { + room.updateItem(this); + } + } + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return this.getBaseItem().allowWalk(); + } + + @Override + public boolean isUsable() { + return true; + } + + private void rotateToMachine(Room room, RoomUnit unit) { + RoomUserRotation rotation = RoomUserRotation.values()[Rotation.Calculate(unit.getX(), unit.getY(), this.getX(), this.getY())]; + + if(Math.abs(unit.getBodyRotation().getValue() - rotation.getValue()) > 1) { + unit.setRotation(rotation); + unit.statusUpdate(true); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionVikingCotie.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionVikingCotie.java new file mode 100644 index 0000000..c8fa52b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionVikingCotie.java @@ -0,0 +1,48 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionVikingCotie extends InteractionDefault { + public InteractionVikingCotie(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionVikingCotie(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (this.getExtradata().isEmpty()) { + this.setExtradata("0"); + } + + if (client != null && client.getHabbo().getHabboInfo().getId() == this.getUserId()) { + if (client.getHabbo().getRoomUnit().getEffectId() == 172 || client.getHabbo().getRoomUnit().getEffectId() == 173) { + int state = Integer.valueOf(this.getExtradata()); + + if (state < 5) { + state++; + this.setExtradata(state + ""); + room.updateItem(this); + + if (state == 5) { + AchievementManager.progressAchievement(client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("ViciousViking")); + } + } + } + } + } + + @Override + public boolean allowWiredResetState() { + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionVoteCounter.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionVoteCounter.java new file mode 100644 index 0000000..54ea473 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionVoteCounter.java @@ -0,0 +1,106 @@ +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.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class InteractionVoteCounter extends HabboItem { + + private boolean frozen; + private int votes; + private List votedUsers; + + public InteractionVoteCounter(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + if(!this.getExtradata().contains(",")) { + this.setExtradata("1,0"); // frozen,votes + } + + String[] bits = this.getExtradata().split(","); + frozen = bits[0].equals("1"); + votes = Integer.parseInt(bits[1]); + votedUsers = new ArrayList<>(); + } + + public InteractionVoteCounter(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + + if(!extradata.contains(",")) { + extradata = "1,0"; + } + + String[] bits = extradata.split(","); + frozen = bits[0].equals("1"); + votes = Integer.parseInt(bits[1]); + votedUsers = new ArrayList<>(); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0) + 3); + serverMessage.appendString(this.frozen ? "0" : "1"); + serverMessage.appendInt(this.votes); + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + private void updateExtradata() { + this.setExtradata((this.frozen ? "1" : "0") + "," + this.votes); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (!((client != null && room != null && room.hasRights(client.getHabbo())) || (objects.length >= 2 && objects[1] instanceof WiredEffectType))) + return; + + this.frozen = !this.frozen; + + if(!frozen) { + this.votes = 0; + this.votedUsers.clear(); + } + + updateExtradata(); + this.needsUpdate(true); + room.updateItem(this); + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + public void vote(Room room, int UserId, int vote) { + if(frozen) + return; + + if(votedUsers.contains(UserId)) + return; + + votedUsers.add(UserId); + + votes += vote; + updateExtradata(); + this.needsUpdate(true); + room.updateItem(this); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWater.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWater.java new file mode 100644 index 0000000..d697ee4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWater.java @@ -0,0 +1,298 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import gnu.trove.set.hash.THashSet; +import org.apache.commons.math3.util.Pair; + +import java.awt.*; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class InteractionWater extends InteractionDefault { + + private static final String DEEP_WATER_NAME = "bw_water_2"; + + private final boolean isDeepWater; + private boolean isInRoom; + + public InteractionWater(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.isDeepWater = baseItem.getName().equalsIgnoreCase(DEEP_WATER_NAME); + this.isInRoom = this.getRoomId() != 0; + } + + public InteractionWater(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.isDeepWater = false; + this.isInRoom = this.getRoomId() != 0; + } + + @Override + public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + super.onMove(room, oldLocation, newLocation); + this.updateWaters(room, oldLocation); + } + + @Override + public void onPickUp(Room room) { + this.isInRoom = false; + this.updateWaters(room, null); + + Object[] empty = new Object[]{}; + for (Habbo habbo : room.getHabbosOnItem(this)) { + try { + this.onWalkOff(habbo.getRoomUnit(), room, empty); + } catch (Exception e) { + + } + } + + for (Bot bot : room.getBotsOnItem(this)) { + try { + this.onWalkOff(bot.getRoomUnit(), room, empty); + } catch (Exception e) { + } + } + } + + @Override + public void onPlace(Room room) { + this.isInRoom = true; + this.updateWaters(room, null); + super.onPlace(room); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + Pet pet = room.getPet(roomUnit); + + if(pet == null) + return; + + if (!pet.getRoomUnit().hasStatus(RoomUnitStatus.SWIM) && pet.getPetData().canSwim) { + pet.getRoomUnit().setStatus(RoomUnitStatus.SWIM, ""); + } + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + + Pet pet = room.getPet(roomUnit); + + if(pet == null) + return; + + pet.getRoomUnit().removeStatus(RoomUnitStatus.SWIM); + } + + @Override + public boolean allowWiredResetState() { + return false; + } + + @Override + public boolean canToggle(Habbo habbo, Room room) { + return false; + } + + @Override + public boolean canStackAt(Room room, List>> itemsAtLocation) { + for (Pair> set : itemsAtLocation) { + for (HabboItem item : set.getValue()) { + if (!(item instanceof InteractionWater)) { + return false; + } + } + } + + return super.canStackAt(room, itemsAtLocation); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + if (!super.canWalkOn(roomUnit, room, objects)) return false; + + Pet pet = room.getPet(roomUnit); + + return pet == null || pet.getPetData().canSwim; + } + + private void updateWaters(Room room, RoomTile oldLocation) { + // Update ourself. + this.updateWater(room); + + // Find targets containing furni to update. + Rectangle target = this.getRectangle(1, 1); + Rectangle targetOld = null; + + if (oldLocation != null) { + targetOld = RoomLayout.getRectangle( + oldLocation.x - 1, + oldLocation.y - 1, + this.getBaseItem().getWidth() + 2, + this.getBaseItem().getLength() + 2, + this.getRotation()); + } + + // Update neighbouring water. + for (HabboItem item : room.getRoomSpecialTypes().getItemsOfType(InteractionWater.class)) { + // We already updated ourself. + if (item == this) { + continue; + } + + // Check if found water furni is touching or intersecting our water furni. + // Check the same for the old location + Rectangle itemRectangle = item.getRectangle(); + + if (target.intersects(itemRectangle) || (targetOld != null && targetOld.intersects(itemRectangle))) { + ((InteractionWater) item).updateWater(room); + } + } + + // Update water items we might have missed in the old location. + if (targetOld != null) { + for (HabboItem item : room.getRoomSpecialTypes().getItemsOfType(InteractionWaterItem.class)) { + if (targetOld.intersects(item.getRectangle())) { + ((InteractionWaterItem) item).update(); + } + } + } + } + + private void updateWater(Room room) { + Rectangle target = this.getRectangle(); + + // Only update water item furnis that are intersecting with us. + for (HabboItem item : room.getRoomSpecialTypes().getItemsOfType(InteractionWaterItem.class)) { + if (target.intersects(item.getRectangle())) { + ((InteractionWaterItem) item).update(); + } + } + + // Prepare bits for cutting off water. + byte _1 = 0; + byte _2 = 0; + byte _3 = 0; + byte _4 = 0; + byte _5 = 0; + byte _6 = 0; + byte _7 = 0; + byte _8 = 0; + byte _9 = 0; + byte _10 = 0; + byte _11 = 0; + byte _12 = 0; + + // Check if we are touching a water tile. + if (this.isValidForMask(room, this.getX() - 1, this.getY() - 1, this.getZ(), true)) { + _1 = 1; + } + if (this.isValidForMask(room, this.getX(), this.getY() - 1, this.getZ())) { + _2 = 1; + } + if (this.isValidForMask(room, this.getX() + 1, this.getY() - 1, this.getZ())) { + _3 = 1; + } + if (this.isValidForMask(room, this.getX() + 2, this.getY() - 1, this.getZ(), true)) { + _4 = 1; + } + if (this.isValidForMask(room, this.getX() - 1, this.getY(), this.getZ())) { + _5 = 1; + } + if (this.isValidForMask(room, this.getX() + 2, this.getY(), this.getZ())) { + _6 = 1; + } + if (this.isValidForMask(room, this.getX() - 1, this.getY() + 1, this.getZ())) { + _7 = 1; + } + if (this.isValidForMask(room, this.getX() + 2, this.getY() + 1, this.getZ())) { + _8 = 1; + } + if (this.isValidForMask(room, this.getX() - 1, this.getY() + 2, this.getZ(), true)) { + _9 = 1; + } + if (this.isValidForMask(room, this.getX(), this.getY() + 2, this.getZ())) { + _10 = 1; + } + if (this.isValidForMask(room, this.getX() + 1, this.getY() + 2, this.getZ())) { + _11 = 1; + } + if (this.isValidForMask(room, this.getX() + 2, this.getY() + 2, this.getZ(), true)) { + _12 = 1; + } + + // Check if we are touching invalid tiles. + // if (_1 == 0 && room.getLayout().isVoidTile((short)(this.getX() -1), (short) (this.getY() -1))) _1 = 1; + if (_2 == 0 && room.getLayout().isVoidTile(this.getX(), (short) (this.getY() - 1))) _2 = 1; + if (_3 == 0 && room.getLayout().isVoidTile((short) (this.getX() + 1), (short) (this.getY() - 1))) _3 = 1; + // if (_4 == 0 && room.getLayout().isVoidTile((short) (this.getX() + 2), (short) (this.getY() - 1))) _4 = 1; + if (_5 == 0 && room.getLayout().isVoidTile((short) (this.getX() - 1), this.getY())) _5 = 1; + if (_6 == 0 && room.getLayout().isVoidTile((short) (this.getX() + 2), this.getY())) _6 = 1; + if (_7 == 0 && room.getLayout().isVoidTile((short) (this.getX() - 1), (short) (this.getY() + 1))) _7 = 1; + if (_8 == 0 && room.getLayout().isVoidTile((short) (this.getX() + 2), (short) (this.getY() + 1))) _8 = 1; + // if (_9 == 0 && room.getLayout().isVoidTile((short)(this.getX() -1), (short) (this.getY() + 2))) _9 = 1; + if (_10 == 0 && room.getLayout().isVoidTile(this.getX(), (short) (this.getY() + 2))) _10 = 1; + if (_11 == 0 && room.getLayout().isVoidTile((short) (this.getX() + 1), (short) (this.getY() + 2))) _11 = 1; + // if (_12 == 0 && room.getLayout().isVoidTile((short) (this.getX() + 2), (short) (this.getY() + 2))) _12 = 1; + + // Update water. + int result = (_1 << 11) + | (_2 << 10) + | (_3 << 9) + | (_4 << 8) + | (_5 << 7) + | (_6 << 6) + | (_7 << 5) + | (_8 << 4) + | (_9 << 3) + | (_10 << 2) + | (_11 << 1) + | _12; + + String updatedData = String.valueOf(result); + + if (!this.getExtradata().equals(updatedData)) { + this.setExtradata(updatedData); + this.needsUpdate(true); + room.updateItem(this); + } + } + + private boolean isValidForMask(Room room, int x, int y, double z) { + return this.isValidForMask(room, x, y, z, false); + } + + private boolean isValidForMask(Room room, int x, int y, double z, boolean corner) { + for (HabboItem item : room.getItemsAt(x, y, z)) { + if (item instanceof InteractionWater) { + InteractionWater water = (InteractionWater) item; + + // Take out picked up water from the recalculation. + if (!water.isInRoom) { + continue; + } + + // Allow: + // - masking if both are deepwater or both not. + // - corners too because otherwise causes ugly clipping issues. + // This allows deepwater and normal water to look nice. + if (corner && !this.isDeepWater || water.isDeepWater == this.isDeepWater) { + return true; + } + } + } + + return false; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWaterItem.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWaterItem.java new file mode 100644 index 0000000..4b283da --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWaterItem.java @@ -0,0 +1,94 @@ +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.RoomLayout; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import gnu.trove.set.hash.THashSet; + +import java.awt.*; +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionWaterItem extends InteractionMultiHeight { + public InteractionWaterItem(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionWaterItem(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onPlace(Room room) { + this.update(); + super.onPlace(room); + } + + @Override + public void onPickUp(Room room) { + super.onPickUp(room); + this.setExtradata("0"); + this.needsUpdate(true); + } + + @Override + public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + super.onMove(room, oldLocation, newLocation); + this.update(); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, new Object[] { }); + } + + public void update() { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room == null) { + return; + } + + Rectangle rectangle = this.getRectangle(); + + // Check if every tile of the furni is in water. + boolean foundWater = true; + + for (short x = (short) rectangle.x; x < rectangle.getWidth() + rectangle.x && foundWater; x++) { + for (short y = (short) rectangle.y; y < rectangle.getHeight() + rectangle.y && foundWater; y++) { + boolean tile = false; + THashSet items = room.getItemsAt(room.getLayout().getTile(x, y)); + + for (HabboItem item : items) { + if (item instanceof InteractionWater) { + tile = true; + break; + } + } + + if (!tile) { + foundWater = false; + } + } + } + + // Update data if changed. + String updatedData = foundWater ? "1" : "0"; + + if (!this.getExtradata().equals(updatedData)) { + this.setExtradata(updatedData); + this.needsUpdate(true); + room.updateItemState(this); + } + } + + @Override + public boolean allowWiredResetState() { + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWired.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWired.java new file mode 100644 index 0000000..7aa6231 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWired.java @@ -0,0 +1,132 @@ +package com.eu.habbo.habbohotel.items.interactions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.items.ItemStateComposer; +import gnu.trove.map.hash.TLongLongHashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; + +public abstract class InteractionWired extends InteractionDefault { + private static final Logger LOGGER = LoggerFactory.getLogger(InteractionWired.class); + private long cooldown; + private final HashMap userExecutionCache = new HashMap<>(); + + InteractionWired(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + InteractionWired(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + public abstract boolean execute(RoomUnit roomUnit, Room room, Object[] stuff); + + public abstract String getWiredData(); + + public abstract void serializeWiredData(ServerMessage message, Room room); + + public abstract void loadWiredData(ResultSet set, Room room) throws SQLException; + + @Override + public void run() { + if (this.needsUpdate()) { + String wiredData = this.getWiredData(); + + if (wiredData == null) { + wiredData = ""; + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE items SET wired_data = ? WHERE id = ?")) { + if (this.getRoomId() != 0) { + statement.setString(1, wiredData); + } else { + statement.setString(1, ""); + } + statement.setInt(2, this.getId()); + statement.execute(); + } catch (SQLException e) { + LOGGER.error("Caught SQL exception", e); + } + } + super.run(); + } + + @Override + public void onPickUp(Room room) { + this.onPickUp(); + } + + public abstract void onPickUp(); + + public void activateBox(Room room) { + this.activateBox(room, (RoomUnit)null, 0L); + } + + public void activateBox(Room room, RoomUnit roomUnit, long millis) { + if (!room.isHideWired()) { + this.setExtradata(this.getExtradata().equals("1") ? "0" : "1"); + room.sendComposer(new ItemStateComposer(this).compose()); + } + if (roomUnit != null) { + this.addUserExecutionCache(roomUnit.getId(), millis); + } + } + + protected long requiredCooldown() { + return 50L; + } + + + public boolean canExecute(long newMillis) { + return newMillis - this.cooldown >= this.requiredCooldown(); + } + + public void setCooldown(long newMillis) { + this.cooldown = newMillis; + } + + @Override + public boolean allowWiredResetState() { + return false; + } + + @Override + public boolean isUsable() { + return true; + } + + public boolean userCanExecute(int roomUnitId, long timestamp) { + if (roomUnitId == -1) { + return true; + } else { + if (this.userExecutionCache.containsKey((long)roomUnitId)) { + long lastTimestamp = this.userExecutionCache.get((long)roomUnitId); + if (timestamp - lastTimestamp < Math.max(100L, this.requiredCooldown())) { + return false; + } + } + + return true; + } + } + + public void clearUserExecutionCache() { + this.userExecutionCache.clear(); + } + + public void addUserExecutionCache(int roomUnitId, long timestamp) { + this.userExecutionCache.put((long)roomUnitId, timestamp); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredCondition.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredCondition.java new file mode 100644 index 0000000..7bf21fe --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredCondition.java @@ -0,0 +1,52 @@ +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; +import com.eu.habbo.habbohotel.wired.WiredConditionOperator; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.outgoing.wired.WiredConditionDataComposer; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public abstract class InteractionWiredCondition extends InteractionWired { + public InteractionWiredCondition(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionWiredCondition(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (client != null) { + if (room.hasRights(client.getHabbo())) { + client.sendResponse(new WiredConditionDataComposer(this, room)); + this.activateBox(room); + } + } + } + + public abstract WiredConditionType getType(); + + public abstract boolean saveData(ClientMessage packet); + + public WiredConditionOperator operator() { + return WiredConditionOperator.AND; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredEffect.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredEffect.java new file mode 100644 index 0000000..59da2b6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredEffect.java @@ -0,0 +1,62 @@ +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; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import com.eu.habbo.messages.outgoing.wired.WiredEffectDataComposer; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public abstract class InteractionWiredEffect extends InteractionWired { + private int delay; + + public InteractionWiredEffect(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionWiredEffect(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (client != null) { + if (room.hasRights(client.getHabbo())) { + client.sendResponse(new WiredEffectDataComposer(this, room)); + this.activateBox(room); + } + } + } + + public abstract boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException; + + public int getDelay() { + return this.delay; + } + + protected void setDelay(int value) { + this.delay = value; + } + + public abstract WiredEffectType getType(); + + + public boolean requiresTriggeringUser() { + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredExtra.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredExtra.java new file mode 100644 index 0000000..b946d7d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredExtra.java @@ -0,0 +1,38 @@ +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; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public abstract class InteractionWiredExtra extends InteractionWired { + protected InteractionWiredExtra(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + protected InteractionWiredExtra(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (client != null) { + if (room.hasRights(client.getHabbo())) { + this.activateBox(room); + } + } + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredHighscore.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredHighscore.java new file mode 100644 index 0000000..8bef931 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredHighscore.java @@ -0,0 +1,149 @@ +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.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.habbohotel.wired.highscores.WiredHighscoreClearType; +import com.eu.habbo.habbohotel.wired.highscores.WiredHighscoreRow; +import com.eu.habbo.habbohotel.wired.highscores.WiredHighscoreScoreType; +import com.eu.habbo.messages.ServerMessage; +import lombok.extern.slf4j.Slf4j; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +@Slf4j +public class InteractionWiredHighscore extends HabboItem { + public WiredHighscoreScoreType scoreType; + public WiredHighscoreClearType clearType; + private List data; + public InteractionWiredHighscore(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + + this.scoreType = WiredHighscoreScoreType.CLASSIC; + this.clearType = WiredHighscoreClearType.ALLTIME; + + try { + String name = this.getBaseItem().getName().split("_")[1].toUpperCase().split("\\*")[0]; + int ctype = Integer.valueOf(this.getBaseItem().getName().split("\\*")[1]) - 1; + this.scoreType = WiredHighscoreScoreType.valueOf(name); + this.clearType = WiredHighscoreClearType.values()[ctype]; + } catch (Exception e) { + log.error("Caught exception", e); + } + + this.reloadData(); + } + + public InteractionWiredHighscore(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + + this.scoreType = WiredHighscoreScoreType.CLASSIC; + this.clearType = WiredHighscoreClearType.ALLTIME; + + try { + String name = this.getBaseItem().getName().split("_")[1].toUpperCase().split("\\*")[0]; + int ctype = Integer.valueOf(this.getBaseItem().getName().split("\\*")[1]) - 1; + this.scoreType = WiredHighscoreScoreType.valueOf(name); + this.clearType = WiredHighscoreClearType.values()[ctype]; + } catch (Exception e) { + log.error("Caught exception", e); + } + + this.reloadData(); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (!((client != null && room != null && room.hasRights(client.getHabbo())) || (objects.length >= 2 && objects[1] instanceof WiredEffectType))) + return; + + if (this.getExtradata() == null || this.getExtradata().isEmpty() || this.getExtradata().length() == 0) { + this.setExtradata("0"); + } + + try { + int state = Integer.valueOf(this.getExtradata()); + this.setExtradata(Math.abs(state - 1) + ""); + room.updateItem(this); + } catch (Exception e) { + log.error("Caught exception", e); + } + + if(client != null && !(objects.length >= 2 && objects[1] instanceof WiredEffectType)) { + WiredHandler.handle(WiredTriggerType.STATE_CHANGED, client.getHabbo().getRoomUnit(), room, new Object[]{this}); + } + } + + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt(6); + serverMessage.appendString(this.getExtradata()); + serverMessage.appendInt(this.scoreType.type); + serverMessage.appendInt(this.clearType.type); + + if (this.data != null) { + int size = this.data.size(); + if(size > 50) { + size = 50; + } + serverMessage.appendInt(size); + + int count = 0; + for (WiredHighscoreRow row : this.data) { + if(count < 50) { + serverMessage.appendInt(row.getValue()); + + serverMessage.appendInt(row.getUsers().size()); + for (String username : row.getUsers()) { + serverMessage.appendString(username); + } + } + count++; + } + } else { + serverMessage.appendInt(0); + } + + super.serializeExtradata(serverMessage); + } + + @Override + public void onPlace(Room room) { + this.reloadData(); + super.onPlace(room); + } + + @Override + public void onPickUp(Room room) { + if (this.data != null) { + this.data.clear(); + } + } + + public void reloadData() { + this.data = Emulator.getGameEnvironment().getItemManager().getHighscoreManager().getHighscoreRowsForItem(this.getId(), this.clearType, this.scoreType); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredTrigger.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredTrigger.java new file mode 100644 index 0000000..c0bbaab --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredTrigger.java @@ -0,0 +1,61 @@ +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; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.outgoing.wired.WiredTriggerDataComposer; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public abstract class InteractionWiredTrigger extends InteractionWired { + private int delay; + + protected InteractionWiredTrigger(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + protected InteractionWiredTrigger(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (client != null) { + if (room.hasRights(client.getHabbo())) { + client.sendResponse(new WiredTriggerDataComposer(this, room)); + this.activateBox(room); + } + } + } + + public abstract WiredTriggerType getType(); + + public abstract boolean saveData(ClientMessage packet); + + protected int getDelay() { + return this.delay; + } + + protected void setDelay(int value) { + this.delay = value; + } + + public boolean isTriggeredByRoomUnit() { + return false; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionYoutubeTV.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionYoutubeTV.java new file mode 100644 index 0000000..47bbbb1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionYoutubeTV.java @@ -0,0 +1,96 @@ +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.items.YoutubeManager; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.items.youtube.YoutubeVideoComposer; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.concurrent.ScheduledFuture; + +public class InteractionYoutubeTV extends HabboItem { + public YoutubeManager.YoutubePlaylist currentPlaylist = null; + public YoutubeManager.YoutubeVideo currentVideo = null; + public int startedWatchingAt = 0; + public int offset = 0; + public boolean playing = true; + public ScheduledFuture autoAdvance = null; + + public InteractionYoutubeTV(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionYoutubeTV(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + if (this.getExtradata().length() == 0) + this.setExtradata(""); + + serverMessage.appendInt(1 + (this.isLimited() ? 256 : 0)); + serverMessage.appendInt(1); + serverMessage.appendString("THUMBNAIL_URL"); + if (this.currentVideo == null) { + serverMessage.appendString(""); + } else { + serverMessage.appendString(Emulator.getConfig().getValue("imager.url.youtube").replace("%video%", this.currentVideo.getId())); + } + + super.serializeExtradata(serverMessage); + } + + @Override + public void onPickUp(Room room) { + super.onPickUp(room); + + if (this.autoAdvance != null) { + this.cancelAdvancement(); + } + + this.currentVideo = null; + this.currentPlaylist = null; + this.startedWatchingAt = 0; + this.offset = 0; + } + + public void cancelAdvancement() { + if (this.autoAdvance == null) return; + + this.autoAdvance.cancel(true); + this.autoAdvance = null; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + + if (this.currentVideo != null) { + int startTime = this.offset; + if (this.playing) startTime += Emulator.getIntUnixTimestamp() - this.startedWatchingAt; + client.sendResponse(new YoutubeVideoComposer(this.getId(), this.currentVideo, this.playing, startTime)); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameGate.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameGate.java new file mode 100644 index 0000000..b56491b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameGate.java @@ -0,0 +1,55 @@ +package com.eu.habbo.habbohotel.items.interactions.games; + +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public abstract class InteractionGameGate extends InteractionGameTeamItem { + public InteractionGameGate(ResultSet set, Item baseItem, GameTeamColors teamColor) throws SQLException { + super(set, baseItem, teamColor); + this.setExtradata("0"); + } + + public InteractionGameGate(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells, GameTeamColors teamColor) { + super(id, userId, item, extradata, limitedStack, limitedSells, teamColor); + this.setExtradata("0"); + } + + @Override + public void onPickUp(Room room) { + this.setExtradata("0"); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + public void updateState(Game game, int maxPlayers) { + int memberCount = 0; + + if (game.getTeam(this.teamColor) != null) { + memberCount = game.getTeam(this.teamColor).getMembers().size(); + } + + if (memberCount > maxPlayers) { + memberCount = maxPlayers; + } + this.setExtradata(memberCount + ""); + game.getRoom().updateItem(this); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameScoreboard.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameScoreboard.java new file mode 100644 index 0000000..eb416b8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameScoreboard.java @@ -0,0 +1,34 @@ +package com.eu.habbo.habbohotel.items.interactions.games; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public abstract class InteractionGameScoreboard extends InteractionGameTeamItem { + protected InteractionGameScoreboard(ResultSet set, Item baseItem, GameTeamColors teamColor) throws SQLException { + super(set, baseItem, teamColor); + this.setExtradata("0"); + } + + protected InteractionGameScoreboard(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells, GameTeamColors teamColor) { + super(id, userId, item, extradata, limitedStack, limitedSells, teamColor); + this.setExtradata("0"); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public void onPickUp(Room room) { + this.setExtradata("0"); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameTeamItem.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameTeamItem.java new file mode 100644 index 0000000..f52ff6b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameTeamItem.java @@ -0,0 +1,24 @@ +package com.eu.habbo.habbohotel.items.interactions.games; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.users.HabboItem; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public abstract class InteractionGameTeamItem extends HabboItem { + public final GameTeamColors teamColor; + + protected InteractionGameTeamItem(ResultSet set, Item baseItem, GameTeamColors teamColor) throws SQLException { + super(set, baseItem); + + this.teamColor = teamColor; + } + + protected InteractionGameTeamItem(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells, GameTeamColors teamColor) { + super(id, userId, item, extradata, limitedStack, limitedSells); + + this.teamColor = teamColor; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameTimer.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameTimer.java new file mode 100644 index 0000000..da906a9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/InteractionGameTimer.java @@ -0,0 +1,349 @@ +package com.eu.habbo.habbohotel.items.interactions.games; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.games.GameState; +import com.eu.habbo.habbohotel.games.wired.WiredGame; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.threading.runnables.games.GameTimer; +import lombok.extern.slf4j.Slf4j; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; + +@Slf4j +public class InteractionGameTimer extends HabboItem implements Runnable { + private int[] TIMER_INTERVAL_STEPS = new int[] { 30, 60, 120, 180, 300, 600 }; + private int baseTime = 0; + private int timeNow = 0; + private boolean isRunning = false; + private boolean isPaused = false; + private boolean threadActive = false; + + public enum InteractionGameTimerAction { + START_STOP(1), + INCREASE_TIME(2); + + private int action; + + InteractionGameTimerAction(int action) { + this.action = action; + } + + public int getAction() { + return action; + } + + public static InteractionGameTimerAction getByAction(int action) { + if (action == 1) return START_STOP; + if (action == 2) return INCREASE_TIME; + + return START_STOP; + } + } + + public InteractionGameTimer(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + + parseCustomParams(baseItem); + + try { + String[] data = set.getString("extra_data").split("\t"); + + if (data.length >= 2) { + this.baseTime = Integer.parseInt(data[1]); + this.timeNow = this.baseTime; + } + + if (data.length >= 1) { + this.setExtradata(data[0] + "\t0"); + } + } + catch (Exception e) { + this.baseTime = TIMER_INTERVAL_STEPS[0]; + this.timeNow = this.baseTime; + } + } + + public InteractionGameTimer(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + + parseCustomParams(item); + } + + private void parseCustomParams(Item baseItem) { + try { + TIMER_INTERVAL_STEPS = Arrays.stream(baseItem.getCustomParams().split(",")) + .mapToInt(s -> { + try { + return Integer.parseInt(s); + } catch (NumberFormatException e) { + return 0; + } + }).toArray(); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + public void endGame(Room room) { + endGame(room, false); + } + + public void endGame(Room room, boolean isStart) { + this.isRunning = false; + this.isPaused = false; + + for (Game game : room.getGames()) { + if (!game.getState().equals(GameState.IDLE) && !(isStart && game instanceof WiredGame)) { + game.onEnd(); + game.stop(); + } + } + } + + private void createNewGame(Room room) { + for(Class gameClass : Emulator.getGameEnvironment().getRoomManager().getGameTypes()) { + Game existingGame = room.getGame(gameClass); + + if (existingGame != null) { + existingGame.initialise(); + } else { + try { + Game game = gameClass.getDeclaredConstructor(Room.class).newInstance(room); + room.addGame(game); + game.initialise(); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + } + } + + private void pause(Room room) { + for (Game game : room.getGames()) { + game.pause(); + } + } + + private void unpause(Room room) { + for (Game game : room.getGames()) { + game.unpause(); + } + } + + @Override + public void run() { + if (this.needsUpdate() || this.needsDelete()) { + super.run(); + } + } + + @Override + public void onPickUp(Room room) { + this.endGame(room); + + this.setExtradata(this.baseTime + "\t" + this.baseTime); + this.needsUpdate(true); + } + + @Override + public void onPlace(Room room) { + if (this.baseTime < this.TIMER_INTERVAL_STEPS[0]) { + this.baseTime = this.TIMER_INTERVAL_STEPS[0]; + } + + this.timeNow = this.baseTime; + + this.setExtradata(this.timeNow + "\t" + this.baseTime); + room.updateItem(this); + this.needsUpdate(true); + + super.onPlace(room); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString("" + timeNow); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (this.getExtradata().isEmpty()) { + this.setExtradata("0\t" + this.TIMER_INTERVAL_STEPS[0]); + } + + // if wired triggered it + if (objects.length >= 2 && objects[1] instanceof WiredEffectType) { + if(!(!this.isRunning || this.isPaused)) + return; + + boolean wasPaused = this.isPaused; + this.endGame(room, true); + + if(wasPaused) { + WiredHandler.handle(WiredTriggerType.GAME_ENDS, null, room, new Object[]{}); + } + + this.createNewGame(room); + + this.timeNow = this.baseTime; + this.isRunning = true; + this.isPaused = false; + + room.updateItem(this); + WiredHandler.handle(WiredTriggerType.GAME_STARTS, null, room, new Object[]{}); + + if (!this.threadActive) { + this.threadActive = true; + Emulator.getThreading().run(new GameTimer(this), 1000); + } + } else if (client != null) { + if (!(room.hasRights(client.getHabbo()) || client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER))) + return; + + InteractionGameTimerAction state = InteractionGameTimerAction.START_STOP; + + if (objects.length >= 1 && objects[0] instanceof Integer) { + state = InteractionGameTimerAction.getByAction((int) objects[0]); + } + + switch (state) { + case START_STOP: + if (this.isRunning) { // a game has been started + this.isPaused = !this.isPaused; + if (this.isPaused) { + this.pause(room); + } else { + this.unpause(room); + + if (!this.threadActive) { + this.threadActive = true; + Emulator.getThreading().run(new GameTimer(this)); + } + } + } else { + this.isPaused = false; + this.isRunning = true; + this.timeNow = this.baseTime; + room.updateItem(this); + + this.createNewGame(room); + WiredHandler.handle(WiredTriggerType.GAME_STARTS, null, room, new Object[]{this}); + + if (!this.threadActive) { + this.threadActive = true; + Emulator.getThreading().run(new GameTimer(this), 1000); + } + } + + break; + + case INCREASE_TIME: + if (!this.isRunning) { + this.increaseTimer(room); + } else if (this.isPaused) { + this.endGame(room); + this.increaseTimer(room); + WiredHandler.handle(WiredTriggerType.GAME_ENDS, null, room, new Object[]{}); + } + + break; + } + } + + super.onClick(client, room, objects); + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + private void increaseTimer(Room room) { + if (this.isRunning) + return; + + int baseTime = -1; + + if (this.timeNow != this.baseTime) { + baseTime = this.baseTime; + } else { + for (int step : this.TIMER_INTERVAL_STEPS) { + if (this.timeNow < step) { + baseTime = step; + break; + } + } + + if (baseTime == -1) baseTime = this.TIMER_INTERVAL_STEPS[0]; + } + + this.baseTime = baseTime; + this.setExtradata(this.timeNow + "\t" + this.baseTime); + + this.timeNow = this.baseTime; + room.updateItem(this); + this.needsUpdate(true); + } + + @Override + public String getDatabaseExtraData() { + return this.getExtradata(); + } + + @Override + public boolean allowWiredResetState() { + return true; + } + + public boolean isRunning() { + return this.isRunning; + } + + public void setRunning(boolean running) { + this.isRunning = running; + } + + public void setThreadActive(boolean threadActive) { + this.threadActive = threadActive; + } + + public boolean isPaused() { + return this.isPaused; + } + + public void reduceTime() { + this.timeNow--; + } + + public int getTimeNow() { + return this.timeNow; + } + + public void setTimeNow(int timeNow) { + this.timeNow = timeNow; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiPuck.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiPuck.java new file mode 100644 index 0000000..67436d2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiPuck.java @@ -0,0 +1,186 @@ +package com.eu.habbo.habbohotel.items.interactions.games.battlebanzai; + +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.games.GameTeam; +import com.eu.habbo.habbohotel.games.battlebanzai.BattleBanzaiGame; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionPushable; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBattleBanzaiPuck extends InteractionPushable { + public InteractionBattleBanzaiPuck(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionBattleBanzaiPuck(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public int getWalkOnVelocity(RoomUnit roomUnit, Room room) { + return 6; + } + + @Override + public RoomUserRotation getWalkOnDirection(RoomUnit roomUnit, Room room) { + return roomUnit.getBodyRotation(); + } + + @Override + public int getWalkOffVelocity(RoomUnit roomUnit, Room room) { + return 0; + } + + @Override + public RoomUserRotation getWalkOffDirection(RoomUnit roomUnit, Room room) { + return roomUnit.getBodyRotation(); + } + + @Override + public int getDragVelocity(RoomUnit roomUnit, Room room) { + return 1; + } + + @Override + public RoomUserRotation getDragDirection(RoomUnit roomUnit, Room room) { + return roomUnit.getBodyRotation(); + } + + @Override + public int getTackleVelocity(RoomUnit roomUnit, Room room) { + return 6; + } + + @Override + public RoomUserRotation getTackleDirection(RoomUnit roomUnit, Room room) { + return roomUnit.getBodyRotation(); + } + + @Override + public int getNextRollDelay(int currentStep, int totalSteps) { + int t = 2500; + return (totalSteps == 1) ? 500 : 100 * ((t = t / t - 1) * t * t * t * t + 1) + (currentStep * 100); + } + + @Override + public RoomUserRotation getBounceDirection(Room room, RoomUserRotation currentDirection) { + switch (currentDirection) { + default: + case NORTH: + return RoomUserRotation.SOUTH; + + case NORTH_EAST: + if (this.validMove(room, room.getLayout().getTile(this.getX(), this.getY()), room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), RoomUserRotation.NORTH_WEST.getValue()))) + return RoomUserRotation.NORTH_WEST; + else if (this.validMove(room, room.getLayout().getTile(this.getX(), this.getY()), room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), RoomUserRotation.SOUTH_EAST.getValue()))) + return RoomUserRotation.SOUTH_EAST; + else + return RoomUserRotation.SOUTH_WEST; + + case EAST: + return RoomUserRotation.WEST; + + case SOUTH_EAST: + if (this.validMove(room, room.getLayout().getTile(this.getX(), this.getY()), room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), RoomUserRotation.SOUTH_WEST.getValue()))) + return RoomUserRotation.SOUTH_WEST; + else if (this.validMove(room, room.getLayout().getTile(this.getX(), this.getY()), room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), RoomUserRotation.NORTH_EAST.getValue()))) + return RoomUserRotation.NORTH_EAST; + else + return RoomUserRotation.NORTH_WEST; + + case SOUTH: + return RoomUserRotation.NORTH; + + case SOUTH_WEST: + if (this.validMove(room, room.getLayout().getTile(this.getX(), this.getY()), room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), RoomUserRotation.SOUTH_EAST.getValue()))) + return RoomUserRotation.SOUTH_EAST; + else if (this.validMove(room, room.getLayout().getTile(this.getX(), this.getY()), room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), RoomUserRotation.NORTH_WEST.getValue()))) + return RoomUserRotation.NORTH_WEST; + else + return RoomUserRotation.NORTH_EAST; + + case WEST: + return RoomUserRotation.EAST; + + case NORTH_WEST: + if (this.validMove(room, room.getLayout().getTile(this.getX(), this.getY()), room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), RoomUserRotation.NORTH_EAST.getValue()))) + return RoomUserRotation.NORTH_EAST; + else if (this.validMove(room, room.getLayout().getTile(this.getX(), this.getY()), room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), RoomUserRotation.SOUTH_WEST.getValue()))) + return RoomUserRotation.SOUTH_WEST; + else + return RoomUserRotation.SOUTH_EAST; + } + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + } + + @Override + public boolean validMove(Room room, RoomTile from, RoomTile to) { + if (to == null) return false; + HabboItem topItem = room.getTopItemAt(to.x, to.y, this); + return !(!room.getLayout().tileWalkable(to.x, to.y) || (topItem != null && (!topItem.getBaseItem().allowStack() || topItem.getBaseItem().allowSit() || topItem.getBaseItem().allowLay()))); + + //return !(!room.getLayout().tileWalkable(to.x, to.y) || (topItem != null && (!topItem.getBaseItem().setAllowStack() || topItem.getBaseItem().allowSit() || topItem.getBaseItem().allowLay()))); + } + + @Override + public void onDrag(Room room, RoomUnit roomUnit, int velocity, RoomUserRotation direction) { + + } + + @Override + public void onKick(Room room, RoomUnit roomUnit, int velocity, RoomUserRotation direction) { + + } + + @Override + public void onTackle(Room room, RoomUnit roomUnit, int velocity, RoomUserRotation direction) { + + } + + @Override + public void onMove(Room room, RoomTile from, RoomTile to, RoomUserRotation direction, RoomUnit kicker, int nextRoll, int currentStep, int totalSteps) { + Habbo habbo = room.getHabbo(kicker); + + if (habbo != null) { + BattleBanzaiGame game = (BattleBanzaiGame) room.getGame(BattleBanzaiGame.class); + if (game != null) { + GameTeam team = game.getTeamForHabbo(habbo); + if (team != null) { + HabboItem item = room.getTopItemAt(to.x, to.y); + try { + item.onWalkOn(kicker, room, null); + } catch (Exception e) { + return; + } + this.setExtradata(team.teamColor.type + ""); + room.updateItemState(this); + } + } + } + //TODO Implement point counting logic. + } + + @Override + public void onBounce(Room room, RoomUserRotation oldDirection, RoomUserRotation newDirection, RoomUnit kicker) { + + } + + @Override + public void onStop(Room room, RoomUnit kicker, int currentStep, int totalSteps) { + + } + + @Override + public boolean canStillMove(Room room, RoomTile from, RoomTile to, RoomUserRotation direction, RoomUnit kicker, int nextRoll, int currentStep, int totalSteps) { + return to.state == RoomTileState.OPEN && to.isWalkable(); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiSphere.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiSphere.java new file mode 100644 index 0000000..8494b4c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiSphere.java @@ -0,0 +1,44 @@ +package com.eu.habbo.habbohotel.items.interactions.games.battlebanzai; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBattleBanzaiSphere extends HabboItem { + public InteractionBattleBanzaiSphere(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionBattleBanzaiSphere(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiTeleporter.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiTeleporter.java new file mode 100644 index 0000000..98a627f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiTeleporter.java @@ -0,0 +1,76 @@ +package com.eu.habbo.habbohotel.items.interactions.games.battlebanzai; + +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.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.threading.runnables.BanzaiRandomTeleport; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBattleBanzaiTeleporter extends HabboItem { + public InteractionBattleBanzaiTeleporter(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionBattleBanzaiTeleporter(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + if(objects.length < 3) { + HabboItem target = room.getRoomSpecialTypes().getRandomTeleporter(null, this); + if (target == null) return; + + this.setExtradata("1"); + room.updateItemState(this); + roomUnit.removeStatus(RoomUnitStatus.MOVE); + roomUnit.setGoalLocation(roomUnit.getCurrentLocation()); + roomUnit.setCanWalk(false); + Emulator.getThreading().run(new BanzaiRandomTeleport(this, target, roomUnit, room), 500); + } + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiTile.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiTile.java new file mode 100644 index 0000000..8e36461 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/InteractionBattleBanzaiTile.java @@ -0,0 +1,121 @@ +package com.eu.habbo.habbohotel.items.interactions.games.battlebanzai; + +import com.eu.habbo.habbohotel.games.GameState; +import com.eu.habbo.habbohotel.games.battlebanzai.BattleBanzaiGame; +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.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; +import org.apache.commons.math3.util.Pair; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class InteractionBattleBanzaiTile extends HabboItem { + public InteractionBattleBanzaiTile(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionBattleBanzaiTile(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + if (this.getExtradata().isEmpty()) + this.setExtradata("0"); + + int state = Integer.valueOf(this.getExtradata()); + + if (state % 3 == 2) + return; + + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo == null) + return; + + if (this.isLocked()) + return; + + if (habbo.getHabboInfo().getCurrentGame() != null && habbo.getHabboInfo().getCurrentGame().equals(BattleBanzaiGame.class)) { + BattleBanzaiGame game = ((BattleBanzaiGame) room.getGame(BattleBanzaiGame.class)); + + if (game == null) + return; + + if (!game.state.equals(GameState.RUNNING)) + return; + + game.markTile(habbo, this, state); + } + + } + + public boolean isLocked() { + if (this.getExtradata().isEmpty()) + return false; + + return Integer.valueOf(this.getExtradata()) % 3 == 2; + } + + @Override + public boolean canStackAt(Room room, List>> itemsAtLocation) { + for (Pair> set : itemsAtLocation) { + if (set.getValue() != null && !set.getValue().isEmpty()) return false; + } + + return super.canStackAt(room, itemsAtLocation); + } + + @Override + public void onPickUp(Room room) { + super.onPickUp(room); + + this.setExtradata("0"); + room.updateItem(this); + } + + @Override + public void onPlace(Room room) { + super.onPlace(room); + + BattleBanzaiGame game = (BattleBanzaiGame) room.getGame(BattleBanzaiGame.class); + + if (game != null && game.getState() != GameState.IDLE) { + this.setExtradata("1"); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGate.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGate.java new file mode 100644 index 0000000..04def88 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGate.java @@ -0,0 +1,69 @@ +package com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.gates; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.games.GameState; +import com.eu.habbo.habbohotel.games.GameTeam; +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.games.battlebanzai.BattleBanzaiGame; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameGate; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBattleBanzaiGate extends InteractionGameGate { + public InteractionBattleBanzaiGate(ResultSet set, Item baseItem, GameTeamColors teamColor) throws SQLException { + super(set, baseItem, teamColor); + } + + public InteractionBattleBanzaiGate(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells, GameTeamColors teamColor) { + super(id, userId, item, extradata, limitedStack, limitedSells, teamColor); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return room.getGame(BattleBanzaiGame.class) == null || ((BattleBanzaiGame) room.getGame(BattleBanzaiGame.class)).state.equals(GameState.IDLE); + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public boolean isWalkable() { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room == null) return false; + + Game game = room.getGame(BattleBanzaiGame.class); + + return game == null || game.getState() == GameState.IDLE; + } + + //TODO: Move to upper class + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + BattleBanzaiGame game = (BattleBanzaiGame) room.getGame(BattleBanzaiGame.class); + + if (game == null) { + game = BattleBanzaiGame.class.getDeclaredConstructor(Room.class).newInstance(room); + room.addGame(game); + } + + GameTeam team = game.getTeamForHabbo(room.getHabbo(roomUnit)); + + if (team != null) { + game.removeHabbo(room.getHabbo(roomUnit)); + } else { + game.addHabbo(room.getHabbo(roomUnit), this.teamColor); + } + + updateState(game, 5); + + super.onWalkOn(roomUnit, room, objects); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGateBlue.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGateBlue.java new file mode 100644 index 0000000..206bd98 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGateBlue.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.gates; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBattleBanzaiGateBlue extends InteractionBattleBanzaiGate { + public static final GameTeamColors TEAM_COLOR = GameTeamColors.BLUE; + + public InteractionBattleBanzaiGateBlue(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, TEAM_COLOR); + } + + public InteractionBattleBanzaiGateBlue(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, TEAM_COLOR); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGateGreen.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGateGreen.java new file mode 100644 index 0000000..ee488fb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGateGreen.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.gates; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBattleBanzaiGateGreen extends InteractionBattleBanzaiGate { + public static final GameTeamColors TEAM_COLOR = GameTeamColors.GREEN; + + public InteractionBattleBanzaiGateGreen(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, TEAM_COLOR); + } + + public InteractionBattleBanzaiGateGreen(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, TEAM_COLOR); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGateRed.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGateRed.java new file mode 100644 index 0000000..ceeca70 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGateRed.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.gates; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBattleBanzaiGateRed extends InteractionBattleBanzaiGate { + public static final GameTeamColors TEAM_COLOR = GameTeamColors.RED; + + public InteractionBattleBanzaiGateRed(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, TEAM_COLOR); + } + + public InteractionBattleBanzaiGateRed(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, TEAM_COLOR); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGateYellow.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGateYellow.java new file mode 100644 index 0000000..ec6609e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/gates/InteractionBattleBanzaiGateYellow.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.gates; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBattleBanzaiGateYellow extends InteractionBattleBanzaiGate { + public static final GameTeamColors TEAM_COLOR = GameTeamColors.YELLOW; + + public InteractionBattleBanzaiGateYellow(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, TEAM_COLOR); + } + + public InteractionBattleBanzaiGateYellow(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, TEAM_COLOR); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboard.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboard.java new file mode 100644 index 0000000..e3b8c24 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboard.java @@ -0,0 +1,35 @@ +package com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.scoreboards; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameScoreboard; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBattleBanzaiScoreboard extends InteractionGameScoreboard { + public InteractionBattleBanzaiScoreboard(ResultSet set, Item baseItem, GameTeamColors teamColor) throws SQLException { + super(set, baseItem, teamColor); + } + + public InteractionBattleBanzaiScoreboard(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells, GameTeamColors teamColor) { + super(id, userId, item, extradata, limitedStack, limitedSells, teamColor); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboardBlue.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboardBlue.java new file mode 100644 index 0000000..a545273 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboardBlue.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.scoreboards; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBattleBanzaiScoreboardBlue extends InteractionBattleBanzaiScoreboard { + public static final GameTeamColors TEAM_COLOR = GameTeamColors.BLUE; + + public InteractionBattleBanzaiScoreboardBlue(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, TEAM_COLOR); + } + + public InteractionBattleBanzaiScoreboardBlue(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, TEAM_COLOR); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboardGreen.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboardGreen.java new file mode 100644 index 0000000..a42332f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboardGreen.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.scoreboards; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBattleBanzaiScoreboardGreen extends InteractionBattleBanzaiScoreboard { + public static final GameTeamColors TEAM_COLOR = GameTeamColors.GREEN; + + public InteractionBattleBanzaiScoreboardGreen(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, TEAM_COLOR); + } + + public InteractionBattleBanzaiScoreboardGreen(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, TEAM_COLOR); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboardRed.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboardRed.java new file mode 100644 index 0000000..9abf0aa --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboardRed.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.scoreboards; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBattleBanzaiScoreboardRed extends InteractionBattleBanzaiScoreboard { + public static final GameTeamColors TEAM_COLOR = GameTeamColors.RED; + + public InteractionBattleBanzaiScoreboardRed(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, TEAM_COLOR); + } + + public InteractionBattleBanzaiScoreboardRed(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, TEAM_COLOR); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboardYellow.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboardYellow.java new file mode 100644 index 0000000..6b4b895 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/battlebanzai/scoreboards/InteractionBattleBanzaiScoreboardYellow.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.scoreboards; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBattleBanzaiScoreboardYellow extends InteractionBattleBanzaiScoreboard { + public static final GameTeamColors TEAM_COLOR = GameTeamColors.YELLOW; + + public InteractionBattleBanzaiScoreboardYellow(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, TEAM_COLOR); + } + + public InteractionBattleBanzaiScoreboardYellow(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, TEAM_COLOR); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionFootball.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionFootball.java new file mode 100644 index 0000000..6bd2116 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionFootball.java @@ -0,0 +1,259 @@ +package com.eu.habbo.habbohotel.items.interactions.games.football; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.games.football.FootballGame; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionPushable; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTeamItem; +import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoal; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.rooms.items.ItemStateComposer; +import com.eu.habbo.util.pathfinding.Rotation; + +import java.math.BigDecimal; +import java.sql.ResultSet; +import java.sql.SQLException; + + +public class InteractionFootball extends InteractionPushable { + + public InteractionFootball(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionFootball(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + + @Override + public int getWalkOnVelocity(RoomUnit roomUnit, Room room) { + if (roomUnit.getPath().isEmpty() && roomUnit.tilesWalked() == 2 && this.getExtradata().equals("1")) + return 0; + + if (roomUnit.getPath().size() == 0 && roomUnit.tilesWalked() == 1) + return 6; + + return 1; + } + + @Override + public int getWalkOffVelocity(RoomUnit roomUnit, Room room) { + if (roomUnit.getPath().size() == 0 && roomUnit.tilesWalked() == 0) + return 6; + + return 1; + } + + @Override + public int getDragVelocity(RoomUnit roomUnit, Room room) { + if (roomUnit.getPath().isEmpty() && roomUnit.tilesWalked() == 2) + return 0; + + return 1; + } + + @Override + public int getTackleVelocity(RoomUnit roomUnit, Room room) { + return 4; + } + + + @Override + public RoomUserRotation getWalkOnDirection(RoomUnit roomUnit, Room room) { + return roomUnit.getBodyRotation(); + } + + @Override + public RoomUserRotation getWalkOffDirection(RoomUnit roomUnit, Room room) { + RoomTile peek = roomUnit.getPath().peek(); + RoomTile nextWalkTile = peek != null ? room.getLayout().getTile(peek.x, peek.y) : roomUnit.getGoal(); + return RoomUserRotation.values()[(RoomUserRotation.values().length + Rotation.Calculate(roomUnit.getX(), roomUnit.getY(), nextWalkTile.x, nextWalkTile.y) + 4) % 8]; + } + + public RoomUserRotation getDragDirection(RoomUnit roomUnit, Room room) { + return roomUnit.getBodyRotation(); + } + + public RoomUserRotation getTackleDirection(RoomUnit roomUnit, Room room) { + return roomUnit.getBodyRotation(); + } + + + @Override + public int getNextRollDelay(int currentStep, int totalSteps) { + + if(totalSteps > 4) { + if(currentStep <= 4) { + return 125; + } + } + + return 500; + + /*int t = 2500; + return (totalSteps == 1) ? 500 : 100 * ((t = t / t - 1) * t * t * t * t + 1) + (currentStep * 100);*/ + } + + @Override + public RoomUserRotation getBounceDirection(Room room, RoomUserRotation currentDirection) { + switch (currentDirection) { + default: + case NORTH: + return RoomUserRotation.SOUTH; + + case NORTH_EAST: + if (this.validMove(room, room.getLayout().getTile(this.getX(), this.getY()), room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), RoomUserRotation.NORTH_WEST.getValue()))) + return RoomUserRotation.NORTH_WEST; + else if (this.validMove(room, room.getLayout().getTile(this.getX(), this.getY()), room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), RoomUserRotation.SOUTH_EAST.getValue()))) + return RoomUserRotation.SOUTH_EAST; + else + return RoomUserRotation.SOUTH_WEST; + + case EAST: + return RoomUserRotation.WEST; + + case SOUTH_EAST: + if (this.validMove(room, room.getLayout().getTile(this.getX(), this.getY()), room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), RoomUserRotation.SOUTH_WEST.getValue()))) + return RoomUserRotation.SOUTH_WEST; + else if (this.validMove(room, room.getLayout().getTile(this.getX(), this.getY()), room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), RoomUserRotation.NORTH_EAST.getValue()))) + return RoomUserRotation.NORTH_EAST; + else + return RoomUserRotation.NORTH_WEST; + + case SOUTH: + return RoomUserRotation.NORTH; + + case SOUTH_WEST: + if (this.validMove(room, room.getLayout().getTile(this.getX(), this.getY()), room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), RoomUserRotation.SOUTH_EAST.getValue()))) + return RoomUserRotation.SOUTH_EAST; + else if (this.validMove(room, room.getLayout().getTile(this.getX(), this.getY()), room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), RoomUserRotation.NORTH_WEST.getValue()))) + return RoomUserRotation.NORTH_WEST; + else + return RoomUserRotation.NORTH_EAST; + + case WEST: + return RoomUserRotation.EAST; + + case NORTH_WEST: + if (this.validMove(room, room.getLayout().getTile(this.getX(), this.getY()), room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), RoomUserRotation.NORTH_EAST.getValue()))) + return RoomUserRotation.NORTH_EAST; + else if (this.validMove(room, room.getLayout().getTile(this.getX(), this.getY()), room.getLayout().getTileInFront(room.getLayout().getTile(this.getX(), this.getY()), RoomUserRotation.SOUTH_WEST.getValue()))) + return RoomUserRotation.SOUTH_WEST; + else + return RoomUserRotation.SOUTH_EAST; + } + } + + + @Override + public boolean validMove(Room room, RoomTile from, RoomTile to) { + if (to == null || to.state == RoomTileState.INVALID) return false; + HabboItem topItem = room.getTopItemAt(to.x, to.y, this); + + // Move is valid if there isnt any furni yet + if (topItem == null) { + return true; + } + + // If any furni on tile is not stackable, move is invalid (tested on 22-03-2022) + if (room.getItemsAt(to).stream().anyMatch(x -> !x.getBaseItem().allowStack())) { + return false; + } + + // Ball can only go up by 1.65 according to Habbo (tested using stack tile on 22-03-2022) + BigDecimal topItemHeight = BigDecimal.valueOf(topItem.getZ() + topItem.getBaseItem().getHeight()); + BigDecimal ballHeight = BigDecimal.valueOf(this.getZ()); + + if (topItemHeight.subtract(ballHeight).compareTo(new BigDecimal(1.65)) > 0) { + return false; + } + + // If top item is a football goal, the move is only valid if ball is coming from the front side + // Ball shouldn't come from the back or from the sides (tested on 22-03-2022) + if (topItem instanceof InteractionFootballGoal) { + int ballDirection = Rotation.Calculate(from.x, from.y, to.x, to.y); + int goalRotation = topItem.getRotation(); + + switch (goalRotation) { + case 0: + return ballDirection > 2 && ballDirection < 6; + case 2: + return ballDirection > 4; + case 4: + return ballDirection > 6 || ballDirection < 2; + case 6: + return ballDirection > 0 && ballDirection < 4; + } + } + + return topItem.getBaseItem().allowStack(); + } + + //Events + + @Override + public void onDrag(Room room, RoomUnit roomUnit, int velocity, RoomUserRotation direction) { + + } + + @Override + public void onKick(Room room, RoomUnit roomUnit, int velocity, RoomUserRotation direction) { + + } + + @Override + public void onTackle(Room room, RoomUnit roomUnit, int velocity, RoomUserRotation direction) { + + } + + @Override + public void onMove(Room room, RoomTile from, RoomTile to, RoomUserRotation direction, RoomUnit kicker, int nextRoll, int currentStep, int totalSteps) { + FootballGame game = (FootballGame) room.getGame(FootballGame.class); + if (game == null) { + try { + game = FootballGame.class.getDeclaredConstructor(new Class[]{Room.class}).newInstance(room); + room.addGame(game); + } catch (Exception e) { + return; + } + } + HabboItem currentTopItem = room.getTopItemAt(from.x, from.y, this); + HabboItem topItem = room.getTopItemAt(to.x, to.y, this); + if ((topItem != null) && ((currentTopItem == null) || (currentTopItem.getId() != topItem.getId())) && ((topItem instanceof InteractionFootballGoal))) { + GameTeamColors color = ((InteractionGameTeamItem) topItem).teamColor; + game.onScore(kicker, color); + } + + this.setExtradata(Math.abs(currentStep - (totalSteps + 1)) + ""); + room.sendComposer(new ItemStateComposer(this).compose()); + + /*this.setExtradata(nextRoll <= 200 ? "8" : (nextRoll <= 250 ? "7" : (nextRoll <= 300 ? "6" : (nextRoll <= 350 ? "5" : (nextRoll <= 400 ? "4" : (nextRoll <= 450 ? "3" : (nextRoll <= 500 ? "2" : "1"))))))); + room.sendComposer(new ItemStateComposer(this).compose());*/ + } + + @Override + public void onBounce(Room room, RoomUserRotation oldDirection, RoomUserRotation newDirection, RoomUnit kicker) { + + } + + @Override + public void onStop(Room room, RoomUnit kicker, int currentStep, int totalSteps) { + this.setExtradata("0"); + room.sendComposer(new ItemStateComposer(this).compose()); + } + + @Override + public boolean canStillMove(Room room, RoomTile from, RoomTile to, RoomUserRotation direction, RoomUnit kicker, int nextRoll, int currentStep, int totalSteps) { + HabboItem topItem = room.getTopItemAt(from.x, from.y, this); + return !((Emulator.getRandom().nextInt(10) >= 3 && room.hasHabbosAt(to.x, to.y)) || (topItem != null && topItem.getBaseItem().getName().startsWith("fball_goal_") && currentStep != 1)); + } + + @Override + public void onPickUp(Room room) { + this.setExtradata("0"); + } + +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionFootballGate.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionFootballGate.java new file mode 100644 index 0000000..265b4cb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionFootballGate.java @@ -0,0 +1,148 @@ +package com.eu.habbo.habbohotel.items.interactions.games.football; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.users.clothingvalidation.ClothingValidationManager; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer; +import com.eu.habbo.messages.outgoing.users.UpdateUserLookComposer; +import com.eu.habbo.plugin.EventHandler; +import com.eu.habbo.plugin.events.users.UserDisconnectEvent; +import com.eu.habbo.plugin.events.users.UserExitRoomEvent; +import com.eu.habbo.plugin.events.users.UserSavedLookEvent; +import com.eu.habbo.util.figure.FigureUtil; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFootballGate extends HabboItem { + private static final String CACHE_KEY = "fball_gate_look"; + private String figureM; + private String figureF; + + public InteractionFootballGate(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + + String[] bits = set.getString("extra_data").split(";"); + this.figureM = bits.length > 0 ? bits[0] : ""; + this.figureF = bits.length > 1 ? bits[1] : ""; + } + + public InteractionFootballGate(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + + String[] bits = extradata.split(";"); + this.figureM = bits.length > 0 ? bits[0] : ""; + this.figureF = bits.length > 1 ? bits[1] : ""; + } + + @EventHandler + public static void onUserDisconnectEvent(UserDisconnectEvent event) { + if (event.habbo != null) { + removeLook(event.habbo); + } + } + + @EventHandler + public static void onUserExitRoomEvent(UserExitRoomEvent event) { + if (event.habbo != null) { + removeLook(event.habbo); + } + } + + @EventHandler + public static void onUserSavedLookEvent(UserSavedLookEvent event) { + if (event.habbo != null) { + removeLook(event.habbo); + } + } + + private static void removeLook(Habbo habbo) { + if (habbo.getHabboStats().cache.containsKey(CACHE_KEY)) { + habbo.getHabboInfo().setLook((String) habbo.getHabboStats().cache.get(CACHE_KEY)); + habbo.getHabboStats().cache.remove(CACHE_KEY); + habbo.getClient().sendResponse(new UpdateUserLookComposer(habbo)); + if (habbo.getHabboInfo().getCurrentRoom() != null) { + habbo.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserDataComposer(habbo).compose()); + } + } + } + + public void setFigureM(String look) { + this.figureM = look; + + this.setExtradata(this.figureM + ";" + this.figureF); + this.needsUpdate(true); + Emulator.getThreading().run(this); + } + + public void setFigureF(String look) { + this.figureF = look; + + this.setExtradata(this.figureM + ";" + this.figureF); + this.needsUpdate(true); + Emulator.getThreading().run(this); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.figureM + "," + this.figureF); + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + Habbo habbo = room.getHabbo(roomUnit); + if (habbo != null) { + if (habbo.getHabboStats().cache.containsKey(CACHE_KEY)) { + String oldlook = (String) habbo.getHabboStats().cache.get(CACHE_KEY); + + UserSavedLookEvent lookEvent = new UserSavedLookEvent(habbo, habbo.getHabboInfo().getGender(), oldlook); + Emulator.getPluginManager().fireEvent(lookEvent); + if (!lookEvent.isCancelled()) { + habbo.getHabboInfo().setLook(ClothingValidationManager.VALIDATE_ON_FBALLGATE ? ClothingValidationManager.validateLook(habbo, lookEvent.newLook, lookEvent.gender.name()) : lookEvent.newLook); + Emulator.getThreading().run(habbo.getHabboInfo()); + habbo.getClient().sendResponse(new UpdateUserLookComposer(habbo)); + room.sendComposer(new RoomUserDataComposer(habbo).compose()); + } + + habbo.getHabboStats().cache.remove(CACHE_KEY); + } else { + String finalLook = FigureUtil.mergeFigures(habbo.getHabboInfo().getLook(), habbo.getHabboInfo().getGender() == HabboGender.F ? this.figureF : this.figureM, new String[]{"hd", "hr", "ha", "he", "ea", "fa"}, new String[]{"ch", "ca", "cc", "cp", "lg", "wa", "sh"}); + + UserSavedLookEvent lookEvent = new UserSavedLookEvent(habbo, habbo.getHabboInfo().getGender(), finalLook); + Emulator.getPluginManager().fireEvent(lookEvent); + if (!lookEvent.isCancelled()) { + habbo.getHabboStats().cache.put(CACHE_KEY, habbo.getHabboInfo().getLook()); + habbo.getHabboInfo().setLook(ClothingValidationManager.VALIDATE_ON_FBALLGATE ? ClothingValidationManager.validateLook(habbo, lookEvent.newLook, lookEvent.gender.name()) : lookEvent.newLook); + Emulator.getThreading().run(habbo.getHabboInfo()); + habbo.getClient().sendResponse(new UpdateUserLookComposer(habbo)); + room.sendComposer(new RoomUserDataComposer(habbo).compose()); + } + } + } + + super.onWalkOn(roomUnit, room, objects); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoal.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoal.java new file mode 100644 index 0000000..a3ef520 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoal.java @@ -0,0 +1,44 @@ +package com.eu.habbo.habbohotel.items.interactions.games.football.goals; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTeamItem; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFootballGoal extends InteractionGameTeamItem { + public InteractionFootballGoal(ResultSet set, Item baseItem, GameTeamColors teamColor) throws SQLException { + super(set, baseItem, teamColor); + } + + public InteractionFootballGoal(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells, GameTeamColors teamColor) { + super(id, userId, item, extradata, limitedStack, limitedSells, teamColor); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return this.getBaseItem().allowWalk(); + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoalBlue.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoalBlue.java new file mode 100644 index 0000000..34d2b52 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoalBlue.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.items.interactions.games.football.goals; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFootballGoalBlue extends InteractionFootballGoal { + public InteractionFootballGoalBlue(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, GameTeamColors.BLUE); + } + + public InteractionFootballGoalBlue(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, GameTeamColors.BLUE); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoalGreen.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoalGreen.java new file mode 100644 index 0000000..42276c9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoalGreen.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.items.interactions.games.football.goals; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFootballGoalGreen extends InteractionFootballGoal { + public InteractionFootballGoalGreen(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, GameTeamColors.GREEN); + } + + public InteractionFootballGoalGreen(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, GameTeamColors.GREEN); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoalRed.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoalRed.java new file mode 100644 index 0000000..b4d9b5d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoalRed.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.items.interactions.games.football.goals; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFootballGoalRed extends InteractionFootballGoal { + public InteractionFootballGoalRed(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, GameTeamColors.RED); + } + + public InteractionFootballGoalRed(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, GameTeamColors.RED); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoalYellow.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoalYellow.java new file mode 100644 index 0000000..ba72503 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/goals/InteractionFootballGoalYellow.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.items.interactions.games.football.goals; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFootballGoalYellow extends InteractionFootballGoal { + public InteractionFootballGoalYellow(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, GameTeamColors.YELLOW); + } + + public InteractionFootballGoalYellow(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, GameTeamColors.YELLOW); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboard.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboard.java new file mode 100644 index 0000000..2ef7f30 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboard.java @@ -0,0 +1,137 @@ +package com.eu.habbo.habbohotel.items.interactions.games.football.scoreboards; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameScoreboard; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredEffectType; + +import java.sql.ResultSet; +import java.sql.SQLException; + + +public class InteractionFootballScoreboard extends InteractionGameScoreboard { + private int score; + + public InteractionFootballScoreboard(ResultSet set, Item baseItem, GameTeamColors teamColor) throws SQLException { + super(set, baseItem, teamColor); + + try { + this.score = Integer.parseInt(this.getExtradata()); + } catch (Exception e) { + this.score = 0; + } + } + + public InteractionFootballScoreboard(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells, GameTeamColors teamColor) { + super(id, userId, item, extradata, limitedStack, limitedSells, teamColor); + + try { + this.score = Integer.parseInt(extradata); + } catch (Exception e) { + this.score = 0; + } + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + + public int changeScore(int amount) { + this.score += amount; + + if (this.score > 99) { + this.score = 0; + } + + if (this.score < 0) { + this.score = 99; + } + + this.setExtradata(this.score + ""); + this.needsUpdate(true); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room != null) { + room.updateItem(this); + } + + return this.score; + } + + public int getScore() { + return this.score; + } + + public void setScore(int amount) { + this.score = amount; + + if (this.score > 99) { + this.score = 0; + } + + if (this.score < 0) { + this.score = 99; + } + + this.setExtradata(this.score + ""); + this.needsUpdate(true); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room != null) { + room.updateItem(this); + } + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + + if (objects.length >= 1 && objects[0] instanceof Integer && client != null && !(objects.length >= 2 && objects[1] instanceof WiredEffectType)) { + int state = (Integer) objects[0]; + + switch (state) { + case 1: { + this.changeScore(1); + } + break; + + case 2: { + this.changeScore(-1); + } + break; + + default: + this.setScore(0); + break; + } + } else { + this.changeScore(1); + } + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboardBlue.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboardBlue.java new file mode 100644 index 0000000..1a4cd21 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboardBlue.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.items.interactions.games.football.scoreboards; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFootballScoreboardBlue extends InteractionFootballScoreboard { + public InteractionFootballScoreboardBlue(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, GameTeamColors.BLUE); + } + + public InteractionFootballScoreboardBlue(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, GameTeamColors.BLUE); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboardGreen.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboardGreen.java new file mode 100644 index 0000000..1f785c0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboardGreen.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.items.interactions.games.football.scoreboards; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFootballScoreboardGreen extends InteractionFootballScoreboard { + public InteractionFootballScoreboardGreen(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, GameTeamColors.GREEN); + } + + public InteractionFootballScoreboardGreen(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, GameTeamColors.GREEN); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboardRed.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboardRed.java new file mode 100644 index 0000000..6d65b7e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboardRed.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.items.interactions.games.football.scoreboards; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFootballScoreboardRed extends InteractionFootballScoreboard { + public InteractionFootballScoreboardRed(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, GameTeamColors.RED); + } + + public InteractionFootballScoreboardRed(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, GameTeamColors.RED); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboardYellow.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboardYellow.java new file mode 100644 index 0000000..731a9e8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/scoreboards/InteractionFootballScoreboardYellow.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.items.interactions.games.football.scoreboards; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFootballScoreboardYellow extends InteractionFootballScoreboard { + public InteractionFootballScoreboardYellow(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, GameTeamColors.YELLOW); + } + + public InteractionFootballScoreboardYellow(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, GameTeamColors.YELLOW); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/InteractionFreezeBlock.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/InteractionFreezeBlock.java new file mode 100644 index 0000000..84ed555 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/InteractionFreezeBlock.java @@ -0,0 +1,129 @@ +package com.eu.habbo.habbohotel.items.interactions.games.freeze; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.games.GameState; +import com.eu.habbo.habbohotel.games.freeze.FreezeGame; +import com.eu.habbo.habbohotel.games.freeze.FreezeGamePlayer; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFreezeBlock extends HabboItem { + public InteractionFreezeBlock(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionFreezeBlock(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (client == null) + return; + + HabboItem item = null; + THashSet items = room.getItemsAt(room.getLayout().getTile(this.getX(), this.getY())); + + for (HabboItem i : items) { + if (i instanceof InteractionFreezeTile) { + if (item == null || i.getZ() <= item.getZ()) { + item = i; + } + } + } + + if (item != null) { + FreezeGame game = (FreezeGame) room.getGame(FreezeGame.class); + + if (game == null) + return; + + game.throwBall(client.getHabbo(), (InteractionFreezeTile) item); + } + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + if (this.getExtradata().length() == 0) { + this.setExtradata("0"); + } + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return this.isWalkable(); + } + + @Override + public boolean isWalkable() { + return !this.getExtradata().isEmpty() && !this.getExtradata().equals("0"); + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + if (this.getExtradata().isEmpty() || this.getExtradata().equalsIgnoreCase("0")) + return; + + FreezeGame game = (FreezeGame) room.getGame(FreezeGame.class); + if (game == null || !game.state.equals(GameState.RUNNING)) + return; + + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo == null || habbo.getHabboInfo().getCurrentGame() != FreezeGame.class) + return; + + FreezeGamePlayer player = (FreezeGamePlayer) habbo.getHabboInfo().getGamePlayer(); + + if (player == null) + return; + + int powerUp; + try { + powerUp = Integer.valueOf(this.getExtradata()) / 1000; + } catch (NumberFormatException e) { + powerUp = 0; + } + + if (powerUp >= 2 && powerUp <= 7) { + if (powerUp == 6 && !player.canPickupLife()) + return; + + this.setExtradata((powerUp + 10) * 1000 + ""); + + room.updateItem(this); + + game.givePowerUp(player, powerUp); + + AchievementManager.progressAchievement(player.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("FreezePowerUp")); + } + } + + @Override + public void onPickUp(Room room) { + this.setExtradata("0"); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/InteractionFreezeExitTile.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/InteractionFreezeExitTile.java new file mode 100644 index 0000000..cf07b29 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/InteractionFreezeExitTile.java @@ -0,0 +1,50 @@ +package com.eu.habbo.habbohotel.items.interactions.games.freeze; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFreezeExitTile extends HabboItem { + public InteractionFreezeExitTile(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionFreezeExitTile(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public void onPickUp(Room room) { + this.setExtradata("0"); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/InteractionFreezeTile.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/InteractionFreezeTile.java new file mode 100644 index 0000000..5b98b82 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/InteractionFreezeTile.java @@ -0,0 +1,84 @@ +package com.eu.habbo.habbohotel.items.interactions.games.freeze; + +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.games.freeze.FreezeGame; +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.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; +import org.apache.commons.math3.util.Pair; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class InteractionFreezeTile extends HabboItem { + public InteractionFreezeTile(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionFreezeTile(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (client == null) + return; + + if (client.getHabbo().getRoomUnit().getCurrentLocation().x == this.getX() && client.getHabbo().getRoomUnit().getCurrentLocation().y == this.getY()) { + FreezeGame game = (FreezeGame) room.getGame(FreezeGame.class); + + if (game != null) + game.throwBall(client.getHabbo(), this); + } + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public void onPickUp(Room room) { + this.setExtradata("0"); + } + + @Override + public boolean allowWiredResetState() { + return false; + } + + + @Override + public boolean canStackAt(Room room, List>> itemsAtLocation) { + for (Pair> set : itemsAtLocation) { + if (set.getValue() != null && !set.getValue().isEmpty()) return false; + } + + return super.canStackAt(room, itemsAtLocation); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGate.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGate.java new file mode 100644 index 0000000..ec583fd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGate.java @@ -0,0 +1,67 @@ +package com.eu.habbo.habbohotel.items.interactions.games.freeze.gates; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.games.GameState; +import com.eu.habbo.habbohotel.games.GameTeam; +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.games.freeze.FreezeGame; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameGate; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFreezeGate extends InteractionGameGate { + public InteractionFreezeGate(ResultSet set, Item baseItem, GameTeamColors teamColor) throws SQLException { + super(set, baseItem, teamColor); + } + + public InteractionFreezeGate(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells, GameTeamColors teamColor) { + super(id, userId, item, extradata, limitedStack, limitedSells, teamColor); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return room.getGame(FreezeGame.class) == null || ((FreezeGame) room.getGame(FreezeGame.class)).state.equals(GameState.IDLE); + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + } + + @Override + public boolean isWalkable() { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room == null) return false; + + Game game = room.getGame(FreezeGame.class); + + return game == null || game.getState() == GameState.IDLE; + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + FreezeGame game = (FreezeGame) room.getGame(FreezeGame.class); + + if (game == null) { + game = FreezeGame.class.getDeclaredConstructor(Room.class).newInstance(room); + room.addGame(game); + } + + GameTeam team = game.getTeamForHabbo(room.getHabbo(roomUnit)); + + if (team != null) { + game.removeHabbo(room.getHabbo(roomUnit)); + } else { + game.addHabbo(room.getHabbo(roomUnit), this.teamColor); + } + + updateState(game, 5); + + super.onWalkOn(roomUnit, room, objects); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGateBlue.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGateBlue.java new file mode 100644 index 0000000..9004025 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGateBlue.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.items.interactions.games.freeze.gates; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFreezeGateBlue extends InteractionFreezeGate { + public static final GameTeamColors TEAM_COLOR = GameTeamColors.BLUE; + + public InteractionFreezeGateBlue(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, TEAM_COLOR); + } + + public InteractionFreezeGateBlue(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, TEAM_COLOR); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGateGreen.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGateGreen.java new file mode 100644 index 0000000..dd62a2e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGateGreen.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.items.interactions.games.freeze.gates; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFreezeGateGreen extends InteractionFreezeGate { + public static final GameTeamColors TEAM_COLOR = GameTeamColors.GREEN; + + public InteractionFreezeGateGreen(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, TEAM_COLOR); + } + + public InteractionFreezeGateGreen(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, TEAM_COLOR); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGateRed.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGateRed.java new file mode 100644 index 0000000..7f50205 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGateRed.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.items.interactions.games.freeze.gates; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFreezeGateRed extends InteractionFreezeGate { + public static final GameTeamColors TEAM_COLOR = GameTeamColors.RED; + + public InteractionFreezeGateRed(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, TEAM_COLOR); + } + + public InteractionFreezeGateRed(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, TEAM_COLOR); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGateYellow.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGateYellow.java new file mode 100644 index 0000000..418ce0e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/gates/InteractionFreezeGateYellow.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.items.interactions.games.freeze.gates; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFreezeGateYellow extends InteractionFreezeGate { + public static final GameTeamColors TEAM_COLOR = GameTeamColors.YELLOW; + + public InteractionFreezeGateYellow(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, TEAM_COLOR); + } + + public InteractionFreezeGateYellow(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, TEAM_COLOR); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboard.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboard.java new file mode 100644 index 0000000..2baee00 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboard.java @@ -0,0 +1,35 @@ +package com.eu.habbo.habbohotel.items.interactions.games.freeze.scoreboards; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameScoreboard; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFreezeScoreboard extends InteractionGameScoreboard { + InteractionFreezeScoreboard(ResultSet set, Item baseItem, GameTeamColors teamColor) throws SQLException { + super(set, baseItem, teamColor); + } + + InteractionFreezeScoreboard(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells, GameTeamColors teamColor) { + super(id, userId, item, extradata, limitedStack, limitedSells, teamColor); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboardBlue.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboardBlue.java new file mode 100644 index 0000000..9c00562 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboardBlue.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.items.interactions.games.freeze.scoreboards; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFreezeScoreboardBlue extends InteractionFreezeScoreboard { + public static final GameTeamColors TEAM_COLOR = GameTeamColors.BLUE; + + public InteractionFreezeScoreboardBlue(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, TEAM_COLOR); + } + + public InteractionFreezeScoreboardBlue(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, TEAM_COLOR); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboardGreen.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboardGreen.java new file mode 100644 index 0000000..3ce6653 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboardGreen.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.items.interactions.games.freeze.scoreboards; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFreezeScoreboardGreen extends InteractionFreezeScoreboard { + public static final GameTeamColors TEAM_COLOR = GameTeamColors.GREEN; + + public InteractionFreezeScoreboardGreen(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, TEAM_COLOR); + } + + public InteractionFreezeScoreboardGreen(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, TEAM_COLOR); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboardRed.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboardRed.java new file mode 100644 index 0000000..9846fa5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboardRed.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.items.interactions.games.freeze.scoreboards; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFreezeScoreboardRed extends InteractionFreezeScoreboard { + public static final GameTeamColors TEAM_COLOR = GameTeamColors.RED; + + public InteractionFreezeScoreboardRed(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, TEAM_COLOR); + } + + public InteractionFreezeScoreboardRed(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, TEAM_COLOR); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboardYellow.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboardYellow.java new file mode 100644 index 0000000..1c9d94e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/freeze/scoreboards/InteractionFreezeScoreboardYellow.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.items.interactions.games.freeze.scoreboards; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionFreezeScoreboardYellow extends InteractionFreezeScoreboard { + public static final GameTeamColors TEAM_COLOR = GameTeamColors.YELLOW; + + public InteractionFreezeScoreboardYellow(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, TEAM_COLOR); + } + + public InteractionFreezeScoreboardYellow(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, TEAM_COLOR); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/InteractionTagField.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/InteractionTagField.java new file mode 100644 index 0000000..2e97d3f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/InteractionTagField.java @@ -0,0 +1,82 @@ +package com.eu.habbo.habbohotel.items.interactions.games.tag; + +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.games.tag.TagGame; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public abstract class InteractionTagField extends HabboItem { + public Class gameClazz; + + public InteractionTagField(ResultSet set, Item baseItem, Class gameClazz) throws SQLException { + super(set, baseItem); + + this.gameClazz = gameClazz; + } + + public InteractionTagField(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells, Class gameClazz) { + super(id, userId, item, extradata, limitedStack, limitedSells); + + this.gameClazz = gameClazz; + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + return habbo.getHabboInfo().getCurrentGame() == null || habbo.getHabboInfo().getCurrentGame() == this.gameClazz; + } + + return false; + } + + @Override + public boolean isWalkable() { + return true; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + if (habbo.getHabboInfo().getCurrentGame() == null) { + TagGame game = (TagGame) room.getGame(this.gameClazz); + + if (game == null) { + game = (TagGame) this.gameClazz.getDeclaredConstructor(Room.class).newInstance(room); + room.addGame(game); + } + + game.addHabbo(habbo, null); + habbo.getHabboInfo().setCurrentGame(this.gameClazz); + } + } + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/InteractionTagPole.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/InteractionTagPole.java new file mode 100644 index 0000000..0b9598e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/InteractionTagPole.java @@ -0,0 +1,48 @@ +package com.eu.habbo.habbohotel.items.interactions.games.tag; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionTagPole extends HabboItem { + public InteractionTagPole(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionTagPole(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public void onPickUp(Room room) { + this.setExtradata("0"); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/bunnyrun/InteractionBunnyrunField.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/bunnyrun/InteractionBunnyrunField.java new file mode 100644 index 0000000..ac996a8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/bunnyrun/InteractionBunnyrunField.java @@ -0,0 +1,34 @@ +package com.eu.habbo.habbohotel.items.interactions.games.tag.bunnyrun; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.games.tag.BunnyrunGame; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagField; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBunnyrunField extends InteractionTagField { + public InteractionBunnyrunField(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, BunnyrunGame.class); + } + + public InteractionBunnyrunField(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, BunnyrunGame.class); + } + + @Override + public void onPlace(Room room) { + super.onPlace(room); + + Habbo itemOwner = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getUserId()); + + if (itemOwner != null) { + AchievementManager.progressAchievement(itemOwner, Emulator.getGameEnvironment().getAchievementManager().getAchievement("RbBunnyTag")); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/bunnyrun/InteractionBunnyrunPole.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/bunnyrun/InteractionBunnyrunPole.java new file mode 100644 index 0000000..9c0ae73 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/bunnyrun/InteractionBunnyrunPole.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.items.interactions.games.tag.bunnyrun; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagPole; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionBunnyrunPole extends InteractionTagPole { + public InteractionBunnyrunPole(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionBunnyrunPole(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/icetag/InteractionIceTagField.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/icetag/InteractionIceTagField.java new file mode 100644 index 0000000..f83c64f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/icetag/InteractionIceTagField.java @@ -0,0 +1,58 @@ +package com.eu.habbo.habbohotel.items.interactions.games.tag.icetag; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.games.tag.IceTagGame; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagField; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; + +public class InteractionIceTagField extends InteractionTagField { + private final HashMap stepTimes = new HashMap<>(); + + public InteractionIceTagField(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, IceTagGame.class); + } + + public InteractionIceTagField(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, IceTagGame.class); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + Habbo habbo = room.getHabbo(roomUnit); + if (habbo != null) + this.stepTimes.put(habbo, Emulator.getIntUnixTimestamp()); + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + + Habbo habbo = room.getHabbo(roomUnit); + if (habbo != null && this.stepTimes.containsKey(habbo)) { + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("TagC"), (Emulator.getIntUnixTimestamp() - this.stepTimes.get(habbo)) / 60); + this.stepTimes.remove(habbo); + } + } + + @Override + public void onPlace(Room room) { + super.onPlace(room); + + Habbo itemOwner = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getUserId()); + + if (itemOwner != null) { + AchievementManager.progressAchievement(itemOwner, Emulator.getGameEnvironment().getAchievementManager().getAchievement("TagA")); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/icetag/InteractionIceTagPole.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/icetag/InteractionIceTagPole.java new file mode 100644 index 0000000..b2fe44c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/icetag/InteractionIceTagPole.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.items.interactions.games.tag.icetag; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagPole; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionIceTagPole extends InteractionTagPole { + public InteractionIceTagPole(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionIceTagPole(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/rollerskate/InteractionRollerskateField.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/rollerskate/InteractionRollerskateField.java new file mode 100644 index 0000000..c25374c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/tag/rollerskate/InteractionRollerskateField.java @@ -0,0 +1,57 @@ +package com.eu.habbo.habbohotel.items.interactions.games.tag.rollerskate; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.games.tag.RollerskateGame; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagField; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; + +public class InteractionRollerskateField extends InteractionTagField { + private final HashMap stepTimes = new HashMap<>(); + + public InteractionRollerskateField(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, RollerskateGame.class); + } + + public InteractionRollerskateField(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, RollerskateGame.class); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + Habbo habbo = room.getHabbo(roomUnit); + if (habbo != null) + this.stepTimes.put(habbo, Emulator.getIntUnixTimestamp()); + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + + Habbo habbo = room.getHabbo(roomUnit); + if (habbo != null && this.stepTimes.containsKey(habbo)) { + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("RbTagC"), (Emulator.getIntUnixTimestamp() - this.stepTimes.get(habbo)) / 60); + this.stepTimes.remove(habbo); + } + } + + @Override + public void onPlace(Room room) { + super.onPlace(room); + + Habbo itemOwner = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getUserId()); + + if (itemOwner != null) { + AchievementManager.progressAchievement(itemOwner, Emulator.getGameEnvironment().getAchievementManager().getAchievement("RbTagA")); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/interfaces/ConditionalGate.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/interfaces/ConditionalGate.java new file mode 100644 index 0000000..3f1b06c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/interfaces/ConditionalGate.java @@ -0,0 +1,8 @@ +package com.eu.habbo.habbohotel.items.interactions.interfaces; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; + +public interface ConditionalGate { + public void onRejected(RoomUnit roomUnit, Room room, Object[] objects); +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionMonsterPlantSeed.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionMonsterPlantSeed.java new file mode 100644 index 0000000..cbd2ea2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionMonsterPlantSeed.java @@ -0,0 +1,85 @@ +package com.eu.habbo.habbohotel.items.interactions.pets; + +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.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionMonsterPlantSeed extends HabboItem { + public InteractionMonsterPlantSeed(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + + if (this.getExtradata().isEmpty()) { + this.setExtradata("" + randomRarityLevel()); + this.needsUpdate(true); + } + } + + public InteractionMonsterPlantSeed(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + + if (this.getExtradata().isEmpty()) { + this.setExtradata("" + randomRarityLevel()); + this.needsUpdate(true); + } + } + + public static int randomGoldenRarityLevel() { + int number = Emulator.getRandom().nextInt(66); + int count = 0; + for (int i = 8; i < 11; i++) { + count += 11 - i; + if (number <= count) { + return i; + } + } + return 10; + } + + public static int randomRarityLevel() { + int number = Emulator.getRandom().nextInt(66); + int count = 0; + for (int i = 1; i < 11; i++) { + count += 11 - i; + if (number <= count) { + return i; + } + } + return 10; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return false; + } + + @Override + public boolean isWalkable() { + return false; + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt(1 + (this.isLimited() ? 256 : 0)); + serverMessage.appendInt(1); + serverMessage.appendString("rarity"); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionNest.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionNest.java new file mode 100644 index 0000000..d729338 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionNest.java @@ -0,0 +1,85 @@ +package com.eu.habbo.habbohotel.items.interactions.pets; + +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.pets.RideablePet; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionNest extends HabboItem { + public InteractionNest(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionNest(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return true; + } + + @Override + public boolean isWalkable() { + return this.getBaseItem().allowWalk(); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + Pet pet = room.getPet(roomUnit); + + if (pet == null) + return; + + if (pet instanceof RideablePet && ((RideablePet) pet).getRider() != null) + return; + + if (!pet.getPetData().haveNest(this)) + return; + + if (pet.getEnergy() > 85) + return; + + pet.setTask(PetTasks.NEST); + pet.getRoomUnit().setGoalLocation(room.getLayout().getTile(this.getX(), this.getY())); + pet.getRoomUnit().clearStatus(); + pet.getRoomUnit().removeStatus(RoomUnitStatus.MOVE); + pet.getRoomUnit().setStatus(RoomUnitStatus.LAY, room.getStackHeight(this.getX(), this.getY(), false) + ""); + room.sendComposer(new RoomUserStatusComposer(roomUnit).compose()); + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionPetBreedingNest.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionPetBreedingNest.java new file mode 100644 index 0000000..9ec50ff --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionPetBreedingNest.java @@ -0,0 +1,172 @@ +package com.eu.habbo.habbohotel.items.interactions.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetManager; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.pets.PetPackageNameValidationComposer; +import com.eu.habbo.messages.outgoing.rooms.pets.breeding.PetBreedingCompleted; +import com.eu.habbo.messages.outgoing.rooms.pets.breeding.PetBreedingResultComposer; +import com.eu.habbo.threading.runnables.QueryDeleteHabboItem; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionPetBreedingNest extends HabboItem { + public Pet petOne = null; + public Pet petTwo = null; + + public InteractionPetBreedingNest(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionPetBreedingNest(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) { + return room.getPet(roomUnit) != null && !this.boxFull(); + } + + @Override + public boolean isWalkable() { + return true; + } + + + @Override + public void serializeExtradata(ServerMessage serverMessage) { + serverMessage.appendInt((this.isLimited() ? 256 : 0)); + serverMessage.appendString(this.getExtradata()); + + super.serializeExtradata(serverMessage); + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + Pet pet = room.getPet(roomUnit); + + if (pet != null) { + if (!this.boxFull()) { + this.addPet(pet); + + if (this.boxFull()) { + Habbo ownerPetOne = room.getHabbo(this.petOne.getUserId()); + Habbo ownerPetTwo = room.getHabbo(this.petTwo.getUserId()); + + if (ownerPetOne != null && ownerPetTwo != null && this.petOne.getPetData().getType() == this.petTwo.getPetData().getType() && this.petOne.getPetData().getOffspringType() != -1) { + ownerPetTwo.getClient().sendResponse(new PetBreedingResultComposer(this.getId(), this.petOne.getPetData().getOffspringType(), this.petOne, ownerPetOne.getHabboInfo().getUsername(), this.petTwo, ownerPetTwo.getHabboInfo().getUsername())); + this.setExtradata("1"); + room.updateItem(this); + } + } + } + } + } + + public boolean addPet(Pet pet) { + if (this.petOne == null) { + this.petOne = pet; + this.petOne.getRoomUnit().setCanWalk(false); + return true; + } else if (this.petTwo == null && this.petOne != pet) { + this.petTwo = pet; + this.petTwo.getRoomUnit().setCanWalk(false); + return true; + } + + return false; + } + + public boolean boxFull() { + return this.petOne != null && this.petTwo != null; + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + if (this.petOne != null && this.petOne.getRoomUnit() == roomUnit) this.petOne = null; + if (this.petTwo != null && this.petTwo.getRoomUnit() == roomUnit) this.petTwo = null; + + this.setExtradata("0"); + room.updateItem(this); + } + + @Override + public boolean allowWiredResetState() { + return false; + } + + public void stopBreeding(Habbo habbo) { + this.setExtradata("0"); + habbo.getHabboInfo().getCurrentRoom().updateItem(this); + + if (this.petOne != null) { + habbo.getClient().sendResponse(new PetPackageNameValidationComposer(this.getId(), PetPackageNameValidationComposer.CLOSE_WIDGET, "")); + } + if (this.petTwo.getUserId() != habbo.getHabboInfo().getId()) { + Habbo owner = this.petTwo.getRoom().getHabbo(this.petTwo.getUserId()); + if (owner != null) { + owner.getClient().sendResponse(new PetPackageNameValidationComposer(this.getId(), PetPackageNameValidationComposer.CLOSE_WIDGET, "")); + } + } + + this.freePets(); + + } + + private void freePets() { + if (this.petOne != null) { + this.petOne.getRoomUnit().setCanWalk(true); + this.petOne.setTask(PetTasks.FREE); + this.petOne = null; + } + + if (this.petTwo != null) { + this.petTwo.getRoomUnit().setCanWalk(true); + this.petTwo.setTask(PetTasks.FREE); + this.petTwo = null; + } + } + + public void breed(Habbo habbo, String name, int petOneId, int petTwoId) { + Emulator.getThreading().run(new QueryDeleteHabboItem(this.getId())); + + this.setExtradata("2"); + habbo.getHabboInfo().getCurrentRoom().updateItem(this); + + HabboItem box = this; + Pet petOne = this.petOne; + Pet petTwo = this.petTwo; + Emulator.getThreading().run(() -> { + Pet offspring = Emulator.getGameEnvironment().getPetManager().createPet(petOne.getPetData().getOffspringType(), (int) Math.min(Math.round(Math.max(1d, PetManager.getNormalDistributionForBreeding(petOne.getLevel(), petTwo.getLevel()).sample())), 20), name, habbo.getClient()); + + //habbo.getClient().sendResponse(new PetPackageNameValidationComposer(box.getId(), PetPackageNameValidationComposer.CLOSE_WIDGET, "")); + habbo.getHabboInfo().getCurrentRoom().placePet(offspring, box.getX(), box.getY(), box.getZ(), box.getRotation()); + offspring.needsUpdate = true; + offspring.run(); + InteractionPetBreedingNest.this.freePets(); + habbo.getHabboInfo().getCurrentRoom().removeHabboItem(box); + habbo.getClient().sendResponse(new PetBreedingCompleted(offspring.getId(), Emulator.getGameEnvironment().getPetManager().getRarityForOffspring(offspring))); + + if (box.getBaseItem().getName().startsWith("pet_breeding_")) { + String boxType = box.getBaseItem().getName().replace("pet_breeding_", ""); + String achievement = boxType.substring(0, 1).toUpperCase() + boxType.substring(1) + "Breeder"; + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement(achievement)); + } + }, 2000); + + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionPetDrink.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionPetDrink.java new file mode 100644 index 0000000..a18ada6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionPetDrink.java @@ -0,0 +1,57 @@ +package com.eu.habbo.habbohotel.items.interactions.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionDefault; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import com.eu.habbo.threading.runnables.PetClearPosture; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionPetDrink extends InteractionDefault { + public InteractionPetDrink(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionPetDrink(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + Pet pet = room.getPet(roomUnit); + + if (pet != null) { + if (pet.getPetData().haveDrinkItem(this)) { + if (pet.levelThirst >= 35) { + pet.setTask(PetTasks.EAT); + pet.getRoomUnit().setGoalLocation(room.getLayout().getTile(this.getX(), this.getY())); + pet.getRoomUnit().setRotation(RoomUserRotation.values()[this.getRotation()]); + pet.getRoomUnit().clearStatus(); + pet.getRoomUnit().removeStatus(RoomUnitStatus.MOVE); + pet.getRoomUnit().setStatus(RoomUnitStatus.EAT, "0"); + pet.addThirst(-75); + room.sendComposer(new RoomUserStatusComposer(roomUnit).compose()); + Emulator.getThreading().run(new PetClearPosture(pet, RoomUnitStatus.EAT, null, true), 500); + + AchievementManager.progressAchievement(Emulator.getGameEnvironment().getHabboManager().getHabbo(pet.getUserId()), Emulator.getGameEnvironment().getAchievementManager().getAchievement("PetFeeding"), 75); + } + } + } + } + + @Override + public boolean allowWiredResetState() { + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionPetFood.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionPetFood.java new file mode 100644 index 0000000..8f2dd02 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionPetFood.java @@ -0,0 +1,57 @@ +package com.eu.habbo.habbohotel.items.interactions.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionDefault; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import com.eu.habbo.threading.runnables.PetEatAction; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionPetFood extends InteractionDefault { + public InteractionPetFood(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionPetFood(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + if (this.getExtradata().length() == 0) + this.setExtradata("0"); + + Pet pet = room.getPet(roomUnit); + + if (pet != null) { + if (pet.getPetData().haveFoodItem(this)) { + if (pet.levelHunger >= 35) { + pet.setTask(PetTasks.EAT); + pet.getRoomUnit().setGoalLocation(room.getLayout().getTile(this.getX(), this.getY())); + pet.getRoomUnit().setRotation(RoomUserRotation.values()[this.getRotation()]); + pet.getRoomUnit().clearStatus(); + pet.getRoomUnit().removeStatus(RoomUnitStatus.MOVE); + pet.getRoomUnit().setStatus(RoomUnitStatus.EAT, "0"); + room.sendComposer(new RoomUserStatusComposer(roomUnit).compose()); + Emulator.getThreading().run(new PetEatAction(pet, this)); + } + } + } + } + + + @Override + public boolean allowWiredResetState() { + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionPetToy.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionPetToy.java new file mode 100644 index 0000000..caeaf54 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/pets/InteractionPetToy.java @@ -0,0 +1,75 @@ +package com.eu.habbo.habbohotel.items.interactions.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionDefault; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.threading.runnables.PetClearPosture; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionPetToy extends InteractionDefault { + public InteractionPetToy(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.setExtradata("0"); + } + + public InteractionPetToy(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.setExtradata("0"); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + Pet pet = room.getPet(roomUnit); + + if (pet != null) { + if (pet.getEnergy() <= 35) { + return; + } + + pet.setTask(PetTasks.PLAY); + pet.getRoomUnit().setGoalLocation(room.getLayout().getTile(this.getX(), this.getY())); + pet.getRoomUnit().setRotation(RoomUserRotation.values()[this.getRotation()]); + pet.getRoomUnit().clearStatus(); + pet.getRoomUnit().removeStatus(RoomUnitStatus.MOVE); + pet.getRoomUnit().setStatus(RoomUnitStatus.PLAY, "0"); + pet.packetUpdate = true; + HabboItem item = this; + Emulator.getThreading().run(() -> { + pet.addHappyness(25); + item.setExtradata("0"); + room.updateItem(item); + new PetClearPosture(pet, RoomUnitStatus.PLAY, null, true).run(); + }, 2500 + (Emulator.getRandom().nextInt(20) * 500)); + this.setExtradata("1"); + room.updateItemState(this); + } + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + + Pet pet = room.getPet(roomUnit); + + if (pet != null) { + this.setExtradata("0"); + room.updateItemState(this); + } + } + + @Override + public boolean allowWiredResetState() { + return false; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/InteractionTotemHead.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/InteractionTotemHead.java new file mode 100644 index 0000000..aa9dcb6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/InteractionTotemHead.java @@ -0,0 +1,95 @@ +package com.eu.habbo.habbohotel.items.interactions.totems; + +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionDefault; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionTotemHead extends InteractionDefault { + + public InteractionTotemHead(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionTotemHead(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + public TotemType getTotemType() { + int extraData; + try { + extraData = Integer.parseInt(this.getExtradata()); + } catch(NumberFormatException ex) { + extraData = 0; + } + if(extraData < 3) { + return TotemType.fromInt(extraData + 1); + } + return TotemType.fromInt((int)Math.ceil((extraData - 2) / 4.0f)); + } + + public TotemColor getTotemColor() { + int extraData; + try { + extraData = Integer.parseInt(this.getExtradata()); + }catch(NumberFormatException ex) { + extraData = 0; + } + if(extraData < 3) { + return TotemColor.NONE; + } + return TotemColor.fromInt(extraData - 3 - (4 * (getTotemType().type - 1))); + } + + private void update(Room room, RoomTile tile) { + InteractionTotemLegs legs = null; + + for(HabboItem item : room.getItemsAt(tile)) { + if(item instanceof InteractionTotemLegs && item.getZ() < this.getZ()) + legs = (InteractionTotemLegs)item; + } + + if(legs == null) + return; + + this.setExtradata(((4 * this.getTotemType().type) + legs.getTotemColor().color) - 1 + ""); + } + + public void updateTotemState(Room room) { + updateTotemState(room, room.getLayout().getTile(this.getX(), this.getY())); + } + + public void updateTotemState(Room room, RoomTile tile) { + this.setExtradata(getTotemType().type - 1 + ""); + update(room, tile); + this.needsUpdate(true); + room.updateItem(this); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (!((client != null && room != null && room.hasRights(client.getHabbo())) || (objects.length >= 2 && objects[1] instanceof WiredEffectType))) + return; + + TotemType newType = TotemType.fromInt(getTotemType().type + 1); + if(newType == TotemType.NONE) { + newType = TotemType.TROLL; + } + + this.setExtradata(newType.type - 1 + ""); + + updateTotemState(room); + } + + @Override + public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + super.onMove(room, oldLocation, newLocation); + updateTotemState(room, newLocation); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/InteractionTotemLegs.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/InteractionTotemLegs.java new file mode 100644 index 0000000..d8d83da --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/InteractionTotemLegs.java @@ -0,0 +1,66 @@ +package com.eu.habbo.habbohotel.items.interactions.totems; + +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionDefault; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionTotemLegs extends InteractionDefault { + public InteractionTotemLegs(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionTotemLegs(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + public TotemType getTotemType() { + int extraData; + try { + extraData = Integer.parseInt(this.getExtradata()); + } catch(NumberFormatException ex) { + extraData = 0; + } + return TotemType.fromInt((int)Math.ceil((extraData + 1) / 4.0f)); + } + + public TotemColor getTotemColor() { + int extraData; + try { + extraData = Integer.parseInt(this.getExtradata()); + } catch(NumberFormatException ex) { + extraData = 0; + } + return TotemColor.fromInt(extraData - (4 * (getTotemType().type - 1))); + } + + private void updateHead(Room room, RoomTile tile) { + for(HabboItem item : room.getItemsAt(tile)) { + if(item instanceof InteractionTotemHead && item.getZ() > this.getZ()) + ((InteractionTotemHead)item).updateTotemState(room); + } + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + + if (!((client != null && room != null && room.hasRights(client.getHabbo())) || (objects.length >= 2 && objects[1] instanceof WiredEffectType))) + return; + + updateHead(room, room.getLayout().getTile(this.getX(), this.getY())); + } + + @Override + public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + super.onMove(room, oldLocation, newLocation); + + updateHead(room, oldLocation); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/InteractionTotemPlanet.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/InteractionTotemPlanet.java new file mode 100644 index 0000000..2c49e91 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/InteractionTotemPlanet.java @@ -0,0 +1,94 @@ +package com.eu.habbo.habbohotel.items.interactions.totems; + +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionDefault; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.users.inventory.EffectsComponent; +import com.eu.habbo.messages.outgoing.inventory.UserEffectsListComposer; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class InteractionTotemPlanet extends InteractionDefault { + public InteractionTotemPlanet(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public InteractionTotemPlanet(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + public TotemPlanetType getPlanetType() { + int extraData; + try { + extraData = Integer.parseInt(this.getExtradata()); + } catch(NumberFormatException ex) { + extraData = 0; + } + return TotemPlanetType.fromInt(extraData); + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if(client.getHabbo().getHabboInfo().getId() != this.getUserId()) { + super.onClick(client, room, objects); + return; + } + + InteractionTotemLegs legs = null; + InteractionTotemHead head = null; + + THashSet items = room.getItemsAt(room.getLayout().getTile(this.getX(), this.getY())); + + for(HabboItem item : items) { + if(item instanceof InteractionTotemLegs && item.getZ() < this.getZ()) + legs = (InteractionTotemLegs)item; + } + + if(legs == null) { + super.onClick(client, room, objects); + return; + } + + for(HabboItem item : items) { + if(item instanceof InteractionTotemHead && item.getZ() > legs.getZ()) + head = (InteractionTotemHead)item; + } + + if(head == null) { + super.onClick(client, room, objects); + return; + } + + int effectId = 0; + + if(getPlanetType() == TotemPlanetType.SUN && head.getTotemType() == TotemType.BIRD && legs.getTotemType() == TotemType.BIRD && legs.getTotemColor() == TotemColor.RED) { + effectId = 25; + } + else if(getPlanetType() == TotemPlanetType.EARTH && head.getTotemType() == TotemType.TROLL && legs.getTotemType() == TotemType.TROLL && legs.getTotemColor() == TotemColor.YELLOW) { + effectId = 23; + } + else if(getPlanetType() == TotemPlanetType.EARTH && head.getTotemType() == TotemType.SNAKE && legs.getTotemType() == TotemType.BIRD && legs.getTotemColor() == TotemColor.YELLOW) { + effectId = 26; + } + else if(getPlanetType() == TotemPlanetType.MOON && head.getTotemType() == TotemType.SNAKE && legs.getTotemType() == TotemType.SNAKE && legs.getTotemColor() == TotemColor.BLUE) { + effectId = 24; + } + + if(effectId > 0) { + if(client.getHabbo().getInventory().getEffectsComponent().ownsEffect(effectId)) { + client.getHabbo().getInventory().getEffectsComponent().enableEffect(effectId); + return; + } + + EffectsComponent.HabboEffect effect = client.getHabbo().getInventory().getEffectsComponent().createEffect(effectId); + client.getHabbo().getInventory().getEffectsComponent().enableEffect(effectId); + return; + } + + super.onClick(client, room, objects); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/TotemColor.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/TotemColor.java new file mode 100644 index 0000000..340bb47 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/TotemColor.java @@ -0,0 +1,24 @@ +package com.eu.habbo.habbohotel.items.interactions.totems; + +public enum TotemColor { + + NONE(0), + RED(1), + YELLOW(2), + BLUE(3); + + public final int color; + + TotemColor(int color) { + this.color = color; + } + + public static TotemColor fromInt(int color) { + for(TotemColor totemColor : TotemColor.values()) { + if(totemColor.color == color) + return totemColor; + } + + return NONE; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/TotemPlanetType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/TotemPlanetType.java new file mode 100644 index 0000000..bf8c737 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/TotemPlanetType.java @@ -0,0 +1,22 @@ +package com.eu.habbo.habbohotel.items.interactions.totems; + +public enum TotemPlanetType { + MOON(0), + SUN(1), + EARTH(2); + + public final int type; + + TotemPlanetType(int type) { + this.type = type; + } + + public static TotemPlanetType fromInt(int type) { + for(TotemPlanetType planetType : TotemPlanetType.values()) { + if(planetType.type == type) + return planetType; + } + + return MOON; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/TotemType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/TotemType.java new file mode 100644 index 0000000..b82d909 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/totems/TotemType.java @@ -0,0 +1,24 @@ +package com.eu.habbo.habbohotel.items.interactions.totems; + +public enum TotemType { + + NONE(0), + TROLL(1), + SNAKE(2), + BIRD(3); + + public final int type; + + TotemType(int type) { + this.type = type; + } + + public static TotemType fromInt(int type) { + for(TotemType totemType : TotemType.values()) { + if(totemType.type == type) + return totemType; + } + + return NONE; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/WiredSettings.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/WiredSettings.java new file mode 100644 index 0000000..b6027a0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/WiredSettings.java @@ -0,0 +1,63 @@ +package com.eu.habbo.habbohotel.items.interactions.wired; + +public class WiredSettings { + private int[] intParams; + private String stringParam; + private int[] furniIds; + private int stuffTypeSelectionCode; + private int delay; + + public WiredSettings(int[] intParams, String stringParam, int[] furniIds, int stuffTypeSelectionCode, int delay) + { + this.furniIds = furniIds; + this.intParams = intParams; + this.stringParam = stringParam; + this.stuffTypeSelectionCode = stuffTypeSelectionCode; + this.delay = delay; + } + + public WiredSettings(int[] intParams, String stringParam, int[] furniIds, int stuffTypeSelectionCode) + { + this(intParams, stringParam, furniIds, stuffTypeSelectionCode, 0); + } + + public int getStuffTypeSelectionCode() { + return stuffTypeSelectionCode; + } + + public void setStuffTypeSelectionCode(int stuffTypeSelectionCode) { + this.stuffTypeSelectionCode = stuffTypeSelectionCode; + } + + public int[] getFurniIds() { + return furniIds; + } + + public void setFurniIds(int[] furniIds) { + this.furniIds = furniIds; + } + + public String getStringParam() { + return stringParam; + } + + public void setStringParam(String stringParam) { + this.stringParam = stringParam; + } + + public int[] getIntParams() { + return intParams; + } + + public void setIntParams(int[] intParams) { + this.intParams = intParams; + } + + public int getDelay() { + return delay; + } + + public void setDelay(int delay) { + this.delay = delay; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/WiredSuper.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/WiredSuper.java new file mode 100644 index 0000000..46084d9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/WiredSuper.java @@ -0,0 +1,117 @@ +package com.eu.habbo.habbohotel.items.interactions.wired; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.ItemManager; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredHighscore; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.highscores.WiredHighscoreDataEntry; +import com.eu.habbo.habbohotel.wired.highscores.WiredHighscoreManager; +import gnu.trove.set.hash.THashSet; + +import java.util.Collections; +import java.util.List; + +// Mikee: Lazy, sorry. +// Mikee: Yeah, duplicate code, sorry. +public class WiredSuper { + + public static void addPoint(final RoomUnit roomUnit, final Room room, final int scoreToAdd) { + final Habbo habbo = room.getHabbo(roomUnit); + + if (habbo == null) { + return; + } + + final ItemManager itemManager = Emulator.getGameEnvironment().getItemManager(); + final WiredHighscoreManager wiredHighscoreManager = itemManager.getHighscoreManager(); + final THashSet wiredHighscores = room.getRoomSpecialTypes().getWiredHighscores(); + final List userIds = Collections.singletonList(habbo.getHabboInfo().getId()); + + for (final InteractionWiredHighscore highscore : wiredHighscores) { + final int itemId = highscore.getId(); + final WiredHighscoreDataEntry entry = new WiredHighscoreDataEntry(itemId, userIds, scoreToAdd, true, Emulator.getIntUnixTimestamp()); + + wiredHighscoreManager.addOrUpdateHighscoreData(entry); + } + + for (final InteractionWiredHighscore highscore : wiredHighscores) { + highscore.reloadData(); + + room.updateItem(highscore); + } + } + + public static void setPoint(final RoomUnit roomUnit, final Room room, final int scoreToAdd) { + final Habbo habbo = room.getHabbo(roomUnit); + + if (habbo == null) { + return; + } + + final ItemManager itemManager = Emulator.getGameEnvironment().getItemManager(); + final WiredHighscoreManager wiredHighscoreManager = itemManager.getHighscoreManager(); + final THashSet wiredHighscores = room.getRoomSpecialTypes().getWiredHighscores(); + final List userIds = Collections.singletonList(habbo.getHabboInfo().getId()); + + for (final InteractionWiredHighscore highscore : wiredHighscores) { + final int itemId = highscore.getId(); + final WiredHighscoreDataEntry entry = new WiredHighscoreDataEntry(itemId, userIds, scoreToAdd, true, Emulator.getIntUnixTimestamp()); + + wiredHighscoreManager.setHighscoreData(entry); + } + + for (final InteractionWiredHighscore highscore : wiredHighscores) { + highscore.reloadData(); + + room.updateItem(highscore); + } + } + + public static boolean noTotalClassement(RoomUnit roomUnit, Room room) { + final Habbo habbo = room.getHabbo(roomUnit); + + if (habbo == null) { + return false; + } + + final ItemManager itemManager = Emulator.getGameEnvironment().getItemManager(); + final WiredHighscoreManager wiredHighscoreManager = itemManager.getHighscoreManager(); + final THashSet wiredHighscores = room.getRoomSpecialTypes().getWiredHighscores(); + final List userIds = Collections.singletonList(habbo.getHabboInfo().getId()); + + for (final InteractionWiredHighscore highscore : wiredHighscores) { + final WiredHighscoreDataEntry entry = wiredHighscoreManager.getHighscoreRow(highscore.getId(), userIds); + + if (entry != null) { + return false; + } + } + + return true; + } + + public static boolean totalPointEqual(RoomUnit roomUnit, Room room, int score) { + final Habbo habbo = room.getHabbo(roomUnit); + + if (habbo == null) { + return false; + } + + final ItemManager itemManager = Emulator.getGameEnvironment().getItemManager(); + final WiredHighscoreManager wiredHighscoreManager = itemManager.getHighscoreManager(); + final THashSet wiredHighscores = room.getRoomSpecialTypes().getWiredHighscores(); + final List userIds = Collections.singletonList(habbo.getHabboInfo().getId()); + + for (final InteractionWiredHighscore highscore : wiredHighscores) { + final WiredHighscoreDataEntry entry = wiredHighscoreManager.getHighscoreRow(highscore.getId(), userIds); + + if (entry != null && entry.getScore() == score) { + return true; + } + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/WiredTriggerReset.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/WiredTriggerReset.java new file mode 100644 index 0000000..81dd028 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/WiredTriggerReset.java @@ -0,0 +1,5 @@ +package com.eu.habbo.habbohotel.items.interactions.wired; + +public interface WiredTriggerReset { + void resetTimer(); +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionDateRangeActive.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionDateRangeActive.java new file mode 100644 index 0000000..d4b9296 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionDateRangeActive.java @@ -0,0 +1,110 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredConditionDateRangeActive extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.DATE_RANGE; + + private int startDate; + private int endDate; + + public WiredConditionDateRangeActive(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionDateRangeActive(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(2); + message.appendInt(this.startDate); + message.appendInt(this.endDate); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.startDate); + message.appendInt(this.endDate); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + this.startDate = packet.readInt(); + this.endDate = packet.readInt(); + return true; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + int time = Emulator.getIntUnixTimestamp(); + return this.startDate < time && this.endDate >= time; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.startDate, + this.endDate + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.startDate = data.startDate; + this.endDate = data.endDate; + } else { + String[] data = wiredData.split("\t"); + + if (data.length == 2) { + try { + this.startDate = Integer.parseInt(data[0]); + this.endDate = Integer.parseInt(data[1]); + } catch (Exception e) { + } + } + } + } + + @Override + public void onPickUp() { + this.startDate = 0; + this.endDate = 0; + } + + static class JsonData { + int startDate; + int endDate; + + public JsonData(int startDate, int endDate) { + this.startDate = startDate; + this.endDate = endDate; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniHaveFurni.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniHaveFurni.java new file mode 100644 index 0000000..ddce19a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniHaveFurni.java @@ -0,0 +1,194 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredConditionFurniHaveFurni extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.FURNI_HAS_FURNI; + + private boolean all; + private THashSet items; + + public WiredConditionFurniHaveFurni(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.items = new THashSet<>(); + } + + public WiredConditionFurniHaveFurni(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.items = new THashSet<>(); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + this.refresh(); + + if(this.items.isEmpty()) + return true; + + if(this.all) { + return this.items.stream().allMatch(item -> { + double minZ = item.getZ() + Item.getCurrentHeight(item); + THashSet occupiedTiles = room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + return occupiedTiles.stream().anyMatch(tile -> room.getItemsAt(tile).stream().anyMatch(matchedItem -> matchedItem != item && matchedItem.getZ() >= minZ)); + }); + } + else { + return this.items.stream().anyMatch(item -> { + double minZ = item.getZ() + Item.getCurrentHeight(item); + THashSet occupiedTiles = room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + return occupiedTiles.stream().anyMatch(tile -> room.getItemsAt(tile).stream().anyMatch(matchedItem -> matchedItem != item && matchedItem.getZ() >= minZ)); + }); + } + } + + @Override + public String getWiredData() { + this.refresh(); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.all, + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.all = data.all; + + for(int id : data.itemIds) { + HabboItem item = room.getHabboItem(id); + + if (item != null) { + this.items.add(item); + } + } + + } else { + String[] data = wiredData.split(":"); + + if (data.length >= 1) { + this.all = (data[0].equals("1")); + + if (data.length == 2) { + String[] items = data[1].split(";"); + + for (String s : items) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) + this.items.add(item); + } + } + } + } + } + + @Override + public void onPickUp() { + this.items.clear(); + this.all = false; + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + this.refresh(); + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + + for (HabboItem item : this.items) + message.appendInt(item.getId()); + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.all ? 1 : 0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + int count; + packet.readInt(); + + this.all = packet.readInt() == 1; + + packet.readString(); + + count = packet.readInt(); + if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; + + this.items.clear(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room != null) { + for (int i = 0; i < count; i++) { + HabboItem item = room.getHabboItem(packet.readInt()); + + if (item != null) + this.items.add(item); + } + + return true; + } + return false; + } + + private void refresh() { + THashSet items = new THashSet<>(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room == null) { + items.addAll(this.items); + } else { + for (HabboItem item : this.items) { + if (room.getHabboItem(item.getId()) == null) + items.add(item); + } + } + + for (HabboItem item : items) { + this.items.remove(item); + } + } + + static class JsonData { + boolean all; + List itemIds; + + public JsonData(boolean all, List itemIds) { + this.all = all; + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniHaveHabbo.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniHaveHabbo.java new file mode 100644 index 0000000..a0d0708 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniHaveHabbo.java @@ -0,0 +1,193 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredConditionFurniHaveHabbo extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.FURNI_HAVE_HABBO; + + protected boolean all; + protected THashSet items; + + public WiredConditionFurniHaveHabbo(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.items = new THashSet<>(); + } + + public WiredConditionFurniHaveHabbo(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.items = new THashSet<>(); + } + + @Override + public void onPickUp() { + this.items.clear(); + this.all = false; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + this.refresh(); + + if (this.items.isEmpty()) + return true; + + Collection habbos = room.getHabbos(); + Collection bots = room.getCurrentBots().valueCollection(); + Collection pets = room.getCurrentPets().valueCollection(); + + return this.items.stream().allMatch(item -> { + THashSet occupiedTiles = room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + return habbos.stream().anyMatch(character -> occupiedTiles.contains(character.getRoomUnit().getCurrentLocation())) || + bots.stream().anyMatch(character -> occupiedTiles.contains(character.getRoomUnit().getCurrentLocation())) || + pets.stream().anyMatch(character -> occupiedTiles.contains(character.getRoomUnit().getCurrentLocation())); + }); + } + + @Override + public String getWiredData() { + this.refresh(); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.all, + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items.clear(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.all = data.all; + + for(int id : data.itemIds) { + HabboItem item = room.getHabboItem(id); + + if (item != null) { + this.items.add(item); + } + } + } else { + String[] data = wiredData.split(":"); + + if (data.length >= 1) { + this.all = (data[0].equals("1")); + + if (data.length == 2) { + String[] items = data[1].split(";"); + + for (String s : items) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) + this.items.add(item); + } + } + } + } + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + this.refresh(); + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + + for (HabboItem item : this.items) + message.appendInt(item.getId()); + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.all ? 1 : 0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + int count; + packet.readInt(); + + packet.readString(); + + count = packet.readInt(); + if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; + + this.items.clear(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room != null) { + for (int i = 0; i < count; i++) { + HabboItem item = room.getHabboItem(packet.readInt()); + + if (item != null) + this.items.add(item); + } + + return true; + } + + return false; + } + + private void refresh() { + THashSet items = new THashSet<>(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room == null) { + items.addAll(this.items); + } else { + for (HabboItem item : this.items) { + if (room.getHabboItem(item.getId()) == null) + items.add(item); + } + } + + for (HabboItem item : items) { + this.items.remove(item); + } + } + + static class JsonData { + boolean all; + List itemIds; + + public JsonData(boolean all, List itemIds) { + this.all = all; + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniTypeMatch.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniTypeMatch.java new file mode 100644 index 0000000..47c42d6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionFurniTypeMatch.java @@ -0,0 +1,165 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredConditionFurniTypeMatch extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.STUFF_IS; + + private THashSet items = new THashSet<>(); + + public WiredConditionFurniTypeMatch(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionFurniTypeMatch(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void onPickUp() { + this.items.clear(); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + this.refresh(); + + if(items.isEmpty()) + return false; + + if (stuff != null) { + if (stuff.length >= 1) { + if (stuff[0] instanceof HabboItem) { + HabboItem triggeringItem = (HabboItem)stuff[0]; + return this.items.stream().anyMatch(item -> item == triggeringItem); + } + } + } + + return false; + } + + @Override + public String getWiredData() { + this.refresh(); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items.clear(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + + for(int id : data.itemIds) { + HabboItem item = room.getHabboItem(id); + + if (item != null) { + this.items.add(item); + } + } + } else { + String[] data = wiredData.split(";"); + + for (String s : data) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) { + this.items.add(item); + } + } + } + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + this.refresh(); + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + + for (HabboItem item : this.items) + message.appendInt(item.getId()); + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + packet.readString(); + + int count = packet.readInt(); + if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; + + this.items.clear(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room != null) { + for (int i = 0; i < count; i++) { + this.items.add(room.getHabboItem(packet.readInt())); + } + } + + return true; + } + + private void refresh() { + THashSet items = new THashSet<>(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room == null) { + items.addAll(this.items); + } else { + for (HabboItem item : this.items) { + if (room.getHabboItem(item.getId()) == null) + items.add(item); + } + } + + for (HabboItem item : items) { + this.items.remove(item); + } + } + + static class JsonData { + List itemIds; + + public JsonData(List itemIds) { + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionGroupMember.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionGroupMember.java new file mode 100644 index 0000000..cc01ba7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionGroupMember.java @@ -0,0 +1,75 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredConditionGroupMember extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.ACTOR_IN_GROUP; + + public WiredConditionGroupMember(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionGroupMember(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (room.getGuildId() == 0) + return false; + + Habbo habbo = room.getHabbo(roomUnit); + + return habbo != null && habbo.getHabboStats().hasGuild(room.getGuildId()); + } + + @Override + public String getWiredData() { + return ""; + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + + } + + @Override + public void onPickUp() { + + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHabboCount.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHabboCount.java new file mode 100644 index 0000000..d5e93e2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHabboCount.java @@ -0,0 +1,107 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredConditionHabboCount extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.USER_COUNT; + + private int lowerLimit = 0; + private int upperLimit = 50; + + public WiredConditionHabboCount(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionHabboCount(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + int count = room.getUserCount(); + + return count >= this.lowerLimit && count <= this.upperLimit; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.lowerLimit, + this.upperLimit + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.lowerLimit = data.lowerLimit; + this.upperLimit = data.upperLimit; + } else { + String[] data = wiredData.split(":"); + + this.lowerLimit = Integer.parseInt(data[0]); + this.upperLimit = Integer.parseInt(data[1]); + } + } + + @Override + public void onPickUp() { + this.lowerLimit = 0; + this.upperLimit = 50; + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(2); + message.appendInt(this.lowerLimit); + message.appendInt(this.upperLimit); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.lowerLimit = packet.readInt(); + this.upperLimit = packet.readInt(); + + return true; + } + + static class JsonData { + int lowerLimit; + int upperLimit; + + public JsonData(int lowerLimit, int upperLimit) { + this.lowerLimit = lowerLimit; + this.upperLimit = upperLimit; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHabboHasEffect.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHabboHasEffect.java new file mode 100644 index 0000000..7e1580f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHabboHasEffect.java @@ -0,0 +1,94 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredConditionHabboHasEffect extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.ACTOR_WEARS_EFFECT; + + protected int effectId = 0; + + public WiredConditionHabboHasEffect(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionHabboHasEffect(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (roomUnit == null) return false; + return roomUnit.getEffectId() == this.effectId; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.effectId + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.effectId = data.effectId; + } else { + this.effectId = Integer.parseInt(wiredData); + } + } + + @Override + public void onPickUp() { + this.effectId = 0; + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(true); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.effectId + ""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.effectId = packet.readInt(); + + return true; + } + + static class JsonData { + int effectId; + + public JsonData(int effectId) { + this.effectId = effectId; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHabboHasHandItem.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHabboHasHandItem.java new file mode 100644 index 0000000..0d351e9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHabboHasHandItem.java @@ -0,0 +1,103 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredConditionHabboHasHandItem extends InteractionWiredCondition { + private static final Logger LOGGER = LoggerFactory.getLogger(WiredConditionHabboHasHandItem.class); + + public static final WiredConditionType type = WiredConditionType.ACTOR_HAS_HANDITEM; + + private int handItem; + + public WiredConditionHabboHasHandItem(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionHabboHasHandItem(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.handItem); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.handItem = packet.readInt(); + + return true; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (roomUnit == null) return false; + return roomUnit.getHandItem() == this.handItem; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.handItem + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + try { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.handItem = data.handItemId; + } else { + this.handItem = Integer.parseInt(wiredData); + } + } catch (Exception e) { + LOGGER.error("Caught exception", e); + } + } + + @Override + public void onPickUp() { + this.handItem = 0; + } + + static class JsonData { + int handItemId; + + public JsonData(int handItemId) { + this.handItemId = handItemId; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHabboWearsBadge.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHabboWearsBadge.java new file mode 100644 index 0000000..b4f0df9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionHabboWearsBadge.java @@ -0,0 +1,106 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredConditionHabboWearsBadge extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.ACTOR_WEARS_BADGE; + + protected String badge = ""; + + public WiredConditionHabboWearsBadge(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionHabboWearsBadge(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + synchronized (habbo.getInventory().getBadgesComponent().getWearingBadges()) { + for (HabboBadge badge : habbo.getInventory().getBadgesComponent().getWearingBadges()) { + if (badge.getCode().equalsIgnoreCase(this.badge)) { + return true; + } + } + } + } + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.badge + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.badge = data.badge; + } else { + this.badge = wiredData; + } + } + + @Override + public void onPickUp() { + this.badge = ""; + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.badge); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.badge = packet.readString(); + + return true; + } + + static class JsonData { + String badge; + + public JsonData(String badge) { + this.badge = badge; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionLessTimeElapsed.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionLessTimeElapsed.java new file mode 100644 index 0000000..b40ee5e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionLessTimeElapsed.java @@ -0,0 +1,99 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredConditionLessTimeElapsed extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.TIME_LESS_THAN; + + private int cycles; + + public WiredConditionLessTimeElapsed(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionLessTimeElapsed(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + return (Emulator.getIntUnixTimestamp() - room.getLastTimerReset()) / 0.5 < this.cycles; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.cycles + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + try { + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.cycles = data.cycles; + } else { + if (!wiredData.equals("")) + this.cycles = Integer.parseInt(wiredData); + } + } catch (Exception e) { + } + } + + @Override + public void onPickUp() { + this.cycles = 0; + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.cycles); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.cycles = packet.readInt(); + + return true; + } + + static class JsonData { + int cycles; + + public JsonData(int cycles) { + this.cycles = cycles; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMatchStatePosition.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMatchStatePosition.java new file mode 100644 index 0000000..76ece81 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMatchStatePosition.java @@ -0,0 +1,242 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.items.interactions.wired.interfaces.InteractionWiredMatchFurniSettings; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredMatchFurniSetting; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredConditionMatchStatePosition extends InteractionWiredCondition implements InteractionWiredMatchFurniSettings { + public static final WiredConditionType type = WiredConditionType.MATCH_SSHOT; + + private THashSet settings; + + private boolean state; + private boolean position; + private boolean direction; + + public WiredConditionMatchStatePosition(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.settings = new THashSet<>(); + } + + public WiredConditionMatchStatePosition(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.settings = new THashSet<>(); + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + this.refresh(); + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.settings.size()); + + for (WiredMatchFurniSetting item : this.settings) + message.appendInt(item.item_id); + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(4); + message.appendInt(this.state ? 1 : 0); + message.appendInt(this.direction ? 1 : 0); + message.appendInt(this.position ? 1 : 0); + message.appendInt(10); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + int count; + packet.readInt(); + + this.state = packet.readInt() == 1; + this.direction = packet.readInt() == 1; + this.position = packet.readInt() == 1; + + packet.readString(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room == null) + return true; + + count = packet.readInt(); + if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; + + this.settings.clear(); + + for (int i = 0; i < count; i++) { + int itemId = packet.readInt(); + HabboItem item = room.getHabboItem(itemId); + + if (item != null) + this.settings.add(new WiredMatchFurniSetting(item.getId(), item.getExtradata(), item.getRotation(), item.getX(), item.getY())); + } + + return true; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (this.settings.isEmpty()) + return true; + + THashSet s = new THashSet<>(); + + for (WiredMatchFurniSetting setting : this.settings) { + HabboItem item = room.getHabboItem(setting.item_id); + + if (item != null) { + if (this.state) { + if (!item.getExtradata().equals(setting.state)) + return false; + } + + if (this.position) { + if (!(setting.x == item.getX() && setting.y == item.getY())) + return false; + } + + if (this.direction) { + if (setting.rotation != item.getRotation()) + return false; + } + } else { + s.add(setting); + } + } + + if (!s.isEmpty()) { + for (WiredMatchFurniSetting setting : s) { + this.settings.remove(setting); + } + } + + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.state, + this.position, + this.direction, + new ArrayList<>(this.settings) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.state = data.state; + this.position = data.position; + this.direction = data.direction; + this.settings.addAll(data.settings); + } else { + String[] data = wiredData.split(":"); + + int itemCount = Integer.parseInt(data[0]); + + String[] items = data[1].split(";"); + + for (int i = 0; i < itemCount; i++) { + String[] stuff = items[i].split("-"); + + if (stuff.length >= 5) + this.settings.add(new WiredMatchFurniSetting(Integer.parseInt(stuff[0]), stuff[1], Integer.parseInt(stuff[2]), Integer.parseInt(stuff[3]), Integer.parseInt(stuff[4]))); + } + + this.state = data[2].equals("1"); + this.direction = data[3].equals("1"); + this.position = data[4].equals("1"); + } + } + + @Override + public void onPickUp() { + this.settings.clear(); + this.direction = false; + this.position = false; + this.state = false; + } + + private void refresh() { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room != null) { + THashSet remove = new THashSet<>(); + + for (WiredMatchFurniSetting setting : this.settings) { + HabboItem item = room.getHabboItem(setting.item_id); + if (item == null) { + remove.add(setting); + } + } + + for (WiredMatchFurniSetting setting : remove) { + this.settings.remove(setting); + } + } + } + + @Override + public THashSet getMatchFurniSettings() { + return this.settings; + } + + @Override + public boolean shouldMatchState() { + return this.state; + } + + @Override + public boolean shouldMatchRotation() { + return this.direction; + } + + @Override + public boolean shouldMatchPosition() { + return this.position; + } + + static class JsonData { + boolean state; + boolean position; + boolean direction; + List settings; + + public JsonData(boolean state, boolean position, boolean direction, List settings) { + this.state = state; + this.position = position; + this.direction = direction; + this.settings = settings; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMoreTimeElapsed.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMoreTimeElapsed.java new file mode 100644 index 0000000..0be6ba1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionMoreTimeElapsed.java @@ -0,0 +1,99 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredConditionMoreTimeElapsed extends InteractionWiredCondition { + private static final WiredConditionType type = WiredConditionType.TIME_MORE_THAN; + + private int cycles; + + public WiredConditionMoreTimeElapsed(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionMoreTimeElapsed(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + return (Emulator.getIntUnixTimestamp() - room.getLastTimerReset()) / 0.5 > this.cycles; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.cycles + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + try { + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.cycles = data.cycles; + } else { + if (!wiredData.equals("")) + this.cycles = Integer.parseInt(wiredData); + } + } catch (Exception e) { + } + } + + @Override + public void onPickUp() { + this.cycles = 0; + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.cycles); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.cycles = packet.readInt(); + + return true; + } + + static class JsonData { + int cycles; + + public JsonData(int cycles) { + this.cycles = cycles; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniHaveFurni.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniHaveFurni.java new file mode 100644 index 0000000..279f61b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniHaveFurni.java @@ -0,0 +1,201 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredConditionOperator; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredConditionNotFurniHaveFurni extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.NOT_FURNI_HAVE_FURNI; + + private boolean all; + private THashSet items; + + public WiredConditionNotFurniHaveFurni(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.items = new THashSet<>(); + } + + public WiredConditionNotFurniHaveFurni(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.items = new THashSet<>(); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + this.refresh(); + + if (this.items.isEmpty()) + return true; + + if(this.all) { + return this.items.stream().allMatch(item -> { + double minZ = item.getZ() + Item.getCurrentHeight(item); + THashSet occupiedTiles = room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + return occupiedTiles.stream().noneMatch(tile -> room.getItemsAt(tile).stream().anyMatch(matchedItem -> matchedItem != item && matchedItem.getZ() >= minZ)); + }); + } + else { + return this.items.stream().anyMatch(item -> { + double minZ = item.getZ() + Item.getCurrentHeight(item); + THashSet occupiedTiles = room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + return occupiedTiles.stream().noneMatch(tile -> room.getItemsAt(tile).stream().anyMatch(matchedItem -> matchedItem != item && matchedItem.getZ() >= minZ)); + }); + } + } + + @Override + public String getWiredData() { + this.refresh(); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.all, + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items.clear(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.all = data.all; + + for (int id : data.itemIds) { + HabboItem item = room.getHabboItem(id); + + if (item != null) { + this.items.add(item); + } + } + } else { + String[] data = wiredData.split(":"); + + if (data.length >= 1) { + this.all = (data[0].equals("1")); + + if (data.length == 2) { + String[] items = data[1].split(";"); + + for (String s : items) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) + this.items.add(item); + } + } + } + } + } + + @Override + public void onPickUp() { + this.all = false; + this.items.clear(); + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + this.refresh(); + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + + for (HabboItem item : this.items) + message.appendInt(item.getId()); + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.all ? 1 : 0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.all = packet.readInt() == 1; + + packet.readString(); + + int count = packet.readInt(); + if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; + + this.items.clear(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room != null) { + for (int i = 0; i < count; i++) { + HabboItem item = room.getHabboItem(packet.readInt()); + + if (item != null) + this.items.add(item); + } + + return true; + } + return false; + } + + private void refresh() { + THashSet items = new THashSet<>(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room == null) { + items.addAll(this.items); + } else { + for (HabboItem item : this.items) { + if (room.getHabboItem(item.getId()) == null) + items.add(item); + } + } + + for (HabboItem item : items) { + this.items.remove(item); + } + } + + @Override + public WiredConditionOperator operator() { + // NICE TRY BUT THAT'S NOT HOW IT WORKS. NOTHING IN HABBO IS AN "OR" CONDITION - EVERY CONDITION MUST BE SUCCESS FOR THE STACK TO EXECUTE, BUT LET'S LEAVE IT IMPLEMENTED FOR PLUGINS TO USE. + //return this.all ? WiredConditionOperator.AND : WiredConditionOperator.OR; + return WiredConditionOperator.AND; + } + + static class JsonData { + boolean all; + List itemIds; + + public JsonData(boolean all, List itemIds) { + this.all = all; + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniHaveHabbo.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniHaveHabbo.java new file mode 100644 index 0000000..87f3bc9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniHaveHabbo.java @@ -0,0 +1,192 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredConditionNotFurniHaveHabbo extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.NOT_FURNI_HAVE_HABBO; + + protected boolean all; + protected THashSet items; + + public WiredConditionNotFurniHaveHabbo(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.items = new THashSet<>(); + } + + public WiredConditionNotFurniHaveHabbo(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.items = new THashSet<>(); + } + + @Override + public void onPickUp() { + this.items.clear(); + this.all = false; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + this.refresh(); + + if (this.items.isEmpty()) + return true; + + Collection habbos = room.getHabbos(); + Collection bots = room.getCurrentBots().valueCollection(); + Collection pets = room.getCurrentPets().valueCollection(); + + return this.items.stream().noneMatch(item -> { + THashSet occupiedTiles = room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + return habbos.stream().anyMatch(character -> occupiedTiles.contains(character.getRoomUnit().getCurrentLocation())) || + bots.stream().anyMatch(character -> occupiedTiles.contains(character.getRoomUnit().getCurrentLocation())) || + pets.stream().anyMatch(character -> occupiedTiles.contains(character.getRoomUnit().getCurrentLocation())); + }); + } + + @Override + public String getWiredData() { + this.refresh(); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.all, + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items.clear(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + WiredConditionFurniHaveHabbo.JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, WiredConditionFurniHaveHabbo.JsonData.class); + this.all = data.all; + + for(int id : data.itemIds) { + HabboItem item = room.getHabboItem(id); + + if (item != null) { + this.items.add(item); + } + } + } else { + String[] data = wiredData.split(":"); + + if (data.length >= 1) { + this.all = (data[0].equals("1")); + + if (data.length == 2) { + String[] items = data[1].split(";"); + + for (String s : items) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) + this.items.add(item); + } + } + } + } + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + this.refresh(); + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + + for (HabboItem item : this.items) + message.appendInt(item.getId()); + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.all ? 1 : 0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + packet.readString(); + + int count = packet.readInt(); + if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; + + this.items.clear(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room != null) { + for (int i = 0; i < count; i++) { + HabboItem item = room.getHabboItem(packet.readInt()); + + if (item != null) + this.items.add(item); + } + + return true; + } + + return false; + } + + private void refresh() { + THashSet items = new THashSet<>(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room == null) { + items.addAll(this.items); + } else { + for (HabboItem item : this.items) { + if (room.getHabboItem(item.getId()) == null) + items.add(item); + } + } + + for (HabboItem item : items) { + this.items.remove(item); + } + } + + static class JsonData { + boolean all; + List itemIds; + + public JsonData(boolean all, List itemIds) { + this.all = all; + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniTypeMatch.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniTypeMatch.java new file mode 100644 index 0000000..30c9ea5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotFurniTypeMatch.java @@ -0,0 +1,165 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredConditionNotFurniTypeMatch extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.NOT_STUFF_IS; + + private THashSet items = new THashSet<>(); + + public WiredConditionNotFurniTypeMatch(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionNotFurniTypeMatch(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + this.refresh(); + + if(items.isEmpty()) + return true; + + if (stuff != null) { + if (stuff.length >= 1) { + if (stuff[0] instanceof HabboItem) { + HabboItem triggeringItem = (HabboItem)stuff[0]; + return this.items.stream().noneMatch(item -> item == triggeringItem); + } + } + } + + return true; + } + + @Override + public String getWiredData() { + this.refresh(); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items.clear(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + WiredConditionFurniTypeMatch.JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, WiredConditionFurniTypeMatch.JsonData.class); + + for(int id : data.itemIds) { + HabboItem item = room.getHabboItem(id); + + if (item != null) { + this.items.add(item); + } + } + } else { + String[] data = set.getString("wired_data").split(";"); + + for (String s : data) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) { + this.items.add(item); + } + } + } + } + + @Override + public void onPickUp() { + this.items.clear(); + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + this.refresh(); + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + + for (HabboItem item : this.items) + message.appendInt(item.getId()); + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + packet.readString(); + + int count = packet.readInt(); + if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; + + this.items.clear(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room != null) { + for (int i = 0; i < count; i++) { + this.items.add(room.getHabboItem(packet.readInt())); + } + } + + return true; + } + + private void refresh() { + THashSet items = new THashSet<>(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room == null) { + items.addAll(this.items); + } else { + for (HabboItem item : this.items) { + if (room.getHabboItem(item.getId()) == null) + items.add(item); + } + } + + for (HabboItem item : items) { + this.items.remove(item); + } + } + + static class JsonData { + List itemIds; + + public JsonData(List itemIds) { + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotHabboCount.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotHabboCount.java new file mode 100644 index 0000000..3075c4f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotHabboCount.java @@ -0,0 +1,106 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredConditionNotHabboCount extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.NOT_USER_COUNT; + + private int lowerLimit = 10; + private int upperLimit = 20; + + public WiredConditionNotHabboCount(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionNotHabboCount(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + int count = room.getUserCount(); + + return count < this.lowerLimit || count > this.upperLimit; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.lowerLimit, + this.upperLimit + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + WiredConditionHabboCount.JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, WiredConditionHabboCount.JsonData.class); + this.lowerLimit = data.lowerLimit; + this.upperLimit = data.upperLimit; + } else { + String[] data = wiredData.split(":"); + this.lowerLimit = Integer.parseInt(data[0]); + this.upperLimit = Integer.parseInt(data[1]); + } + } + + @Override + public void onPickUp() { + this.upperLimit = 0; + this.lowerLimit = 20; + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(2); + message.appendInt(this.lowerLimit); + message.appendInt(this.upperLimit); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.lowerLimit = packet.readInt(); + this.upperLimit = packet.readInt(); + + return true; + } + + static class JsonData { + int lowerLimit; + int upperLimit; + + public JsonData(int lowerLimit, int upperLimit) { + this.lowerLimit = lowerLimit; + this.upperLimit = upperLimit; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotHabboHasEffect.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotHabboHasEffect.java new file mode 100644 index 0000000..ae1c20b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotHabboHasEffect.java @@ -0,0 +1,94 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredConditionNotHabboHasEffect extends InteractionWiredCondition { + private static final WiredConditionType type = WiredConditionType.NOT_ACTOR_WEARS_EFFECT; + + protected int effectId; + + public WiredConditionNotHabboHasEffect(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionNotHabboHasEffect(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (roomUnit == null) return false; + return roomUnit.getEffectId() != this.effectId; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.effectId + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.effectId = data.effectId; + } else { + this.effectId = Integer.parseInt(wiredData); + } + } + + @Override + public void onPickUp() { + this.effectId = 0; + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.effectId + ""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.effectId = packet.readInt(); + + return true; + } + + static class JsonData { + int effectId; + + public JsonData(int effectId) { + this.effectId = effectId; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotHabboWearsBadge.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotHabboWearsBadge.java new file mode 100644 index 0000000..6df96d6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotHabboWearsBadge.java @@ -0,0 +1,107 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredConditionNotHabboWearsBadge extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.NOT_ACTOR_WEARS_BADGE; + + protected String badge = ""; + + public WiredConditionNotHabboWearsBadge(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionNotHabboWearsBadge(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + synchronized (habbo.getInventory().getBadgesComponent().getWearingBadges()) { + for (HabboBadge b : habbo.getInventory().getBadgesComponent().getWearingBadges()) { + if (b.getCode().equalsIgnoreCase(this.badge)) + return false; + } + } + return true; + } + + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.badge + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.badge = data.badge; + } else { + this.badge = wiredData; + } + } + + @Override + public void onPickUp() { + this.badge = ""; + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.badge); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.badge = packet.readString(); + + return true; + } + + static class JsonData { + String badge; + + public JsonData(String badge) { + this.badge = badge; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotInGroup.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotInGroup.java new file mode 100644 index 0000000..520f28b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotInGroup.java @@ -0,0 +1,75 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredConditionNotInGroup extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.NOT_ACTOR_IN_GROUP; + + public WiredConditionNotInGroup(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionNotInGroup(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (room.getGuildId() == 0) + return false; + + Habbo habbo = room.getHabbo(roomUnit); + + return habbo == null || !habbo.getHabboStats().hasGuild(room.getGuildId()); + } + + @Override + public String getWiredData() { + return ""; + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + + } + + @Override + public void onPickUp() { + + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotInTeam.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotInTeam.java new file mode 100644 index 0000000..b805c7b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotInTeam.java @@ -0,0 +1,107 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredConditionNotInTeam extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.NOT_ACTOR_IN_TEAM; + + private GameTeamColors teamColor = GameTeamColors.RED; + + public WiredConditionNotInTeam(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionNotInTeam(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + return habbo.getHabboInfo().getGamePlayer() == null || !habbo.getHabboInfo().getGamePlayer().getTeamColor().equals(this.teamColor); // user is not part of any team + } + + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.teamColor + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + try { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.teamColor = data.teamColor; + } else { + if (!wiredData.equals("")) + this.teamColor = GameTeamColors.values()[Integer.parseInt(wiredData)]; + } + } catch (Exception e) { + this.teamColor = GameTeamColors.RED; + } + } + + @Override + public void onPickUp() { + this.teamColor = GameTeamColors.RED; + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.teamColor.type); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.teamColor = GameTeamColors.values()[packet.readInt()]; + + return true; + } + + static class JsonData { + GameTeamColors teamColor; + + public JsonData(GameTeamColors teamColor) { + this.teamColor = teamColor; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotMatchStatePosition.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotMatchStatePosition.java new file mode 100644 index 0000000..bc29186 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotMatchStatePosition.java @@ -0,0 +1,32 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.wired.interfaces.InteractionWiredMatchFurniSettings; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredConditionType; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredConditionNotMatchStatePosition extends WiredConditionMatchStatePosition { + public static final WiredConditionType type = WiredConditionType.NOT_MATCH_SSHOT; + + public WiredConditionNotMatchStatePosition(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionNotMatchStatePosition(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + return !super.execute(roomUnit, room, stuff); + } + + @Override + public WiredConditionType getType() { + return type; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotTriggerOnFurni.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotTriggerOnFurni.java new file mode 100644 index 0000000..21ea027 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionNotTriggerOnFurni.java @@ -0,0 +1,39 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredConditionType; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredConditionNotTriggerOnFurni extends WiredConditionTriggerOnFurni { + public static final WiredConditionType type = WiredConditionType.NOT_ACTOR_ON_FURNI; + + public WiredConditionNotTriggerOnFurni(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionNotTriggerOnFurni(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (roomUnit == null) + return false; + + this.refresh(); + + if (this.items.isEmpty()) + return true; + + return !triggerOnFurni(roomUnit, room); + } + + @Override + public WiredConditionType getType() { + return type; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTeamMember.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTeamMember.java new file mode 100644 index 0000000..027db81 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTeamMember.java @@ -0,0 +1,109 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredConditionTeamMember extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.ACTOR_IN_TEAM; + + private GameTeamColors teamColor = GameTeamColors.RED; + + public WiredConditionTeamMember(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionTeamMember(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + if (habbo.getHabboInfo().getGamePlayer() != null) { + return habbo.getHabboInfo().getGamePlayer().getTeamColor().equals(this.teamColor); + } + } + + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.teamColor + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + try { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.teamColor = data.teamColor; + } else { + if (!wiredData.equals("")) + this.teamColor = GameTeamColors.values()[Integer.parseInt(wiredData)]; + } + } catch (Exception e) { + this.teamColor = GameTeamColors.RED; + } + } + + @Override + public void onPickUp() { + this.teamColor = GameTeamColors.RED; + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.teamColor.type); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.teamColor = GameTeamColors.values()[packet.readInt()]; + + return true; + } + + static class JsonData { + GameTeamColors teamColor; + + public JsonData(GameTeamColors teamColor) { + this.teamColor = teamColor; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTriggerOnFurni.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTriggerOnFurni.java new file mode 100644 index 0000000..61e3fd7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTriggerOnFurni.java @@ -0,0 +1,173 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.conditions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredConditionOperator; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredConditionTriggerOnFurni extends InteractionWiredCondition { + public static final WiredConditionType type = WiredConditionType.TRIGGER_ON_FURNI; + + protected THashSet items = new THashSet<>(); + + public WiredConditionTriggerOnFurni(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredConditionTriggerOnFurni(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (roomUnit == null) + return false; + + this.refresh(); + + if (this.items.isEmpty()) + return false; + + return triggerOnFurni(roomUnit, room); + } + + protected boolean triggerOnFurni(RoomUnit roomUnit, Room room) { + THashSet itemsAtUser = room.getItemsAt(roomUnit.getCurrentLocation()); + return this.items.stream().anyMatch(itemsAtUser::contains); + } + + @Override + public String getWiredData() { + this.refresh(); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items.clear(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + + for(int id : data.itemIds) { + HabboItem item = room.getHabboItem(id); + + if (item != null) { + this.items.add(item); + } + } + } else { + String[] data = wiredData.split(";"); + + for (String s : data) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) { + this.items.add(item); + } + } + } + } + + @Override + public void onPickUp() { + this.items.clear(); + } + + @Override + public WiredConditionType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + this.refresh(); + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + + for (HabboItem item : this.items) + message.appendInt(item.getId()); + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + packet.readString(); + + int count = packet.readInt(); + if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false; + + this.items.clear(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room != null) { + for (int i = 0; i < count; i++) { + HabboItem item = room.getHabboItem(packet.readInt()); + + if (item != null) { + this.items.add(item); + } + } + } + + return true; + } + + protected void refresh() { + THashSet items = new THashSet<>(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room == null) { + items.addAll(this.items); + } else { + for (HabboItem item : this.items) { + if (item.getRoomId() != room.getId()) + items.add(item); + } + } + + this.items.removeAll(items); + } + + @Override + public WiredConditionOperator operator() { + return WiredConditionOperator.AND; + } + + static class JsonData { + List itemIds; + + public JsonData(List itemIds) { + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectAlert.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectAlert.java new file mode 100644 index 0000000..14e8348 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectAlert.java @@ -0,0 +1,35 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredEffectAlert extends WiredEffectWhisper { + public WiredEffectAlert(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectAlert(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + habbo.alert(this.message + .replace("%online%", Emulator.getGameEnvironment().getHabboManager().getOnlineCount() + "") + .replace("%username%", habbo.getHabboInfo().getUsername()) + .replace("%roomsloaded%", Emulator.getGameEnvironment().getRoomManager().loadedRoomsCount() + "")); + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotClothes.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotClothes.java new file mode 100644 index 0000000..f0a5b3f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotClothes.java @@ -0,0 +1,156 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import com.google.gson.Gson; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.regex.Pattern; + +public class WiredEffectBotClothes extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.BOT_CLOTHES; + + private String botName = ""; + private String botLook = ""; + + public WiredEffectBotClothes(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectBotClothes(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.botName + ((char) 9) + "" + this.botLook); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + String dataString = packet.readString(); + packet.readInt(); + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + String splitBy = "\t"; + if(!dataString.contains(splitBy)) + throw new WiredSaveException("Malformed data string"); + + String[] data = dataString.split(Pattern.quote(splitBy)); + + if (data.length != 2) + throw new WiredSaveException("Malformed data string. Invalid data length"); + + this.botName = data[0].substring(0, Math.min(data[0].length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.botLook = data[1]; + this.setDelay(delay); + + return true; + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + List bots = room.getBots(this.botName); + + if (bots.size() == 1) { + Bot bot = bots.get(0); + bot.setFigure(this.botLook); + } + + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.botName, this.botLook, this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.botName = data.bot_name; + this.botLook = data.look; + } + else { + String[] data = wiredData.split(((char) 9) + ""); + + if (data.length >= 3) { + this.setDelay(Integer.valueOf(data[0])); + this.botName = data[1]; + this.botLook = data[2]; + } + + this.needsUpdate(true); + } + } + + @Override + public void onPickUp() { + this.botLook = ""; + this.botName = ""; + this.setDelay(0); + } + + public String getBotName() { + return this.botName; + } + + public void setBotName(String botName) { + this.botName = botName; + } + + public String getBotLook() { + return this.botLook; + } + + public void setBotLook(String botLook) { + this.botLook = botLook; + } + + static class JsonData { + String bot_name; + String look; + int delay; + + public JsonData(String bot_name, String look, int delay) { + this.bot_name = bot_name; + this.look = look; + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotFollowHabbo.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotFollowHabbo.java new file mode 100644 index 0000000..ee1b28b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotFollowHabbo.java @@ -0,0 +1,172 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredEffectBotFollowHabbo extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.BOT_FOLLOW_AVATAR; + + private String botName = ""; + private int mode = 0; + + public WiredEffectBotFollowHabbo(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectBotFollowHabbo(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.botName); + message.appendInt(1); + message.appendInt(this.mode); + message.appendInt(1); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + int mode = packet.readInt(); + + if(mode != 0 && mode != 1) + throw new WiredSaveException("Mode is invalid"); + + String botName = packet.readString().replace("\t", ""); + botName = botName.substring(0, Math.min(botName.length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + packet.readInt(); + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.botName = botName; + this.mode = mode; + this.setDelay(delay); + + return true; + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + + List bots = room.getBots(this.botName); + + if (habbo != null && bots.size() == 1) { + Bot bot = bots.get(0); + + if (this.mode == 1) { + bot.startFollowingHabbo(habbo); + } else { + bot.stopFollowingHabbo(); + } + + return true; + } + + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.botName, this.mode, this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.mode = data.mode; + this.botName = data.bot_name; + } + else { + String[] data = wiredData.split(((char) 9) + ""); + + if (data.length == 3) { + this.setDelay(Integer.valueOf(data[0])); + this.mode = (data[1].equalsIgnoreCase("1") ? 1 : 0); + this.botName = data[2]; + } + + this.needsUpdate(true); + } + } + + @Override + public void onPickUp() { + this.botName = ""; + this.mode = 0; + this.setDelay(0); + } + + @Override + public boolean requiresTriggeringUser() { + return true; + } + + static class JsonData { + String bot_name; + int mode; + int delay; + + public JsonData(String bot_name, int mode, int delay) { + this.bot_name = bot_name; + this.mode = mode; + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotGiveHandItem.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotGiveHandItem.java new file mode 100644 index 0000000..27fc788 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotGiveHandItem.java @@ -0,0 +1,187 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import com.eu.habbo.threading.runnables.RoomUnitGiveHanditem; +import com.eu.habbo.threading.runnables.RoomUnitWalkToLocation; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredEffectBotGiveHandItem extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.BOT_GIVE_HANDITEM; + + private String botName = ""; + private int itemId; + + public WiredEffectBotGiveHandItem(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectBotGiveHandItem(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.botName); + message.appendInt(1); + message.appendInt(this.itemId); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + + int itemId = packet.readInt(); + + if(itemId < 0) + itemId = 0; + + String botName = packet.readString(); + packet.readInt(); + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.itemId = itemId; + this.botName = botName.substring(0, Math.min(botName.length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.setDelay(delay); + + return true; + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + List bots = room.getBots(this.botName); + + if (habbo != null && bots.size() == 1) { + Bot bot = bots.get(0); + + List tasks = new ArrayList<>(); + tasks.add(new RoomUnitGiveHanditem(roomUnit, room, this.itemId)); + tasks.add(new RoomUnitGiveHanditem(bot.getRoomUnit(), room, 0)); + tasks.add(() -> { + if(roomUnit.getRoom() != null && roomUnit.getRoom().getId() == room.getId() && roomUnit.getCurrentLocation().distance(bot.getRoomUnit().getCurrentLocation()) < 2) { + WiredHandler.handle(WiredTriggerType.BOT_REACHED_AVTR, bot.getRoomUnit(), room, new Object[]{}); + } + }); + + RoomTile tile = bot.getRoomUnit().getClosestAdjacentTile(roomUnit.getX(), roomUnit.getY(), true); + + if(tile != null) { + bot.getRoomUnit().setGoalLocation(tile); + } + + Emulator.getThreading().run(new RoomUnitGiveHanditem(bot.getRoomUnit(), room, this.itemId)); + Emulator.getThreading().run(new RoomUnitWalkToLocation(bot.getRoomUnit(), tile, room, tasks, tasks)); + + return true; + } + + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.botName, this.itemId, this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.itemId = data.item_id; + this.botName = data.bot_name; + } + else { + String[] data = wiredData.split(((char) 9) + ""); + + if (data.length == 3) { + this.setDelay(Integer.valueOf(data[0])); + this.itemId = Integer.valueOf(data[1]); + this.botName = data[2]; + } + + this.needsUpdate(true); + } + } + + @Override + public void onPickUp() { + this.botName = ""; + this.itemId = 0; + this.setDelay(0); + } + + @Override + public boolean requiresTriggeringUser() { + return true; + } + + static class JsonData { + String bot_name; + int item_id; + int delay; + + public JsonData(String bot_name, int item_id, int delay) { + this.bot_name = bot_name; + this.item_id = item_id; + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTalk.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTalk.java new file mode 100644 index 0000000..735b0f3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTalk.java @@ -0,0 +1,208 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.regex.Pattern; + +public class WiredEffectBotTalk extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.BOT_TALK; + + private int mode; + private String botName = ""; + private String message = ""; + + public WiredEffectBotTalk(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectBotTalk(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.botName + "" + ((char) 9) + "" + this.message); + message.appendInt(1); + message.appendInt(this.mode); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + + int mode = packet.readInt(); + + if(mode != 0 && mode != 1) + throw new WiredSaveException("Mode is invalid"); + + String dataString = packet.readString(); + + String splitBy = "\t"; + if(!dataString.contains(splitBy)) + throw new WiredSaveException("Malformed data string"); + + String[] data = dataString.split(Pattern.quote(splitBy)); + + if (data.length != 2) + throw new WiredSaveException("Malformed data string. Invalid data length"); + + packet.readInt(); + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.setDelay(delay); + this.botName = data[0].substring(0, Math.min(data[0].length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.message = data[1].substring(0, Math.min(data[1].length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.mode = mode; + + return true; + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + String message = this.message; + + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + message = message.replace(Emulator.getTexts().getValue("wired.variable.username", "%username%"), habbo.getHabboInfo().getUsername()) + .replace(Emulator.getTexts().getValue("wired.variable.credits", "%credits%"), habbo.getHabboInfo().getCredits() + "") + .replace(Emulator.getTexts().getValue("wired.variable.pixels", "%pixels%"), habbo.getHabboInfo().getPixels() + "") + .replace(Emulator.getTexts().getValue("wired.variable.points", "%points%"), habbo.getHabboInfo().getCurrencyAmount(Emulator.getConfig().getInt("seasonal.primary.type")) + "") + .replace(Emulator.getTexts().getValue("wired.variable.owner", "%owner%"), room.getOwnerName()) + .replace(Emulator.getTexts().getValue("wired.variable.item_count", "%item_count%"), room.itemCount() + "") + .replace(Emulator.getTexts().getValue("wired.variable.name", "%name%"), this.botName) + .replace(Emulator.getTexts().getValue("wired.variable.roomname", "%roomname%"), room.getName()) + .replace(Emulator.getTexts().getValue("wired.variable.user_count", "%user_count%"), room.getUserCount() + ""); + } + + List bots = room.getBots(this.botName); + + if (bots.size() == 1) { + Bot bot = bots.get(0); + + if(!WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, bot.getRoomUnit(), room, new Object[]{ message })) { + if (this.mode == 1) { + bot.shout(message); + } else { + bot.talk(message); + } + } + } + + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.botName, this.mode, this.message, this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.mode = data.mode; + this.botName = data.bot_name; + this.message = data.message; + } + else { + String[] data = wiredData.split(((char) 9) + ""); + + if (data.length == 4) { + this.setDelay(Integer.valueOf(data[0])); + this.mode = data[1].equalsIgnoreCase("1") ? 1 : 0; + this.botName = data[2]; + this.message = data[3]; + } + + this.needsUpdate(true); + } + } + + @Override + public void onPickUp() { + this.mode = 0; + this.botName = ""; + this.message = ""; + this.setDelay(0); + } + + public int getMode() { + return this.mode; + } + + public void setMode(int mode) { + this.mode = mode; + } + + public String getBotName() { + return this.botName; + } + + public void setBotName(String botName) { + this.botName = botName; + } + + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + protected long requiredCooldown() { + return 500; + } + + static class JsonData { + String bot_name; + int mode; + String message; + int delay; + + public JsonData(String bot_name, int mode, String message, int delay) { + this.bot_name = bot_name; + this.mode = mode; + this.message = message; + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTalkToHabbo.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTalkToHabbo.java new file mode 100644 index 0000000..8fede69 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTalkToHabbo.java @@ -0,0 +1,207 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +public class WiredEffectBotTalkToHabbo extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.BOT_TALK_TO_AVATAR; + + private int mode; + private String botName = ""; + private String message = ""; + + public WiredEffectBotTalkToHabbo(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectBotTalkToHabbo(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.botName + "" + ((char) 9) + "" + this.message); + message.appendInt(1); + message.appendInt(this.mode); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + + int mode = packet.readInt(); + + if(mode != 0 && mode != 1) + throw new WiredSaveException("Mode is invalid"); + + String dataString = packet.readString(); + String splitBy = "\t"; + if(!dataString.contains(splitBy)) + throw new WiredSaveException("Malformed data string"); + + String[] data = dataString.split(Pattern.quote(splitBy)); + + if (data.length != 2) + throw new WiredSaveException("Malformed data string. Invalid data length"); + + packet.readInt(); + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.botName = data[0].substring(0, Math.min(data[0].length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.message = data[1].substring(0, Math.min(data[1].length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.mode = mode; + this.setDelay(delay); + + return true; + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + String m = this.message; + m = m.replace(Emulator.getTexts().getValue("wired.variable.username", "%username%"), habbo.getHabboInfo().getUsername()) + .replace(Emulator.getTexts().getValue("wired.variable.credits", "%credits%"), habbo.getHabboInfo().getCredits() + "") + .replace(Emulator.getTexts().getValue("wired.variable.pixels", "%pixels%"), habbo.getHabboInfo().getPixels() + "") + .replace(Emulator.getTexts().getValue("wired.variable.points", "%points%"), habbo.getHabboInfo().getCurrencyAmount(Emulator.getConfig().getInt("seasonal.primary.type")) + "") + .replace(Emulator.getTexts().getValue("wired.variable.owner", "%owner%"), room.getOwnerName()) + .replace(Emulator.getTexts().getValue("wired.variable.item_count", "%item_count%"), room.itemCount() + "") + .replace(Emulator.getTexts().getValue("wired.variable.name", "%name%"), this.botName) + .replace(Emulator.getTexts().getValue("wired.variable.roomname", "%roomname%"), room.getName()) + .replace(Emulator.getTexts().getValue("wired.variable.user_count", "%user_count%"), room.getUserCount() + ""); + + List bots = room.getBots(this.botName); + + if (bots.size() != 1) { + return false; + } + + Bot bot = bots.get(0); + + if(!WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, bot.getRoomUnit(), room, new Object[]{ m })) { + if (this.mode == 1) { + bot.whisper(m, habbo); + } else { + bot.talk(habbo.getHabboInfo().getUsername() + ": " + m); + } + } + + return true; + } + + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.botName, this.mode, this.message, this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.mode = data.mode; + this.botName = data.bot_name; + this.message = data.message; + } + else { + String[] data = wiredData.split(((char) 9) + ""); + + if (data.length == 4) { + this.setDelay(Integer.valueOf(data[0])); + this.mode = data[1].equalsIgnoreCase("1") ? 1 : 0; + this.botName = data[2]; + this.message = data[3]; + } + + this.needsUpdate(true); + } + } + + @Override + public void onPickUp() { + this.botName = ""; + this.message = ""; + this.mode = 0; + this.setDelay(0); + } + + @Override + public boolean requiresTriggeringUser() { + return true; + } + + static class JsonData { + String bot_name; + int mode; + String message; + int delay; + + public JsonData(String bot_name, int mode, String message, int delay) { + this.bot_name = bot_name; + this.mode = mode; + this.message = message; + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTeleport.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTeleport.java new file mode 100644 index 0000000..07bbac6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotTeleport.java @@ -0,0 +1,260 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +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.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserEffectComposer; +import com.eu.habbo.threading.runnables.RoomUnitTeleport; +import com.eu.habbo.threading.runnables.SendRoomUnitEffectComposer; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredEffectBotTeleport extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.BOT_TELEPORT; + + private THashSet items; + private String botName = ""; + + public WiredEffectBotTeleport(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.items = new THashSet<>(); + } + + public WiredEffectBotTeleport(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.items = new THashSet<>(); + } + + public static void teleportUnitToTile(RoomUnit roomUnit, RoomTile tile) { + if (roomUnit == null || tile == null || roomUnit.isWiredTeleporting) + return; + + Room room = roomUnit.getRoom(); + + if (room == null) { + return; + } + + // makes a temporary effect + + roomUnit.getRoom().unIdle(roomUnit.getRoom().getHabbo(roomUnit)); + room.sendComposer(new RoomUserEffectComposer(roomUnit, 4).compose()); + Emulator.getThreading().run(new SendRoomUnitEffectComposer(room, roomUnit), WiredHandler.TELEPORT_DELAY + 1000); + + if (tile == roomUnit.getCurrentLocation()) { + return; + } + + if (tile.state == RoomTileState.INVALID || tile.state == RoomTileState.BLOCKED) { + RoomTile alternativeTile = null; + List optionalTiles = room.getLayout().getTilesAround(tile); + + Collections.reverse(optionalTiles); + for (RoomTile optionalTile : optionalTiles) { + if (optionalTile.state != RoomTileState.INVALID && optionalTile.state != RoomTileState.BLOCKED) { + alternativeTile = optionalTile; + break; + } + } + + if (alternativeTile != null) { + tile = alternativeTile; + } + } + + Emulator.getThreading().run(() -> { roomUnit.isWiredTeleporting = true; }, Math.max(0, WiredHandler.TELEPORT_DELAY - 500)); + Emulator.getThreading().run(new RoomUnitTeleport(roomUnit, room, tile.x, tile.y, tile.getStackHeight() + (tile.state == RoomTileState.SIT ? -0.5 : 0), roomUnit.getEffectId()), WiredHandler.TELEPORT_DELAY); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + THashSet items = new THashSet<>(); + + for (HabboItem item : this.items) { + if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) + items.add(item); + } + + for (HabboItem item : items) { + this.items.remove(item); + } + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + for (HabboItem item : this.items) + message.appendInt(item.getId()); + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.botName); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + String botName = packet.readString(); + int itemsCount = packet.readInt(); + + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); + } + + List newItems = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.add(it); + } + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.items.clear(); + this.items.addAll(newItems); + this.botName = botName.substring(0, Math.min(botName.length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.setDelay(delay); + + return true; + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (this.items.isEmpty()) + return false; + + List bots = room.getBots(this.botName); + + if (bots.size() != 1) { + return false; + } + + Bot bot = bots.get(0); + + int i = Emulator.getRandom().nextInt(this.items.size()) + 1; + int j = 1; + + for (HabboItem item : this.items) { + if (item.getRoomId() != 0 && item.getRoomId() == bot.getRoom().getId()) { + if (i == j) { + teleportUnitToTile(bot.getRoomUnit(), room.getLayout().getTile(item.getX(), item.getY())); + return true; + } else { + j++; + } + } + } + + return true; + } + + @Override + public String getWiredData() { + ArrayList itemIds = new ArrayList<>(); + + if (this.items != null) { + for (HabboItem item : this.items) { + if (item.getRoomId() != 0) { + itemIds.add(item.getId()); + } + } + } + + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.botName, itemIds, this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items = new THashSet<>(); + + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.botName = data.bot_name; + + for(int itemId : data.items) { + HabboItem item = room.getHabboItem(itemId); + + if (item != null) + this.items.add(item); + } + } + else { + String[] wiredDataSplit = set.getString("wired_data").split("\t"); + + if (wiredDataSplit.length >= 2) { + this.setDelay(Integer.valueOf(wiredDataSplit[0])); + String[] data = wiredDataSplit[1].split(";"); + + if (data.length > 1) { + this.botName = data[0]; + + for (int i = 1; i < data.length; i++) { + HabboItem item = room.getHabboItem(Integer.valueOf(data[i])); + + if (item != null) + this.items.add(item); + } + } + } + + this.needsUpdate(true); + } + } + + @Override + public void onPickUp() { + this.botName = ""; + this.items.clear(); + this.setDelay(0); + } + + static class JsonData { + String bot_name; + List items; + int delay; + + public JsonData(String bot_name, List items, int delay) { + this.bot_name = bot_name; + this.items = items; + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotWalkToFurni.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotWalkToFurni.java new file mode 100644 index 0000000..73906c8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectBotWalkToFurni.java @@ -0,0 +1,211 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredEffectBotWalkToFurni extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.BOT_MOVE; + + private List items; + private String botName = ""; + + public WiredEffectBotWalkToFurni(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.items = new ArrayList<>(); + } + + public WiredEffectBotWalkToFurni(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.items = new ArrayList<>(); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + THashSet items = new THashSet<>(); + + for (HabboItem item : this.items) { + if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) + items.add(item); + } + + for (HabboItem item : items) { + this.items.remove(item); + } + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + for (HabboItem item : this.items) + message.appendInt(item.getId()); + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.botName); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + String botName = packet.readString(); + int itemsCount = packet.readInt(); + + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); + } + + List newItems = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.add(it); + } + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.items.clear(); + this.items.addAll(newItems); + this.botName = botName.substring(0, Math.min(botName.length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.setDelay(delay); + + return true; + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + List bots = room.getBots(this.botName); + + if (this.items.isEmpty() || bots.size() != 1) { + return true; + } + + Bot bot = bots.get(0); + this.items.removeIf(item -> item == null || item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null); + + // Bots shouldn't walk to the tile they are already standing on + List possibleItems = this.items.stream() + .filter(item -> !room.getBotsOnItem(item).contains(bot)) + .collect(Collectors.toList()); + + // Get a random tile of possible tiles to walk to + if (possibleItems.size() > 0) { + HabboItem item = possibleItems.get(Emulator.getRandom().nextInt(possibleItems.size())); + + if (item.getRoomId() != 0 && item.getRoomId() == bot.getRoom().getId()) { + bot.getRoomUnit().setGoalLocation(room.getLayout().getTile(item.getX(), item.getY())); + } + } + + return true; + } + + @Override + public String getWiredData() { + ArrayList itemIds = new ArrayList<>(); + + if (this.items != null) { + for (HabboItem item : this.items) { + if (item.getRoomId() != 0) { + itemIds.add(item.getId()); + } + } + } + + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.botName, itemIds, this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items = new ArrayList<>(); + + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.botName = data.bot_name; + + for(int itemId : data.items) { + HabboItem item = room.getHabboItem(itemId); + + if (item != null) + this.items.add(item); + } + } + else { + String[] wiredDataSplit = set.getString("wired_data").split("\t"); + + if (wiredDataSplit.length >= 2) { + this.setDelay(Integer.valueOf(wiredDataSplit[0])); + String[] data = wiredDataSplit[1].split(";"); + + if (data.length > 1) { + this.botName = data[0]; + + for (int i = 1; i < data.length; i++) { + HabboItem item = room.getHabboItem(Integer.valueOf(data[i])); + + if (item != null) + this.items.add(item); + } + } + } + + this.needsUpdate(true); + } + } + + @Override + public void onPickUp() { + this.items.clear(); + this.botName = ""; + this.setDelay(0); + } + + static class JsonData { + String bot_name; + List items; + int delay; + + public JsonData(String bot_name, List items, int delay) { + this.bot_name = bot_name; + this.items = items; + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectChangeFurniDirection.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectChangeFurniDirection.java new file mode 100644 index 0000000..0ce892d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectChangeFurniDirection.java @@ -0,0 +1,301 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.*; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class WiredEffectChangeFurniDirection extends InteractionWiredEffect { + public static final int ACTION_WAIT = 0; + public static final int ACTION_TURN_RIGHT_45 = 1; + public static final int ACTION_TURN_RIGHT_90 = 2; + public static final int ACTION_TURN_LEFT_45 = 3; + public static final int ACTION_TURN_LEFT_90 = 4; + public static final int ACTION_TURN_BACK = 5; + public static final int ACTION_TURN_RANDOM = 6; + + public static final WiredEffectType type = WiredEffectType.MOVE_DIRECTION; + + private final THashMap items = new THashMap<>(0); + private RoomUserRotation startRotation = RoomUserRotation.NORTH; + private int blockedAction = 0; + + public WiredEffectChangeFurniDirection(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectChangeFurniDirection(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + THashSet items = new THashSet<>(); + + for (HabboItem item : this.items.keySet()) { + if (Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) + items.add(item); + } + + for (HabboItem item : items) { + this.items.remove(item); + } + + if (this.items.isEmpty()) return false; + + for (Map.Entry entry : this.items.entrySet()) { + HabboItem item = entry.getKey(); + RoomTile targetTile = room.getLayout().getTileInFront(room.getLayout().getTile(item.getX(), item.getY()), entry.getValue().direction.getValue()); + + int count = 1; + while ((targetTile == null || targetTile.state == RoomTileState.INVALID || room.furnitureFitsAt(targetTile, item, item.getRotation(), false) != FurnitureMovementError.NONE) && count < 8) { + entry.getValue().direction = this.nextRotation(entry.getValue().direction); + + RoomTile tile = room.getLayout().getTileInFront(room.getLayout().getTile(item.getX(), item.getY()), entry.getValue().direction.getValue()); + if (tile != null && tile.state != RoomTileState.INVALID) { + targetTile = tile; + } + + count++; + } + } + + for (Map.Entry entry : this.items.entrySet()) { + HabboItem item = entry.getKey(); + int newDirection = entry.getValue().direction.getValue(); + + RoomTile targetTile = room.getLayout().getTileInFront(room.getLayout().getTile(item.getX(), item.getY()), newDirection); + + if(item.getRotation() != entry.getValue().rotation) { + if(room.furnitureFitsAt(targetTile, item, entry.getValue().rotation, false) != FurnitureMovementError.NONE) + continue; + + room.moveFurniTo(entry.getKey(), targetTile, entry.getValue().rotation, null, true); + } + + boolean hasRoomUnits = false; + THashSet newOccupiedTiles = room.getLayout().getTilesAt(targetTile, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + for(RoomTile tile : newOccupiedTiles) { + for (RoomUnit _roomUnit : room.getRoomUnits(tile)) { + hasRoomUnits = true; + if(_roomUnit.getCurrentLocation() == targetTile) { + Emulator.getThreading().run(() -> WiredHandler.handle(WiredTriggerType.COLLISION, _roomUnit, room, new Object[]{entry.getKey()})); + break; + } + } + } + + if (targetTile != null && targetTile.state != RoomTileState.INVALID && room.furnitureFitsAt(targetTile, item, item.getRotation(), false) == FurnitureMovementError.NONE) { + if (!hasRoomUnits) { + RoomTile oldLocation = room.getLayout().getTile(entry.getKey().getX(), entry.getKey().getY()); + double oldZ = entry.getKey().getZ(); + if(room.moveFurniTo(entry.getKey(), targetTile, item.getRotation(), null, false) == FurnitureMovementError.NONE) { + room.sendComposer(new FloorItemOnRollerComposer(entry.getKey(), null, oldLocation, oldZ, targetTile, entry.getKey().getZ(), 0, room).compose()); + } + } + } + } + + return false; + } + + @Override + public String getWiredData() { + ArrayList settings = new ArrayList<>(this.items.values()); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.startRotation, this.blockedAction, settings, this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + + this.items.clear(); + + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.startRotation = data.start_direction; + this.blockedAction = data.blocked_action; + + for(WiredChangeDirectionSetting setting : data.items) { + HabboItem item = room.getHabboItem(setting.item_id); + + if (item != null) { + this.items.put(item, setting); + } + } + } + else { + String[] data = wiredData.split("\t"); + + if (data.length >= 4) { + this.setDelay(Integer.parseInt(data[0])); + this.startRotation = RoomUserRotation.fromValue(Integer.parseInt(data[1])); + this.blockedAction = Integer.parseInt(data[2]); + + int itemCount = Integer.parseInt(data[3]); + + if (itemCount > 0) { + for (int i = 4; i < data.length; i++) { + String[] subData = data[i].split(":"); + + if (subData.length >= 2) { + HabboItem item = room.getHabboItem(Integer.parseInt(subData[0])); + + if (item != null) { + int rotation = item.getRotation(); + + if (subData.length > 2) { + rotation = Integer.parseInt(subData[2]); + } + + this.items.put(item, new WiredChangeDirectionSetting(item.getId(), rotation, RoomUserRotation.fromValue(Integer.parseInt(subData[1])))); + } + } + } + } + } + + this.needsUpdate(true); + } + } + + @Override + public void onPickUp() { + this.setDelay(0); + this.items.clear(); + this.blockedAction = 0; + this.startRotation = RoomUserRotation.NORTH; + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + for (Map.Entry item : this.items.entrySet()) { + message.appendInt(item.getKey().getId()); + } + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(2); + message.appendInt(this.startRotation != null ? this.startRotation.getValue() : 0); + message.appendInt(this.blockedAction); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + int startDirectionInt = packet.readInt(); + + if(startDirectionInt < 0 || startDirectionInt > 7 || (startDirectionInt % 2) != 0) { + throw new WiredSaveException("Start direction is invalid"); + } + + RoomUserRotation startDirection = RoomUserRotation.fromValue(startDirectionInt); + + int blockedActionInt = packet.readInt(); + + if(blockedActionInt < 0 || blockedActionInt > 6) { + throw new WiredSaveException("Blocked action is invalid"); + } + + packet.readString(); + + int itemsCount = packet.readInt(); + + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); + } + + THashMap newItems = new THashMap<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.put(it, new WiredChangeDirectionSetting(it.getId(), it.getRotation(), startDirection)); + } + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.items.clear(); + this.items.putAll(newItems); + this.startRotation = startDirection; + this.blockedAction = blockedActionInt; + this.setDelay(delay); + + return true; + } + + private RoomUserRotation nextRotation(RoomUserRotation currentRotation) { + switch (this.blockedAction) { + case ACTION_TURN_BACK: + return RoomUserRotation.fromValue(currentRotation.getValue()).getOpposite(); + case ACTION_TURN_LEFT_45: + return RoomUserRotation.counterClockwise(currentRotation); + case ACTION_TURN_LEFT_90: + return RoomUserRotation.counterClockwise(RoomUserRotation.counterClockwise(currentRotation)); + case ACTION_TURN_RIGHT_45: + return RoomUserRotation.clockwise(currentRotation); + case ACTION_TURN_RIGHT_90: + return RoomUserRotation.clockwise(RoomUserRotation.clockwise(currentRotation)); + case ACTION_TURN_RANDOM: + return RoomUserRotation.fromValue(Emulator.getRandom().nextInt(8)); + case ACTION_WAIT: + default: + return currentRotation; + } + } + + @Override + protected long requiredCooldown() { + return 495; + } + + static class JsonData { + RoomUserRotation start_direction; + int blocked_action; + List items; + int delay; + + public JsonData(RoomUserRotation start_direction, int blocked_action, List items, int delay) { + this.start_direction = start_direction; + this.blocked_action = blocked_action; + this.items = items; + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveEffect.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveEffect.java new file mode 100644 index 0000000..5b98543 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveEffect.java @@ -0,0 +1,36 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredEffectGiveEffect extends WiredEffectWhisper { + public WiredEffectGiveEffect(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectGiveEffect(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + int effectId; + + try { + effectId = Integer.valueOf(this.message); + } catch (Exception e) { + return false; + } + + if (effectId >= 0) { + room.giveEffect(roomUnit, effectId, Integer.MAX_VALUE); + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveHandItem.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveHandItem.java new file mode 100644 index 0000000..ca39a49 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveHandItem.java @@ -0,0 +1,34 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredEffectGiveHandItem extends WiredEffectWhisper { + public WiredEffectGiveHandItem(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectGiveHandItem(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + try { + int itemId = Integer.valueOf(this.message); + + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + room.giveHandItem(habbo, itemId); + } + } catch (Exception e) { + } + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveHotelviewBonusRarePoints.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveHotelviewBonusRarePoints.java new file mode 100644 index 0000000..4d21822 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveHotelviewBonusRarePoints.java @@ -0,0 +1,151 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.hotelview.BonusRareComposer; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredEffectGiveHotelviewBonusRarePoints extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.SHOW_MESSAGE; + + private int amount = 0; + + public WiredEffectGiveHotelviewBonusRarePoints(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectGiveHotelviewBonusRarePoints(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.amount + ""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(type.code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) { + packet.readInt(); + + try { + this.amount = Integer.parseInt(packet.readString()); + } catch (Exception e) { + return false; + } + + packet.readInt(); + this.setDelay(packet.readInt()); + + return true; + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo == null) + return false; + + if (this.amount > 0) { + habbo.givePoints(Emulator.getConfig().getInt("hotelview.promotional.points.type"), this.amount); + habbo.getClient().sendResponse(new BonusRareComposer(habbo)); + } + + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.getDelay(), this.amount)); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + this.amount = 0; + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.amount = data.amount; + } else { + if (wiredData.split("\t").length >= 2) { + super.setDelay(Integer.parseInt(wiredData.split("\t")[0])); + + try { + this.amount = Integer.parseInt(wiredData.split("\t")[1]); + } catch (Exception e) { + } + } + } + } + + @Override + public void onPickUp() { + this.amount = 0; + this.setDelay(0); + } + + @Override + public boolean requiresTriggeringUser() { + return true; + } + + static class JsonData { + int delay; + int amount; + + public JsonData(int delay, int amount) { + this.delay = delay; + this.amount = amount; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveHotelviewHofPoints.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveHotelviewHofPoints.java new file mode 100644 index 0000000..0bd6216 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveHotelviewHofPoints.java @@ -0,0 +1,153 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredEffectGiveHotelviewHofPoints extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.SHOW_MESSAGE; + + private int amount = 0; + + public WiredEffectGiveHotelviewHofPoints(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectGiveHotelviewHofPoints(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.amount + ""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(type.code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) { + packet.readInt(); + + try { + this.amount = Integer.valueOf(packet.readString()); + } catch (Exception e) { + return false; + } + packet.readInt(); + this.setDelay(packet.readInt()); + + return true; + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo == null) + return false; + + if (this.amount > 0) { + habbo.getHabboStats().hofPoints += this.amount; + Emulator.getThreading().run(habbo.getHabboStats()); + } + + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.amount, this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.amount = data.amount; + this.setDelay(data.delay); + } + else { + this.amount = 0; + + if (wiredData.split("\t").length >= 2) { + super.setDelay(Integer.valueOf(wiredData.split("\t")[0])); + + try { + this.amount = Integer.valueOf(this.getWiredData().split("\t")[1]); + } catch (Exception e) { + } + } + + this.needsUpdate(true); + } + } + + @Override + public void onPickUp() { + this.amount = 0; + this.setDelay(0); + } + + @Override + public boolean requiresTriggeringUser() { + return true; + } + + static class JsonData { + int amount; + int delay; + + public JsonData(int amount, int delay) { + this.amount = amount; + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveRespect.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveRespect.java new file mode 100644 index 0000000..4a3b966 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveRespect.java @@ -0,0 +1,154 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredEffectGiveRespect extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.SHOW_MESSAGE; + + private int respects = 0; + + public WiredEffectGiveRespect(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectGiveRespect(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.respects + ""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(type.code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) { + packet.readInt(); + + try { + this.respects = Integer.valueOf(packet.readString()); + } catch (Exception e) { + return false; + } + + packet.readInt(); + this.setDelay(packet.readInt()); + + return true; + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo == null) + return false; + + habbo.getHabboStats().respectPointsReceived += this.respects; + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("RespectEarned"), this.respects); + + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.respects, this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.respects = data.amount; + this.setDelay(data.delay); + } + else { + String[] data = wiredData.split("\t"); + this.respects = 0; + + if (data.length >= 2) { + super.setDelay(Integer.valueOf(data[0])); + + try { + this.respects = Integer.valueOf(data[1]); + } catch (Exception e) { + } + } + + this.needsUpdate(true); + } + } + + @Override + public void onPickUp() { + this.respects = 0; + this.setDelay(0); + } + + @Override + public boolean requiresTriggeringUser() { + return true; + } + + static class JsonData { + int amount; + int delay; + + public JsonData(int amount, int delay) { + this.amount = amount; + this.delay = delay; + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveReward.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveReward.java new file mode 100644 index 0000000..f4c3a2b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveReward.java @@ -0,0 +1,247 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredGiveRewardItem; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.generic.alerts.UpdateFailedComposer; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredEffectGiveReward extends InteractionWiredEffect { + public final static int LIMIT_ONCE = 0; + public final static int LIMIT_N_DAY = 1; + public final static int LIMIT_N_HOURS = 2; + public final static int LIMIT_N_MINUTES = 3; + + public final static WiredEffectType type = WiredEffectType.GIVE_REWARD; + public int limit; + public int limitationInterval; + public int given; + public int rewardTime; + public boolean uniqueRewards; + + public THashSet rewardItems = new THashSet<>(); + + public WiredEffectGiveReward(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectGiveReward(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + + return habbo != null && WiredHandler.getReward(habbo, this); + } + + @Override + public String getWiredData() { + + ArrayList rewards = new ArrayList<>(this.rewardItems); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.limit, this.given, this.rewardTime, this.uniqueRewards, this.limitationInterval, rewards, this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.limit = data.limit; + this.given = data.given; + this.rewardTime = data.reward_time; + this.uniqueRewards = data.unique_rewards; + this.limitationInterval = data.limit_interval; + this.rewardItems.clear(); + this.rewardItems.addAll(data.rewards); + } + else { + String[] data = wiredData.split(":"); + if (data.length > 0) { + this.limit = Integer.valueOf(data[0]); + this.given = Integer.valueOf(data[1]); + this.rewardTime = Integer.valueOf(data[2]); + this.uniqueRewards = data[3].equals("1"); + this.limitationInterval = Integer.valueOf(data[4]); + this.setDelay(Integer.valueOf(data[5])); + + if (data.length > 6) { + if (!data[6].equalsIgnoreCase("\t")) { + String[] items = data[6].split(";"); + + this.rewardItems.clear(); + + for (String s : items) { + try { + this.rewardItems.add(new WiredGiveRewardItem(s)); + } catch (Exception e) { + } + } + } + } + + this.needsUpdate(true); + } + } + } + + @Override + public void onPickUp() { + this.limit = 0; + this.limitationInterval = 0; + this.given = 0; + this.rewardTime = 0; + this.uniqueRewards = false; + this.rewardItems.clear(); + this.setDelay(0); + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + + if (client.getHabbo().hasPermission(Permission.ACC_SUPERWIRED)) { + client.getHabbo().whisper(Emulator.getTexts().getValue("hotel.wired.superwired.info"), RoomChatMessageBubbles.BOT); + } + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(this.rewardItems.size()); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + StringBuilder s = new StringBuilder(); + + for (WiredGiveRewardItem item : this.rewardItems) { + s.append(item.wiredString()).append(";"); + } + message.appendString(s.toString()); + message.appendInt(4); + message.appendInt(this.rewardTime); + message.appendInt(this.uniqueRewards); + message.appendInt(this.limit); + message.appendInt(this.limitationInterval); + message.appendInt(this.limit > 0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) { + if (gameClient.getHabbo().hasPermission(Permission.ACC_SUPERWIRED)) { + int argsLength = packet.readInt(); + this.rewardTime = packet.readInt(); + this.uniqueRewards = packet.readInt() == 1; + this.limit = packet.readInt(); + this.limitationInterval = packet.readInt(); + this.given = 0; + + String data = packet.readString(); + + String[] items = data.split(";"); + + this.rewardItems.clear(); + + int i = 1; + for (String s : items) { + String[] d = s.split(","); + + if (d.length == 3) { + if (!(d[1].contains(":") || d[1].contains(";"))) { + this.rewardItems.add(new WiredGiveRewardItem(i, d[0].equalsIgnoreCase("0"), d[1], Integer.valueOf(d[2]))); + continue; + } + } + + gameClient.sendResponse(new UpdateFailedComposer(Emulator.getTexts().getValue("alert.superwired.invalid"))); + return false; + } + + packet.readInt(); + this.setDelay(packet.readInt()); + + WiredHandler.dropRewards(this.getId()); + return true; + } + + gameClient.getHabbo().whisper("U cannot do this.", RoomChatMessageBubbles.ALERT); + return false; + } + + @Override + public boolean requiresTriggeringUser() { + return true; + } + + @Override + protected long requiredCooldown() { + return 0; + } + + static class JsonData { + int limit; + int given; + int reward_time; + boolean unique_rewards; + int limit_interval; + List rewards; + int delay; + + public JsonData(int limit, int given, int reward_time, boolean unique_rewards, int limit_interval, List rewards, int delay) { + this.limit = limit; + this.given = given; + this.reward_time = reward_time; + this.unique_rewards = unique_rewards; + this.limit_interval = limit_interval; + this.rewards = rewards; + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScore.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScore.java new file mode 100644 index 0000000..6632c2e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScore.java @@ -0,0 +1,219 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import gnu.trove.iterator.TObjectIntIterator; +import gnu.trove.map.TObjectIntMap; +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class WiredEffectGiveScore extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.GIVE_SCORE; + + private int score; + private int count; + + private TObjectIntMap> data = new TObjectIntHashMap<>(); + + public WiredEffectGiveScore(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectGiveScore(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null && habbo.getHabboInfo().getCurrentGame() != null) { + Game game = room.getGame(habbo.getHabboInfo().getCurrentGame()); + + if (game == null) + return false; + + int gameStartTime = game.getStartTime(); + + TObjectIntMap> dataClone = new TObjectIntHashMap<>(this.data); + + TObjectIntIterator> iterator = dataClone.iterator(); + + for (int i = dataClone.size(); i-- > 0; ) { + iterator.advance(); + + Map.Entry map = iterator.key(); + + if (map.getValue() == habbo.getHabboInfo().getId()) { + if (map.getKey() == gameStartTime) { + if (iterator.value() < this.count) { + iterator.setValue(iterator.value() + 1); + + habbo.getHabboInfo().getGamePlayer().addScore(this.score, true); + + return true; + } + } else { + iterator.remove(); + } + } + } + + try { + this.data.put(new AbstractMap.SimpleEntry<>(gameStartTime, habbo.getHabboInfo().getId()), 1); + } + catch(IllegalArgumentException e) { + + } + + + if (habbo.getHabboInfo().getGamePlayer() != null) { + habbo.getHabboInfo().getGamePlayer().addScore(this.score, true); + } + + return true; + } + + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.score, this.count, this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.score = data.score; + this.count = data.count; + this.setDelay(data.delay); + } + else { + String[] data = wiredData.split(";"); + + if (data.length == 3) { + this.score = Integer.valueOf(data[0]); + this.count = Integer.valueOf(data[1]); + this.setDelay(Integer.valueOf(data[2])); + } + + this.needsUpdate(true); + } + } + + @Override + public void onPickUp() { + this.score = 0; + this.count = 0; + this.setDelay(0); + } + + @Override + public WiredEffectType getType() { + return WiredEffectGiveScore.type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(2); + message.appendInt(this.score); + message.appendInt(this.count); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + + int score = packet.readInt(); + + if(score < 1 || score > 100) + throw new WiredSaveException("Score is invalid"); + + int timesPerGame = packet.readInt(); + + if(timesPerGame < 1 || timesPerGame > 10) + throw new WiredSaveException("Times per game is invalid"); + + packet.readString(); + packet.readInt(); + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.score = score; + this.count = timesPerGame; + this.setDelay(delay); + + return true; + } + + @Override + public boolean requiresTriggeringUser() { + return true; + } + + static class JsonData { + int score; + int count; + int delay; + + public JsonData(int score, int count, int delay) { + this.score = score; + this.count = count; + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScoreToTeam.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScoreToTeam.java new file mode 100644 index 0000000..dcbc148 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScoreToTeam.java @@ -0,0 +1,171 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.games.GameState; +import com.eu.habbo.habbohotel.games.GameTeam; +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import gnu.trove.map.hash.TIntIntHashMap; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredEffectGiveScoreToTeam extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.GIVE_SCORE_TEAM; + + private int points; + private int count; + private GameTeamColors teamColor = GameTeamColors.RED; + + private TIntIntHashMap startTimes = new TIntIntHashMap(); + + public WiredEffectGiveScoreToTeam(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + public WiredEffectGiveScoreToTeam(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + for (Game game : room.getGames()) { + if (game != null && game.state.equals(GameState.RUNNING)) { + int c = this.startTimes.get(game.getStartTime()); + + if (c < this.count) { + GameTeam team = game.getTeam(this.teamColor); + + if (team != null) { + team.addTeamScore(this.points); + + this.startTimes.put(game.getStartTime(), c + 1); + } + } + } + } + + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.points, this.count, this.teamColor, this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.points = data.score; + this.count = data.count; + this.teamColor = data.team; + this.setDelay(data.delay); + } + else { + String[] data = set.getString("wired_data").split(";"); + + if (data.length == 4) { + this.points = Integer.valueOf(data[0]); + this.count = Integer.valueOf(data[1]); + this.teamColor = GameTeamColors.values()[Integer.valueOf(data[2])]; + this.setDelay(Integer.valueOf(data[3])); + } + + this.needsUpdate(true); + } + } + + @Override + public void onPickUp() { + this.startTimes.clear(); + this.points = 0; + this.count = 0; + this.teamColor = GameTeamColors.RED; + this.setDelay(0); + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(3); + message.appendInt(this.points); + message.appendInt(this.count); + message.appendInt(this.teamColor.type); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + + int points = packet.readInt(); + + if(points < 1 || points > 100) + throw new WiredSaveException("Points is invalid"); + + int timesPerGame = packet.readInt(); + + if(timesPerGame < 1 || timesPerGame > 10) + throw new WiredSaveException("Times per game is invalid"); + + int team = packet.readInt(); + + if(team < 1 || team > 4) + throw new WiredSaveException("Team is invalid"); + + packet.readString(); + packet.readInt(); + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.points = points; + this.count = timesPerGame; + this.teamColor = GameTeamColors.values()[team]; + this.setDelay(delay); + + return true; + } + + static class JsonData { + int score; + int count; + GameTeamColors team; + int delay; + + public JsonData(int score, int count, GameTeamColors team, int delay) { + this.score = score; + this.count = count; + this.team = team; + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectJoinTeam.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectJoinTeam.java new file mode 100644 index 0000000..8d36700 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectJoinTeam.java @@ -0,0 +1,171 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.games.wired.WiredGame; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredEffectJoinTeam extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.JOIN_TEAM; + + private GameTeamColors teamColor = GameTeamColors.RED; + + public WiredEffectJoinTeam(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectJoinTeam(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + WiredGame game = (WiredGame) room.getGameOrCreate(WiredGame.class); + + if (habbo.getHabboInfo().getGamePlayer() != null && habbo.getHabboInfo().getCurrentGame() != null && (habbo.getHabboInfo().getCurrentGame() != WiredGame.class || (habbo.getHabboInfo().getCurrentGame() == WiredGame.class && habbo.getHabboInfo().getGamePlayer().getTeamColor() != this.teamColor))) { + // remove from current game + Game currentGame = room.getGame(habbo.getHabboInfo().getCurrentGame()); + currentGame.removeHabbo(habbo); + } + + if(habbo.getHabboInfo().getGamePlayer() == null) { + game.addHabbo(habbo, this.teamColor); + } + + return true; + } + + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.teamColor, this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.teamColor = data.team; + } + else { + String[] data = set.getString("wired_data").split("\t"); + + if (data.length >= 1) { + this.setDelay(Integer.valueOf(data[0])); + + if (data.length >= 2) { + this.teamColor = GameTeamColors.values()[Integer.valueOf(data[1])]; + } + } + + this.needsUpdate(true); + } + } + + @Override + public void onPickUp() { + this.teamColor = GameTeamColors.RED; + this.setDelay(0); + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.teamColor.type); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + int team = packet.readInt(); + + if(team < 1 || team > 4) + throw new WiredSaveException("Team is invalid"); + + packet.readInt(); + packet.readString(); + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.teamColor = GameTeamColors.values()[team]; + this.setDelay(delay); + + return true; + } + + @Override + public boolean requiresTriggeringUser() { + return true; + } + + static class JsonData { + GameTeamColors team; + int delay; + + public JsonData(GameTeamColors team, int delay) { + this.team = team; + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectKickHabbo.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectKickHabbo.java new file mode 100644 index 0000000..e0f2ecd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectKickHabbo.java @@ -0,0 +1,180 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserWhisperComposer; +import com.eu.habbo.threading.runnables.RoomUnitKick; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredEffectKickHabbo extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.KICK_USER; + + private String message = ""; + + public WiredEffectKickHabbo(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectKickHabbo(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (room == null) + return false; + + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + if (habbo.hasPermission(Permission.ACC_UNKICKABLE)) { + habbo.whisper(Emulator.getTexts().getValue("hotel.wired.kickexception.unkickable")); + return true; + } + + if (habbo.getHabboInfo().getId() == room.getOwnerId()) { + habbo.whisper(Emulator.getTexts().getValue("hotel.wired.kickexception.owner")); + return true; + } + + room.giveEffect(habbo, 4, 2); + + if (!this.message.isEmpty()) + habbo.getClient().sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(this.message, habbo, habbo, RoomChatMessageBubbles.ALERT))); + + Emulator.getThreading().run(new RoomUnitKick(habbo, room, true), 2000); + + return true; + } + + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.message, this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.message = data.message; + } + else { + try { + String[] data = set.getString("wired_data").split("\t"); + + if (data.length >= 1) { + this.setDelay(Integer.valueOf(data[0])); + + if (data.length >= 2) { + this.message = data[1]; + } + } + } catch (Exception e) { + this.message = ""; + this.setDelay(0); + } + + this.needsUpdate(true); + } + } + + @Override + public void onPickUp() { + this.message = ""; + this.setDelay(0); + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.message); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + String message = packet.readString(); + packet.readInt(); + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.message = message.substring(0, Math.min(message.length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + this.setDelay(delay); + + return true; + } + + @Override + public boolean requiresTriggeringUser() { + return true; + } + + static class JsonData { + String message; + int delay; + + public JsonData(String message, int delay) { + this.message = message; + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectLeaveTeam.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectLeaveTeam.java new file mode 100644 index 0000000..deff061 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectLeaveTeam.java @@ -0,0 +1,139 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.games.wired.WiredGame; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredEffectLeaveTeam extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.LEAVE_TEAM; + + public WiredEffectLeaveTeam(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectLeaveTeam(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + if (habbo.getHabboInfo().getCurrentGame() != null) { + Game game = room.getGame(habbo.getHabboInfo().getCurrentGame()); + + if (game == null) { + game = room.getGameOrCreate(WiredGame.class); + } + + if (game != null) { + game.removeHabbo(habbo); + return true; + } + } + } + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + } + else { + this.setDelay(Integer.valueOf(wiredData)); + } + } + + @Override + public void onPickUp() { + this.setDelay(0); + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + packet.readString(); + packet.readInt(); + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.setDelay(delay); + return true; + } + + static class JsonData { + int delay; + + public JsonData(int delay) { + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMatchFurni.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMatchFurni.java new file mode 100644 index 0000000..bb615d8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMatchFurni.java @@ -0,0 +1,279 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.wired.interfaces.InteractionWiredMatchFurniSettings; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredMatchFurniSetting; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; +import gnu.trove.set.hash.THashSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +public class WiredEffectMatchFurni extends InteractionWiredEffect implements InteractionWiredMatchFurniSettings { + private static final Logger LOGGER = LoggerFactory.getLogger(WiredEffectMatchFurni.class); + + private static final WiredEffectType type = WiredEffectType.MATCH_SSHOT; + public boolean checkForWiredResetPermission = true; + private THashSet settings; + private boolean state = false; + private boolean direction = false; + private boolean position = false; + + public WiredEffectMatchFurni(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.settings = new THashSet<>(0); + } + + public WiredEffectMatchFurni(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.settings = new THashSet<>(0); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + + if(this.settings.isEmpty()) + return true; + + for (WiredMatchFurniSetting setting : this.settings) { + HabboItem item = room.getHabboItem(setting.item_id); + if (item != null) { + if (this.state && (this.checkForWiredResetPermission && item.allowWiredResetState())) { + if (!setting.state.equals(" ") && !item.getExtradata().equals(setting.state)) { + item.setExtradata(setting.state); + room.updateItemState(item); + } + } + + RoomTile oldLocation = room.getLayout().getTile(item.getX(), item.getY()); + double oldZ = item.getZ(); + + if(this.direction && !this.position) { + if(item.getRotation() != setting.rotation && room.furnitureFitsAt(oldLocation, item, setting.rotation, false) == FurnitureMovementError.NONE) { + room.moveFurniTo(item, oldLocation, setting.rotation, null, true); + } + } + else if(this.position) { + boolean slideAnimation = !this.direction || item.getRotation() == setting.rotation; + RoomTile newLocation = room.getLayout().getTile((short) setting.x, (short) setting.y); + int newRotation = this.direction ? setting.rotation : item.getRotation(); + + if(newLocation != null && newLocation.state != RoomTileState.INVALID && (newLocation != oldLocation || newRotation != item.getRotation()) && room.furnitureFitsAt(newLocation, item, newRotation, true) == FurnitureMovementError.NONE) { + if(room.moveFurniTo(item, newLocation, newRotation, null, !slideAnimation) == FurnitureMovementError.NONE) { + if(slideAnimation) { + room.sendComposer(new FloorItemOnRollerComposer(item, null, oldLocation, oldZ, newLocation, item.getZ(), 0, room).compose()); + } + } + } + } + + } + } + + return true; + } + + @Override + public String getWiredData() { + this.refresh(); + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.state, this.direction, this.position, new ArrayList(this.settings), this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.state = data.state; + this.direction = data.direction; + this.position = data.position; + this.settings.clear(); + this.settings.addAll(data.items); + } + else { + String[] data = set.getString("wired_data").split(":"); + + int itemCount = Integer.parseInt(data[0]); + + String[] items = data[1].split(Pattern.quote(";")); + + for (int i = 0; i < items.length; i++) { + try { + + String[] stuff = items[i].split(Pattern.quote("-")); + + if (stuff.length >= 5) { + this.settings.add(new WiredMatchFurniSetting(Integer.parseInt(stuff[0]), stuff[1], Integer.parseInt(stuff[2]), Integer.parseInt(stuff[3]), Integer.parseInt(stuff[4]))); + } + + } catch (Exception e) { + LOGGER.error("Caught exception", e); + } + } + + this.state = data[2].equals("1"); + this.direction = data[3].equals("1"); + this.position = data[4].equals("1"); + this.setDelay(Integer.parseInt(data[5])); + this.needsUpdate(true); + } + } + + @Override + public void onPickUp() { + this.settings.clear(); + this.state = false; + this.direction = false; + this.position = false; + this.setDelay(0); + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + this.refresh(); + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.settings.size()); + + for (WiredMatchFurniSetting item : this.settings) + message.appendInt(item.item_id); + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(3); + message.appendInt(this.state ? 1 : 0); + message.appendInt(this.direction ? 1 : 0); + message.appendInt(this.position ? 1 : 0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + + boolean setState = packet.readInt() == 1; + boolean setDirection = packet.readInt() == 1; + boolean setPosition = packet.readInt() == 1; + + packet.readString(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room == null) + throw new WiredSaveException("Trying to save wired in unloaded room"); + + int itemsCount = packet.readInt(); + + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); + } + + List newSettings = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newSettings.add(new WiredMatchFurniSetting(it.getId(), this.checkForWiredResetPermission && it.allowWiredResetState() ? it.getExtradata() : " ", it.getRotation(), it.getX(), it.getY())); + } + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.state = setState; + this.direction = setDirection; + this.position = setPosition; + this.settings.clear(); + this.settings.addAll(newSettings); + this.setDelay(delay); + + return true; + } + + private void refresh() { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room != null && room.isLoaded()) { + THashSet remove = new THashSet<>(); + + for (WiredMatchFurniSetting setting : this.settings) { + HabboItem item = room.getHabboItem(setting.item_id); + if (item == null) { + remove.add(setting); + } + } + + for (WiredMatchFurniSetting setting : remove) { + this.settings.remove(setting); + } + } + } + + @Override + public THashSet getMatchFurniSettings() { + return this.settings; + } + + @Override + public boolean shouldMatchState() { + return this.state; + } + + @Override + public boolean shouldMatchRotation() { + return this.direction; + } + + @Override + public boolean shouldMatchPosition() { + return this.position; + } + + static class JsonData { + boolean state; + boolean direction; + boolean position; + List items; + int delay; + + public JsonData(boolean state, boolean direction, boolean position, List items, int delay) { + this.state = state; + this.direction = direction; + this.position = position; + this.items = items; + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniAway.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniAway.java new file mode 100644 index 0000000..76fe1ed --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniAway.java @@ -0,0 +1,228 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredEffectMoveFurniAway extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.FLEE; + + private THashSet items = new THashSet<>(); + + public WiredEffectMoveFurniAway(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectMoveFurniAway(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + THashSet items = new THashSet<>(); + + for (HabboItem item : this.items) { + if (item.getRoomId() == 0) + items.add(item); + } + + this.items.removeAll(items); + + for (HabboItem item : this.items) { + RoomTile t = room.getLayout().getTile(item.getX(), item.getY()); + + RoomUnit target = room.getRoomUnits().stream().min(Comparator.comparingDouble(a -> a.getCurrentLocation().distance(t))).orElse(null); + + if (target != null) { + if (target.getCurrentLocation().distance(t) <= 1) { + Emulator.getThreading().run(() -> WiredHandler.handle(WiredTriggerType.COLLISION, target, room, new Object[]{item}), 500); + continue; + } + + int x = 0; + int y = 0; + + if (target.getX() == item.getX()) { + if (item.getY() < target.getY()) + y--; + else + y++; + } else if (target.getY() == item.getY()) { + if (item.getX() < target.getX()) + x--; + else + x++; + } else if (target.getX() - item.getX() > target.getY() - item.getY()) { + if (target.getX() - item.getX() > 0) + x--; + else + x++; + } else { + if (target.getY() - item.getY() > 0) + y--; + else + y++; + } + + RoomTile newLocation = room.getLayout().getTile((short) (item.getX() + x), (short) (item.getY() + y)); + RoomTile oldLocation = room.getLayout().getTile(item.getX(), item.getY()); + double oldZ = item.getZ(); + + if(newLocation != null && newLocation.state != RoomTileState.INVALID && newLocation != oldLocation && room.furnitureFitsAt(newLocation, item, item.getRotation(), true) == FurnitureMovementError.NONE) { + if(room.moveFurniTo(item, newLocation, item.getRotation(), null, false) == FurnitureMovementError.NONE) { + room.sendComposer(new FloorItemOnRollerComposer(item, null, oldLocation, oldZ, newLocation, item.getZ(), 0, room).compose()); + } + } + } + } + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.getDelay(), + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items = new THashSet<>(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + for (Integer id: data.itemIds) { + HabboItem item = room.getHabboItem(id); + if (item != null) { + this.items.add(item); + } + } + } else { + String[] wiredDataOld = wiredData.split("\t"); + + if (wiredDataOld.length >= 1) { + this.setDelay(Integer.parseInt(wiredDataOld[0])); + } + if (wiredDataOld.length == 2) { + if (wiredDataOld[1].contains(";")) { + for (String s : wiredDataOld[1].split(";")) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) + this.items.add(item); + } + } + } + } + } + + @Override + public void onPickUp() { + this.items.clear(); + this.setDelay(0); + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + THashSet items = new THashSet<>(); + + for (HabboItem item : this.items) { + if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) + items.add(item); + } + + for (HabboItem item : items) { + this.items.remove(item); + } + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + for (HabboItem item : this.items) + message.appendInt(item.getId()); + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + packet.readString(); + int itemsCount = packet.readInt(); + + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); + } + + List newItems = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.add(it); + } + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.items.clear(); + this.items.addAll(newItems); + this.setDelay(delay); + + return true; + } + + @Override + protected long requiredCooldown() { + return 495; + } + + static class JsonData { + int delay; + List itemIds; + + public JsonData(int delay, List itemIds) { + this.delay = delay; + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniTo.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniTo.java new file mode 100644 index 0000000..3b9367e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniTo.java @@ -0,0 +1,241 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class WiredEffectMoveFurniTo extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.MOVE_FURNI_TO; + private final List items = new ArrayList<>(); + private int direction; + private int spacing = 1; + private Map indexOffset = new LinkedHashMap<>(); + + public WiredEffectMoveFurniTo(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectMoveFurniTo(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room == null) + return false; + + this.items.clear(); + this.indexOffset.clear(); + + packet.readInt(); + + this.direction = packet.readInt(); + this.spacing = packet.readInt(); + packet.readString(); + + int count = packet.readInt(); + for (int i = 0; i < count; i++) { + this.items.add(room.getHabboItem(packet.readInt())); + } + + this.setDelay(packet.readInt()); + + return true; + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + List items = new ArrayList<>(); + + for (HabboItem item : this.items) { + if (Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) + items.add(item); + } + + for (HabboItem item : items) { + this.items.remove(item); + } + + if (this.items.isEmpty()) + return false; + + if (stuff != null && stuff.length > 0) { + for (Object object : stuff) { + if (object instanceof HabboItem) { + HabboItem targetItem = this.items.get(Emulator.getRandom().nextInt(this.items.size())); + + if (targetItem != null) { + int indexOffset = 0; + if (!this.indexOffset.containsKey(targetItem.getId())) { + this.indexOffset.put(targetItem.getId(), indexOffset); + } else { + indexOffset = this.indexOffset.get(targetItem.getId()) + this.spacing; + } + + RoomTile objectTile = room.getLayout().getTile(targetItem.getX(), targetItem.getY()); + + if (objectTile != null) { + THashSet refreshTiles = room.getLayout().getTilesAt(room.getLayout().getTile(((HabboItem) object).getX(), ((HabboItem) object).getY()), ((HabboItem) object).getBaseItem().getWidth(), ((HabboItem) object).getBaseItem().getLength(), ((HabboItem) object).getRotation()); + + RoomTile tile = room.getLayout().getTileInFront(objectTile, this.direction, indexOffset); + if (tile == null || !tile.getAllowStack()) { + indexOffset = 0; + tile = room.getLayout().getTileInFront(objectTile, this.direction, indexOffset); + } + + room.sendComposer(new FloorItemOnRollerComposer((HabboItem) object, null, tile, tile.getStackHeight() - ((HabboItem) object).getZ(), room).compose()); + refreshTiles.addAll(room.getLayout().getTilesAt(room.getLayout().getTile(((HabboItem) object).getX(), ((HabboItem) object).getY()), ((HabboItem) object).getBaseItem().getWidth(), ((HabboItem) object).getBaseItem().getLength(), ((HabboItem) object).getRotation())); + room.updateTiles(refreshTiles); + this.indexOffset.put(targetItem.getId(), indexOffset); + } + } + } + } + } + + return true; + } + + @Override + public String getWiredData() { + THashSet itemsToRemove = new THashSet<>(); + + for (HabboItem item : this.items) { + if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) + itemsToRemove.add(item); + } + + for (HabboItem item : itemsToRemove) { + this.items.remove(item); + } + + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.direction, + this.spacing, + this.getDelay(), + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + THashSet items = new THashSet<>(); + + for (HabboItem item : this.items) { + if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) + items.add(item); + } + + for (HabboItem item : items) { + this.items.remove(item); + } + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + for (HabboItem item : this.items) + message.appendInt(item.getId()); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(2); + message.appendInt(this.direction); + message.appendInt(this.spacing); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + message.appendInt(0); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items.clear(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.direction = data.direction; + this.spacing = data.spacing; + this.setDelay(data.delay); + + for (Integer id: data.itemIds) { + HabboItem item = room.getHabboItem(id); + if (item != null) { + this.items.add(item); + } + } + } else { + String[] data = wiredData.split("\t"); + + if (data.length == 4) { + try { + this.direction = Integer.parseInt(data[0]); + this.spacing = Integer.parseInt(data[1]); + this.setDelay(Integer.parseInt(data[2])); + } catch (Exception e) { + } + + for (String s : data[3].split("\r")) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) + this.items.add(item); + } + } + } + } + + @Override + public void onPickUp() { + this.setDelay(0); + this.items.clear(); + this.direction = 0; + this.spacing = 0; + this.indexOffset.clear(); + } + + @Override + protected long requiredCooldown() { + return 495; + } + + static class JsonData { + int direction; + int spacing; + int delay; + List itemIds; + + public JsonData(int direction, int spacing, int delay, List itemIds) { + this.direction = direction; + this.spacing = spacing; + this.delay = delay; + this.itemIds = itemIds; + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniTowards.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniTowards.java new file mode 100644 index 0000000..c069dc9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveFurniTowards.java @@ -0,0 +1,365 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; +import com.eu.habbo.threading.runnables.WiredCollissionRunnable; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Wired effect: move to closest user + * Confirmed as working exactly like Habbo.com 03/05/2019 04:00 + * + * @author Beny. + */ +public class WiredEffectMoveFurniTowards extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.CHASE; + + private THashSet items; + + private THashMap lastDirections; + + + public WiredEffectMoveFurniTowards(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.items = new THashSet<>(); + this.lastDirections = new THashMap<>(); + } + + public WiredEffectMoveFurniTowards(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.items = new THashSet<>(); + this.lastDirections = new THashMap<>(); + } + + public List getAvailableDirections(HabboItem item, Room room) { + List availableDirections = new ArrayList<>(); + RoomLayout layout = room.getLayout(); + + RoomTile currentTile = layout.getTile(item.getX(), item.getY()); + + RoomUserRotation[] rotations = new RoomUserRotation[]{RoomUserRotation.NORTH, RoomUserRotation.EAST, RoomUserRotation.SOUTH, RoomUserRotation.WEST}; + + for (RoomUserRotation rot : rotations) { + RoomTile tile = layout.getTileInFront(currentTile, rot.getValue()); + + if (tile == null || tile.state == RoomTileState.BLOCKED || tile.state == RoomTileState.INVALID) + continue; + + if (!layout.tileExists(tile.x, tile.y)) + continue; + + if (room.furnitureFitsAt(tile, item, item.getRotation()) == FurnitureMovementError.INVALID_MOVE) + continue; + + HabboItem topItem = room.getTopItemAt(tile.x, tile.y); + if (topItem != null && !topItem.getBaseItem().allowStack()) + continue; + + if (tile.getAllowStack()) { + availableDirections.add(rot); + } + } + + return availableDirections; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + + THashSet items = new THashSet<>(); + + for (HabboItem item : this.items) { + if (Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) + items.add(item); + } + + for (HabboItem item : items) { + this.items.remove(item); + } + + for (HabboItem item : this.items) { + + if (item == null) + continue; + + // direction the furni will move in + RoomUserRotation moveDirection = null; + RoomUserRotation lastDirection = lastDirections.get(item.getId()); + + // 1. Check if any user is within 3 tiles from the item + RoomUnit target = null; // closest found user + RoomLayout layout = room.getLayout(); + boolean collided = false; + + if (layout == null) { + break; + } + + for (int i = 0; i < 3; i++) { + if (target != null) + break; + + RoomUserRotation[] rotations = new RoomUserRotation[]{RoomUserRotation.NORTH, RoomUserRotation.EAST, RoomUserRotation.SOUTH, RoomUserRotation.WEST}; + + for (RoomUserRotation rot : rotations) { + RoomTile startTile = layout.getTile(item.getX(), item.getY()); + + for (int ii = 0; ii <= i; ii++) { + if (startTile == null) + break; + + startTile = layout.getTileInFront(startTile, rot.getValue()); + } + + if (startTile != null && layout.tileExists(startTile.x, startTile.y)) { + Collection roomUnitsAtTile = room.getRoomUnitsAt(startTile); + if (roomUnitsAtTile.size() > 0) { + target = roomUnitsAtTile.iterator().next(); + if (i == 0) { // i = 0 means right next to it + collided = true; + Emulator.getThreading().run(new WiredCollissionRunnable(target, room, new Object[]{item})); + } + break; + } + } + } + } + + if (collided) + continue; + + if (target != null) { + if (target.getX() == item.getX()) { + if (item.getY() < target.getY()) + moveDirection = RoomUserRotation.SOUTH; + else + moveDirection = RoomUserRotation.NORTH; + } else if (target.getY() == item.getY()) { + if (item.getX() < target.getX()) + moveDirection = RoomUserRotation.EAST; + else + moveDirection = RoomUserRotation.WEST; + } else if (target.getX() - item.getX() > target.getY() - item.getY()) { + if (target.getX() - item.getX() > 0) + moveDirection = RoomUserRotation.EAST; + else + moveDirection = RoomUserRotation.WEST; + } else { + if (target.getY() - item.getY() > 0) + moveDirection = RoomUserRotation.SOUTH; + else + moveDirection = RoomUserRotation.NORTH; + } + } + + + // 2. Get a random direction + /* + getAvailableDirections: + 0 available - don't move + 1 available - move in that direction + 2 available - if lastdirection = null move in random possible direction + else if direction[0] = lastdirection opposite, move in direction[1] + else move in direction[0] + 3+ available - move in random direction, but never the opposite + */ + + List availableDirections = this.getAvailableDirections(item, room); + + if (moveDirection != null && !availableDirections.contains(moveDirection)) + moveDirection = null; + + if (moveDirection == null) { + if (availableDirections.size() == 0) { + continue; + } else if (availableDirections.size() == 1) { + moveDirection = availableDirections.iterator().next(); + } else if (availableDirections.size() == 2) { + if (lastDirection == null) { + moveDirection = availableDirections.get(Emulator.getRandom().nextInt(availableDirections.size())); + } else { + RoomUserRotation oppositeLast = lastDirection.getOpposite(); + + if (availableDirections.get(0) == oppositeLast) { + moveDirection = availableDirections.get(1); + } else { + moveDirection = availableDirections.get(0); + } + } + } else { + if (lastDirection != null) { + RoomUserRotation opposite = lastDirection.getOpposite(); + availableDirections.remove(opposite); + } + moveDirection = availableDirections.get(Emulator.getRandom().nextInt(availableDirections.size())); + } + } + + RoomTile newTile = room.getLayout().getTileInFront(room.getLayout().getTile(item.getX(), item.getY()), moveDirection.getValue()); + + RoomTile oldLocation = room.getLayout().getTile(item.getX(), item.getY()); + double oldZ = item.getZ(); + + if(newTile != null) { + lastDirections.put(item.getId(), moveDirection); + if(newTile.state != RoomTileState.INVALID && newTile != oldLocation && room.furnitureFitsAt(newTile, item, item.getRotation(), true) == FurnitureMovementError.NONE) { + if (room.moveFurniTo(item, newTile, item.getRotation(), null, false) == FurnitureMovementError.NONE) { + room.sendComposer(new FloorItemOnRollerComposer(item, null, oldLocation, oldZ, newTile, item.getZ(), 0, room).compose()); + } + } + } + } + + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.getDelay(), + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items = new THashSet<>(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + + for (Integer id: data.itemIds) { + HabboItem item = room.getHabboItem(id); + if (item != null) { + this.items.add(item); + } + } + } else { + String[] wiredDataOld = wiredData.split("\t"); + + if (wiredDataOld.length >= 1) { + this.setDelay(Integer.parseInt(wiredDataOld[0])); + } + if (wiredDataOld.length == 2) { + if (wiredDataOld[1].contains(";")) { + for (String s : wiredDataOld[1].split(";")) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) + this.items.add(item); + } + } + } + } + } + + @Override + public void onPickUp() { + this.items.clear(); + this.setDelay(0); + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + THashSet items = new THashSet<>(); + + for (HabboItem item : this.items) { + if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) + items.add(item); + } + + for (HabboItem item : items) { + this.items.remove(item); + } + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + for (HabboItem item : this.items) + message.appendInt(item.getId()); + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + packet.readString(); + + int itemsCount = packet.readInt(); + + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); + } + + List newItems = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.add(it); + } + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.items.clear(); + this.items.addAll(newItems); + this.setDelay(delay); + + return true; + } + + @Override + protected long requiredCooldown() { + return 495; + } + + static class JsonData { + int delay; + List itemIds; + + public JsonData(int delay, List itemIds) { + this.delay = delay; + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveRotateFurni.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveRotateFurni.java new file mode 100644 index 0000000..5928e67 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveRotateFurni.java @@ -0,0 +1,333 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.ICycleable; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; +import gnu.trove.set.hash.THashSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredEffectMoveRotateFurni extends InteractionWiredEffect implements ICycleable { + + private static final Logger LOGGER = LoggerFactory.getLogger(WiredEffectMoveRotateFurni.class); + + public static final WiredEffectType type = WiredEffectType.MOVE_ROTATE; + private final THashSet items = new THashSet<>(WiredHandler.MAXIMUM_FURNI_SELECTION / 2); + private int direction; + private int rotation; + private THashSet itemCooldowns; + + public WiredEffectMoveRotateFurni(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.itemCooldowns = new THashSet<>(); + } + + public WiredEffectMoveRotateFurni(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.itemCooldowns = new THashSet<>(); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + // remove items that are no longer in the room + this.items.removeIf(item -> Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null); + + for (HabboItem item : this.items) { + if(this.itemCooldowns.contains(item)) + continue; + + int newRotation = this.rotation > 0 ? this.getNewRotation(item) : item.getRotation(); + RoomTile newLocation = room.getLayout().getTile(item.getX(), item.getY()); + RoomTile oldLocation = room.getLayout().getTile(item.getX(), item.getY()); + double oldZ = item.getZ(); + + if(this.direction > 0) { + RoomUserRotation moveDirection = this.getMovementDirection(); + newLocation = room.getLayout().getTile( + (short) (item.getX() + ((moveDirection == RoomUserRotation.WEST || moveDirection == RoomUserRotation.NORTH_WEST || moveDirection == RoomUserRotation.SOUTH_WEST) ? -1 : (((moveDirection == RoomUserRotation.EAST || moveDirection == RoomUserRotation.SOUTH_EAST || moveDirection == RoomUserRotation.NORTH_EAST) ? 1 : 0)))), + (short) (item.getY() + ((moveDirection == RoomUserRotation.NORTH || moveDirection == RoomUserRotation.NORTH_EAST || moveDirection == RoomUserRotation.NORTH_WEST) ? 1 : ((moveDirection == RoomUserRotation.SOUTH || moveDirection == RoomUserRotation.SOUTH_EAST || moveDirection == RoomUserRotation.SOUTH_WEST) ? -1 : 0))) + ); + } + + boolean slideAnimation = item.getRotation() == newRotation; + + FurnitureMovementError furniMoveTest = room.furnitureFitsAt(newLocation, item, newRotation, true); + if(newLocation != null && newLocation.state != RoomTileState.INVALID && (newLocation != oldLocation || newRotation != item.getRotation()) && (furniMoveTest == FurnitureMovementError.NONE || ((furniMoveTest == FurnitureMovementError.TILE_HAS_BOTS || furniMoveTest == FurnitureMovementError.TILE_HAS_HABBOS || furniMoveTest == FurnitureMovementError.TILE_HAS_PETS) && newLocation == oldLocation))) { + if(room.furnitureFitsAt(newLocation, item, newRotation, false) == FurnitureMovementError.NONE && room.moveFurniTo(item, newLocation, newRotation, null, !slideAnimation) == FurnitureMovementError.NONE) { + this.itemCooldowns.add(item); + if(slideAnimation) { + room.sendComposer(new FloorItemOnRollerComposer(item, null, oldLocation, oldZ, newLocation, item.getZ(), 0, room).compose()); + } + } + } + } + + return true; + } + + @Override + public String getWiredData() { + THashSet itemsToRemove = new THashSet<>(this.items.size() / 2); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + for (HabboItem item : this.items) { + if (item.getRoomId() != this.getRoomId() || (room != null && room.getHabboItem(item.getId()) == null)) + itemsToRemove.add(item); + } + + for (HabboItem item : itemsToRemove) { + this.items.remove(item); + } + + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.direction, + this.rotation, + this.getDelay(), + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items.clear(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.direction = data.direction; + this.rotation = data.rotation; + for (Integer id: data.itemIds) { + HabboItem item = room.getHabboItem(id); + if (item != null) { + this.items.add(item); + } + } + } else { + String[] data = wiredData.split("\t"); + + if (data.length == 4) { + try { + this.direction = Integer.parseInt(data[0]); + this.rotation = Integer.parseInt(data[1]); + this.setDelay(Integer.parseInt(data[2])); + } catch (Exception e) { + System.out.println(e); + } + + for (String s : data[3].split("\r")) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) + this.items.add(item); + } + } + } + } + + @Override + public void onPickUp() { + this.direction = 0; + this.rotation = 0; + this.items.clear(); + this.setDelay(0); + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + THashSet items = new THashSet<>(); + + for (HabboItem item : this.items) { + if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) + items.add(item); + } + + for (HabboItem item : items) { + this.items.remove(item); + } + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + for (HabboItem item : this.items) + message.appendInt(item.getId()); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(2); + message.appendInt(this.direction); + message.appendInt(this.rotation); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room == null) + return false; + + packet.readInt(); + + this.direction = packet.readInt(); + this.rotation = packet.readInt(); + + packet.readString(); + + int count = packet.readInt(); + if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count", 5)) return false; + + this.items.clear(); + for (int i = 0; i < count; i++) { + this.items.add(room.getHabboItem(packet.readInt())); + } + + this.setDelay(packet.readInt()); + + return true; + } + + + /** + * Returns a new rotation for an item based on the wired options + * + * @param item HabboItem + * @return new rotation + */ + private int getNewRotation(HabboItem item) { + int rotationToAdd = 0; + + if(item.getMaximumRotations() == 2) { + return item.getRotation() == 0 ? 4 : 0; + } + else if(item.getMaximumRotations() == 1) { + return item.getRotation(); + } + else if(item.getMaximumRotations() > 4) { + if (this.rotation == 1) { + return item.getRotation() == item.getMaximumRotations() - 1 ? 0 : item.getRotation() + 1; + } else if (this.rotation == 2) { + return item.getRotation() > 0 ? item.getRotation() - 1 : item.getMaximumRotations() - 1; + } else if (this.rotation == 3) { //Random rotation + THashSet possibleRotations = new THashSet<>(); + for (int i = 0; i < item.getMaximumRotations(); i++) + { + possibleRotations.add(i); + } + + possibleRotations.remove(item.getRotation()); + + if(possibleRotations.size() > 0) { + int index = Emulator.getRandom().nextInt(possibleRotations.size()); + Iterator iter = possibleRotations.iterator(); + for (int i = 0; i < index; i++) { + iter.next(); + } + return iter.next(); + } + } + } + else { + if (this.rotation == 1) { + return (item.getRotation() + 2) % 8; + } else if (this.rotation == 2) { + int rot = (item.getRotation() - 2) % 8; + if(rot < 0) { + rot += 8; + } + return rot; + } else if (this.rotation == 3) { //Random rotation + THashSet possibleRotations = new THashSet<>(); + for (int i = 0; i < item.getMaximumRotations(); i++) + { + possibleRotations.add(i * 2); + } + + possibleRotations.remove(item.getRotation()); + + if(possibleRotations.size() > 0) { + int index = Emulator.getRandom().nextInt(possibleRotations.size()); + Iterator iter = possibleRotations.iterator(); + for (int i = 0; i < index; i++) { + iter.next(); + } + return iter.next(); + } + } + } + + return item.getRotation(); + } + + /** + * Returns the direction of movement based on the wired settings + * + * @return direction + */ + private RoomUserRotation getMovementDirection() { + RoomUserRotation movemementDirection = RoomUserRotation.NORTH; + if (this.direction == 1) { + movemementDirection = RoomUserRotation.values()[Emulator.getRandom().nextInt(RoomUserRotation.values().length / 2) * 2]; + } else if (this.direction == 2) { + if (Emulator.getRandom().nextInt(2) == 1) { + movemementDirection = RoomUserRotation.EAST; + } else { + movemementDirection = RoomUserRotation.WEST; + } + } else if (this.direction == 3) { + if (Emulator.getRandom().nextInt(2) != 1) { + movemementDirection = RoomUserRotation.SOUTH; + } + } else if (this.direction == 4) { + movemementDirection = RoomUserRotation.SOUTH; + } else if (this.direction == 5) { + movemementDirection = RoomUserRotation.EAST; + } else if (this.direction == 7) { + movemementDirection = RoomUserRotation.WEST; + } + return movemementDirection; + } + + @Override + public void cycle(Room room) { + this.itemCooldowns.clear(); + } + + static class JsonData { + int direction; + int rotation; + int delay; + List itemIds; + + public JsonData(int direction, int rotation, int delay, List itemIds) { + this.direction = direction; + this.rotation = rotation; + this.delay = delay; + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMuteHabbo.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMuteHabbo.java new file mode 100644 index 0000000..3978801 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMuteHabbo.java @@ -0,0 +1,141 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserWhisperComposer; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredEffectMuteHabbo extends InteractionWiredEffect { + private static final WiredEffectType type = WiredEffectType.MUTE_TRIGGER; + + private int length = 5; + private String message = ""; + + public WiredEffectMuteHabbo(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectMuteHabbo(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.message); + message.appendInt(1); + message.appendInt(this.length); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) { + packet.readInt(); + this.length = packet.readInt(); + this.message = packet.readString(); + packet.readInt(); + this.setDelay(packet.readInt()); + + return true; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (roomUnit == null) + return true; + + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + if (room.hasRights(habbo)) + return false; + + room.muteHabbo(habbo, 60); + + habbo.getClient().sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(this.message.replace("%user%", habbo.getHabboInfo().getUsername()).replace("%online_count%", Emulator.getGameEnvironment().getHabboManager().getOnlineCount() + "").replace("%room_count%", Emulator.getGameEnvironment().getRoomManager().getActiveRooms().size() + ""), habbo, habbo, RoomChatMessageBubbles.WIRED))); + } + + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.getDelay(), + this.length, + this.message + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.length = data.length; + this.message = data.message; + } else { + String[] data = wiredData.split("\t"); + + if (data.length >= 3) { + try { + this.setDelay(Integer.valueOf(data[0])); + this.length = Integer.valueOf(data[1]); + this.message = data[2]; + } catch (Exception e) { + } + } + } + } + + @Override + public void onPickUp() { + this.setDelay(0); + this.message = ""; + this.length = 0; + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public boolean requiresTriggeringUser() { + return true; + } + + static class JsonData { + int delay; + int length; + String message; + + public JsonData(int delay, int length, String message) { + this.delay = delay; + this.length = length; + this.message = message; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectResetTimers.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectResetTimers.java new file mode 100644 index 0000000..583e4f6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectResetTimers.java @@ -0,0 +1,131 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.threading.runnables.WiredResetTimers; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredEffectResetTimers extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.RESET_TIMERS; + + private int delay = 0; + + public WiredEffectResetTimers(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectResetTimers(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.getDelay()); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) { + packet.readInt(); + packet.readString(); + packet.readInt(); + this.delay = packet.readInt(); + this.setDelay(this.delay); + + return true; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Emulator.getThreading().run(new WiredResetTimers(room), this.delay); + + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.delay + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.delay = data.delay; + } else { + try { + if (!wiredData.equals("")) { + this.delay = Integer.parseInt(wiredData); + } + } catch (Exception e) { + } + } + + this.setDelay(this.delay); + } + + @Override + public void onPickUp() { + this.delay = 0; + this.setDelay(0); + } + + @Override + public WiredEffectType getType() { + return type; + } + + static class JsonData { + int delay; + + public JsonData(int delay) { + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectTeleport.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectTeleport.java new file mode 100644 index 0000000..304703f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectTeleport.java @@ -0,0 +1,254 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +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.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserEffectComposer; +import com.eu.habbo.threading.runnables.RoomUnitTeleport; +import com.eu.habbo.threading.runnables.SendRoomUnitEffectComposer; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredEffectTeleport extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.TELEPORT; + + protected List items; + + public WiredEffectTeleport(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.items = new ArrayList<>(); + } + + public WiredEffectTeleport(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.items = new ArrayList<>(); + } + + public static void teleportUnitToTile(RoomUnit roomUnit, RoomTile tile) { + if (roomUnit == null || tile == null || roomUnit.isWiredTeleporting) + return; + + Room room = roomUnit.getRoom(); + + if (room == null) { + return; + } + + // makes a temporary effect + + roomUnit.getRoom().unIdle(roomUnit.getRoom().getHabbo(roomUnit)); + room.sendComposer(new RoomUserEffectComposer(roomUnit, 4).compose()); + Emulator.getThreading().run(new SendRoomUnitEffectComposer(room, roomUnit), WiredHandler.TELEPORT_DELAY + 1000); + + if (tile == roomUnit.getCurrentLocation()) { + return; + } + + if (tile.state == RoomTileState.INVALID || tile.state == RoomTileState.BLOCKED) { + RoomTile alternativeTile = null; + List optionalTiles = room.getLayout().getTilesAround(tile); + + Collections.reverse(optionalTiles); + for (RoomTile optionalTile : optionalTiles) { + if (optionalTile.state != RoomTileState.INVALID && optionalTile.state != RoomTileState.BLOCKED) { + alternativeTile = optionalTile; + break; + } + } + + if (alternativeTile != null) { + tile = alternativeTile; + } + } + + Emulator.getThreading().run(() -> { roomUnit.isWiredTeleporting = true; }, Math.max(0, WiredHandler.TELEPORT_DELAY - 500)); + Emulator.getThreading().run(new RoomUnitTeleport(roomUnit, room, tile.x, tile.y, tile.getStackHeight() + (tile.state == RoomTileState.SIT ? -0.5 : 0), roomUnit.getEffectId()), WiredHandler.TELEPORT_DELAY); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + THashSet items = new THashSet<>(); + + for (HabboItem item : this.items) { + if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) + items.add(item); + } + + for (HabboItem item : items) { + this.items.remove(item); + } + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + for (HabboItem item : this.items) + message.appendInt(item.getId()); + + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + packet.readString(); + + int itemsCount = packet.readInt(); + + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); + } + + List newItems = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.add(it); + } + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.items.clear(); + this.items.addAll(newItems); + this.setDelay(delay); + + return true; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + this.items.removeIf(item -> item == null || item.getRoomId() != this.getRoomId() + || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null); + + if (!this.items.isEmpty()) { + int i = Emulator.getRandom().nextInt(this.items.size()); + HabboItem item = this.items.get(i); + + teleportUnitToTile(roomUnit, room.getLayout().getTile(item.getX(), item.getY())); + return true; + } + + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.getDelay(), + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items = new ArrayList<>(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + for (Integer id: data.itemIds) { + HabboItem item = room.getHabboItem(id); + if (item != null) { + this.items.add(item); + } + } + } else { + String[] wiredDataOld = wiredData.split("\t"); + + if (wiredDataOld.length >= 1) { + this.setDelay(Integer.parseInt(wiredDataOld[0])); + } + if (wiredDataOld.length == 2) { + if (wiredDataOld[1].contains(";")) { + for (String s : wiredDataOld[1].split(";")) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) + this.items.add(item); + } + } + } + } + } + + @Override + public void onPickUp() { + this.items.clear(); + this.setDelay(0); + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public boolean requiresTriggeringUser() { + return true; + } + + @Override + protected long requiredCooldown() { + return 50L; + } + + static class JsonData { + int delay; + List itemIds; + + public JsonData(int delay, List itemIds) { + this.delay = delay; + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectToggleFurni.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectToggleFurni.java new file mode 100644 index 0000000..d3d5ab6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectToggleFurni.java @@ -0,0 +1,282 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.*; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameGate; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameScoreboard; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTimer; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiTeleporter; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiTile; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeBlock; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeExitTile; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeTile; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagField; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagPole; +import com.eu.habbo.habbohotel.items.interactions.pets.*; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.stream.Collectors; + +public class WiredEffectToggleFurni extends InteractionWiredEffect { + private static final Logger LOGGER = LoggerFactory.getLogger(WiredEffectToggleFurni.class); + + public static final WiredEffectType type = WiredEffectType.TOGGLE_STATE; + + private final CopyOnWriteArraySet items; + + private static final List> FORBIDDEN_TYPES = new ArrayList>() { + { + this.add(InteractionWired.class); + this.add(InteractionTeleport.class); + this.add(InteractionPushable.class); + this.add(InteractionTagPole.class); + this.add(InteractionTagField.class); + this.add(InteractionCrackable.class); + this.add(InteractionGameScoreboard.class); + this.add(InteractionGameGate.class); + this.add(InteractionFreezeTile.class); + this.add(InteractionFreezeBlock.class); + this.add(InteractionFreezeExitTile.class); + this.add(InteractionBattleBanzaiTeleporter.class); + this.add(InteractionBattleBanzaiTile.class); + this.add(InteractionMonsterPlantSeed.class); + this.add(InteractionPetBreedingNest.class); + this.add(InteractionPetDrink.class); + this.add(InteractionPetFood.class); + this.add(InteractionPetToy.class); + this.add(InteractionBadgeDisplay.class); + this.add(InteractionClothing.class); + this.add(InteractionVendingMachine.class); + this.add(InteractionGift.class); + this.add(InteractionPressurePlate.class); + this.add(InteractionMannequin.class); + this.add(InteractionGymEquipment.class); + this.add(InteractionHopper.class); + this.add(InteractionObstacle.class); + this.add(InteractionOneWayGate.class); + this.add(InteractionPuzzleBox.class); + this.add(InteractionRoller.class); + this.add(InteractionSwitch.class); + this.add(InteractionTent.class); + this.add(InteractionTrap.class); + this.add(InteractionTrophy.class); + this.add(InteractionWater.class); + } + }; + + public WiredEffectToggleFurni(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.items = new CopyOnWriteArraySet<>(); + } + + public WiredEffectToggleFurni(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.items = new CopyOnWriteArraySet<>(); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + THashSet items = new THashSet<>(); + + for (HabboItem item : this.items) { + if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) + items.add(item); + } + + for (HabboItem item : items) { + this.items.remove(item); + } + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + for (HabboItem item : this.items) { + message.appendInt(item.getId()); + } + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + packet.readString(); + + int itemsCount = packet.readInt(); + + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); + } + + List newItems = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.add(it); + } + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.items.clear(); + this.items.addAll(newItems); + this.setDelay(delay); + + return true; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + + HabboItem triggerItem = null; + + THashSet itemsToRemove = new THashSet<>(); + for (HabboItem item : this.items) { + if (item == null || item.getRoomId() == 0 || FORBIDDEN_TYPES.stream().anyMatch(a -> a.isAssignableFrom(item.getClass()))) { + itemsToRemove.add(item); + continue; + } + + try { + if (item.getBaseItem().getStateCount() > 1 || item instanceof InteractionGameTimer) { + int state = 0; + if (!item.getExtradata().isEmpty()) { + try { + state = Integer.parseInt(item.getExtradata()); // assumes that extradata is state, could be something else for trophies etc. + } catch (NumberFormatException ignored) { + + } + } + item.onClick(habbo != null && !(item instanceof InteractionGameTimer) ? habbo.getClient() : null, room, new Object[]{state, this.getType()}); + } + } catch (Exception e) { + LOGGER.error("Caught exception", e); + } + } + + this.items.removeAll(itemsToRemove); + + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.getDelay(), + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items.clear(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + for (Integer id: data.itemIds) { + HabboItem item = room.getHabboItem(id); + + if (item instanceof InteractionFreezeBlock || item instanceof InteractionFreezeTile || item instanceof InteractionCrackable) { + continue; + } + + if (item != null) { + this.items.add(item); + } + } + } else { + String[] wiredDataOld = wiredData.split("\t"); + + if (wiredDataOld.length >= 1) { + this.setDelay(Integer.parseInt(wiredDataOld[0])); + } + if (wiredDataOld.length == 2) { + if (wiredDataOld[1].contains(";")) { + for (String s : wiredDataOld[1].split(";")) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item instanceof InteractionFreezeBlock || item instanceof InteractionFreezeTile || item instanceof InteractionCrackable) + continue; + + if (item != null) + this.items.add(item); + } + } + } + } + } + + @Override + public void onPickUp() { + this.items.clear(); + this.setDelay(0); + } + + @Override + public WiredEffectType getType() { + return type; + } + + static class JsonData { + int delay; + List itemIds; + + public JsonData(int delay, List itemIds) { + this.delay = delay; + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectToggleRandom.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectToggleRandom.java new file mode 100644 index 0000000..4fbd920 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectToggleRandom.java @@ -0,0 +1,261 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.*; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameGate; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameScoreboard; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTimer; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiTeleporter; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiTile; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeBlock; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeExitTile; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeTile; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagField; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagPole; +import com.eu.habbo.habbohotel.items.interactions.pets.*; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredEffectToggleRandom extends InteractionWiredEffect { + private static final Logger LOGGER = LoggerFactory.getLogger(WiredEffectToggleRandom.class); + + public static final WiredEffectType type = WiredEffectType.TOGGLE_RANDOM; + + private final THashSet items = new THashSet<>(); + + private static final List> FORBIDDEN_TYPES = new ArrayList>() { + { + this.add(InteractionWired.class); + this.add(InteractionTeleport.class); + this.add(InteractionPushable.class); + this.add(InteractionTagPole.class); + this.add(InteractionTagField.class); + this.add(InteractionCrackable.class); + this.add(InteractionGameScoreboard.class); + this.add(InteractionGameGate.class); + this.add(InteractionFreezeTile.class); + this.add(InteractionFreezeBlock.class); + this.add(InteractionFreezeExitTile.class); + this.add(InteractionBattleBanzaiTeleporter.class); + this.add(InteractionBattleBanzaiTile.class); + this.add(InteractionMonsterPlantSeed.class); + this.add(InteractionPetBreedingNest.class); + this.add(InteractionPetDrink.class); + this.add(InteractionPetFood.class); + this.add(InteractionPetToy.class); + this.add(InteractionBadgeDisplay.class); + this.add(InteractionClothing.class); + this.add(InteractionVendingMachine.class); + this.add(InteractionGift.class); + this.add(InteractionPressurePlate.class); + this.add(InteractionMannequin.class); + this.add(InteractionGymEquipment.class); + this.add(InteractionHopper.class); + this.add(InteractionObstacle.class); + this.add(InteractionOneWayGate.class); + this.add(InteractionPuzzleBox.class); + this.add(InteractionRoller.class); + this.add(InteractionSwitch.class); + this.add(InteractionTent.class); + this.add(InteractionTrap.class); + this.add(InteractionTrophy.class); + this.add(InteractionWater.class); + } + }; + + public WiredEffectToggleRandom(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectToggleRandom(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + THashSet items = new THashSet<>(); + + for (HabboItem item : this.items) { + if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) + items.add(item); + } + + for (HabboItem item : items) { + this.items.remove(item); + } + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + for (HabboItem item : this.items) { + message.appendInt(item.getId()); + } + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + packet.readString(); + + int itemsCount = packet.readInt(); + + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); + } + + List newItems = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.add(it); + } + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.items.clear(); + this.items.addAll(newItems); + this.setDelay(delay); + + return true; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + THashSet items = this.items; + + for (HabboItem item : items) { + if (item.getRoomId() == 0 || FORBIDDEN_TYPES.stream().anyMatch(a -> a.isAssignableFrom(item.getClass()))) { + this.items.remove(item); + continue; + } + + try { + item.setExtradata(Emulator.getRandom().nextInt(item.getBaseItem().getStateCount() + 1) + ""); + room.updateItem(item); + } catch (Exception e) { + LOGGER.error("Caught exception", e); + } + } + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.getDelay(), + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items.clear(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + for (Integer id: data.itemIds) { + HabboItem item = room.getHabboItem(id); + + if (item instanceof InteractionFreezeBlock || item instanceof InteractionGameTimer || item instanceof InteractionCrackable) + continue; + + if (item != null) + this.items.add(item); + } + } else { + String[] wiredDataOld = wiredData.split("\t"); + + if (wiredDataOld.length >= 1) { + this.setDelay(Integer.parseInt(wiredDataOld[0])); + } + if (wiredDataOld.length == 2) { + if (wiredDataOld[1].contains(";")) { + for (String s : wiredDataOld[1].split(";")) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item instanceof InteractionFreezeBlock || item instanceof InteractionGameTimer || item instanceof InteractionCrackable) + continue; + + if (item != null) + this.items.add(item); + } + } + } + } + } + + @Override + public void onPickUp() { + this.items.clear(); + this.setDelay(0); + } + + @Override + public WiredEffectType getType() { + return type; + } + + static class JsonData { + int delay; + List itemIds; + + public JsonData(int delay, List itemIds) { + this.delay = delay; + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectTriggerStacks.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectTriggerStacks.java new file mode 100644 index 0000000..db37872 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectTriggerStacks.java @@ -0,0 +1,224 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredEffectTriggerStacks extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.CALL_STACKS; + + private THashSet items; + + public WiredEffectTriggerStacks(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.items = new THashSet<>(); + } + + public WiredEffectTriggerStacks(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.items = new THashSet<>(); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + THashSet items = new THashSet<>(); + + for (HabboItem item : this.items) { + if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) + items.add(item); + } + + for (HabboItem item : items) { + this.items.remove(item); + } + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + for (HabboItem item : this.items) { + message.appendInt(item.getId()); + } + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + packet.readString(); + + int itemsCount = packet.readInt(); + + if(itemsCount > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) { + throw new WiredSaveException("Too many furni selected"); + } + + List newItems = new ArrayList<>(); + + for (int i = 0; i < itemsCount; i++) { + int itemId = packet.readInt(); + HabboItem it = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(itemId); + + if(it == null) + throw new WiredSaveException(String.format("Item %s not found", itemId)); + + newItems.add(it); + } + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.items.clear(); + this.items.addAll(newItems); + this.setDelay(delay); + + return true; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + + if (stuff == null || (stuff.length >= 1 && stuff[stuff.length - 1] instanceof WiredEffectTriggerStacks)) { + return false; + } + + THashSet usedTiles = new THashSet<>(); + + boolean found; + + for (HabboItem item : this.items) { + //if(item instanceof InteractionWiredTrigger) + { + found = false; + for (RoomTile tile : usedTiles) { + if (tile.x == item.getX() && tile.y == item.getY()) { + found = true; + break; + } + } + + if (!found) { + usedTiles.add(room.getLayout().getTile(item.getX(), item.getY())); + } + } + } + Object[] newStuff = new Object[stuff.length + 1]; + System.arraycopy(stuff, 0, newStuff, 0, stuff.length); + newStuff[newStuff.length - 1] = this; + WiredHandler.executeEffectsAtTiles(usedTiles, roomUnit, room, stuff); + + return true; + } + + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.getDelay(), + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items = new THashSet<>(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + for (Integer id: data.itemIds) { + HabboItem item = room.getHabboItem(id); + if (item != null) { + this.items.add(item); + } + } + } else { + String[] wiredDataOld = wiredData.split("\t"); + + if (wiredDataOld.length >= 1) { + this.setDelay(Integer.parseInt(wiredDataOld[0])); + } + if (wiredDataOld.length == 2) { + if (wiredDataOld[1].contains(";")) { + for (String s : wiredDataOld[1].split(";")) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) + this.items.add(item); + } + } + } + } + } + + @Override + public void onPickUp() { + this.items.clear(); + this.setDelay(0); + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + protected long requiredCooldown() { + return 250; + } + + static class JsonData { + int delay; + List itemIds; + + public JsonData(int delay, List itemIds) { + this.delay = delay; + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectWhisper.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectWhisper.java new file mode 100644 index 0000000..56d6f35 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectWhisper.java @@ -0,0 +1,173 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.effects; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredChangeDirectionSetting; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.wired.WiredSaveException; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserWhisperComposer; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredEffectWhisper extends InteractionWiredEffect { + public static final WiredEffectType type = WiredEffectType.SHOW_MESSAGE; + + protected String message = ""; + + public WiredEffectWhisper(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredEffectWhisper(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.message); + message.appendInt(0); + message.appendInt(0); + message.appendInt(type.code); + message.appendInt(this.getDelay()); + + if (this.requiresTriggeringUser()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getTriggers(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredTrigger object) { + if (!object.isTriggeredByRoomUnit()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet, GameClient gameClient) throws WiredSaveException { + packet.readInt(); + + String message = packet.readString(); + + if(gameClient.getHabbo() == null || !gameClient.getHabbo().hasPermission(Permission.ACC_SUPERWIRED)) { + message = Emulator.getGameEnvironment().getWordFilter().filter(message, null); + message = message.substring(0, Math.min(message.length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100))); + } + + packet.readInt(); + + int delay = packet.readInt(); + + if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) + throw new WiredSaveException("Delay too long"); + + this.message = message; + this.setDelay(delay); + return true; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (this.message.length() > 0) { + if (roomUnit != null) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + String msg = this.message.replace("%user%", habbo.getHabboInfo().getUsername()).replace("%online_count%", Emulator.getGameEnvironment().getHabboManager().getOnlineCount() + "").replace("%room_count%", Emulator.getGameEnvironment().getRoomManager().getActiveRooms().size() + ""); + habbo.getClient().sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(msg, habbo, habbo, RoomChatMessageBubbles.WIRED))); + Emulator.getThreading().run(() -> WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, roomUnit, room, new Object[]{ msg })); + + if (habbo.getRoomUnit().isIdle()) { + habbo.getRoomUnit().getRoom().unIdle(habbo); + } + return true; + } + } else { + for (Habbo h : room.getHabbos()) { + h.getClient().sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(this.message.replace("%user%", h.getHabboInfo().getUsername()).replace("%online_count%", Emulator.getGameEnvironment().getHabboManager().getOnlineCount() + "").replace("%room_count%", Emulator.getGameEnvironment().getRoomManager().getActiveRooms().size() + ""), h, h, RoomChatMessageBubbles.WIRED))); + } + + return true; + } + } + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData(this.message, this.getDelay())); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if(wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.setDelay(data.delay); + this.message = data.message; + } + else { + this.message = ""; + + if (wiredData.split("\t").length >= 2) { + super.setDelay(Integer.valueOf(wiredData.split("\t")[0])); + this.message = wiredData.split("\t")[1]; + } + + this.needsUpdate(true); + } + } + + @Override + public void onPickUp() { + this.message = ""; + this.setDelay(0); + } + + @Override + public WiredEffectType getType() { + return type; + } + + @Override + public boolean requiresTriggeringUser() { + return true; + } + + static class JsonData { + String message; + int delay; + + public JsonData(String message, int delay) { + this.message = message; + this.delay = delay; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredBlob.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredBlob.java new file mode 100644 index 0000000..ebdef5f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredBlob.java @@ -0,0 +1,121 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.extra; + +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.games.GamePlayer; +import com.eu.habbo.habbohotel.games.GameState; +import com.eu.habbo.habbohotel.games.battlebanzai.BattleBanzaiGame; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionDefault; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import lombok.extern.slf4j.Slf4j; + +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class WiredBlob extends InteractionDefault { + + enum WiredBlobState { + ACTIVE("0"), + USED("1"); + + private String state; + WiredBlobState(String state) { + this.state = state; + } + + public String getState() { + return state; + } + } + + private int POINTS_REWARD = 0; + private boolean RESETS_WITH_GAME = true; + + public WiredBlob(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + + this.parseCustomParams(); + } + + public WiredBlob(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + + this.parseCustomParams(); + } + + @Override + public void onPlace(Room room) { + super.onPlace(room); + + this.setExtradata(WiredBlobState.USED.getState()); + room.updateItem(this); + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOn(roomUnit, room, objects); + + if (!this.getExtradata().equals(WiredBlobState.ACTIVE.getState())) return; + + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + GamePlayer player = habbo.getHabboInfo().getGamePlayer(); + + if (player != null) { + player.addScore(this.POINTS_REWARD, true); + + BattleBanzaiGame battleBanzaiGame = (BattleBanzaiGame) room.getGame(BattleBanzaiGame.class); + + if (battleBanzaiGame != null && battleBanzaiGame.getState() != GameState.IDLE) { + battleBanzaiGame.refreshCounters(habbo.getHabboInfo().getGamePlayer().getTeamColor()); + } + + this.setExtradata(WiredBlobState.USED.getState()); + room.updateItem(this); + } + } + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (!this.RESETS_WITH_GAME && objects != null && objects.length == 2 && objects[1].equals(WiredEffectType.TOGGLE_STATE) && room.getGames().stream().anyMatch(game -> game.getState().equals(GameState.RUNNING) || game.getState().equals(GameState.PAUSED))) { + this.setExtradata(this.getExtradata().equals(WiredBlobState.ACTIVE.getState()) ? WiredBlobState.USED.getState() : WiredBlobState.ACTIVE.getState()); + room.updateItem(this); + } + } + + public void onGameStart(Room room) { + if (this.RESETS_WITH_GAME) { + this.setExtradata(WiredBlobState.ACTIVE.getState()); + room.updateItem(this); + } + } + + public void onGameEnd(Room room) { + this.setExtradata(WiredBlobState.USED.getState()); + room.updateItem(this); + } + + private void parseCustomParams() { + String[] params = this.getBaseItem().getCustomParams().split(","); + + if (params.length != 2) { + log.error("Wired blobs should have customparams with two parameters (points,resetsWithGame)"); + return; + } + + try { + this.POINTS_REWARD = Integer.parseInt(params[0]); + } catch (NumberFormatException e) { + log.error("Wired blobs should have customparams with the first parameter being the amount of points (number)"); + return; + } + + this.RESETS_WITH_GAME = params[1].equalsIgnoreCase("true"); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredExtraRandom.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredExtraRandom.java new file mode 100644 index 0000000..b8d8e3b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredExtraRandom.java @@ -0,0 +1,50 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.extra; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredExtra; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredExtraRandom extends InteractionWiredExtra { + public WiredExtraRandom(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredExtraRandom(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + return false; + } + + @Override + public String getWiredData() { + return null; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + + } + + @Override + public void onPickUp() { + + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredExtraUnseen.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredExtraUnseen.java new file mode 100644 index 0000000..a7b0456 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredExtraUnseen.java @@ -0,0 +1,87 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.extra; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredExtra; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredExtraUnseen extends InteractionWiredExtra { + public List seenList = new ArrayList<>(); + + public WiredExtraUnseen(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredExtraUnseen(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + return false; + } + + @Override + public String getWiredData() { + return null; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + + } + + @Override + public void onPickUp() { + this.seenList.clear(); + } + + @Override + public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + + } + + @Override + public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + super.onMove(room, oldLocation, newLocation); + this.seenList.clear(); + } + + public InteractionWiredEffect getUnseenEffect(List effects) { + List unseenEffects = new ArrayList<>(); + for (InteractionWiredEffect effect : effects) { + if (!this.seenList.contains(effect.getId())) { + unseenEffects.add(effect); + } + } + + InteractionWiredEffect effect = null; + if (!unseenEffects.isEmpty()) { + effect = unseenEffects.get(0); + } else { + this.seenList.clear(); + + if (!effects.isEmpty()) { + effect = effects.get(0); + } + } + + if (effect != null) { + this.seenList.add(effect.getId()); + } + return effect; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/interfaces/InteractionWiredMatchFurniSettings.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/interfaces/InteractionWiredMatchFurniSettings.java new file mode 100644 index 0000000..6db447f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/interfaces/InteractionWiredMatchFurniSettings.java @@ -0,0 +1,11 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.interfaces; + +import com.eu.habbo.habbohotel.wired.WiredMatchFurniSetting; +import gnu.trove.set.hash.THashSet; + +public interface InteractionWiredMatchFurniSettings { + public THashSet getMatchFurniSettings(); + public boolean shouldMatchState(); + public boolean shouldMatchRotation(); + public boolean shouldMatchPosition(); +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerAtSetTime.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerAtSetTime.java new file mode 100644 index 0000000..f636464 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerAtSetTime.java @@ -0,0 +1,136 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.items.interactions.wired.WiredTriggerReset; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.threading.runnables.WiredExecuteTask; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredTriggerAtSetTime extends InteractionWiredTrigger implements WiredTriggerReset { + public final static WiredTriggerType type = WiredTriggerType.AT_GIVEN_TIME; + + public int executeTime; + public int taskId; + + public WiredTriggerAtSetTime(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredTriggerAtSetTime(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.executeTime + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.executeTime = data.executeTime; + } else { + if (wiredData.length() >= 1) { + this.executeTime = (Integer.parseInt(wiredData)); + } + } + + if (this.executeTime < 500) { + this.executeTime = 20 * 500; + } + this.taskId = 1; + Emulator.getThreading().run(new WiredExecuteTask(this, Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId())), this.executeTime); + } + + @Override + public void onPickUp() { + this.executeTime = 0; + this.taskId = 0; + } + + @Override + public WiredTriggerType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.executeTime / 500); + message.appendInt(1); + message.appendInt(this.getType().code); + + if (!this.isTriggeredByRoomUnit()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getEffects(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredEffect object) { + if (object.requiresTriggeringUser()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + this.executeTime = packet.readInt() * 500; + + this.resetTimer(); + + return true; + } + + @Override + public void resetTimer() { + this.taskId++; + + Emulator.getThreading().run(new WiredExecuteTask(this, Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId())), this.executeTime); + } + + static class JsonData { + int executeTime; + + public JsonData(int executeTime) { + this.executeTime = executeTime; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerAtTimeLong.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerAtTimeLong.java new file mode 100644 index 0000000..751d21c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerAtTimeLong.java @@ -0,0 +1,134 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.items.interactions.wired.WiredTriggerReset; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.threading.runnables.WiredExecuteTask; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredTriggerAtTimeLong extends InteractionWiredTrigger implements WiredTriggerReset { + private static final WiredTriggerType type = WiredTriggerType.AT_GIVEN_TIME; + public int taskId; + private int executeTime; + + public WiredTriggerAtTimeLong(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredTriggerAtTimeLong(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.executeTime + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.executeTime = data.executeTime; + } else { + if (wiredData.length() >= 1) { + this.executeTime = (Integer.parseInt(wiredData)); + } + } + + if (this.executeTime < 500) { + this.executeTime = 20 * 500; + } + this.taskId = 1; + Emulator.getThreading().run(new WiredExecuteTask(this, Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId())), this.executeTime); + } + + @Override + public void onPickUp() { + this.executeTime = 0; + this.taskId = 0; + } + + @Override + public WiredTriggerType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.executeTime / 500); + message.appendInt(1); + message.appendInt(this.getType().code); + + if (!this.isTriggeredByRoomUnit()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getEffects(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredEffect object) { + if (object.requiresTriggeringUser()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.executeTime = packet.readInt() * 500; + + return true; + } + + @Override + public void resetTimer() { + this.taskId++; + + Emulator.getThreading().run(new WiredExecuteTask(this, Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId())), this.executeTime); + } + + static class JsonData { + int executeTime; + + public JsonData(int executeTime) { + this.executeTime = executeTime; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerBotReachedFurni.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerBotReachedFurni.java new file mode 100644 index 0000000..596fbc8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerBotReachedFurni.java @@ -0,0 +1,187 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredTriggerBotReachedFurni extends InteractionWiredTrigger { + private static final Logger LOGGER = LoggerFactory.getLogger(WiredTriggerBotReachedFurni.class); + + public final static WiredTriggerType type = WiredTriggerType.WALKS_ON_FURNI; + + private THashSet items; + private String botName = ""; + + public WiredTriggerBotReachedFurni(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.items = new THashSet<>(); + } + + public WiredTriggerBotReachedFurni(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.items = new THashSet<>(); + } + + @Override + public WiredTriggerType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + THashSet items = new THashSet<>(); + + if (Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()) == null) { + items.addAll(this.items); + } else { + for (HabboItem item : this.items) { + if (Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) + items.add(item); + } + } + + for (HabboItem item : items) { + this.items.remove(item); + } + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + for (HabboItem item : this.items) { + message.appendInt(item.getId()); + } + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.botName); + message.appendInt(0); + message.appendInt(0); + message.appendInt(WiredTriggerType.BOT_REACHED_STF.code); + + if (!this.isTriggeredByRoomUnit()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getEffects(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredEffect object) { + if (object.requiresTriggeringUser()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.botName = packet.readString(); + + this.items.clear(); + + int count = packet.readInt(); + + for (int i = 0; i < count; i++) { + this.items.add(Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(packet.readInt())); + } + + return true; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (stuff.length >= 1) { + if (stuff[0] instanceof HabboItem) { + return this.items.contains(stuff[0]) && room.getBots(this.botName).stream().anyMatch(bot -> bot.getRoomUnit() == roomUnit); + } + } + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.botName, + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items.clear(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.botName = data.botName; + for (Integer id: data.itemIds) { + HabboItem item = room.getHabboItem(id); + if (item != null) { + this.items.add(item); + } + } + } else { + String[] data = wiredData.split(":"); + + if (data.length == 1) { + this.botName = data[0]; + } else if (data.length == 2) { + this.botName = data[0]; + + String[] items = data[1].split(";"); + + for (String id : items) { + try { + HabboItem item = room.getHabboItem(Integer.parseInt(id)); + + if (item != null) + this.items.add(item); + } catch (Exception e) { + LOGGER.error("Caught exception", e); + } + } + } + } + } + + @Override + public void onPickUp() { + this.items.clear(); + this.botName = ""; + } + + static class JsonData { + String botName; + List itemIds; + + public JsonData(String botName, List itemIds) { + this.botName = botName; + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerBotReachedHabbo.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerBotReachedHabbo.java new file mode 100644 index 0000000..0e7b22f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerBotReachedHabbo.java @@ -0,0 +1,100 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class WiredTriggerBotReachedHabbo extends InteractionWiredTrigger { + public final static WiredTriggerType type = WiredTriggerType.BOT_REACHED_AVTR; + + private String botName = ""; + + public WiredTriggerBotReachedHabbo(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredTriggerBotReachedHabbo(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public WiredTriggerType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.botName); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.botName = packet.readString(); + + return true; + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + return room.getBots(this.botName).stream().anyMatch(bot -> bot.getRoomUnit() == roomUnit); + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.botName + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.botName = data.botName; + } else { + this.botName = wiredData; + } + } + + @Override + public void onPickUp() { + this.botName = ""; + } + + @Override + public boolean isTriggeredByRoomUnit() { + return true; + } + + static class JsonData { + String botName; + + public JsonData(String botName) { + this.botName = botName; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerCollision.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerCollision.java new file mode 100644 index 0000000..4e44660 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerCollision.java @@ -0,0 +1,76 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredTriggerCollision extends InteractionWiredTrigger { + private static final WiredTriggerType type = WiredTriggerType.COLLISION; + + public WiredTriggerCollision(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredTriggerCollision(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + return stuff.length > 0 && stuff[0] instanceof HabboItem; + } + + @Override + public String getWiredData() { + return ""; + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + + } + + @Override + public void onPickUp() { + + } + + @Override + public WiredTriggerType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(type.code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + return true; + } + + @Override + public boolean isTriggeredByRoomUnit() { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerFurniStateToggled.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerFurniStateToggled.java new file mode 100644 index 0000000..f97f332 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerFurniStateToggled.java @@ -0,0 +1,165 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredTriggerFurniStateToggled extends InteractionWiredTrigger { + private static final WiredTriggerType type = WiredTriggerType.STATE_CHANGED; + + private THashSet items; + + public WiredTriggerFurniStateToggled(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.items = new THashSet<>(); + } + + public WiredTriggerFurniStateToggled(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.items = new THashSet<>(); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (stuff.length >= 1) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + for (Object object : stuff) { + if (object instanceof WiredEffectType) { + return false; + } + } + + if (stuff[0] instanceof HabboItem) { + return this.items.contains(stuff[0]); + } + } + } + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items = new THashSet<>(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + for (Integer id: data.itemIds) { + HabboItem item = room.getHabboItem(id); + if (item != null) { + this.items.add(item); + } + } + } else { + if (wiredData.split(":").length >= 3) { + super.setDelay(Integer.parseInt(wiredData.split(":")[0])); + + if (!wiredData.split(":")[2].equals("\t")) { + for (String s : wiredData.split(":")[2].split(";")) { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) + this.items.add(item); + } + } + } + } + } + + @Override + public void onPickUp() { + this.items.clear(); + } + + @Override + public WiredTriggerType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + THashSet items = new THashSet<>(); + + for (HabboItem item : this.items) { + if (item.getRoomId() != this.getRoomId()) { + items.add(item); + continue; + } + + if (room.getHabboItem(item.getId()) == null) { + items.add(item); + } + } + + for (HabboItem item : items) { + this.items.remove(item); + } + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + for (HabboItem item : this.items) { + message.appendInt(item.getId()); + } + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + packet.readString(); + + this.items.clear(); + + int count = packet.readInt(); + + for (int i = 0; i < count; i++) { + this.items.add(Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(packet.readInt())); + } + + return true; + } + + @Override + public boolean isTriggeredByRoomUnit() { + return true; + } + + static class JsonData { + List itemIds; + + public JsonData(List itemIds) { + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerGameEnds.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerGameEnds.java new file mode 100644 index 0000000..abb8417 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerGameEnds.java @@ -0,0 +1,89 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredTriggerGameEnds extends InteractionWiredTrigger { + private static final WiredTriggerType type = WiredTriggerType.GAME_ENDS; + + public WiredTriggerGameEnds(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredTriggerGameEnds(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + return true; + } + + @Override + public String getWiredData() { + return ""; + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + } + + @Override + public void onPickUp() { + + } + + @Override + public WiredTriggerType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + + if (!this.isTriggeredByRoomUnit()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getEffects(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredEffect object) { + if (object.requiresTriggeringUser()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet) { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerGameStarts.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerGameStarts.java new file mode 100644 index 0000000..5631cb4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerGameStarts.java @@ -0,0 +1,89 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredTriggerGameStarts extends InteractionWiredTrigger { + private static final WiredTriggerType type = WiredTriggerType.GAME_STARTS; + + public WiredTriggerGameStarts(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredTriggerGameStarts(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + return true; + } + + @Override + public String getWiredData() { + return ""; + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + } + + @Override + public void onPickUp() { + + } + + @Override + public WiredTriggerType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.type.code); + + if (!this.isTriggeredByRoomUnit()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getEffects(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredEffect object) { + if (object.requiresTriggeringUser()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet) { + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboEntersRoom.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboEntersRoom.java new file mode 100644 index 0000000..9a1400b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboEntersRoom.java @@ -0,0 +1,107 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredTriggerHabboEntersRoom extends InteractionWiredTrigger { + public static final WiredTriggerType type = WiredTriggerType.ENTER_ROOM; + + private String username = ""; + + public WiredTriggerHabboEntersRoom(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredTriggerHabboEntersRoom(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null) { + if (this.username.length() > 0) { + return habbo.getHabboInfo().getUsername().equalsIgnoreCase(this.username); + } + + return true; + } + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.username + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.username = data.username; + } else { + this.username = wiredData; + } + } + + @Override + public void onPickUp() { + this.username = ""; + } + + @Override + public WiredTriggerType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.username); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + this.username = packet.readString(); + + return true; + } + + @Override + public boolean isTriggeredByRoomUnit() { + return true; + } + + static class JsonData { + String username; + + public JsonData(String username) { + this.username = username; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboSaysKeyword.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboSaysKeyword.java new file mode 100644 index 0000000..f3b90ae --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboSaysKeyword.java @@ -0,0 +1,118 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredTriggerHabboSaysKeyword extends InteractionWiredTrigger { + private static final WiredTriggerType type = WiredTriggerType.SAY_SOMETHING; + + private boolean ownerOnly = false; + private String key = ""; + + public WiredTriggerHabboSaysKeyword(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredTriggerHabboSaysKeyword(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (this.key.length() > 0) { + if (stuff[0] instanceof String) { + if (((String) stuff[0]).toLowerCase().contains(this.key.toLowerCase())) { + Habbo habbo = room.getHabbo(roomUnit); + return !this.ownerOnly || (habbo != null && room.getOwnerId() == habbo.getHabboInfo().getId()); + } + } + } + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.ownerOnly, + this.key + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.ownerOnly = data.ownerOnly; + this.key = data.key; + } else { + String[] data = wiredData.split("\t"); + + if (data.length == 2) { + this.ownerOnly = data[0].equalsIgnoreCase("1"); + this.key = data[1]; + } + } + } + + @Override + public void onPickUp() { + this.ownerOnly = false; + this.key = ""; + } + + @Override + public WiredTriggerType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(this.key); + message.appendInt(0); + message.appendInt(1); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + this.ownerOnly = packet.readInt() == 1; + this.key = packet.readString(); + + return true; + } + + @Override + public boolean isTriggeredByRoomUnit() { + return true; + } + + static class JsonData { + boolean ownerOnly; + String key; + + public JsonData(boolean ownerOnly, String key) { + this.ownerOnly = ownerOnly; + this.key = key; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboWalkOffFurni.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboWalkOffFurni.java new file mode 100644 index 0000000..64e9dae --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboWalkOffFurni.java @@ -0,0 +1,158 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredTriggerHabboWalkOffFurni extends InteractionWiredTrigger { + public static final WiredTriggerType type = WiredTriggerType.WALKS_OFF_FURNI; + + private THashSet items; + + public WiredTriggerHabboWalkOffFurni(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.items = new THashSet<>(); + } + + public WiredTriggerHabboWalkOffFurni(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.items = new THashSet<>(); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (stuff.length >= 1) { + if (stuff[0] instanceof HabboItem) { + return this.items.contains(stuff[0]); + } + } + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new WiredTriggerFurniStateToggled.JsonData( + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items.clear(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + for (Integer id: data.itemIds) { + HabboItem item = room.getHabboItem(id); + if (item != null) { + this.items.add(item); + } + } + } else { + if (wiredData.split(":").length >= 3) { + super.setDelay(Integer.parseInt(wiredData.split(":")[0])); + + if (!wiredData.split(":")[2].equals("\t")) { + for (String s : wiredData.split(":")[2].split(";")) { + if (s.isEmpty()) + continue; + + try { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) + this.items.add(item); + } catch (Exception e) { + } + } + } + } + } + } + + @Override + public void onPickUp() { + this.items.clear(); + } + + @Override + public WiredTriggerType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + THashSet items = new THashSet<>(); + + if (room == null) { + items.addAll(this.items); + } else { + for (HabboItem item : this.items) { + if (room.getHabboItem(item.getId()) == null) + items.add(item); + } + } + + for (HabboItem item : items) { + this.items.remove(item); + } + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + for (HabboItem item : this.items) { + message.appendInt(item.getId()); + } + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + packet.readString(); + + this.items.clear(); + + int count = packet.readInt(); + + for (int i = 0; i < count; i++) { + this.items.add(Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(packet.readInt())); + } + + return true; + } + + @Override + public boolean isTriggeredByRoomUnit() { + return true; + } + + static class JsonData { + List itemIds; + + public JsonData(List itemIds) { + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboWalkOnFurni.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboWalkOnFurni.java new file mode 100644 index 0000000..257f23b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerHabboWalkOnFurni.java @@ -0,0 +1,159 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredTriggerHabboWalkOnFurni extends InteractionWiredTrigger { + public static final WiredTriggerType type = WiredTriggerType.WALKS_ON_FURNI; + + private THashSet items; + + public WiredTriggerHabboWalkOnFurni(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + this.items = new THashSet<>(); + } + + public WiredTriggerHabboWalkOnFurni(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + this.items = new THashSet<>(); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (stuff.length >= 1) { + if (stuff[0] instanceof HabboItem) { + return this.items.contains(stuff[0]); + } + } + return false; + } + + @Override + public WiredTriggerType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + THashSet items = new THashSet<>(); + + if (Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()) == null) { + items.addAll(this.items); + } else { + for (HabboItem item : this.items) { + if (Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null) + items.add(item); + } + } + + for (HabboItem item : items) { + this.items.remove(item); + } + + message.appendBoolean(false); + message.appendInt(WiredHandler.MAXIMUM_FURNI_SELECTION); + message.appendInt(this.items.size()); + for (HabboItem item : this.items) { + message.appendInt(item.getId()); + } + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + packet.readString(); + + this.items.clear(); + + int count = packet.readInt(); + + for (int i = 0; i < count; i++) { + this.items.add(Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(packet.readInt())); + } + + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.items.stream().map(HabboItem::getId).collect(Collectors.toList()) + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + this.items.clear(); + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + for (Integer id: data.itemIds) { + HabboItem item = room.getHabboItem(id); + if (item != null) { + this.items.add(item); + } + } + } else { + if (wiredData.split(":").length >= 3) { + super.setDelay(Integer.parseInt(wiredData.split(":")[0])); + + if (!wiredData.split(":")[2].equals("\t")) { + for (String s : wiredData.split(":")[2].split(";")) { + if (s.isEmpty()) + continue; + + try { + HabboItem item = room.getHabboItem(Integer.parseInt(s)); + + if (item != null) + this.items.add(item); + } catch (Exception e) { + } + } + } + } + } + } + + @Override + public void onPickUp() { + this.items.clear(); + } + + @Override + public boolean isTriggeredByRoomUnit() { + return true; + } + + static class JsonData { + List itemIds; + + public JsonData(List itemIds) { + this.itemIds = itemIds; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerRepeater.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerRepeater.java new file mode 100644 index 0000000..e7ad614 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerRepeater.java @@ -0,0 +1,162 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.ICycleable; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.items.interactions.wired.WiredTriggerReset; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredTriggerRepeater extends InteractionWiredTrigger implements ICycleable, WiredTriggerReset { + public static final WiredTriggerType type = WiredTriggerType.PERIODICALLY; + public static final int DEFAULT_DELAY = 10 * 500; + + protected int repeatTime = DEFAULT_DELAY; + protected int counter = 0; + + public WiredTriggerRepeater(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredTriggerRepeater(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.repeatTime + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.repeatTime = data.repeatTime; + } else { + if (wiredData.length() >= 1) { + this.repeatTime = (Integer.valueOf(wiredData)); + } + } + + if (this.repeatTime < 500) { + this.repeatTime = 20 * 500; + } + } + + @Override + public void onPickUp() { + this.repeatTime = DEFAULT_DELAY; + this.counter = 0; + } + + @Override + public WiredTriggerType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.repeatTime / 500); + message.appendInt(0); + message.appendInt(this.getType().code); + + if (!this.isTriggeredByRoomUnit()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getEffects(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredEffect object) { + if (object.requiresTriggeringUser()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.repeatTime = packet.readInt() * 500; + this.counter = 0; + + if (this.repeatTime < 500) { + this.repeatTime = 500; + } + + return true; + } + + @Override + public void cycle(Room room) { + this.counter += 500; + long currentMillis = System.currentTimeMillis(); + String Key = Double.toString(this.getX()) + Double.toString(this.getY()); + + room.repeatersLastTick.putIfAbsent(Key, currentMillis); + + if (this.counter >= this.repeatTime && room.repeatersLastTick.get(Key) < currentMillis - 450) { + this.counter = 0; + if (this.getRoomId() != 0) { + if (room.isLoaded()) { + room.repeatersLastTick.put(Key, currentMillis); + WiredHandler.handle(this, null, room, new Object[]{this}); + } + } + } + } + + @Override + public void resetTimer() { + this.counter = 0; + if (this.getRoomId() != 0) { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room != null && room.isLoaded()) { + WiredHandler.handle(this, null, room, new Object[]{this}); + } + } + } + + static class JsonData { + int repeatTime; + + public JsonData(int repeatTime) { + this.repeatTime = repeatTime; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerRepeaterLong.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerRepeaterLong.java new file mode 100644 index 0000000..1480122 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerRepeaterLong.java @@ -0,0 +1,156 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.ICycleable; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.items.interactions.wired.WiredTriggerReset; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.procedure.TObjectProcedure; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class WiredTriggerRepeaterLong extends InteractionWiredTrigger implements ICycleable, WiredTriggerReset { + public static final int DEFAULT_DELAY = 10 * 5000; + private static final WiredTriggerType type = WiredTriggerType.PERIODICALLY_LONG; + private int repeatTime = DEFAULT_DELAY; + private int counter = 0; + + public WiredTriggerRepeaterLong(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredTriggerRepeaterLong(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + return true; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.repeatTime + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.repeatTime = data.repeatTime; + } else { + if (wiredData.length() >= 1) { + this.repeatTime = (Integer.valueOf(wiredData)); + } + } + + if (this.repeatTime < 5000) { + this.repeatTime = 20 * 5000; + } + } + + @Override + public void onPickUp() { + this.repeatTime = DEFAULT_DELAY; + } + + @Override + public WiredTriggerType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.repeatTime / 5000); + message.appendInt(0); + message.appendInt(this.getType().code); + + if (!this.isTriggeredByRoomUnit()) { + List invalidTriggers = new ArrayList<>(); + room.getRoomSpecialTypes().getEffects(this.getX(), this.getY()).forEach(new TObjectProcedure() { + @Override + public boolean execute(InteractionWiredEffect object) { + if (object.requiresTriggeringUser()) { + invalidTriggers.add(object.getBaseItem().getSpriteId()); + } + return true; + } + }); + message.appendInt(invalidTriggers.size()); + for (Integer i : invalidTriggers) { + message.appendInt(i); + } + } else { + message.appendInt(0); + } + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + + this.repeatTime = packet.readInt() * 5000; + this.counter = 0; + return true; + } + + + @Override + public void cycle(Room room) { + this.counter += 500; + long currentMillis = System.currentTimeMillis(); + String Key = Double.toString(this.getX()) + Double.toString(this.getY()); + + room.repeatersLastTick.putIfAbsent(Key, currentMillis); + + if (this.counter >= this.repeatTime && room.repeatersLastTick.get(Key) < currentMillis - 4950) { + this.counter = 0; + if (this.getRoomId() != 0) { + if (room.isLoaded()) { + room.repeatersLastTick.put(Key, currentMillis); + WiredHandler.handle(this, null, room, new Object[]{this}); + } + } + } + } + + @Override + public void resetTimer() { + this.counter = 0; + if (this.getRoomId() != 0) { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room != null && room.isLoaded()) { + WiredHandler.handle(this, null, room, new Object[]{this}); + } + } + } + + static class JsonData { + int repeatTime; + + public JsonData(int repeatTime) { + this.repeatTime = repeatTime; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerScoreAchieved.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerScoreAchieved.java new file mode 100644 index 0000000..1f558d8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerScoreAchieved.java @@ -0,0 +1,106 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.ServerMessage; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredTriggerScoreAchieved extends InteractionWiredTrigger { + private static final WiredTriggerType type = WiredTriggerType.SCORE_ACHIEVED; + private int score = 0; + + public WiredTriggerScoreAchieved(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredTriggerScoreAchieved(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { + if (stuff.length >= 2) { + int points = (Integer) stuff[0]; + int amountAdded = (Integer) stuff[1]; + + return points - amountAdded < this.score && points >= this.score; + } + + return false; + } + + @Override + public String getWiredData() { + return WiredHandler.getGsonBuilder().create().toJson(new JsonData( + this.score + )); + } + + @Override + public void loadWiredData(ResultSet set, Room room) throws SQLException { + String wiredData = set.getString("wired_data"); + + if (wiredData.startsWith("{")) { + JsonData data = WiredHandler.getGsonBuilder().create().fromJson(wiredData, JsonData.class); + this.score = data.score; + } else { + try { + this.score = Integer.parseInt(wiredData); + } catch (Exception e) { + } + } + } + + @Override + public void onPickUp() { + this.score = 0; + } + + @Override + public WiredTriggerType getType() { + return type; + } + + @Override + public void serializeWiredData(ServerMessage message, Room room) { + message.appendBoolean(false); + message.appendInt(5); + message.appendInt(0); + message.appendInt(this.getBaseItem().getSpriteId()); + message.appendInt(this.getId()); + message.appendString(""); + message.appendInt(1); + message.appendInt(this.score); + message.appendInt(0); + message.appendInt(this.getType().code); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public boolean saveData(ClientMessage packet) { + packet.readInt(); + this.score = packet.readInt(); + return true; + } + + @Override + public boolean isTriggeredByRoomUnit() { + return true; + } + + static class JsonData { + int score; + + public JsonData(int score) { + this.score = score; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerTeamLoses.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerTeamLoses.java new file mode 100644 index 0000000..feee267 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerTeamLoses.java @@ -0,0 +1,22 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredTriggerTeamLoses extends WiredTriggerGameStarts { + public WiredTriggerTeamLoses(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredTriggerTeamLoses(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public WiredTriggerType getType() { + return WiredTriggerType.CUSTOM; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerTeamWins.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerTeamWins.java new file mode 100644 index 0000000..afe8124 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/triggers/WiredTriggerTeamWins.java @@ -0,0 +1,22 @@ +package com.eu.habbo.habbohotel.items.interactions.wired.triggers; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WiredTriggerTeamWins extends WiredTriggerGameStarts { + public WiredTriggerTeamWins(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem); + } + + public WiredTriggerTeamWins(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells); + } + + @Override + public WiredTriggerType getType() { + return WiredTriggerType.CUSTOM; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/FriendRequest.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/FriendRequest.java new file mode 100644 index 0000000..705fdae --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/FriendRequest.java @@ -0,0 +1,34 @@ +package com.eu.habbo.habbohotel.messenger; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class FriendRequest { + private int id; + private String username; + private String look; + + public FriendRequest(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.username = set.getString("username"); + this.look = set.getString("look"); + } + + public FriendRequest(int id, String username, String look) { + this.id = id; + this.username = username; + this.look = look; + } + + public int getId() { + return this.id; + } + + public String getUsername() { + return this.username; + } + + public String getLook() { + return this.look; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/Message.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/Message.java new file mode 100644 index 0000000..5008963 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/Message.java @@ -0,0 +1,59 @@ +package com.eu.habbo.habbohotel.messenger; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class Message implements Runnable { + private final int fromId; + private final int toId; + private final int timestamp; + private String message; + + public Message(int fromId, int toId, String message) { + this.fromId = fromId; + this.toId = toId; + this.message = message; + + this.timestamp = Emulator.getIntUnixTimestamp(); + } + + @Override + public void run() { + //TODO Turn into scheduler + if (Messenger.SAVE_PRIVATE_CHATS) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO chatlogs_private (user_from_id, user_to_id, message, timestamp) VALUES (?, ?, ?, ?)")) { + statement.setInt(1, this.fromId); + statement.setInt(2, this.toId); + statement.setString(3, this.message); + statement.setInt(4, this.timestamp); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public int getToId() { + return this.toId; + } + + public int getFromId() { + return this.fromId; + } + + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + + public int getTimestamp() { + return this.timestamp; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/Messenger.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/Messenger.java new file mode 100644 index 0000000..a297ffa --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/Messenger.java @@ -0,0 +1,412 @@ +package com.eu.habbo.habbohotel.messenger; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.eu.habbo.messages.outgoing.friends.UpdateFriendComposer; +import com.eu.habbo.plugin.events.users.friends.UserAcceptFriendRequestEvent; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; +import org.apache.commons.lang3.StringUtils; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Slf4j +public class Messenger { + //Configuration. Loaded from database & updated accordingly. + public static boolean SAVE_PRIVATE_CHATS = false; + public static int MAXIMUM_FRIENDS = 200; + public static int MAXIMUM_FRIENDS_HC = 500; + + private final ConcurrentHashMap friends; + private final THashSet friendRequests; + + public Messenger() { + this.friends = new ConcurrentHashMap<>(); + this.friendRequests = new THashSet<>(); + } + + public static void unfriend(int userOne, int userTwo) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM messenger_friendships WHERE (user_one_id = ? AND user_two_id = ?) OR (user_one_id = ? AND user_two_id = ?)")) { + statement.setInt(1, userOne); + statement.setInt(2, userTwo); + statement.setInt(3, userTwo); + statement.setInt(4, userOne); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public static THashSet searchUsers(String username) { + THashSet users = new THashSet<>(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM users WHERE username LIKE ? ORDER BY username ASC LIMIT " + Emulator.getConfig().getInt("hotel.messenger.search.maxresults"))) { + statement.setString(1, username + "%"); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + users.add(new MessengerBuddy(set, false)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + return users; + } + + /** + * @deprecated + * This method is no longer used and is only kept to avoid breaking any plugins + */ + @Deprecated + public static boolean canFriendRequest(Habbo habbo, String friend) { + Habbo user = Emulator.getGameEnvironment().getHabboManager().getHabbo(friend); + HabboInfo habboInfo; + + if (user != null) { + habboInfo = user.getHabboInfo(); + } else { + habboInfo = HabboManager.getOfflineHabboInfo(friend); + } + + if (habboInfo == null) { + return false; + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM messenger_friendrequests WHERE (user_to_id = ? AND user_from_id = ?) OR (user_to_id = ? AND user_from_id = ?) LIMIT 1")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + statement.setInt(2, habboInfo.getId()); + statement.setInt(3, habboInfo.getId()); + statement.setInt(4, habbo.getHabboInfo().getId()); + try (ResultSet set = statement.executeQuery()) { + if (!set.next()) { + return true; + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return false; + } + + public static boolean friendRequested(int userFrom, int userTo) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM messenger_friendrequests WHERE user_to_id = ? AND user_from_id = ? LIMIT 1")) { + statement.setInt(1, userFrom); + statement.setInt(2, userTo); + + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + return true; + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return false; + } + + public static void makeFriendRequest(int userFrom, int userTo) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO messenger_friendrequests (user_to_id, user_from_id) VALUES (?, ?)")) { + statement.setInt(1, userTo); + statement.setInt(2, userFrom); + statement.executeUpdate(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public static int getFriendCount(int userId) { + Habbo habbo = Emulator.getGameServer().getGameClientManager().getHabbo(userId); + + if (habbo != null) + return habbo.getMessenger().getFriends().size(); + + int count = 0; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT count(id) as count FROM messenger_friendships WHERE user_one_id = ?")) { + statement.setInt(1, userId); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) + count = set.getInt("count"); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return count; + } + + public static THashMap> getFriends(int userId) { + THashMap> map = new THashMap<>(); + map.put(1, new THashSet<>()); + map.put(2, new THashSet<>()); + map.put(3, new THashSet<>()); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.id, users.look, users.username, messenger_friendships.relation FROM messenger_friendships INNER JOIN users ON users.id = messenger_friendships.user_two_id WHERE user_one_id = ? ORDER BY RAND() LIMIT 50")) { + statement.setInt(1, userId); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + if (set.getInt("relation") == 0) + continue; + + MessengerBuddy buddy = new MessengerBuddy(set.getInt("id"), set.getString("username"), set.getString("look"), (short) set.getInt("relation"), userId); + map.get((int) buddy.getRelation()).add(buddy); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + return map; + } + + public static void checkFriendSizeProgress(Habbo habbo) { + int progress = habbo.getHabboStats().getAchievementProgress(Emulator.getGameEnvironment().getAchievementManager().getAchievement("FriendListSize")); + + int toProgress = 1; + + Achievement achievement = Emulator.getGameEnvironment().getAchievementManager().getAchievement("FriendListSize"); + + if (achievement == null) + return; + + if (progress > 0) { + toProgress = habbo.getMessenger().getFriends().size() - progress; + + if (toProgress < 0) { + return; + } + } + + AchievementManager.progressAchievement(habbo, achievement, toProgress); + } + + public void loadFriends(Habbo habbo) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("SELECT " + + "users.id, " + + "users.username, " + + "users.gender, " + + "users.online, " + + "users.look, " + + "users.motto, " + + "messenger_friendships.* FROM messenger_friendships INNER JOIN users ON messenger_friendships.user_two_id = users.id WHERE user_one_id = ?")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + MessengerBuddy buddy = new MessengerBuddy(set); + + if (buddy.getId() == habbo.getHabboInfo().getId()) { + continue; + } + + this.friends.putIfAbsent(set.getInt("id"), buddy); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public MessengerBuddy loadFriend(Habbo habbo, int userId) { + MessengerBuddy buddy = null; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT " + + "users.id, " + + "users.username, " + + "users.gender, " + + "users.online, " + + "users.look, " + + "users.motto, " + + "messenger_friendships.* FROM messenger_friendships INNER JOIN users ON messenger_friendships.user_two_id = users.id WHERE user_one_id = ? AND user_two_id = ? LIMIT 1")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + statement.setInt(2, userId); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + buddy = new MessengerBuddy(set); + this.friends.putIfAbsent(set.getInt("id"), buddy); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return buddy; + } + + public void loadFriendRequests(Habbo habbo) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.id, users.username, users.look FROM messenger_friendrequests INNER JOIN users ON user_from_id = users.id WHERE user_to_id = ?")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + this.friendRequests.add(new FriendRequest(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void removeBuddy(int id) { + this.friends.remove(id); + } + + public void removeBuddy(Habbo habbo) { + this.friends.remove(habbo.getHabboInfo().getId()); + } + + public void addBuddy(MessengerBuddy buddy) { + this.friends.put(buddy.getId(), buddy); + } + + public THashSet getFriends(String username) { + THashSet users = new THashSet<>(); + + for (Map.Entry map : this.friends.entrySet()) { + if (StringUtils.containsIgnoreCase(map.getValue().getUsername(), username)) { + users.add(map.getValue()); + } + } + + return users; + } + + public void connectionChanged(Habbo owner, boolean online, boolean inRoom) { + if (owner != null) { + for (Map.Entry map : this.getFriends().entrySet()) { + if (map.getValue().getOnline() == 0) + continue; + + Habbo habbo = Emulator.getGameServer().getGameClientManager().getHabbo(map.getKey()); + + if (habbo != null) { + if (habbo.getMessenger() != null) { + MessengerBuddy buddy = habbo.getMessenger().getFriend(owner.getHabboInfo().getId()); + + if (buddy != null) { + buddy.setOnline(online); + buddy.inRoom(inRoom); + buddy.setLook(owner.getHabboInfo().getLook()); + buddy.setGender(owner.getHabboInfo().getGender()); + buddy.setUsername(owner.getHabboInfo().getUsername()); + habbo.getClient().sendResponse(new UpdateFriendComposer(habbo, buddy, 0)); + } + } + } + } + } + } + + public void deleteAllFriendRequests(int userTo) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM messenger_friendrequests WHERE user_to_id = ?")) { + statement.setInt(1, userTo); + statement.executeUpdate(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public int deleteFriendRequests(int userFrom, int userTo) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM messenger_friendrequests WHERE (user_to_id = ? AND user_from_id = ?) OR (user_to_id = ? AND user_from_id = ?)")) { + statement.setInt(1, userTo); + statement.setInt(2, userFrom); + statement.setInt(4, userTo); + statement.setInt(3, userFrom); + return statement.executeUpdate(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return 0; + } + + //TODO Needs redesign. userFrom is redundant. + public void acceptFriendRequest(int userFrom, int userTo) { + int count = this.deleteFriendRequests(userFrom, userTo); + + if (count > 0) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO messenger_friendships (user_one_id, user_two_id, friends_since) VALUES (?, ?, ?)")) { + statement.setInt(1, userFrom); + statement.setInt(2, userTo); + statement.setInt(3, Emulator.getIntUnixTimestamp()); + statement.execute(); + + statement.setInt(1, userTo); + statement.setInt(2, userFrom); + statement.setInt(3, Emulator.getIntUnixTimestamp()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + Habbo habboTo = Emulator.getGameServer().getGameClientManager().getHabbo(userTo); + Habbo habboFrom = Emulator.getGameServer().getGameClientManager().getHabbo(userFrom); + + if (habboTo != null && habboFrom != null) { + MessengerBuddy to = new MessengerBuddy(habboFrom, habboTo.getHabboInfo().getId()); + MessengerBuddy from = new MessengerBuddy(habboTo, habboFrom.getHabboInfo().getId()); + + + habboTo.getMessenger().friends.putIfAbsent(habboFrom.getHabboInfo().getId(), to); + habboFrom.getMessenger().friends.putIfAbsent(habboTo.getHabboInfo().getId(), from); + + if (Emulator.getPluginManager().fireEvent(new UserAcceptFriendRequestEvent(habboTo, from)).isCancelled()) { + this.removeBuddy(userTo); + return; + } + + habboTo.getClient().sendResponse(new UpdateFriendComposer(habboTo, to, 1)); + habboFrom.getClient().sendResponse(new UpdateFriendComposer(habboFrom, from, 1)); + } else if (habboTo != null) { + habboTo.getClient().sendResponse(new UpdateFriendComposer(habboTo, this.loadFriend(habboTo, userFrom), 1)); + } else if (habboFrom != null) { + habboFrom.getClient().sendResponse(new UpdateFriendComposer(habboFrom, this.loadFriend(habboFrom, userTo), 1)); + } + } + } + + public ConcurrentHashMap getFriends() { + return this.friends; + } + + public THashSet getFriendRequests() { + synchronized (this.friendRequests) { + return this.friendRequests; + } + } + + public FriendRequest findFriendRequest(String username) { + synchronized (this.friendRequests) { + for (FriendRequest friendRequest : this.friendRequests) { + if (friendRequest.getUsername().equalsIgnoreCase(username)) { + return friendRequest; + } + } + } + + return null; + } + + public MessengerBuddy getFriend(int id) { + return this.friends.get(id); + } + + public void dispose() { + synchronized (this.friends) { + this.friends.clear(); + } + + synchronized (this.friendRequests) { + this.friendRequests.clear(); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/MessengerBuddy.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/MessengerBuddy.java new file mode 100644 index 0000000..9447e8e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/MessengerBuddy.java @@ -0,0 +1,194 @@ +package com.eu.habbo.habbohotel.messenger; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.WordFilter; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.friends.FriendChatMessageComposer; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class MessengerBuddy implements Runnable, ISerialize { + private int id; + private String username; + private HabboGender gender = HabboGender.M; + private int online = 0; + private String look = ""; + private String motto = ""; + private short relation; + private int categoryId = 0; + private boolean inRoom; + private int userOne = 0; + + public MessengerBuddy(ResultSet set) { + try { + this.id = set.getInt("id"); + this.username = set.getString("username"); + this.gender = HabboGender.valueOf(set.getString("gender")); + this.online = set.getInt("online"); + this.motto = set.getString("motto"); + this.look = set.getString("look"); + this.relation = (short) set.getInt("relation"); + this.categoryId = set.getInt("category"); + this.userOne = set.getInt("user_one_id"); + this.inRoom = false; + if (this.online == 1) { + Habbo habbo = Emulator.getGameServer().getGameClientManager().getHabbo(this.username); + + if (habbo != null) { + this.inRoom = habbo.getHabboInfo().getCurrentRoom() != null; + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public MessengerBuddy(ResultSet set, boolean value) { + try { + this.id = set.getInt("id"); + this.username = set.getString("username"); + this.look = set.getString("look"); + this.relation = 0; + this.userOne = 0; + this.online = set.getInt("online"); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public MessengerBuddy(int id, String username, String look, Short relation, int userOne) { + this.id = id; + this.username = username; + this.gender = HabboGender.M; + this.online = 0; + this.motto = ""; + this.look = look; + this.relation = relation; + this.userOne = userOne; + } + + public MessengerBuddy(Habbo habbo, int userOne) { + this.id = habbo.getHabboInfo().getId(); + this.username = habbo.getHabboInfo().getUsername(); + this.gender = habbo.getHabboInfo().getGender(); + this.online = habbo.getHabboInfo().isOnline() ? 1 : 0; + this.motto = habbo.getHabboInfo().getMotto(); + this.look = habbo.getHabboInfo().getLook(); + this.relation = 0; + this.userOne = userOne; + this.inRoom = habbo.getHabboInfo().getCurrentRoom() != null; + } + + public int getId() { + return this.id; + } + + public String getUsername() { + return this.username; + } + + public void setUsername(String username) { + this.username = username; + } + + public HabboGender getGender() { + return this.gender; + } + + public void setGender(HabboGender gender) { + this.gender = gender; + } + + public int getOnline() { + return this.online; + } + + public void setOnline(boolean value) { + this.online = (value ? 1 : 0); + } + + public String getLook() { + return this.look; + } + + public void setLook(String look) { + this.look = look; + } + + public String getMotto() { + return this.motto; + } + + public short getRelation() { + return this.relation; + } + + public void setRelation(int relation) { + this.relation = (short) relation; + Emulator.getThreading().run(this); + } + + public int getCategoryId() { return this.categoryId; } + + public boolean inRoom() { + return this.inRoom; + } + + public void inRoom(boolean value) { + this.inRoom = value; + } + + @Override + public void run() { + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE messenger_friendships SET relation = ? WHERE user_one_id = ? AND user_two_id = ?")) { + statement.setInt(1, this.relation); + statement.setInt(2, this.userOne); + statement.setInt(3, this.id); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void onMessageReceived(Habbo from, String message) { + Habbo habbo = Emulator.getGameServer().getGameClientManager().getHabbo(this.id); + + if (habbo == null) + return; + + Message chatMessage = new Message(from.getHabboInfo().getId(), this.id, message); + Emulator.getThreading().run(chatMessage); + + if (WordFilter.ENABLED_FRIENDCHAT) { + chatMessage.setMessage(Emulator.getGameEnvironment().getWordFilter().filter(chatMessage.getMessage(), from)); + } + + habbo.getClient().sendResponse(new FriendChatMessageComposer(chatMessage)); + } + + @Override + public void serialize(ServerMessage message) { + message.appendInt(this.id); + message.appendString(this.username); + message.appendInt(this.gender.equals(HabboGender.M) ? 0 : 1); + message.appendBoolean(this.online == 1); + message.appendBoolean(this.inRoom); //IN ROOM + message.appendString(this.look); + message.appendInt(this.categoryId); // Friends category ID + message.appendString(this.motto); + message.appendString(""); //Last seen as DATETIMESTRING + message.appendString(""); // Realname or Facebookame as String + message.appendBoolean(false); //Offline messaging. + message.appendBoolean(false); + message.appendBoolean(false); + message.appendShort(this.relation); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/MessengerCategory.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/MessengerCategory.java new file mode 100644 index 0000000..b19a43b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/messenger/MessengerCategory.java @@ -0,0 +1,31 @@ +package com.eu.habbo.habbohotel.messenger; + +public class MessengerCategory { + private int user_id; + private String name; + private int id; + + public MessengerCategory(String name, int user_id, int id) { + this.name = name; + this.user_id = user_id; + this.id = id; + } + + public String getName() { + return name; + } + + public int getUserId() { + return user_id; + } + + public int getId() { + return id; + } + + public void setName(String name) { + this.name = name; + } + public void setId(int id) { this.id = id; } +} + diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/CfhActionType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/CfhActionType.java new file mode 100644 index 0000000..2c6f95d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/CfhActionType.java @@ -0,0 +1,34 @@ +package com.eu.habbo.habbohotel.modtool; + +public enum CfhActionType { + MODS(0), + AUTO_REPLY(1), + AUTO_IGNORE(2), + GUARDIANS(3); + + public final int type; + + CfhActionType(int type) { + this.type = type; + } + + public static CfhActionType get(String name) { + switch (name) { + case "auto_reply": + return CfhActionType.AUTO_REPLY; + + case "auto_ignore": + return CfhActionType.AUTO_IGNORE; + + case "guardians": + return CfhActionType.GUARDIANS; + } + + return CfhActionType.MODS; + } + + @Override + public String toString() { + return this.name().toLowerCase(); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/CfhCategory.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/CfhCategory.java new file mode 100644 index 0000000..dfb196d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/CfhCategory.java @@ -0,0 +1,29 @@ +package com.eu.habbo.habbohotel.modtool; + +import gnu.trove.TCollections; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.TIntObjectHashMap; + +public class CfhCategory { + private final int id; + private final String name; + private final TIntObjectMap topics; + + public CfhCategory(int id, String name) { + this.id = id; + this.name = name; + this.topics = TCollections.synchronizedMap(new TIntObjectHashMap<>()); + } + + public void addTopic(CfhTopic topic) { + this.topics.put(topic.id, topic); + } + + public TIntObjectMap getTopics() { + return this.topics; + } + + public String getName() { + return this.name; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/CfhTopic.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/CfhTopic.java new file mode 100644 index 0000000..1a7f3be --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/CfhTopic.java @@ -0,0 +1,22 @@ +package com.eu.habbo.habbohotel.modtool; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class CfhTopic { + public final int id; + public final String name; + public final CfhActionType action; + public final boolean ignoreTarget; + public final String reply; + public final ModToolPreset defaultSanction; + + public CfhTopic(ResultSet set, ModToolPreset defaultSanction) throws SQLException { + this.id = set.getInt("id"); + this.name = set.getString("name_internal"); + this.action = CfhActionType.get(set.getString("action")); + this.ignoreTarget = set.getString("ignore_target").equalsIgnoreCase("1"); + this.reply = set.getString("auto_reply"); + this.defaultSanction = defaultSanction; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolBan.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolBan.java new file mode 100644 index 0000000..26be296 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolBan.java @@ -0,0 +1,83 @@ +package com.eu.habbo.habbohotel.modtool; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.SimpleDateFormat; + +@Slf4j +public class ModToolBan implements Runnable { + public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public int userId; + public String ip; + public String machineId; + public int staffId; + public int expireDate; + public int timestamp; + public String reason; + public ModToolBanType type; + public int cfhTopic; + + private boolean needsInsert; + + public ModToolBan(ResultSet set) throws SQLException { + this.userId = set.getInt("user_id"); + this.ip = set.getString("ip"); + this.machineId = set.getString("machine_id"); + this.staffId = set.getInt("user_staff_id"); + this.timestamp = set.getInt("timestamp"); + this.expireDate = set.getInt("ban_expire"); + this.reason = set.getString("ban_reason"); + this.type = ModToolBanType.fromString(set.getString("type")); + this.cfhTopic = set.getInt("cfh_topic"); + this.needsInsert = false; + } + + public ModToolBan(int userId, String ip, String machineId, int staffId, int expireDate, String reason, ModToolBanType type, int cfhTopic) { + this.userId = userId; + this.staffId = staffId; + this.timestamp = Emulator.getIntUnixTimestamp(); + this.expireDate = expireDate; + this.reason = reason; + this.ip = ip; + this.machineId = machineId; + this.type = type; + this.cfhTopic = cfhTopic; + this.needsInsert = true; + } + + @Override + public void run() { + if (this.needsInsert) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO bans (user_id, ip, machine_id, user_staff_id, timestamp, ban_expire, ban_reason, type, cfh_topic) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")) { + statement.setInt(1, this.userId); + statement.setString(2, this.ip); + statement.setString(3, this.machineId); + statement.setInt(4, this.staffId); + statement.setInt(5, Emulator.getIntUnixTimestamp()); + statement.setInt(6, this.expireDate); + statement.setString(7, this.reason); + statement.setString(8, this.type.getType()); + statement.setInt(9, this.cfhTopic); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public String listInfo() { + return "Banned User Id: " + this.userId + "\r" + + "Type: " + this.type.getType() + "\r" + + "Reason: " + "" + this.reason + "" + "\r" + + "Moderator Id: " + this.staffId + "\r" + + "Date: " + dateFormat.format(this.timestamp * 1000L) + "\r" + + "Expire Date: " + dateFormat.format(this.expireDate * 1000L) + "\r" + + "IP: " + this.ip + "\r" + + "MachineID: " + this.machineId + "\r" + + "Topic: " + this.cfhTopic; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolBanType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolBanType.java new file mode 100644 index 0000000..76c0142 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolBanType.java @@ -0,0 +1,29 @@ +package com.eu.habbo.habbohotel.modtool; + +public enum ModToolBanType { + ACCOUNT("account"), + MACHINE("machine"), + SUPER("super"), + IP("ip"), + UNKNOWN("???"); + + private final String type; + + ModToolBanType(String type) { + this.type = type; + } + + public static ModToolBanType fromString(String type) { + for (ModToolBanType t : ModToolBanType.values()) { + if (t.type.equalsIgnoreCase(type)) { + return t; + } + } + + return UNKNOWN; + } + + public String getType() { + return this.type; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolCategory.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolCategory.java new file mode 100644 index 0000000..10e28a8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolCategory.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.modtool; + +import gnu.trove.TCollections; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.TIntObjectHashMap; + +public class ModToolCategory { + private final String name; + private final TIntObjectMap presets; + + public ModToolCategory(String name) { + this.name = name; + this.presets = TCollections.synchronizedMap(new TIntObjectHashMap<>()); + } + + public void addPreset(ModToolPreset preset) { + this.presets.put(preset.id, preset); + } + + public TIntObjectMap getPresets() { + return this.presets; + } + + public String getName() { + return this.name; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolChatLog.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolChatLog.java new file mode 100644 index 0000000..0ba469f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolChatLog.java @@ -0,0 +1,30 @@ +package com.eu.habbo.habbohotel.modtool; + +public class ModToolChatLog implements Comparable { + public final int timestamp; + public final int habboId; + public final String username; + public final String message; + public final boolean highlighted; + + public ModToolChatLog(int timestamp, int habboId, String username, String message) { + this.timestamp = timestamp; + this.habboId = habboId; + this.username = username; + this.message = message; + this.highlighted = false; + } + + public ModToolChatLog(int timestamp, int habboId, String username, String message, boolean highlighted) { + this.timestamp = timestamp; + this.habboId = habboId; + this.username = username; + this.message = message; + this.highlighted = highlighted; + } + + @Override + public int compareTo(ModToolChatLog o) { + return o.timestamp - this.timestamp; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolChatRecordDataContext.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolChatRecordDataContext.java new file mode 100644 index 0000000..3790848 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolChatRecordDataContext.java @@ -0,0 +1,25 @@ +package com.eu.habbo.habbohotel.modtool; + +import com.eu.habbo.messages.ServerMessage; + +public enum ModToolChatRecordDataContext { + ROOM_NAME("roomName", 2), + ROOM_ID("roomId", 1), + GROUP_ID("groupId", 1), + THREAD_ID("threadId", 1), + MESSAGE_ID("messageId", 1), + PHOTO_ID("extraDataId", 2); + + public final String key; + public final int type; + + ModToolChatRecordDataContext(String key, int type) { + this.key = key; + this.type = type; + } + + public void append(final ServerMessage message) { + message.appendString(this.key); + message.appendByte(this.type); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolChatRecordDataType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolChatRecordDataType.java new file mode 100644 index 0000000..8d08a88 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolChatRecordDataType.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.modtool; + +public enum ModToolChatRecordDataType { + UNKNOWN(0), + ROOM_TOOL(1), + IM_SESSION(2), + FORUM_THREAD(3), + FORUM_MESSAGE(4), + SELFIE(5), + PHOTO_REPORT(6); + + public final int type; + + ModToolChatRecordDataType(int type) { + this.type = type; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolChatlogType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolChatlogType.java new file mode 100644 index 0000000..b3cac44 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolChatlogType.java @@ -0,0 +1,13 @@ +package com.eu.habbo.habbohotel.modtool; + +public enum ModToolChatlogType { + BOT_PET(0), + YELLOW(1), + BLUE(2); + + public final int type; + + ModToolChatlogType(int type) { + this.type = type; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolIssue.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolIssue.java new file mode 100644 index 0000000..f9b008d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolIssue.java @@ -0,0 +1,111 @@ +package com.eu.habbo.habbohotel.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.threading.runnables.UpdateModToolIssue; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; + +public class ModToolIssue implements ISerialize { + public int id; + public volatile ModToolTicketState state; + public volatile ModToolTicketType type; + public int category; + public int timestamp; + public volatile int priority; + public int reportedId; + public String reportedUsername; + public int roomId; + public int senderId; + public String senderUsername; + public volatile int modId = -1; + public volatile String modName = ""; + public String message; + public ArrayList chatLogs = null; + public int groupId = -1; + public int threadId = -1; + public int commentId = -1; + public HabboItem photoItem = null; + + public ModToolIssue(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.state = ModToolTicketState.getState(set.getInt("state")); + this.timestamp = set.getInt("timestamp"); + this.priority = set.getInt("score"); + this.senderId = set.getInt("sender_id"); + this.senderUsername = set.getString("sender_username"); + this.reportedId = set.getInt("reported_id"); + this.reportedUsername = set.getString("reported_username"); + this.message = set.getString("issue"); + this.modId = set.getInt("mod_id"); + this.modName = set.getString("mod_username"); + this.type = ModToolTicketType.values()[set.getInt("type") - 1]; + this.category = set.getInt("category"); + this.groupId = set.getInt("group_id"); + this.threadId = set.getInt("thread_id"); + this.commentId = set.getInt("comment_id"); + + int photoItemId = set.getInt("photo_item_id"); + + if (photoItemId != -1) { + this.photoItem = Emulator.getGameEnvironment().getItemManager().loadHabboItem(photoItemId); + } + + if (this.modId <= 0) { + this.modName = ""; + this.state = ModToolTicketState.OPEN; + } + } + + public ModToolIssue(int senderId, String senderUserName, int reportedId, String reportedUsername, int reportedRoomId, String message, ModToolTicketType type) { + this.state = ModToolTicketState.OPEN; + this.timestamp = Emulator.getIntUnixTimestamp(); + this.priority = 0; + this.senderId = senderId; + this.senderUsername = senderUserName; + this.reportedUsername = reportedUsername; + this.reportedId = reportedId; + this.roomId = reportedRoomId; + this.message = message; + this.type = type; + this.category = 1; + } + + @Override + public void serialize(ServerMessage message) { + message.appendInt(this.id); //ID + message.appendInt(this.state.getState()); //STATE + message.appendInt(this.type.getType()); //TYPE + message.appendInt(this.category); //CATEGORY ID + message.appendInt(((Emulator.getIntUnixTimestamp() - this.timestamp))); //TIME IN MS AGO + message.appendInt(this.priority); //PRIORITY + message.appendInt(1); + message.appendInt(this.senderId); //Reporter user ID + message.appendString(this.senderUsername); //Reporter user name. + message.appendInt(this.reportedId); //Reported user ID. + message.appendString(this.reportedUsername); //Reported user name. + message.appendInt(this.modId); //ADMIN User ID? + message.appendString(this.modName); //ADMIN User name? + message.appendString(this.message); + message.appendInt(0); + + if (this.chatLogs != null) { + message.appendInt(this.chatLogs.size()); + for (ModToolChatLog chatLog : this.chatLogs) { + message.appendString(chatLog.message); + message.appendInt(0); + message.appendInt(chatLog.message.length()); + } + } else { + message.appendInt(0); + } + } + + public void updateInDatabase() { + Emulator.getThreading().run(new UpdateModToolIssue(this)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolIssueChatlogType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolIssueChatlogType.java new file mode 100644 index 0000000..35db44b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolIssueChatlogType.java @@ -0,0 +1,21 @@ +package com.eu.habbo.habbohotel.modtool; + +public enum ModToolIssueChatlogType { + NORMAL(0), + CHAT(1), + IM(2), + FORUM_THREAD(3), + FORUM_COMMENT(4), + SELFIE(5), + PHOTO(6); + + private int type; + + ModToolIssueChatlogType(int type) { + this.type = type; + } + + public int getType() { + return type; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolManager.java new file mode 100644 index 0000000..73764c0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolManager.java @@ -0,0 +1,725 @@ +package com.eu.habbo.habbohotel.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomState; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.outgoing.modtool.ModToolIssueHandledComposer; +import com.eu.habbo.messages.outgoing.modtool.ModToolIssueInfoComposer; +import com.eu.habbo.messages.outgoing.modtool.ModToolUserInfoComposer; +import com.eu.habbo.plugin.events.support.*; +import com.eu.habbo.threading.runnables.InsertModToolIssue; +import gnu.trove.TCollections; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; +import io.netty.channel.Channel; +import lombok.extern.slf4j.Slf4j; +import java.net.InetSocketAddress; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Slf4j +public class ModToolManager { + private final TIntObjectMap category; + private final THashMap> presets; + private final THashMap tickets; + private final TIntObjectMap cfhCategories; + + public ModToolManager() { + long millis = System.currentTimeMillis(); + this.category = TCollections.synchronizedMap(new TIntObjectHashMap<>()); + this.presets = new THashMap<>(); + this.tickets = new THashMap<>(); + this.cfhCategories = new TIntObjectHashMap<>(); + this.loadModTool(); + log.info("ModTool Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)"); + } + + public static void requestUserInfo(GameClient client, ClientMessage packet) { + int userId = packet.readInt(); + + if (userId <= 0) + return; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.*, users_settings.*, permissions.rank_name, permissions.acc_hide_mail AS hide_mail, permissions.id AS rank_id FROM users INNER JOIN users_settings ON users.id = users_settings.user_id INNER JOIN permissions ON permissions.id = users.rank WHERE users.id = ? LIMIT 1")) { + statement.setInt(1, userId); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + client.sendResponse(new ModToolUserInfoComposer(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + public synchronized void loadModTool() { + this.category.clear(); + this.presets.clear(); + this.cfhCategories.clear(); + + this.presets.put("user", new THashSet<>()); + this.presets.put("room", new THashSet<>()); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + this.loadCategory(connection); + this.loadPresets(connection); + this.loadTickets(connection); + this.loadCfhCategories(connection); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + private void loadCategory(Connection connection) { + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM support_issue_categories")) { + while (set.next()) { + this.category.put(set.getInt("id"), new ModToolCategory(set.getString("name"))); + + try (PreparedStatement settings = connection.prepareStatement("SELECT * FROM support_issue_presets WHERE category = ?")) { + settings.setInt(1, set.getInt("id")); + try (ResultSet presets = settings.executeQuery()) { + while (presets.next()) { + this.category.get(set.getInt("id")).addPreset(new ModToolPreset(presets)); + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + private void loadPresets(Connection connection) { + synchronized (this.presets) { + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM support_presets")) { + while (set.next()) { + this.presets.get(set.getString("type")).add(set.getString("preset")); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + private void loadTickets(Connection connection) { + synchronized (this.tickets) { + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT S.username as sender_username, R.username AS reported_username, M.username as mod_username, support_tickets.* FROM support_tickets INNER JOIN users as S ON S.id = sender_id INNER JOIN users AS R ON R.id = reported_id INNER JOIN users AS M ON M.id = mod_id WHERE state != 0")) { + while (set.next()) { + this.tickets.put(set.getInt("id"), new ModToolIssue(set)); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + private void loadCfhCategories(Connection connection) { + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT " + + "support_cfh_topics.id, " + + "support_cfh_topics.category_id, " + + "support_cfh_topics.name_internal, " + + "support_cfh_topics.action, " + + "support_cfh_topics.auto_reply," + + "support_cfh_topics.ignore_target, " + + "support_cfh_categories.name_internal AS category_name_internal, " + + "support_cfh_categories.id AS support_cfh_category_id, " + + "support_cfh_topics.default_sanction AS default_sanction " + + "FROM support_cfh_topics " + + "LEFT JOIN support_cfh_categories ON support_cfh_categories.id = support_cfh_topics.category_id")) { + while (set.next()) { + if (!this.cfhCategories.containsKey(set.getInt("support_cfh_category_id"))) { + this.cfhCategories.put(set.getInt("support_cfh_category_id"), new CfhCategory(set.getInt("id"), set.getString("category_name_internal"))); + } + + this.cfhCategories.get(set.getInt("support_cfh_category_id")).addTopic(new CfhTopic(set, this.getIssuePreset(set.getInt("default_sanction")))); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public CfhTopic getCfhTopic(int topicId) { + for (CfhCategory category : this.getCfhCategories().valueCollection()) { + for (CfhTopic topic : category.getTopics().valueCollection()) { + if (topic.id == topicId) { + return topic; + } + } + } + + return null; + } + + public ModToolPreset getIssuePreset(int id) { + if (id == 0) + return null; + + final ModToolPreset[] preset = {null}; + this.category.forEachValue(new TObjectProcedure() { + @Override + public boolean execute(ModToolCategory object) { + preset[0] = object.getPresets().get(id); + return preset[0] == null; + } + }); + + return preset[0]; + } + + public void quickTicket(Habbo reported, String reason, String message) { + ModToolIssue issue = new ModToolIssue(0, reason, reported.getHabboInfo().getId(), reported.getHabboInfo().getUsername(), 0, message, ModToolTicketType.AUTOMATIC); + + Emulator.getGameEnvironment().getModToolManager().addTicket(issue); + Emulator.getGameEnvironment().getModToolManager().updateTicketToMods(issue); + } + + public ArrayList getRoomChatlog(int roomId) { + ArrayList chatlogs = new ArrayList<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.username, users.id, chatlogs_room.* FROM chatlogs_room INNER JOIN users ON users.id = chatlogs_room.user_from_id WHERE room_id = ? ORDER BY timestamp DESC LIMIT 150")) { + statement.setInt(1, roomId); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + chatlogs.add(new ModToolChatLog(set.getInt("timestamp"), set.getInt("id"), set.getString("username"), set.getString("message"))); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return chatlogs; + } + + public ArrayList getUserChatlog(int userId) { + ArrayList chatlogs = new ArrayList<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.username, users.id, chatlogs_room.* FROM chatlogs_room INNER JOIN users ON users.id = chatlogs_room.user_from_id WHERE user_from_id = ? ORDER BY chatlogs_room.timestamp DESC LIMIT 150")) { + statement.setInt(1, userId); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + chatlogs.add(new ModToolChatLog(set.getInt("timestamp"), set.getInt("id"), set.getString("username"), set.getString("message"))); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return chatlogs; + } + + public ArrayList getMessengerChatlog(int userOneId, int userTwoId) { + ArrayList chatLogs = new ArrayList<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.username, chatlogs_private.* FROM chatlogs_private INNER JOIN users ON users.id = user_from_id WHERE (user_from_id = ? AND user_to_id = ?) OR (user_from_id = ? AND user_to_id = ?) ORDER BY chatlogs_private.timestamp DESC LIMIT 50")) { + statement.setInt(1, userOneId); + statement.setInt(2, userTwoId); + statement.setInt(3, userTwoId); + statement.setInt(4, userOneId); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + chatLogs.add(new ModToolChatLog(set.getInt("timestamp"), set.getInt("chatlogs_private.user_from_id"), set.getString("users.username"), set.getString("message"))); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return chatLogs; + } + + public ArrayList getUserRoomVisitsAndChatlogs(int userId) { + ArrayList chatlogs = new ArrayList<>(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT rooms.name, users.username, room_enter_log.timestamp AS enter_timestamp, room_enter_log.exit_timestamp, chatlogs_room.* FROM room_enter_log INNER JOIN rooms ON room_enter_log.room_id = rooms.id INNER JOIN users ON room_enter_log.user_id = users.id LEFT JOIN chatlogs_room ON room_enter_log.user_id = chatlogs_room.user_from_id AND room_enter_log.room_id = chatlogs_room.room_id AND chatlogs_room.timestamp >= room_enter_log.timestamp AND chatlogs_room.timestamp < room_enter_log.exit_timestamp WHERE chatlogs_room.user_from_id = ? ORDER BY room_enter_log.timestamp DESC LIMIT 500")) { + statement.setInt(1, userId); + try (ResultSet set = statement.executeQuery()) { + int userid = 0; + String username = "unknown"; + + while (set.next()) { + ModToolRoomVisit visit = null; + + for (ModToolRoomVisit v : chatlogs) { + if (v.timestamp == set.getInt("enter_timestamp") && v.exitTimestamp == set.getInt("exit_timestamp")) { + visit = v; + } + } + + if (visit == null) { + visit = new ModToolRoomVisit(set.getInt("room_id"), set.getString("name"), set.getInt("enter_timestamp"), set.getInt("exit_timestamp")); + chatlogs.add(visit); + } + visit.chat.add(new ModToolChatLog(set.getInt("timestamp"), set.getInt("user_from_id"), set.getString("username"), set.getString("message"))); + + if (userid == 0) + userid = set.getInt("user_from_id"); + + if (username.equals("unknown")) + username = set.getString("username"); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return chatlogs; + } + + public THashSet getUserRoomVisits(int userId) { + THashSet roomVisits = new THashSet<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT rooms.name, room_enter_log.* FROM room_enter_log INNER JOIN rooms ON rooms.id = room_enter_log.room_id WHERE user_id = ? ORDER BY timestamp DESC LIMIT 50")) { + statement.setInt(1, userId); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + roomVisits.add(new ModToolRoomVisit(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return roomVisits; + } + + public THashSet getVisitsForRoom(Room room, int amount, boolean groupUser, int fromTimestamp, int toTimestamp) { + return this.getVisitsForRoom(room, amount, groupUser, fromTimestamp, toTimestamp, ""); + } + + public THashSet getVisitsForRoom(Room room, int amount, boolean groupUser, int fromTimestamp, int toTimestamp, String excludeUsername) { + THashSet roomVisits = new THashSet<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM (" + + "SELECT " + + "users.username as name, " + + "room_enter_log.* " + + "FROM" + + "`room_enter_log` " + + "INNER JOIN " + + "users " + + "ON " + + "users.id = room_enter_log.user_id " + + "WHERE " + + "room_enter_log.room_id = ? " + + (fromTimestamp > 0 ? "AND timestamp >= ? " : "") + + (toTimestamp > 0 ? "AND exit_timestamp <= ? " : "") + + "AND users.username != ? " + + "ORDER BY " + + "timestamp " + + "DESC LIMIT ?) x " + + (groupUser ? "GROUP BY user_id" : "") + + ";")) { + statement.setInt(1, room.getId()); + + if (fromTimestamp > 0) + statement.setInt(2, fromTimestamp); + + if (toTimestamp > 0) + statement.setInt((fromTimestamp > 0 ? 3 : 2), toTimestamp); + + statement.setString((toTimestamp > 0 ? fromTimestamp > 0 ? 4 : 3 : 2), excludeUsername); + + int columnAmount = 3; + if (fromTimestamp > 0) + columnAmount++; + + if (toTimestamp > 0) + columnAmount++; + + statement.setInt(columnAmount, amount); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + roomVisits.add(new ModToolRoomVisit(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return roomVisits; + } + + public ModToolBan createOfflineUserBan(int userId, int staffId, int duration, String reason, ModToolBanType type) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO bans (user_id, ip, machine_id, user_staff_id, ban_expire, ban_reason, type) VALUES (?, (SELECT ip_current FROM users WHERE id = ?), (SELECT machine_id FROM users WHERE id = ?), ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, userId); + statement.setInt(2, userId); + statement.setInt(3, userId); + statement.setInt(4, staffId); + statement.setInt(5, Emulator.getIntUnixTimestamp() + duration); + statement.setString(6, reason); + statement.setString(7, type.getType()); + + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + try (PreparedStatement selectBanStatement = connection.prepareStatement("SELECT * FROM bans WHERE id = ? LIMIT 1")) { + selectBanStatement.setInt(1, set.getInt(1)); + + try (ResultSet selectSet = selectBanStatement.executeQuery()) { + if (selectSet.next()) { + return new ModToolBan(selectSet); + } + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return null; + } + + public void alert(Habbo moderator, Habbo target, String message) { + alert(moderator, target, message, SupportUserAlertedReason.ALERT); + } + + public void alert(Habbo moderator, Habbo target, String message, SupportUserAlertedReason reason) { + if (!moderator.hasPermission(Permission.ACC_SUPPORTTOOL)) { + ScripterManager.scripterDetected(moderator.getClient(), Emulator.getTexts().getValue("scripter.warning.modtools.alert").replace("%username%", moderator.getHabboInfo().getUsername()).replace("%message%", message)); + return; + } + + SupportUserAlertedEvent alertedEvent = new SupportUserAlertedEvent(moderator, target, message, reason); + + if (Emulator.getPluginManager().fireEvent(alertedEvent).isCancelled()) + return; + + if (target != null) + alertedEvent.target.getClient().sendResponse(new ModToolIssueHandledComposer(alertedEvent.message)); + } + + public void kick(Habbo moderator, Habbo target, String message) { + if (moderator.hasPermission(Permission.ACC_SUPPORTTOOL) && !target.hasPermission(Permission.ACC_UNKICKABLE)) { + if (target.getHabboInfo().getCurrentRoom() != null) { + Emulator.getGameEnvironment().getRoomManager().leaveRoom(target, target.getHabboInfo().getCurrentRoom()); + } + this.alert(moderator, target, message, SupportUserAlertedReason.KICKED); + } + } + + public List ban(int targetUserId, Habbo moderator, String reason, int duration, ModToolBanType type, int cfhTopic) { + if (moderator == null) + return null; + + List bans = new ArrayList<>(); + Habbo target = Emulator.getGameEnvironment().getHabboManager().getHabbo(targetUserId); + HabboInfo offlineInfo = target != null ? target.getHabboInfo() : HabboManager.getOfflineHabboInfo(targetUserId); + + if (moderator.getHabboInfo().getRank().getId() < offlineInfo.getRank().getId()) { + return bans; + } + + //if machine id is empty, downgrade ban type to IP ban + if( (type == ModToolBanType.MACHINE || type == ModToolBanType.SUPER) && (offlineInfo == null || offlineInfo.getMachineID().isEmpty())) { + type = ModToolBanType.IP; + } + + //if ip address is empty, downgrade ban type to account ban + if( (type == ModToolBanType.IP || type == ModToolBanType.SUPER) && (offlineInfo == null || offlineInfo.getIpLogin().isEmpty())) { + type = ModToolBanType.ACCOUNT; + } + + ModToolBan ban = new ModToolBan(targetUserId, offlineInfo != null ? offlineInfo.getIpLogin() : "offline", offlineInfo != null ? offlineInfo.getMachineID() : "offline", moderator.getHabboInfo().getId(), Emulator.getIntUnixTimestamp() + duration, reason, type, cfhTopic); + Emulator.getPluginManager().fireEvent(new SupportUserBannedEvent(moderator, target, ban)); + Emulator.getThreading().run(ban); + bans.add(ban); + + if (target != null) { + Emulator.getGameServer().getGameClientManager().disposeClient(target.getClient()); + } + + if ((type == ModToolBanType.IP || type == ModToolBanType.SUPER) && target != null && !ban.ip.equals("offline")) { + for (Habbo h : Emulator.getGameServer().getGameClientManager().getHabbosWithIP(ban.ip)) { + if (h.getHabboInfo().getRank().getId() >= moderator.getHabboInfo().getRank().getId()) continue; + + ban = new ModToolBan(h.getHabboInfo().getId(), h != null ? h.getHabboInfo().getIpLogin() : "offline", h != null ? h.getClient().getMachineId() : "offline", moderator.getHabboInfo().getId(), Emulator.getIntUnixTimestamp() + duration, reason, type, cfhTopic); + Emulator.getPluginManager().fireEvent(new SupportUserBannedEvent(moderator, h, ban)); + Emulator.getThreading().run(ban); + bans.add(ban); + Emulator.getGameServer().getGameClientManager().disposeClient(h.getClient()); + } + } + + if ((type == ModToolBanType.MACHINE || type == ModToolBanType.SUPER) && target != null && !ban.machineId.equals("offline")) { + for (Habbo h : Emulator.getGameServer().getGameClientManager().getHabbosWithMachineId(ban.machineId)) { + if (h.getHabboInfo().getRank().getId() >= moderator.getHabboInfo().getRank().getId()) continue; + + ban = new ModToolBan(h.getHabboInfo().getId(), h != null ? h.getHabboInfo().getIpLogin() : "offline", h != null ? h.getClient().getMachineId() : "offline", moderator.getHabboInfo().getId(), Emulator.getIntUnixTimestamp() + duration, reason, type, cfhTopic); + Emulator.getPluginManager().fireEvent(new SupportUserBannedEvent(moderator, h, ban)); + Emulator.getThreading().run(ban); + bans.add(ban); + Emulator.getGameServer().getGameClientManager().disposeClient(h.getClient()); + } + } + + return bans; + } + + public void roomAction(Room room, Habbo moderator, boolean kickUsers, boolean lockDoor, boolean changeTitle) { + SupportRoomActionEvent roomActionEvent = new SupportRoomActionEvent(moderator, room, kickUsers, lockDoor, changeTitle); + Emulator.getPluginManager().fireEvent(roomActionEvent); + + if (roomActionEvent.changeTitle) { + room.setName(Emulator.getTexts().getValue("hotel.room.inappropriate.title")); + room.setNeedsUpdate(true); + } + + if (roomActionEvent.lockDoor) { + room.setState(RoomState.LOCKED); + room.setNeedsUpdate(true); + } + + if (roomActionEvent.kickUsers) { + for (Habbo habbo : room.getHabbos()) { + if (!(habbo.hasPermission(Permission.ACC_UNKICKABLE) || habbo.hasPermission(Permission.ACC_SUPPORTTOOL) || room.isOwner(habbo))) { + room.kickHabbo(habbo, false); + } + } + } + } + + public ModToolBan checkForBan(int userId) { + ModToolBan ban = null; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM bans WHERE user_id = ? AND ban_expire >= ? AND (type = 'account' OR type = 'super') ORDER BY timestamp LIMIT 1")) { + statement.setInt(1, userId); + statement.setInt(2, Emulator.getIntUnixTimestamp()); + + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + ban = new ModToolBan(set); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return ban; + } + + @Deprecated + public boolean hasIPBan(Channel habbo) { + if (habbo == null) + return false; + + if (habbo.remoteAddress() == null || ((InetSocketAddress) habbo.remoteAddress()).getAddress() == null) + return false; + + return this.hasIPBan(((InetSocketAddress) habbo.remoteAddress()).getAddress().getHostAddress()); + } + + public boolean hasIPBan(String ipAddress) { + boolean banned = false; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM bans WHERE ip = ? AND (type = 'ip' OR type = 'super') AND ban_expire > ? LIMIT 1")) { + statement.setString(1, ipAddress); + statement.setInt(2, Emulator.getIntUnixTimestamp()); + + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + banned = true; + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + return banned; + } + + public boolean hasMACBan(GameClient habbo) { + if (habbo == null) + return false; + + if (habbo.getMachineId().isEmpty()) { + return false; + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM bans WHERE machine_id = ? AND (type = 'machine' OR type = 'super') AND ban_expire > ? LIMIT 1")) { + statement.setString(1, habbo.getMachineId()); + statement.setInt(2, Emulator.getIntUnixTimestamp()); + + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + return true; + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return false; + } + + public boolean unban(String username) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE bans INNER JOIN users ON bans.user_id = users.id SET ban_expire = ?, ban_reason = CONCAT('" + Emulator.getTexts().getValue("unbanned") + ": ', ban_reason) WHERE users.username LIKE ? AND ban_expire > ?")) { + statement.setInt(1, Emulator.getIntUnixTimestamp()); + statement.setString(2, username); + statement.setInt(3, Emulator.getIntUnixTimestamp()); + statement.execute(); + return statement.getUpdateCount() > 0; + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return false; + } + + public void pickTicket(ModToolIssue issue, Habbo habbo) { + issue.modId = habbo.getHabboInfo().getId(); + issue.modName = habbo.getHabboInfo().getUsername(); + issue.state = ModToolTicketState.PICKED; + + this.updateTicketToMods(issue); + issue.updateInDatabase(); + } + + public void updateTicketToMods(ModToolIssue issue) { + SupportTicketStatusChangedEvent event = new SupportTicketStatusChangedEvent(null, issue); + + if (!Emulator.getPluginManager().fireEvent(event).isCancelled()) { + Emulator.getGameEnvironment().getHabboManager().sendPacketToHabbosWithPermission(new ModToolIssueInfoComposer(issue).compose(), Permission.ACC_SUPPORTTOOL); + } + } + + public void addTicket(ModToolIssue issue) { + if (Emulator.getPluginManager().fireEvent(new SupportTicketEvent(null, issue)).isCancelled()) + return; + + if (issue.id == 0) { + new InsertModToolIssue(issue).run(); + } + + synchronized (this.tickets) { + this.tickets.put(issue.id, issue); + } + } + + public void removeTicket(ModToolIssue issue) { + this.removeTicket(issue.id); + } + + public void removeTicket(int issueId) { + synchronized (this.tickets) { + this.tickets.remove(issueId); + } + } + + public void closeTicketAsUseless(ModToolIssue issue, Habbo sender) { + issue.state = ModToolTicketState.CLOSED; + issue.updateInDatabase(); + + if (sender != null) { + sender.getClient().sendResponse(new ModToolIssueHandledComposer(ModToolIssueHandledComposer.USELESS)); + } + + this.updateTicketToMods(issue); + + this.removeTicket(issue); + } + + public void closeTicketAsAbusive(ModToolIssue issue, Habbo sender) { + issue.state = ModToolTicketState.CLOSED; + issue.updateInDatabase(); + if (sender != null) { + sender.getClient().sendResponse(new ModToolIssueHandledComposer(ModToolIssueHandledComposer.ABUSIVE)); + } + + this.updateTicketToMods(issue); + + this.removeTicket(issue); + } + + public void closeTicketAsHandled(ModToolIssue issue, Habbo sender) { + issue.state = ModToolTicketState.CLOSED; + issue.updateInDatabase(); + + if (sender != null) { + sender.getClient().sendResponse(new ModToolIssueHandledComposer(ModToolIssueHandledComposer.HANDLED)); + } + + this.updateTicketToMods(issue); + + this.removeTicket(issue); + } + + public boolean hasPendingTickets(int userId) { + synchronized (this.tickets) { + for (Map.Entry map : this.tickets.entrySet()) { + if (map.getValue().senderId == userId) + return true; + } + } + + return false; + } + + public int totalBans(int userId) { + int total = 0; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT COUNT(*) as total FROM bans WHERE user_id = ?")) { + statement.setInt(1, userId); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + total = set.getInt("total"); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return total; + } + + public TIntObjectMap getCategory() { + return this.category; + } + + public ModToolCategory getCategory(int id) { + return this.category.get(id); + } + + public THashMap> getPresets() { + return this.presets; + } + + public THashMap getTickets() { + return this.tickets; + } + + public ModToolIssue getTicket(int ticketId) { + return this.tickets.get(ticketId); + } + + public TIntObjectMap getCfhCategories() { + return this.cfhCategories; + } + + public List openTicketsForHabbo(Habbo habbo) { + List issues = new ArrayList<>(); + synchronized (this.tickets) { + this.tickets.forEachValue(new TObjectProcedure() { + @Override + public boolean execute(ModToolIssue object) { + if (object.senderId == habbo.getHabboInfo().getId() && object.state == ModToolTicketState.OPEN) { + issues.add(object); + } + + return true; + } + }); + } + + return issues; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolPreset.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolPreset.java new file mode 100644 index 0000000..2b4208c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolPreset.java @@ -0,0 +1,22 @@ +package com.eu.habbo.habbohotel.modtool; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class ModToolPreset { + public final int id; + public final String name; + public final String message; + public final String reminder; + public final int banLength; + public final int muteLength; + + public ModToolPreset(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.name = set.getString("name"); + this.message = set.getString("message"); + this.reminder = set.getString("reminder"); + this.banLength = set.getInt("ban_for"); + this.muteLength = set.getInt("mute_for"); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolRoomVisit.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolRoomVisit.java new file mode 100644 index 0000000..0ccabbd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolRoomVisit.java @@ -0,0 +1,33 @@ +package com.eu.habbo.habbohotel.modtool; + +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class ModToolRoomVisit implements Comparable { + public int roomId; + public String roomName; + public int timestamp; + public int exitTimestamp; + public THashSet chat; + + public ModToolRoomVisit(ResultSet set) throws SQLException { + this.roomId = set.getInt("room_id"); + this.roomName = set.getString("name"); + this.timestamp = set.getInt("timestamp"); + } + + public ModToolRoomVisit(int roomId, String roomName, int timestamp, int exitTimestamp) { + this.roomId = roomId; + this.roomName = roomName; + this.timestamp = timestamp; + this.exitTimestamp = exitTimestamp; + this.chat = new THashSet<>(); + } + + @Override + public int compareTo(ModToolRoomVisit o) { + return o.timestamp - this.timestamp; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolSanctionItem.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolSanctionItem.java new file mode 100644 index 0000000..70d2b37 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolSanctionItem.java @@ -0,0 +1,25 @@ +package com.eu.habbo.habbohotel.modtool; + +public class ModToolSanctionItem { + public int id; + public int habboId; + public int sanctionLevel; + public int probationTimestamp; + public boolean isMuted; + public int muteDuration; + public int tradeLockedUntil; + public String reason; + + public ModToolSanctionItem(int id, int habboId, int sanctionLevel, int probationTimestamp, boolean isMuted, int muteDuration, int tradeLockedUntil, String reason) { + this.id = id; + this.habboId = habboId; + this.sanctionLevel = sanctionLevel; + this.probationTimestamp = probationTimestamp; + this.isMuted = isMuted; + this.muteDuration = muteDuration; + this.tradeLockedUntil = tradeLockedUntil; + this.reason = reason; + } + + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolSanctionLevelItem.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolSanctionLevelItem.java new file mode 100644 index 0000000..d893b4e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolSanctionLevelItem.java @@ -0,0 +1,15 @@ +package com.eu.habbo.habbohotel.modtool; + +public class ModToolSanctionLevelItem { + public int sanctionLevel; + public String sanctionType; + public int sanctionHourLength; + public int sanctionProbationDays; + + public ModToolSanctionLevelItem(int sanctionLevel, String sanctionType, int sanctionHourLength, int sanctionProbationDays) { + this.sanctionLevel = sanctionLevel; + this.sanctionType = sanctionType; + this.sanctionHourLength = sanctionHourLength; + this.sanctionProbationDays = sanctionProbationDays; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolSanctions.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolSanctions.java new file mode 100644 index 0000000..bbe58af --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolSanctions.java @@ -0,0 +1,173 @@ +package com.eu.habbo.habbohotel.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.events.sanctions.SanctionEvent; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Date; + +@Slf4j +public class ModToolSanctions { + private final THashMap> sanctionHashmap; + private final THashMap sanctionLevelsHashmap; + + public ModToolSanctions() { + long millis = System.currentTimeMillis(); + this.sanctionHashmap = new THashMap<>(); + this.sanctionLevelsHashmap = new THashMap<>(); + this.loadModSanctions(); + + log.info("Sanctions Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)"); + } + + public synchronized void loadModSanctions() { + this.sanctionHashmap.clear(); + this.sanctionLevelsHashmap.clear(); + + this.loadSanctionLevels(); + } + + private void loadSanctionLevels() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM sanction_levels")) { + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + this.sanctionLevelsHashmap.put(set.getInt("level"), new ModToolSanctionLevelItem(set.getInt("level"), set.getString("type"), set.getInt("hour_length"), set.getInt("probation_days"))); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public ModToolSanctionLevelItem getSanctionLevelItem(int sanctionLevel) { + return this.sanctionLevelsHashmap.get(sanctionLevel); + } + + public THashMap> getSanctions(int habboId) { + synchronized (this.sanctionHashmap) { + this.sanctionHashmap.clear(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM sanctions WHERE habbo_id = ? ORDER BY id ASC")) { + statement.setInt(1, habboId); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + if (this.sanctionHashmap.get(set.getInt("habbo_id")) == null) { + this.sanctionHashmap.put(set.getInt("habbo_id"), new ArrayList<>()); + } + + ModToolSanctionItem item = new ModToolSanctionItem(set.getInt("id"), set.getInt("habbo_id"), set.getInt("sanction_level"), set.getInt("probation_timestamp"), set.getBoolean("is_muted"), set.getInt("mute_duration"), set.getInt("trade_locked_until"), set.getString("reason")); + + if (!this.sanctionHashmap.get(set.getInt("habbo_id")).contains(item)) { + this.sanctionHashmap.get(set.getInt("habbo_id")).add(item); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return this.sanctionHashmap; + } + } + + private void insertSanction(int habboId, int sanctionLevel, int probationTimestamp, String reason, int tradeLockedUntil, boolean isMuted, int muteDuration) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO sanctions (habbo_id, sanction_level, probation_timestamp, reason, trade_locked_until, is_muted, mute_duration) VALUES (?, ?, ?, ?, ?, ?, ?)")) { + statement.setInt(1, habboId); + statement.setInt(2, sanctionLevel); + statement.setInt(3, probationTimestamp); + statement.setString(4, reason); + statement.setInt(5, tradeLockedUntil); + statement.setBoolean(6, isMuted); + statement.setInt(7, muteDuration); + + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void updateSanction(int rowId, int probationTimestamp) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE sanctions SET probation_timestamp = ? WHERE id = ?")) { + statement.setInt(1, probationTimestamp); + statement.setInt(2, rowId); + + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void updateTradeLockedUntil(int rowId, int tradeLockedUntil) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE sanctions SET trade_locked_until = ? WHERE id = ?")) { + statement.setInt(1, tradeLockedUntil); + statement.setInt(2, rowId); + + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void updateMuteDuration(int rowId, int muteDuration) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE sanctions SET mute_duration = ? WHERE id = ?")) { + statement.setInt(1, muteDuration); + statement.setInt(2, rowId); + + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void run(int habboId, Habbo self, int sanctionLevel, int cfhTopic, String reason, int tradeLockedUntil, boolean isMuted, int muteDuration) { + sanctionLevel++; + + ModToolSanctionLevelItem sanctionLevelItem = getSanctionLevelItem(sanctionLevel); + + insertSanction(habboId, sanctionLevel, buildProbationTimestamp(sanctionLevelItem), reason, tradeLockedUntil, isMuted, muteDuration); + + runSanctionBasedOnLevel(sanctionLevelItem, habboId, reason, cfhTopic, self, muteDuration); + + Emulator.getPluginManager().fireEvent(new SanctionEvent(self, Emulator.getGameEnvironment().getHabboManager().getHabbo(habboId), sanctionLevel)); + } + + private int buildProbationTimestamp(ModToolSanctionLevelItem sanctionLevelItem) { + return Emulator.getIntUnixTimestamp() + (sanctionLevelItem.sanctionProbationDays * 24 * 60 * 60); + } + + public int getProbationDays(ModToolSanctionLevelItem sanctionLevelItem) { + return sanctionLevelItem.sanctionProbationDays; + } + + private void runSanctionBasedOnLevel(ModToolSanctionLevelItem sanctionLevelItem, int habboId, String reason, int cfhTopic, Habbo self, int muteDuration) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(habboId); + + int muteDurationSeconds = 0; + + if (muteDuration > 0) { + Date muteDurationDate = new Date((long) muteDuration * 1000); + long diff = muteDurationDate.getTime() - Emulator.getDate().getTime(); + muteDurationSeconds = Math.toIntExact(diff / 1000); + } + + switch (sanctionLevelItem.sanctionType) { + case "ALERT": habbo.alert(reason); break; + case "BAN": Emulator.getGameEnvironment().getModToolManager().ban(habboId, self, reason, sanctionLevelItem.sanctionHourLength, ModToolBanType.ACCOUNT, cfhTopic); break; + case "MUTE": habbo.mute(muteDurationSeconds == 0 ? 3600 : muteDurationSeconds, false); break; + default: break; + } + } + + public String getSanctionType(ModToolSanctionLevelItem sanctionLevelItem) { + return sanctionLevelItem.sanctionType; + } + + public int getTimeOfSanction(ModToolSanctionLevelItem sanctionLevelItem) { + return sanctionLevelItem.sanctionHourLength; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolTicketState.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolTicketState.java new file mode 100644 index 0000000..4bba6c8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolTicketState.java @@ -0,0 +1,26 @@ +package com.eu.habbo.habbohotel.modtool; + +public enum ModToolTicketState { + CLOSED(0), + OPEN(1), + PICKED(2); + + private final int state; + + ModToolTicketState(int state) { + this.state = state; + } + + public static ModToolTicketState getState(int number) { + for (ModToolTicketState s : ModToolTicketState.values()) { + if (s.state == number) + return s; + } + + return CLOSED; + } + + public int getState() { + return this.state; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolTicketType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolTicketType.java new file mode 100644 index 0000000..4eb8aac --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolTicketType.java @@ -0,0 +1,29 @@ +package com.eu.habbo.habbohotel.modtool; + +public enum ModToolTicketType { + NORMAL(1), + NORMAL_UNKNOWN(2), + AUTOMATIC(3), + AUTOMATIC_IM(4), + GUIDE_SYSTEM(5), + IM(6), + ROOM(7), + PANIC(8), + GUARDIAN(9), + AUTOMATIC_HELPER(10), + DISCUSSION(11), + SELFIE(12), + POTATO(13), + PHOTO(14), + AMBASSADOR(15); + + private final int type; + + ModToolTicketType(int type) { + this.type = type; + } + + public int getType() { + return this.type; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ScripterEvent.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ScripterEvent.java new file mode 100644 index 0000000..8284327 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ScripterEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.habbohotel.modtool; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.events.support.SupportEvent; + +public class ScripterEvent extends SupportEvent { + public final Habbo habbo; + public final String reason; + + public ScripterEvent(Habbo habbo, String reason) { + super(null); + + this.habbo = habbo; + this.reason = reason; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ScripterManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ScripterManager.java new file mode 100644 index 0000000..a37db65 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/ScripterManager.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; + +public class ScripterManager { + public static void scripterDetected(GameClient client, String reason) { + ScripterEvent scripterEvent = new ScripterEvent(client.getHabbo(), reason); + Emulator.getPluginManager().fireEvent(scripterEvent); + + if (scripterEvent.isCancelled()) return; + + if (Emulator.getConfig().getBoolean("scripter.modtool.tickets", true)) { + Emulator.getGameEnvironment().getModToolManager().quickTicket(client.getHabbo(), "Scripter", reason); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/WordFilter.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/WordFilter.java new file mode 100644 index 0000000..66248c5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/WordFilter.java @@ -0,0 +1,204 @@ +package com.eu.habbo.habbohotel.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.messenger.Message; +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.friends.FriendChatMessageComposer; +import com.eu.habbo.plugin.events.users.UserTriggerWordFilterEvent; +import gnu.trove.iterator.hash.TObjectHashIterator; +import gnu.trove.set.hash.THashSet; +import org.apache.commons.lang3.StringUtils; +import lombok.extern.slf4j.Slf4j; + + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.text.Normalizer; +import java.util.regex.Pattern; + +@Slf4j +public class WordFilter { + + private static final Pattern DIACRITICS_AND_FRIENDS = Pattern.compile("[\\p{InCombiningDiacriticalMarks}\\p{IsLm}\\p{IsSk}]+"); + //Configuration. Loaded from database & updated accordingly. + public static boolean ENABLED_FRIENDCHAT = true; + public static String DEFAULT_REPLACEMENT = "bobba"; + protected THashSet autoReportWords = new THashSet<>(); + protected THashSet hideMessageWords = new THashSet<>(); + protected THashSet words = new THashSet<>(); + + public WordFilter() { + long start = System.currentTimeMillis(); + this.reload(); + log.info("WordFilter -> Loaded! (" + (System.currentTimeMillis() - start) + " MS)"); + } + + private static String stripDiacritics(String str) { + str = Normalizer.normalize(str, Normalizer.Form.NFD); + str = DIACRITICS_AND_FRIENDS.matcher(str).replaceAll(""); + return str; + } + + public synchronized void reload() { + if (!Emulator.getConfig().getBoolean("hotel.wordfilter.enabled")) + return; + + this.autoReportWords.clear(); + this.hideMessageWords.clear(); + this.words.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement()) { + try (ResultSet set = statement.executeQuery("SELECT * FROM wordfilter")) { + while (set.next()) { + WordFilterWord word; + + try { + word = new WordFilterWord(set); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + continue; + } + + if (word.autoReport) + this.autoReportWords.add(word); + else if (word.hideMessage) + this.hideMessageWords.add(word); + + this.words.add(word); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public String normalise(String message) { + return DIACRITICS_AND_FRIENDS.matcher(Normalizer.normalize(StringUtils.stripAccents(message), Normalizer.Form.NFKD) + .replaceAll("[,.;:'\"]", " ").replace("I", "l") + .replaceAll("[^\\p{ASCII}*$]", "").replaceAll("\\p{M}", " ") + .replaceAll("^\\p{M}*$]", "").replaceAll("[1|]", "i") + .replace("2", "z").replace("3", "e") + .replace("4", "a").replace("5", "s") + .replace("8", "b").replace("0", "o") + .replace(" ", " ").replace("$", "s") + .replace("ß", "b").trim()).replaceAll(" "); + } + + public boolean autoReportCheck(RoomChatMessage roomChatMessage) { + String message = this.normalise(roomChatMessage.getMessage()).toLowerCase(); + + TObjectHashIterator iterator = this.autoReportWords.iterator(); + + while (iterator.hasNext()) { + WordFilterWord word = (WordFilterWord) iterator.next(); + + if (message.contains(word.key)) { + Emulator.getGameEnvironment().getModToolManager().quickTicket(roomChatMessage.getHabbo(), "Automatic WordFilter", roomChatMessage.getMessage()); + + if (Emulator.getConfig().getBoolean("notify.staff.chat.auto.report")) { + Emulator.getGameEnvironment().getHabboManager().sendPacketToHabbosWithPermission(new FriendChatMessageComposer(new Message(roomChatMessage.getHabbo().getHabboInfo().getId(), 0, Emulator.getTexts().getValue("warning.auto.report").replace("%user%", roomChatMessage.getHabbo().getHabboInfo().getUsername()).replace("%word%", word.key))).compose(), "acc_staff_chat"); + } + return true; + } + } + + return false; + } + + public boolean hideMessageCheck(String message) { + message = this.normalise(message).toLowerCase(); + + TObjectHashIterator iterator = this.hideMessageWords.iterator(); + + while (iterator.hasNext()) { + WordFilterWord word = (WordFilterWord) iterator.next(); + + if (message.contains(word.key)) { + return true; + } + } + + return false; + } + + public String[] filter(String[] messages) { + for (int i = 0; i < messages.length; i++) { + messages[i] = this.filter(messages[i], null); + } + + return messages; + } + + public String filter(String message, Habbo habbo) { + String filteredMessage = message; + if (Emulator.getConfig().getBoolean("hotel.wordfilter.normalise")) { + filteredMessage = this.normalise(filteredMessage); + } + + TObjectHashIterator iterator = this.words.iterator(); + + boolean foundShit = false; + + while (iterator.hasNext()) { + WordFilterWord word = (WordFilterWord) iterator.next(); + + if (StringUtils.containsIgnoreCase(filteredMessage, word.key)) { + if (habbo != null) { + if (Emulator.getPluginManager().fireEvent(new UserTriggerWordFilterEvent(habbo, word)).isCancelled()) + continue; + } + filteredMessage = filteredMessage.replaceAll("(?i)" + Pattern.quote(word.key), word.replacement); + foundShit = true; + + if (habbo != null && word.muteTime > 0) { + habbo.mute(word.muteTime, false); + } + } + } + + if (!foundShit) { + return message; + } + + return filteredMessage; + } + + public void filter(RoomChatMessage roomChatMessage, Habbo habbo) { + String message = roomChatMessage.getMessage().toLowerCase(); + + if (Emulator.getConfig().getBoolean("hotel.wordfilter.normalise")) { + message = this.normalise(message); + } + + TObjectHashIterator iterator = this.words.iterator(); + + while (iterator.hasNext()) { + WordFilterWord word = (WordFilterWord) iterator.next(); + + if (StringUtils.containsIgnoreCase(message, word.key)) { + if (habbo != null) { + if (Emulator.getPluginManager().fireEvent(new UserTriggerWordFilterEvent(habbo, word)).isCancelled()) + continue; + } + + message = message.replaceAll("(?i)" + Pattern.quote(word.key), word.replacement); + roomChatMessage.filtered = true; + } + } + + if (roomChatMessage.filtered) { + roomChatMessage.setMessage(message); + } + } + + public THashSet getWords() { + return new THashSet<>(this.words); + } + + public void addWord(WordFilterWord word) { + this.words.add(word); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/WordFilterWord.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/WordFilterWord.java new file mode 100644 index 0000000..0f8420a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/modtool/WordFilterWord.java @@ -0,0 +1,28 @@ +package com.eu.habbo.habbohotel.modtool; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class WordFilterWord { + public final String key; + public final String replacement; + public final boolean hideMessage; + public final boolean autoReport; + public final int muteTime; + + public WordFilterWord(ResultSet set) throws SQLException { + this.key = set.getString("key"); + this.replacement = set.getString("replacement"); + this.hideMessage = set.getInt("hide") == 1; + this.autoReport = set.getInt("report") == 1; + this.muteTime = set.getInt("mute"); + } + + public WordFilterWord(String key, String replacement) { + this.key = key; + this.replacement = replacement; + this.hideMessage = false; + this.autoReport = false; + this.muteTime = 0; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/DisplayMode.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/DisplayMode.java new file mode 100644 index 0000000..f4b9dbb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/DisplayMode.java @@ -0,0 +1,6 @@ +package com.eu.habbo.habbohotel.navigation; + +public enum DisplayMode { + VISIBLE, + COLLAPSED +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/DisplayOrder.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/DisplayOrder.java new file mode 100644 index 0000000..12d8cbb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/DisplayOrder.java @@ -0,0 +1,6 @@ +package com.eu.habbo.habbohotel.navigation; + +public enum DisplayOrder { + ORDER_NUM, + ACTIVITY +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/EventCategory.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/EventCategory.java new file mode 100644 index 0000000..264c894 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/EventCategory.java @@ -0,0 +1,43 @@ +package com.eu.habbo.habbohotel.navigation; + +import com.eu.habbo.messages.ServerMessage; + +public class EventCategory { + private int id; + private String caption; + private boolean visible; + + public EventCategory(int id, String caption, boolean visible) { + this.id = id; + this.caption = caption; + this.visible = visible; + } + + public EventCategory(String serialized) throws Exception { + String[] parts = serialized.split(","); + + if (parts.length != 3) throw new Exception("A serialized event category should contain 3 fields"); + + this.id = Integer.valueOf(parts[0]); + this.caption = parts[1]; + this.visible = parts[2].equalsIgnoreCase("true"); + } + + public int getId() { + return id; + } + + public String getCaption() { + return caption; + } + + public boolean isVisible() { + return visible; + } + + public void serialize(ServerMessage message) { + message.appendInt(this.id); + message.appendString(this.caption); + message.appendBoolean(this.visible); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/ListMode.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/ListMode.java new file mode 100644 index 0000000..cf4e50b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/ListMode.java @@ -0,0 +1,23 @@ +package com.eu.habbo.habbohotel.navigation; + +public enum ListMode { + LIST(0), + THUMBNAILS(1), + FORCED_THUNBNAILS(2); + + public final int type; + + ListMode(int type) { + this.type = type; + } + + public static ListMode fromType(int type) { + for (ListMode m : ListMode.values()) { + if (m.type == type) { + return m; + } + } + + return LIST; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorFavoriteFilter.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorFavoriteFilter.java new file mode 100644 index 0000000..71225cd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorFavoriteFilter.java @@ -0,0 +1,25 @@ +package com.eu.habbo.habbohotel.navigation; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class NavigatorFavoriteFilter extends NavigatorFilter { + public final static String name = "favorites"; + + public NavigatorFavoriteFilter() { + super(name); + } + + @Override + public List getResult(Habbo habbo) { + List resultLists = new ArrayList<>(); + List rooms = Emulator.getGameEnvironment().getNavigatorManager().getRoomsForCategory("favorites", habbo); + resultLists.add(new SearchResultList(0, "favorites", "", SearchAction.NONE, habbo.getHabboStats().navigatorWindowSettings.getListModeForCategory("favorites", ListMode.LIST), habbo.getHabboStats().navigatorWindowSettings.getDisplayModeForCategory("popular", DisplayMode.VISIBLE), rooms, true, true, DisplayOrder.ACTIVITY, -1)); + return resultLists; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorFilter.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorFilter.java new file mode 100644 index 0000000..52475d0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorFilter.java @@ -0,0 +1,121 @@ +package com.eu.habbo.habbohotel.navigation; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import org.apache.commons.lang3.StringUtils; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public abstract class NavigatorFilter { + public final String viewName; + + public NavigatorFilter(String viewName) { + this.viewName = viewName; + } + + public void filter(Method method, Object value, List collection) { + if (method == null) { + return; + } + + if (value instanceof String) { + if (((String) value).isEmpty()) { + return; + } + } + + for (SearchResultList result : collection) { + if (!result.filter) { + continue; + } + + this.filterRooms(method, value, result.rooms); + } + } + + public void filterRooms(Method method, Object value, List result) { + if (method == null) { + return; + } + + if (value instanceof String) { + if (((String) value).isEmpty()) { + return; + } + } + + List toRemove = new ArrayList<>(); + try { + method.setAccessible(true); + + for (Room room : result) { + Object o = method.invoke(room); + if (o.getClass() == value.getClass()) { + if (o instanceof String) { + NavigatorFilterComparator comparator = Emulator.getGameEnvironment().getNavigatorManager().comperatorForField(method); + + if (comparator != null) { + if (!this.applies(comparator, (String) o, (String) value)) { + toRemove.add(room); + } + } else { + toRemove.add(room); + } + } else if (o instanceof String[]) { + for (String s : (String[]) o) { + NavigatorFilterComparator comparator = Emulator.getGameEnvironment().getNavigatorManager().comperatorForField(method); + + if (comparator != null) { + if (!this.applies(comparator, s, (String) value)) { + toRemove.add(room); + } + } + } + } else { + if (o != value) { + toRemove.add(room); + } + } + } + } + } catch (Exception e) { + } + + result.removeAll(toRemove); + toRemove.clear(); + } + + public abstract List getResult(Habbo habbo); + + public List getResult(Habbo habbo, NavigatorFilterField filterField, String value, int roomCategory) { + return this.getResult(habbo); + } + + private boolean applies(NavigatorFilterComparator comparator, String o, String value) { + switch (comparator) { + case CONTAINS: + if (StringUtils.containsIgnoreCase(o, + value)) { + return true; + } + break; + + case EQUALS: + if (o.equals(value)) { + return true; + } + break; + + case EQUALS_IGNORE_CASE: + if (o.equalsIgnoreCase(value)) { + return true; + } + } + + return false; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorFilterComparator.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorFilterComparator.java new file mode 100644 index 0000000..a492394 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorFilterComparator.java @@ -0,0 +1,7 @@ +package com.eu.habbo.habbohotel.navigation; + +public enum NavigatorFilterComparator { + EQUALS, + EQUALS_IGNORE_CASE, + CONTAINS +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorFilterField.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorFilterField.java new file mode 100644 index 0000000..e7a717c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorFilterField.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.navigation; + +import java.lang.reflect.Method; + +public class NavigatorFilterField { + public final String key; + public final Method field; + public final String databaseQuery; + public final NavigatorFilterComparator comparator; + + public NavigatorFilterField(String key, Method field, String databaseQuery, NavigatorFilterComparator comparator) { + this.key = key; + this.field = field; + this.databaseQuery = databaseQuery; + this.comparator = comparator; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorHotelFilter.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorHotelFilter.java new file mode 100644 index 0000000..0a7825a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorHotelFilter.java @@ -0,0 +1,65 @@ +package com.eu.habbo.habbohotel.navigation; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomCategory; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class NavigatorHotelFilter extends NavigatorFilter { + public final static String name = "hotel_view"; + + public NavigatorHotelFilter() { + super(name); + } + + @Override + public List getResult(Habbo habbo) { + boolean showInvisible = habbo.hasPermission(Permission.ACC_ENTERANYROOM) || habbo.hasPermission(Permission.ACC_ANYROOMOWNER); + List resultLists = new ArrayList<>(); + + int i = 0; + resultLists.add(new SearchResultList(i, "popular", "", SearchAction.NONE, habbo.getHabboStats().navigatorWindowSettings.getListModeForCategory("popular", ListMode.fromType(Emulator.getConfig().getInt("hotel.navigator.popular.listtype"))), habbo.getHabboStats().navigatorWindowSettings.getDisplayModeForCategory("popular"), Emulator.getGameEnvironment().getNavigatorManager().getRoomsForCategory("popular", habbo), false, showInvisible, DisplayOrder.ORDER_NUM, -1)); + i++; + + for (Map.Entry> set : Emulator.getGameEnvironment().getRoomManager().getPopularRoomsByCategory(Emulator.getConfig().getInt("hotel.navigator.popular.category.maxresults")).entrySet()) { + if (!set.getValue().isEmpty()) { + RoomCategory category = Emulator.getGameEnvironment().getRoomManager().getCategory(set.getKey()); + if (category != null) { + resultLists.add(new SearchResultList(i, category.getCaption(), category.getCaption(), SearchAction.MORE, habbo.getHabboStats().navigatorWindowSettings.getListModeForCategory(category.getCaptionSave()), habbo.getHabboStats().navigatorWindowSettings.getDisplayModeForCategory(category.getCaptionSave()), set.getValue(), true, showInvisible, DisplayOrder.ORDER_NUM, category.getOrder())); + } + i++; + } + } + + return resultLists; + } + + @Override + public List getResult(Habbo habbo, NavigatorFilterField filterField, String value, int roomCategory) { + boolean showInvisible = habbo.hasPermission(Permission.ACC_ENTERANYROOM) || habbo.hasPermission(Permission.ACC_ANYROOMOWNER); + if (!filterField.databaseQuery.isEmpty()) { + List resultLists = new ArrayList<>(); + int i = 0; + + for (Map.Entry> set : Emulator.getGameEnvironment().getRoomManager().findRooms(filterField, value, roomCategory, showInvisible).entrySet()) { + if (!set.getValue().isEmpty()) { + RoomCategory category = Emulator.getGameEnvironment().getRoomManager().getCategory(set.getKey()); + + if (category != null) { + resultLists.add(new SearchResultList(i, category.getCaptionSave(), category.getCaption(), SearchAction.MORE, habbo.getHabboStats().navigatorWindowSettings.getListModeForCategory(category.getCaptionSave()), habbo.getHabboStats().navigatorWindowSettings.getDisplayModeForCategory(category.getCaptionSave()), set.getValue(), true, showInvisible, DisplayOrder.ACTIVITY, category.getOrder())); + } + i++; + } + } + + return resultLists; + } else { + return this.getResult(habbo); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorManager.java new file mode 100644 index 0000000..df9304e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorManager.java @@ -0,0 +1,168 @@ +package com.eu.habbo.habbohotel.navigation; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; +import java.lang.reflect.Method; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Slf4j +public class NavigatorManager { + public static int MAXIMUM_RESULTS_PER_PAGE = 10; + public static boolean CATEGORY_SORT_USING_ORDER_NUM = false; + + public final THashMap publicCategories = new THashMap<>(); + public final ConcurrentHashMap filterSettings = new ConcurrentHashMap<>(); + public final THashMap filters = new THashMap<>(); + + public NavigatorManager() { + long millis = System.currentTimeMillis(); + + this.filters.put(NavigatorPublicFilter.name, new NavigatorPublicFilter()); + this.filters.put(NavigatorHotelFilter.name, new NavigatorHotelFilter()); + this.filters.put(NavigatorRoomAdsFilter.name, new NavigatorRoomAdsFilter()); + this.filters.put(NavigatorUserFilter.name, new NavigatorUserFilter()); + this.filters.put(NavigatorFavoriteFilter.name, new NavigatorFavoriteFilter()); + + log.info("Navigator Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)"); + } + + public void loadNavigator() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + synchronized (this.publicCategories) { + this.publicCategories.clear(); + + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM navigator_publiccats WHERE visible = '1' ORDER BY order_num DESC")) { + while (set.next()) { + this.publicCategories.put(set.getInt("id"), new NavigatorPublicCategory(set)); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM navigator_publics WHERE visible = '1'")) { + while (set.next()) { + NavigatorPublicCategory category = this.publicCategories.get(set.getInt("public_cat_id")); + + if (category != null) { + Room room = Emulator.getGameEnvironment().getRoomManager().loadRoom(set.getInt("room_id")); + + if (room != null) { + category.addRoom(room); + } else { + log.error("Public room (ID: {} defined in navigator_publics does not exist!", set.getInt("room_id")); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + synchronized (this.filterSettings) { + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM navigator_filter")) { + while (set.next()) { + Method field = null; + Class clazz = Room.class; + + if (set.getString("field").contains(".")) { + for (String s : (set.getString("field")).split("\\.")) { + try { + field = clazz.getDeclaredMethod(s); + clazz = field.getReturnType(); + } catch (Exception e) { + log.error("Caught exception", e); + break; + } + } + } else { + try { + field = clazz.getDeclaredMethod(set.getString("field")); + } catch (Exception e) { + log.error("Caught exception", e); + continue; + } + } + + if (field != null) { + this.filterSettings.put(set.getString("key"), new NavigatorFilterField(set.getString("key"), field, set.getString("database_query"), NavigatorFilterComparator.valueOf(set.getString("compare").toUpperCase()))); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + List staffPromotedRooms = Emulator.getGameEnvironment().getRoomManager().getRoomsStaffPromoted(); + + for (Room room : staffPromotedRooms) { + this.publicCategories.get(Emulator.getConfig().getInt("hotel.navigator.staffpicks.categoryid")).addRoom(room); + } + } + + public NavigatorFilterComparator comperatorForField(Method field) { + for (Map.Entry set : this.filterSettings.entrySet()) { + if (set.getValue().field == field) { + return set.getValue().comparator; + } + } + + return null; + } + + public List getRoomsForCategory(String category, Habbo habbo) { + List rooms = new ArrayList<>(); + + switch (category) { + case "my": + rooms = Emulator.getGameEnvironment().getRoomManager().getRoomsForHabbo(habbo); + break; + case "favorites": + rooms = Emulator.getGameEnvironment().getRoomManager().getRoomsFavourite(habbo); + break; + case "history_freq": + rooms = Emulator.getGameEnvironment().getRoomManager().getRoomsVisited(habbo, false, 10); + break; + case "my_groups": + rooms = Emulator.getGameEnvironment().getRoomManager().getGroupRooms(habbo, 25); + break; + case "with_rights": + rooms = Emulator.getGameEnvironment().getRoomManager().getRoomsWithRights(habbo); + break; + case "official-root": + rooms = Emulator.getGameEnvironment().getRoomManager().getPublicRooms(); + break; + case "popular": + rooms = Emulator.getGameEnvironment().getRoomManager().getPopularRooms(Emulator.getConfig().getInt("hotel.navigator.popular.amount")); + break; + case "categories": + rooms = Emulator.getGameEnvironment().getRoomManager().getRoomsPromoted(); + break; + case "with_friends": + rooms = Emulator.getGameEnvironment().getRoomManager().getRoomsWithFriendsIn(habbo, 25); + break; + case "highest_score": + rooms = Emulator.getGameEnvironment().getRoomManager().getTopRatedRooms(25); + break; + default: + return null; + } + + Collections.sort(rooms); + + return rooms; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorPublicCategory.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorPublicCategory.java new file mode 100644 index 0000000..23d4de4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorPublicCategory.java @@ -0,0 +1,34 @@ +package com.eu.habbo.habbohotel.navigation; + +import com.eu.habbo.habbohotel.rooms.Room; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class NavigatorPublicCategory { + public final int id; + public final String name; + public final List rooms; + public final ListMode image; + public final int order; + + public NavigatorPublicCategory(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.name = set.getString("name"); + this.image = set.getString("image").equals("1") ? ListMode.THUMBNAILS : ListMode.LIST; + this.order = set.getInt("order_num"); + this.rooms = new ArrayList<>(); + } + + public void addRoom(Room room) { + room.preventUncaching = true; + this.rooms.add(room); + } + + public void removeRoom(Room room) { + this.rooms.remove(room); + room.preventUncaching = room.isPublicRoom(); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorPublicFilter.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorPublicFilter.java new file mode 100644 index 0000000..40ae72b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorPublicFilter.java @@ -0,0 +1,35 @@ +package com.eu.habbo.habbohotel.navigation; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.util.ArrayList; +import java.util.List; + +public class NavigatorPublicFilter extends NavigatorFilter { + public final static String name = "official_view"; + + public NavigatorPublicFilter() { + super(name); + } + + @Override + public List getResult(Habbo habbo) { + boolean showInvisible = habbo.hasPermission(Permission.ACC_ENTERANYROOM) || habbo.hasPermission(Permission.ACC_ANYROOMOWNER); + List resultLists = new ArrayList<>(); + + int i = 0; + resultLists.add(new SearchResultList(i, "official-root", "", SearchAction.NONE, habbo.getHabboStats().navigatorWindowSettings.getListModeForCategory("official-root", ListMode.THUMBNAILS), habbo.getHabboStats().navigatorWindowSettings.getDisplayModeForCategory("official-root"), Emulator.getGameEnvironment().getNavigatorManager().getRoomsForCategory("official-root", habbo), false, showInvisible, DisplayOrder.ORDER_NUM, -1)); + i++; + + for (NavigatorPublicCategory category : Emulator.getGameEnvironment().getNavigatorManager().publicCategories.values()) { + if (!category.rooms.isEmpty()) { + resultLists.add(new SearchResultList(i, "", category.name, SearchAction.NONE, habbo.getHabboStats().navigatorWindowSettings.getListModeForCategory(category.name, category.image), habbo.getHabboStats().navigatorWindowSettings.getDisplayModeForCategory(category.name), category.rooms, true, showInvisible, DisplayOrder.ORDER_NUM, category.order)); + i++; + } + } + + return resultLists; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorRoomAdsFilter.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorRoomAdsFilter.java new file mode 100644 index 0000000..a27d3c6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorRoomAdsFilter.java @@ -0,0 +1,24 @@ +package com.eu.habbo.habbohotel.navigation; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.util.ArrayList; +import java.util.List; + +public class NavigatorRoomAdsFilter extends NavigatorFilter { + public final static String name = "roomads_view"; + + public NavigatorRoomAdsFilter() { + super(name); + } + + @Override + public List getResult(Habbo habbo) { + boolean showInvisible = habbo.hasPermission(Permission.ACC_ENTERANYROOM) || habbo.hasPermission(Permission.ACC_ANYROOMOWNER); + List resultList = new ArrayList<>(); + resultList.add(new SearchResultList(0, "categories", "", SearchAction.NONE, habbo.getHabboStats().navigatorWindowSettings.getListModeForCategory("categories", ListMode.LIST), habbo.getHabboStats().navigatorWindowSettings.getDisplayModeForCategory("official-root", DisplayMode.VISIBLE), Emulator.getGameEnvironment().getNavigatorManager().getRoomsForCategory("categories", habbo), false, showInvisible, DisplayOrder.ACTIVITY, 0)); + return resultList; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorSavedSearch.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorSavedSearch.java new file mode 100644 index 0000000..8bcbc62 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorSavedSearch.java @@ -0,0 +1,34 @@ +package com.eu.habbo.habbohotel.navigation; + +public class NavigatorSavedSearch { + private String searchCode; + private String filter; + private int id; + + public NavigatorSavedSearch(String searchCode, String filter) { + this.searchCode = searchCode; + this.filter = filter; + } + + public NavigatorSavedSearch(String searchCode, String filter, int id) { + this.searchCode = searchCode; + this.filter = filter; + this.id = id; + } + + public String getSearchCode() { + return searchCode; + } + + public String getFilter() { + return filter; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorUserFilter.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorUserFilter.java new file mode 100644 index 0000000..38f7020 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorUserFilter.java @@ -0,0 +1,58 @@ +package com.eu.habbo.habbohotel.navigation; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class NavigatorUserFilter extends NavigatorFilter { + public final static String name = "myworld_view"; + + public NavigatorUserFilter() { + super(name); + } + + @Override + public List getResult(Habbo habbo) { + int i = 0; + List resultLists = new ArrayList<>(); + + List rooms = Emulator.getGameEnvironment().getNavigatorManager().getRoomsForCategory("my", habbo); + resultLists.add(new SearchResultList(i, "my", "", SearchAction.NONE, habbo.getHabboStats().navigatorWindowSettings.getListModeForCategory("my"), habbo.getHabboStats().navigatorWindowSettings.getDisplayModeForCategory("my"), rooms, true, true, DisplayOrder.ORDER_NUM, i)); + i++; + + List favoriteRooms = Emulator.getGameEnvironment().getNavigatorManager().getRoomsForCategory("favorites", habbo); + if (!favoriteRooms.isEmpty()) { + resultLists.add(new SearchResultList(i, "favorites", "", SearchAction.NONE, habbo.getHabboStats().navigatorWindowSettings.getListModeForCategory("favorites"), habbo.getHabboStats().navigatorWindowSettings.getDisplayModeForCategory("favorites"), favoriteRooms, true, true, DisplayOrder.ORDER_NUM, i)); + i++; + } + + List frequentlyVisited = Emulator.getGameEnvironment().getNavigatorManager().getRoomsForCategory("history_freq", habbo); + if (!frequentlyVisited.isEmpty()) { + resultLists.add(new SearchResultList(i, "history_freq", "", SearchAction.NONE, habbo.getHabboStats().navigatorWindowSettings.getListModeForCategory("history_freq"), habbo.getHabboStats().navigatorWindowSettings.getDisplayModeForCategory("history_freq"), frequentlyVisited, true, true, DisplayOrder.ORDER_NUM, i)); + i++; + } + + List groupRooms = Emulator.getGameEnvironment().getNavigatorManager().getRoomsForCategory("my_groups", habbo); + if (!groupRooms.isEmpty()) { + resultLists.add(new SearchResultList(i, "my_groups", "", SearchAction.NONE, habbo.getHabboStats().navigatorWindowSettings.getListModeForCategory("my_groups"), habbo.getHabboStats().navigatorWindowSettings.getDisplayModeForCategory("my_groups"), groupRooms, true, true, DisplayOrder.ORDER_NUM, i)); + i++; + } + + List friendRooms = Emulator.getGameEnvironment().getNavigatorManager().getRoomsForCategory("with_friends", habbo); + if (!friendRooms.isEmpty()) { + resultLists.add(new SearchResultList(i, "with_friends", "", SearchAction.NONE, habbo.getHabboStats().navigatorWindowSettings.getListModeForCategory("with_friends"), habbo.getHabboStats().navigatorWindowSettings.getDisplayModeForCategory("with_friends"), friendRooms, true, true, DisplayOrder.ORDER_NUM, i)); + i++; + } + + List rightRooms = Emulator.getGameEnvironment().getNavigatorManager().getRoomsForCategory("with_rights", habbo); + if (!rightRooms.isEmpty()) { + resultLists.add(new SearchResultList(i, "with_rights", "", SearchAction.NONE, habbo.getHabboStats().navigatorWindowSettings.getListModeForCategory("with_rights"), habbo.getHabboStats().navigatorWindowSettings.getDisplayModeForCategory("with_rights"), rightRooms, true, true, DisplayOrder.ORDER_NUM, i)); + } + + return resultLists; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/SearchAction.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/SearchAction.java new file mode 100644 index 0000000..299d00a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/SearchAction.java @@ -0,0 +1,13 @@ +package com.eu.habbo.habbohotel.navigation; + +public enum SearchAction { + NONE(0), + MORE(1), + BACK(2); + + public final int type; + + SearchAction(int type) { + this.type = type; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/SearchResultList.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/SearchResultList.java new file mode 100644 index 0000000..00feccd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/navigation/SearchResultList.java @@ -0,0 +1,79 @@ +package com.eu.habbo.habbohotel.navigation; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomState; +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class SearchResultList implements ISerialize, Comparable { + public final int order; + public final String code; + public final String query; + public final SearchAction action; + public final ListMode mode; + public final DisplayMode hidden; + public final List rooms; + public final boolean filter; + public final boolean showInvisible; + public final DisplayOrder displayOrder; + public final int categoryOrder; + + public SearchResultList(int order, String code, String query, SearchAction action, ListMode mode, DisplayMode hidden, List rooms, boolean filter, boolean showInvisible, DisplayOrder displayOrder, int categoryOrder) { + this.order = order; + this.code = code; + this.query = query; + this.action = action; + this.mode = mode; + this.rooms = rooms; + this.hidden = hidden; + this.filter = filter; + this.showInvisible = showInvisible; + this.displayOrder = displayOrder; + this.categoryOrder = categoryOrder; + } + + @Override + public void serialize(ServerMessage message) { + message.appendString(this.code); //Search Code + message.appendString(this.query); //Text + message.appendInt(this.action.type); //Action Allowed (0 (Nothing), 1 (More Results), 2 (Go Back)) + message.appendBoolean(this.hidden.equals(DisplayMode.COLLAPSED)); //Closed + message.appendInt(this.mode.type); //Display Mode (0 (List), 1 (Thumbnails), 2 (Thumbnail no choice)) + + synchronized (this.rooms) { + if (!this.showInvisible) { + List toRemove = new ArrayList<>(); + for (Room room : this.rooms) { + if (room.getState() == RoomState.INVISIBLE) { + toRemove.add(room); + } + } + + this.rooms.removeAll(toRemove); + } + + message.appendInt(this.rooms.size()); + + Collections.sort(this.rooms); + for (Room room : this.rooms) { + room.serialize(message); + } + } + } + + @Override + public int compareTo(SearchResultList o) { + if (this.displayOrder == DisplayOrder.ACTIVITY) { + if (this.code.equalsIgnoreCase("popular")) { + return -1; + } + + return this.rooms.size() - o.rooms.size(); + } + return this.categoryOrder - o.categoryOrder; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/Permission.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/Permission.java new file mode 100644 index 0000000..469f907 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/Permission.java @@ -0,0 +1,52 @@ +package com.eu.habbo.habbohotel.permissions; + +public class Permission { + public static String ACC_ANYCHATCOLOR = "acc_anychatcolor"; // allows them to pick and choose any color from the chat bubbles. + public static String ACC_ANYROOMOWNER = "acc_anyroomowner"; + public static String ACC_EMPTY_OTHERS = "acc_empty_others"; + public static String ACC_ENABLE_OTHERS = "acc_enable_others"; + public static String ACC_SEE_WHISPERS = "acc_see_whispers"; + public static String ACC_SEE_TENTCHAT = "acc_see_tentchat"; + public static String ACC_SUPERWIRED = "acc_superwired"; + public static String ACC_SUPPORTTOOL = "acc_supporttool"; + public static String ACC_UNKICKABLE = "acc_unkickable"; + public static String ACC_GUILDGATE = "acc_guildgate"; + public static String ACC_MOVEROTATE = "acc_moverotate"; + public static String ACC_PLACEFURNI = "acc_placefurni"; + public static String ACC_UNLIMITED_BOTS = "acc_unlimited_bots"; + public static String ACC_UNLIMITED_PETS = "acc_unlimited_pets"; + public static String ACC_HIDE_IP = "acc_hide_ip"; + public static String ACC_HIDE_MAIL = "acc_hide_mail"; + public static String ACC_NOT_MIMICED = "acc_not_mimiced"; + public static String ACC_CHAT_NO_FLOOD = "acc_chat_no_flood"; + public static String ACC_STAFF_PICK = "acc_staff_pick"; + public static String ACC_ENTERANYROOM = "acc_enteranyroom"; // + public static String ACC_FULLROOMS = "acc_fullrooms"; + public static String ACC_INFINITE_CREDITS = "acc_infinite_credits"; + public static String ACC_INFINITE_PIXELS = "acc_infinite_pixels"; + public static String ACC_INFINITE_POINTS = "acc_infinite_points"; + public static String ACC_AMBASSADOR = "acc_ambassador"; + public static String ACC_CHAT_NO_LIMIT = "acc_chat_no_limit"; + public static String ACC_CHAT_NO_FILTER = "acc_chat_no_filter"; + public static String ACC_NOMUTE = "acc_nomute"; + public static String ACC_GUILD_ADMIN = "acc_guild_admin"; + public static String ACC_CATALOG_IDS = "acc_catalog_ids"; + public static String ACC_MODTOOL_TICKET_Q = "acc_modtool_ticket_q"; + public static String ACC_MODTOOL_USER_LOGS = "acc_modtool_user_logs"; + public static String ACC_MODTOOL_USER_ALERT = "acc_modtool_user_alert"; + public static String ACC_MODTOOL_USER_KICK = "acc_modtool_user_kick"; + public static String ACC_MODTOOL_USER_BAN = "acc_modtool_user_ban"; + public static String ACC_MODTOOL_ROOM_INFO = "acc_modtool_room_info"; + public static String ACC_MODTOOL_ROOM_LOGS = "acc_modtool_room_logs"; + public static String ACC_TRADE_ANYWHERE = "acc_trade_anywhere"; + public static String ACC_HELPER_USE_GUIDE_TOOL = "acc_helper_use_guide_tool"; + public static String ACC_HELPER_GIVE_GUIDE_TOURS = "acc_helper_give_guide_tours"; + public static String ACC_HELPER_JUDGE_CHAT_REVIEWS = "acc_helper_judge_chat_reviews"; + public static String ACC_FLOORPLAN_EDITOR = "acc_floorplan_editor"; + public final String key; + public final PermissionSetting setting; + public Permission(String key, PermissionSetting setting) { + this.key = key; + this.setting = setting; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/PermissionSetting.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/PermissionSetting.java new file mode 100644 index 0000000..d064d3d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/PermissionSetting.java @@ -0,0 +1,24 @@ +package com.eu.habbo.habbohotel.permissions; + +public enum PermissionSetting { + + DISALLOWED, + + + ALLOWED, + + + ROOM_OWNER; + + public static PermissionSetting fromString(String value) { + switch (value) { + case "1": + return ALLOWED; + case "2": + return ROOM_OWNER; + + } + + return DISALLOWED; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/PermissionsManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/PermissionsManager.java new file mode 100644 index 0000000..ceac7fd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/PermissionsManager.java @@ -0,0 +1,139 @@ +package com.eu.habbo.habbohotel.permissions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.HabboPlugin; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntIntHashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import lombok.extern.slf4j.Slf4j; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +@Slf4j +public class PermissionsManager { + private final TIntObjectHashMap ranks; + private final TIntIntHashMap enables; + private final THashMap> badges; + + public PermissionsManager() { + long millis = System.currentTimeMillis(); + this.ranks = new TIntObjectHashMap<>(); + this.enables = new TIntIntHashMap(); + this.badges = new THashMap>(); + + this.reload(); + + log.info("Permissions Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)"); + } + + public void reload() { + this.loadPermissions(); + this.loadEnables(); + } + + private void loadPermissions() { + this.badges.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM permissions ORDER BY id ASC")) { + while (set.next()) { + Rank rank = null; + if (!this.ranks.containsKey(set.getInt("id"))) { + rank = new Rank(set); + this.ranks.put(set.getInt("id"), rank); + } else { + rank = this.ranks.get(set.getInt("id")); + rank.load(set); + } + + if (rank != null && !rank.getBadge().isEmpty()) { + if (!this.badges.containsKey(rank.getBadge())) { + this.badges.put(rank.getBadge(), new ArrayList()); + } + + this.badges.get(rank.getBadge()).add(rank); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + private void loadEnables() { + synchronized (this.enables) { + this.enables.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM special_enables")) { + while (set.next()) { + this.enables.put(set.getInt("effect_id"), set.getInt("min_rank")); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + + public boolean rankExists(int rankId) { + return this.ranks.containsKey(rankId); + } + + + public Rank getRank(int rankId) { + return this.ranks.get(rankId); + } + + + public Rank getRankByName(String rankName) { + for (Rank rank : this.ranks.valueCollection()) { + if (rank.getName().equalsIgnoreCase(rankName)) + return rank; + } + + return null; + } + + + public boolean isEffectBlocked(int effectId, int rank) { + return this.enables.contains(effectId) && this.enables.get(effectId) > rank; + } + + + public boolean hasPermission(Habbo habbo, String permission) { + return this.hasPermission(habbo, permission, false); + } + + + public boolean hasPermission(Habbo habbo, String permission, boolean withRoomRights) { + if (!this.hasPermission(habbo.getHabboInfo().getRank(), permission, withRoomRights)) { + for (HabboPlugin plugin : Emulator.getPluginManager().getPlugins()) { + if (plugin.hasPermission(habbo, permission)) { + return true; + } + } + + return false; + } + + return true; + } + + + public boolean hasPermission(Rank rank, String permission, boolean withRoomRights) { + return rank.hasPermission(permission, withRoomRights); + } + + public Set getStaffBadges() { + return this.badges.keySet(); + } + + public List getRanksByBadgeCode(String code) { + return this.badges.get(code); + } + + public List getAllRanks() { + return new ArrayList<>(this.ranks.valueCollection()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/Rank.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/Rank.java new file mode 100644 index 0000000..20929cd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/permissions/Rank.java @@ -0,0 +1,139 @@ +package com.eu.habbo.habbohotel.permissions; + +import gnu.trove.map.hash.THashMap; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +public class Rank { + + private final int id; + + + private final int level; + private final THashMap permissions; + private final THashMap variables; + private String name; + private String badge; + private int roomEffect; + + + private boolean logCommands; + + + private String prefix; + + + private String prefixColor; + + + private boolean hasPrefix; + private int diamondsTimerAmount; + private int creditsTimerAmount; + private int pixelsTimerAmount; + private int gotwTimerAmount; + + public Rank(ResultSet set) throws SQLException { + this.permissions = new THashMap<>(); + this.variables = new THashMap<>(); + this.id = set.getInt("id"); + this.level = set.getInt("level"); + this.diamondsTimerAmount = 1; + this.creditsTimerAmount = 1; + this.pixelsTimerAmount = 1; + this.gotwTimerAmount = 1; + + this.load(set); + } + + public void load(ResultSet set) throws SQLException { + ResultSetMetaData meta = set.getMetaData(); + this.name = set.getString("rank_name"); + this.badge = set.getString("badge"); + this.roomEffect = set.getInt("room_effect"); + this.logCommands = set.getString("log_commands").equals("1"); + this.prefix = set.getString("prefix"); + this.prefixColor = set.getString("prefix_color"); + this.diamondsTimerAmount = set.getInt("auto_points_amount"); + this.creditsTimerAmount = set.getInt("auto_credits_amount"); + this.pixelsTimerAmount = set.getInt("auto_pixels_amount"); + this.gotwTimerAmount = set.getInt("auto_gotw_amount"); + this.hasPrefix = !this.prefix.isEmpty(); + for (int i = 1; i < meta.getColumnCount() + 1; i++) { + String columnName = meta.getColumnName(i); + if (columnName.startsWith("cmd_") || columnName.startsWith("acc_")) { + this.permissions.put(meta.getColumnName(i), new Permission(columnName, PermissionSetting.fromString(set.getString(i)))); + } else { + this.variables.put(meta.getColumnName(i), set.getString(i)); + } + } + } + + public boolean hasPermission(String key, boolean isRoomOwner) { + if (this.permissions.containsKey(key)) { + Permission permission = this.permissions.get(key); + + return permission.setting == PermissionSetting.ALLOWED || permission.setting == PermissionSetting.ROOM_OWNER && isRoomOwner; + + } + + return false; + } + + + public int getId() { + return this.id; + } + + + public int getLevel() { + return this.level; + } + + + public String getName() { + return this.name; + } + + public String getBadge() { + return this.badge; + } + + public THashMap getPermissions() { + return this.permissions; + } + + public THashMap getVariables() { + return this.variables; + } + + public int getRoomEffect() { + return this.roomEffect; + } + + public boolean isLogCommands() { + return this.logCommands; + } + + public String getPrefix() { + return this.prefix; + } + + public String getPrefixColor() { + return this.prefixColor; + } + + public boolean hasPrefix() { + return this.hasPrefix; + } + + public int getDiamondsTimerAmount() { return this.diamondsTimerAmount; } + + public int getCreditsTimerAmount() { return this.creditsTimerAmount; } + + public int getPixelsTimerAmount() { return this.pixelsTimerAmount; } + + public int getGotwTimerAmount() { return this.gotwTimerAmount; } +} + diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/GnomePet.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/GnomePet.java new file mode 100644 index 0000000..3b520aa --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/GnomePet.java @@ -0,0 +1,89 @@ +package com.eu.habbo.habbohotel.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.ServerMessage; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class GnomePet extends Pet implements IPetLook { + private final String gnomeData; + + public GnomePet(ResultSet set) throws SQLException { + super(set); + + this.gnomeData = set.getString("gnome_data"); + } + + public GnomePet(int type, int race, String color, String name, int userId, String gnomeData) { + super(type, race, color, name, userId); + + this.gnomeData = gnomeData; + } + + @Override + public void serialize(ServerMessage message) { + message.appendInt(this.getId()); + message.appendString(this.getName()); + message.appendInt(this.petData.getType()); + message.appendInt(this.race); + message.appendString(this.color); + message.appendInt(0); + message.appendInt(0); + message.appendInt(0); + } + + @Override + public void run() { + if (this.needsUpdate) { + super.run(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users_pets SET gnome_data = ? WHERE id = ? LIMIT 1")) { + statement.setString(1, this.gnomeData); + statement.setInt(2, this.id); + statement.executeUpdate(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + @Override + public String getLook() { + return this.getPetData().getType() + " 0 FFFFFF " + this.gnomeData; + } + + @Override + public void scratched(Habbo habbo) { + super.scratched(habbo); + + if (this.getPetData().getType() == 26) { + if (habbo != null) { + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("GnomeRespectGiver")); + } + AchievementManager.progressAchievement(Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getUserId()), Emulator.getGameEnvironment().getAchievementManager().getAchievement("GnomeRespectReceiver")); + } else if (this.getPetData().getType() == 27) { + if (habbo != null) { + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("LeprechaunRespectGiver")); + } + AchievementManager.progressAchievement(Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getUserId()), Emulator.getGameEnvironment().getAchievementManager().getAchievement("LeprechaunRespectReceiver")); + } + + } + + @Override + protected void levelUp() { + super.levelUp(); + + if (this.getPetData().getType() == 26) { + AchievementManager.progressAchievement(Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getUserId()), Emulator.getGameEnvironment().getAchievementManager().getAchievement("GnomeLevelUp")); + } else if (this.getPetData().getType() == 27) { + AchievementManager.progressAchievement(Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getUserId()), Emulator.getGameEnvironment().getAchievementManager().getAchievement("LeprechaunLevelUp")); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/HorsePet.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/HorsePet.java new file mode 100644 index 0000000..26094ad --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/HorsePet.java @@ -0,0 +1,66 @@ +package com.eu.habbo.habbohotel.pets; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class HorsePet extends RideablePet { + private int hairColor; + private int hairStyle; + + public HorsePet(ResultSet set) throws SQLException { + super(set); + this.hairColor = set.getInt("hair_color"); + this.hairStyle = set.getInt("hair_style"); + this.hasSaddle(set.getString("saddle").equalsIgnoreCase("1")); + this.setAnyoneCanRide(set.getString("ride").equalsIgnoreCase("1")); + this.setSaddleItemId(set.getInt("saddle_item_id")); + } + + public HorsePet(int type, int race, String color, String name, int userId) { + super(type, race, color, name, userId); + this.hairColor = 0; + this.hairStyle = -1; + this.hasSaddle(false); + this.setAnyoneCanRide(false); + } + + @Override + public void run() { + if (this.needsUpdate) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users_pets SET hair_style = ?, hair_color = ?, saddle = ?, ride = ?, saddle_item_id = ? WHERE id = ?")) { + statement.setInt(1, this.hairStyle); + statement.setInt(2, this.hairColor); + statement.setString(3, this.hasSaddle() ? "1" : "0"); + statement.setString(4, this.anyoneCanRide() ? "1" : "0"); + statement.setInt(5, this.getSaddleItemId()); + statement.setInt(6, super.getId()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + super.run(); + } + } + + public int getHairColor() { + return this.hairColor; + } + + public void setHairColor(int hairColor) { + this.hairColor = hairColor; + } + + public int getHairStyle() { + return this.hairStyle; + } + + public void setHairStyle(int hairStyle) { + this.hairStyle = hairStyle; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/IPetLook.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/IPetLook.java new file mode 100644 index 0000000..905b859 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/IPetLook.java @@ -0,0 +1,5 @@ +package com.eu.habbo.habbohotel.pets; + +public interface IPetLook { + String getLook(); +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/MonsterplantPet.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/MonsterplantPet.java new file mode 100644 index 0000000..1828ecd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/MonsterplantPet.java @@ -0,0 +1,396 @@ +package com.eu.habbo.habbohotel.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.rooms.pets.PetStatusUpdateComposer; +import com.eu.habbo.messages.outgoing.rooms.pets.RoomPetRespectComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import org.apache.commons.math3.util.Pair; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.Map; + +@Slf4j +public class MonsterplantPet extends Pet implements IPetLook { + public static final Map> bodyRarity = new LinkedHashMap>() { + { + this.put(1, new Pair<>("Blungon", 0)); + this.put(2, new Pair<>("Wailzor", 1)); + this.put(3, new Pair<>("Stumpy", 1)); + this.put(4, new Pair<>("Sunspike", 2)); + this.put(5, new Pair<>("Squarg", 0)); + this.put(6, new Pair<>("Shroomer", 3)); + this.put(7, new Pair<>("Zuchinu", 3)); + this.put(8, new Pair<>("Abysswirl", 5)); + this.put(9, new Pair<>("Weggylum", 2)); + this.put(10, new Pair<>("Wystique", 4)); + this.put(11, new Pair<>("Hairbullis", 4)); + this.put(12, new Pair<>("Snozzle", 5)); //Rarity??? + } + }; + public static final Map> colorRarity = new LinkedHashMap>() { + { + this.put(0, new Pair<>("Aenueus", 0)); + this.put(1, new Pair<>("Griseus", 1)); + this.put(2, new Pair<>("Phoenicus", 2)); + this.put(3, new Pair<>("Viridulus", 1)); + this.put(4, new Pair<>("Cyaneus", 5)); + this.put(5, new Pair<>("Incarnatus", 2)); + this.put(6, new Pair<>("Azureus", 4)); + this.put(7, new Pair<>("Atamasc", 4)); + this.put(8, new Pair<>("Amethyst", 3)); + this.put(9, new Pair<>("Fulvus", 0)); + this.put(10, new Pair<>("Cinereus", 3)); + } + }; + public static final ArrayList> indexedBody = new ArrayList<>(MonsterplantPet.bodyRarity.values()); + public static final ArrayList> indexedColors = new ArrayList<>(MonsterplantPet.colorRarity.values()); + public static int growTime = (30 * 60); + public static int timeToLive = (3 * 24 * 60 * 60); //3 days + private final int nose; + private final int noseColor; + private final int eyes; + private final int eyesColor; + private final int mouth; + private final int mouthColor; + public String look; + private int type; + private int hue; + private int deathTimestamp = Emulator.getIntUnixTimestamp() + timeToLive; + private boolean canBreed = true; + private boolean publiclyBreedable = false; + private int growthStage = 0; + private boolean hasDied = false; + + public MonsterplantPet(ResultSet set) throws SQLException { + super(set); + this.type = set.getInt("mp_type"); + this.hue = set.getInt("mp_color"); + this.nose = set.getInt("mp_nose"); + this.noseColor = set.getInt("mp_nose_color"); + this.eyes = set.getInt("mp_eyes"); + this.eyesColor = set.getInt("mp_eyes_color"); + this.mouth = set.getInt("mp_mouth"); + this.mouthColor = set.getInt("mp_mouth_color"); + this.deathTimestamp = set.getInt("mp_death_timestamp"); + this.publiclyBreedable = set.getString("mp_allow_breed").equals("1"); + this.canBreed = set.getString("mp_breedable").equals("1"); + this.hasDied = set.getInt("mp_is_dead") == 1; + } + + public MonsterplantPet(int userId, int type, int hue, int nose, int noseColor, int mouth, int mouthColor, int eyes, int eyesColor) { + super(16, 0, "", "", userId); + + this.type = type; + this.hue = hue; + this.nose = nose; + this.noseColor = noseColor; + this.mouth = mouth; + this.mouthColor = mouthColor; + this.eyes = eyes; + this.eyesColor = eyesColor; + } + + @Override + public String getName() { + String name = "Unknownis"; + + if (colorRarity.containsKey(this.hue)) { + name = colorRarity.get(this.hue).getKey(); + } + + if (bodyRarity.containsKey(this.type)) { + name += " " + bodyRarity.get(this.type).getKey(); + } + + return name; + } + + @Override + public void run() { + if (this.needsUpdate) { + super.run(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users_pets SET mp_type = ?, mp_color = ?, mp_nose = ?, mp_eyes = ?, mp_mouth = ?, mp_nose_color = ?, mp_eyes_color = ?, mp_mouth_color = ?, mp_death_timestamp = ?, mp_breedable = ?, mp_allow_breed = ?, mp_is_dead = ? WHERE id = ?")) { + statement.setInt(1, this.type); + statement.setInt(2, this.hue); + statement.setInt(3, this.nose); + statement.setInt(4, this.eyes); + statement.setInt(5, this.mouth); + statement.setInt(6, this.noseColor); + statement.setInt(7, this.eyesColor); + statement.setInt(8, this.mouthColor); + statement.setInt(9, this.deathTimestamp); + statement.setString(10, this.canBreed ? "1" : "0"); + statement.setString(11, this.publiclyBreedable ? "1" : "0"); + statement.setInt(12, this.hasDied ? 1 : 0); + statement.setInt(13, this.id); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + @Override + public void cycle() { + if (this.room != null && this.roomUnit != null) { + if (this.isDead()) { + this.roomUnit.removeStatus(RoomUnitStatus.GESTURE); + + if (!this.hasDied) { + AchievementManager.progressAchievement(Emulator.getGameEnvironment().getHabboManager().getHabbo(this.userId), Emulator.getGameEnvironment().getAchievementManager().getAchievement("MonsterPlantGardenOfDeath")); + + this.hasDied = true; + this.needsUpdate = true; + } + + this.roomUnit.clearStatus(); + this.roomUnit.setStatus(RoomUnitStatus.RIP, ""); + this.packetUpdate = true; + } else { + int difference = Emulator.getIntUnixTimestamp() - this.created + 1; + if (difference >= growTime) { + this.growthStage = 7; + boolean clear = false; + for (RoomUnitStatus s : this.roomUnit.getStatusMap().keySet()) { + if (s.equals(RoomUnitStatus.GROW)) { + clear = true; + } + } + + if (clear) { + this.roomUnit.clearStatus(); + this.packetUpdate = true; + } + } else { + int g = (int) Math.ceil(difference / (growTime / 7.0)); + + if (g > this.growthStage) { + this.growthStage = g; + this.roomUnit.clearStatus(); + this.roomUnit.setStatus(RoomUnitStatus.fromString("grw" + this.growthStage), ""); + this.packetUpdate = true; + } + } + + if (Emulator.getRandom().nextInt(1000) < 10) { + super.updateGesture(Emulator.getIntUnixTimestamp()); + this.packetUpdate = true; + } + } + } + + super.cycle(); + } + + public int getType() { + return this.type; + } + + public int getRarity() { + if (bodyRarity.containsKey(this.type) && colorRarity.containsKey(this.hue)) { + return bodyRarity.get(this.type).getValue() + colorRarity.get(this.hue).getValue(); + } + return 0; + } + + @Override + public String getLook() { + return "16 0 FFFFFF " + + "5 " + + "0 -1 10 " + + "1 " + this.type + " " + this.hue + " " + + "2 " + this.mouth + " " + this.mouthColor + " " + + "3 " + this.nose + " " + this.noseColor + " " + + "4 " + this.eyes + " " + this.eyesColor; + } + + + @Override + public void serialize(ServerMessage message) { + message.appendInt(this.getId()); + message.appendString(this.getName()); + message.appendInt(this.petData.getType()); + message.appendInt(this.race); + message.appendString(this.getLook().substring(5)); + message.appendInt(this.getRarity()); + message.appendInt(5); + message.appendInt(0); + message.appendInt(-1); + message.appendInt(10); + message.appendInt(1); + message.appendInt(this.type); + message.appendInt(this.hue); + message.appendInt(2); + message.appendInt(this.mouth); + message.appendInt(this.mouthColor); + message.appendInt(3); + message.appendInt(this.nose); + message.appendInt(this.noseColor); + message.appendInt(4); + message.appendInt(this.eyes); + message.appendInt(this.eyesColor); + + message.appendInt(this.growthStage); + } + + public int remainingTimeToLive() { + return Math.max(0, this.deathTimestamp - Emulator.getIntUnixTimestamp()); + } + + public boolean isDead() { + return Emulator.getIntUnixTimestamp() >= this.deathTimestamp; + } + + public void setDeathTimestamp(int deathTimestamp) { + this.deathTimestamp = deathTimestamp; + } + + public int getGrowthStage() { + return this.growthStage; + } + + public int remainingGrowTime() { + if (this.growthStage == 7) { + return 0; + } + + return Math.max(0, growTime - (Emulator.getIntUnixTimestamp() - this.created)); + } + + public boolean isFullyGrown() { + return this.growthStage == 7; + } + + public boolean canBreed() { + return this.canBreed; + } + + public void setCanBreed(boolean canBreed) { + this.canBreed = canBreed; + } + + public boolean breedable() { + return this.isFullyGrown() && this.canBreed && !this.isDead(); + } + + public boolean isPubliclyBreedable() { + return this.publiclyBreedable; + } + + public void setPubliclyBreedable(boolean isPubliclyBreedable) { + this.publiclyBreedable = isPubliclyBreedable; + } + + public void breed(MonsterplantPet pet) { + if (this.canBreed && pet.canBreed) { + this.canBreed = false; + this.publiclyBreedable = false; + + pet.setCanBreed(false); + pet.setPubliclyBreedable(false); + this.room.sendComposer(new PetStatusUpdateComposer(pet).compose()); + this.room.sendComposer(new PetStatusUpdateComposer(this).compose()); + + this.getRoomUnit().setStatus(RoomUnitStatus.GESTURE, "reb"); + pet.getRoomUnit().setStatus(RoomUnitStatus.GESTURE, "reb"); + + this.room.sendComposer(new RoomUserStatusComposer(this.getRoomUnit()).compose()); + this.room.sendComposer(new RoomUserStatusComposer(pet.getRoomUnit()).compose()); + + this.getRoomUnit().removeStatus(RoomUnitStatus.GESTURE); + pet.getRoomUnit().removeStatus(RoomUnitStatus.GESTURE); + + Habbo ownerOne = this.room.getHabbo(this.getUserId()); + Habbo ownerTwo = null; + + if (this.getUserId() != pet.getUserId()) { + ownerTwo = this.room.getHabbo(pet.getUserId()); + } + + Item seedBase; + + if (this.getRarity() < 8 || pet.getRarity() < 8 || Emulator.getRandom().nextInt(100) > this.getRarity() + pet.getRarity()) { + seedBase = Emulator.getGameEnvironment().getItemManager().getItem(Emulator.getConfig().getInt("monsterplant.seed.item_id")); + } else { + seedBase = Emulator.getGameEnvironment().getItemManager().getItem(Emulator.getConfig().getInt("monsterplant.seed_rare.item_id")); + } + + if (seedBase != null) { + HabboItem seed; + if (ownerOne != null) { + AchievementManager.progressAchievement(ownerOne, Emulator.getGameEnvironment().getAchievementManager().getAchievement("MonsterPlantBreeder"), 5); + seed = Emulator.getGameEnvironment().getItemManager().createItem(ownerOne.getHabboInfo().getId(), seedBase, 0, 0, ""); + ownerOne.getInventory().getItemsComponent().addItem(seed); + ownerOne.getClient().sendResponse(new AddHabboItemComposer(seed)); + ownerOne.getClient().sendResponse(new InventoryRefreshComposer()); + } + + if (ownerTwo != null) { + AchievementManager.progressAchievement(ownerTwo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("MonsterPlantBreeder"), 5); + seed = Emulator.getGameEnvironment().getItemManager().createItem(ownerTwo.getHabboInfo().getId(), seedBase, 0, 0, ""); + ownerTwo.getInventory().getItemsComponent().addItem(seed); + ownerTwo.getClient().sendResponse(new AddHabboItemComposer(seed)); + ownerTwo.getClient().sendResponse(new InventoryRefreshComposer()); + } + } + } + } + + private boolean mayScratch() { + // Monsterplant petting is available when: + // ((energy / max_energy) < 0.98) = true + // You can find the minimum deathTimestamp by solving (insert a timestamp for timestamp, solve for death_timestamp): + // (((death_timestamp - timestamp) / 259200)) < 0.98 + // This information was found in the Habbo swf, com.sulake.habbo.ui.widget.infostand.InfoStandPetView.as + // this._Str_2304("pettreat", ((_local_3 / _local_4) < 0.98)); + final float energy = this.getEnergy(); + final float energyMax = this.getMaxEnergy(); + + return ((energy / energyMax) < 0.98); + } + + @Override + public int getMaxEnergy() { + return MonsterplantPet.timeToLive; + } + + @Override + public int getEnergy() { + if (this.isDead()) { + return 100; + } + + return this.deathTimestamp - Emulator.getIntUnixTimestamp(); + } + + @Override + public synchronized void scratched(Habbo habbo) { + if (this.mayScratch()) { + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("MonsterPlantTreater"), 5); + this.setDeathTimestamp(Emulator.getIntUnixTimestamp() + MonsterplantPet.timeToLive); + this.addHappyness(10); + this.addExperience(10); + this.room.sendComposer(new PetStatusUpdateComposer(this).compose()); + this.room.sendComposer(new RoomPetRespectComposer(this, RoomPetRespectComposer.PET_TREATED).compose()); + } + } + + @Override + public boolean canWalk() { + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/Pet.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/Pet.java new file mode 100644 index 0000000..6f9b976 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/Pet.java @@ -0,0 +1,754 @@ +package com.eu.habbo.habbohotel.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.pets.PetLevelUpdatedComposer; +import com.eu.habbo.messages.outgoing.rooms.pets.RoomPetExperienceComposer; +import com.eu.habbo.messages.outgoing.rooms.pets.RoomPetRespectComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserRemoveComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserTalkComposer; +import com.eu.habbo.plugin.events.pets.PetTalkEvent; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; +import java.sql.*; +import java.util.Calendar; +import java.util.Map; +import java.util.TimeZone; + +@Slf4j +public class Pet implements ISerialize, Runnable { + public int levelThirst; + public int levelHunger; + public boolean needsUpdate = false; + public boolean packetUpdate = false; + protected int id; + protected int userId; + protected Room room; + protected String name; + protected PetData petData; + protected int race; + protected String color; + protected int happyness; + protected int experience; + protected int energy; + protected int respect; + protected int created; + protected int level; + RoomUnit roomUnit; + private int chatTimeout; + private int tickTimeout = Emulator.getIntUnixTimestamp(); + private int happynessDelay = Emulator.getIntUnixTimestamp(); + private int gestureTickTimeout = Emulator.getIntUnixTimestamp(); + private int randomActionTickTimeout = Emulator.getIntUnixTimestamp(); + private int postureTimeout = Emulator.getIntUnixTimestamp(); + private int stayStartedAt = 0; + private int idleCommandTicks = 0; + private int freeCommandTicks = -1; + + private PetTasks task = PetTasks.FREE; + + private boolean muted = false; + + public Pet(ResultSet set) throws SQLException { + super(); + this.id = set.getInt("id"); + this.userId = set.getInt("user_id"); + this.room = null; + this.name = set.getString("name"); + this.petData = Emulator.getGameEnvironment().getPetManager().getPetData(set.getInt("type")); + if (this.petData == null) { + log.error("WARNING! Missing pet data for type: " + set.getInt("type") + "! Insert a new entry into the pet_actions table for this type!"); + this.petData = Emulator.getGameEnvironment().getPetManager().getPetData(0); + } + this.race = set.getInt("race"); + this.experience = set.getInt("experience"); + this.happyness = set.getInt("happyness"); + this.energy = set.getInt("energy"); + this.respect = set.getInt("respect"); + this.created = set.getInt("created"); + this.color = set.getString("color"); + this.levelThirst = set.getInt("thirst"); + this.levelHunger = set.getInt("hunger"); + this.level = PetManager.getLevel(this.experience); + } + + public Pet(int type, int race, String color, String name, int userId) { + this.id = 0; + this.userId = userId; + this.room = null; + this.name = name; + this.petData = Emulator.getGameEnvironment().getPetManager().getPetData(type); + + if (this.petData == null) { + log.warn("Missing pet data for type: " + type + "! Insert a new entry into the pet_actions table for this type!"); + } + + this.race = race; + this.color = color; + this.experience = 0; + this.happyness = 100; + this.energy = 100; + this.respect = 0; + this.levelThirst = 0; + this.levelHunger = 0; + this.created = Emulator.getIntUnixTimestamp(); + this.level = 1; + } + + + protected void say(String message) { + if (this.roomUnit != null && this.room != null && !message.isEmpty()) { + RoomChatMessage chatMessage = new RoomChatMessage(message, this.roomUnit, RoomChatMessageBubbles.NORMAL); + PetTalkEvent talkEvent = new PetTalkEvent(this, chatMessage); + if (!Emulator.getPluginManager().fireEvent(talkEvent).isCancelled()) { + this.room.petChat(new RoomUserTalkComposer(chatMessage).compose()); + } + } + } + + + public void say(PetVocal vocal) { + if (vocal != null) + this.say(vocal.message); + } + + + public void addEnergy(int amount) { + this.energy += amount; + + if (this.energy > PetManager.maxEnergy(this.level)) + this.energy = PetManager.maxEnergy(this.level); + + if (this.energy < 0) + this.energy = 0; + } + + + public void addHappyness(int amount) { + this.happyness += amount; + + if (this.happyness > 100) + this.happyness = 100; + + if (this.happyness < 0) + this.happyness = 0; + } + + public int getRespect() { + return this.respect; + } + + public void addRespect() { + this.respect++; + } + + + public int daysAlive() { + return (Emulator.getIntUnixTimestamp() - this.created) / 86400; + } + + + public String bornDate() { + + Calendar cal = Calendar.getInstance(TimeZone.getDefault()); + cal.setTime(new java.util.Date(this.created)); + + return cal.get(Calendar.DAY_OF_MONTH) + "/" + cal.get(Calendar.MONTH) + "/" + cal.get(Calendar.YEAR); + } + + @Override + public void run() { + if (this.needsUpdate) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + if (this.id > 0) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE users_pets SET room_id = ?, experience = ?, energy = ?, respect = ?, x = ?, y = ?, z = ?, rot = ?, hunger = ?, thirst = ?, happyness = ?, created = ? WHERE id = ?")) { + statement.setInt(1, (this.room == null ? 0 : this.room.getId())); + statement.setInt(2, this.experience); + statement.setInt(3, this.energy); + statement.setInt(4, this.respect); + statement.setInt(5, this.roomUnit != null ? this.roomUnit.getX() : 0); + statement.setInt(6, this.roomUnit != null ? this.roomUnit.getY() : 0); + statement.setDouble(7, this.roomUnit != null ? this.roomUnit.getZ() : 0.0); + statement.setInt(8, this.roomUnit != null ? this.roomUnit.getBodyRotation().getValue() : 0); + statement.setInt(9, this.levelHunger); + statement.setInt(10, this.levelThirst); + statement.setInt(11, this.happyness); + statement.setInt(12, this.created); + statement.setInt(13, this.id); + statement.execute(); + } + } else if (this.id == 0) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO users_pets (user_id, room_id, name, race, type, color, experience, energy, respect, created) VALUES (?, 0, ?, ?, ?, ?, 0, 0, 0, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, this.userId); + statement.setString(2, this.name); + statement.setInt(3, this.race); + statement.setInt(4, 0); + + if (this.petData != null) { + statement.setInt(4, this.petData.getType()); + } + + statement.setString(5, this.color); + statement.setInt(6, this.created); + statement.execute(); + + try (ResultSet set = statement.getGeneratedKeys()) { + if (set.next()) { + this.id = set.getInt(1); + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.needsUpdate = false; + } + } + + public void cycle() { + this.idleCommandTicks++; + + int time = Emulator.getIntUnixTimestamp(); + if (this.roomUnit != null && this.task != PetTasks.RIDE) { + if (time - this.gestureTickTimeout > 5 && this.roomUnit.hasStatus(RoomUnitStatus.GESTURE)) { + this.roomUnit.removeStatus(RoomUnitStatus.GESTURE); + this.packetUpdate = true; + } + + if (time - this.postureTimeout > 1 && this.task == null) { + this.clearPosture(); + this.postureTimeout = time + 120; + } + + if (this.freeCommandTicks > 0) { + this.freeCommandTicks--; + + if (this.freeCommandTicks == 0) { + this.freeCommand(); + } + } + + if (!this.roomUnit.isWalking()) { + if (this.roomUnit.getWalkTimeOut() < time && this.canWalk()) { + RoomTile tile = this.room.getRandomWalkableTile(); + + if (tile != null) { + this.roomUnit.setGoalLocation(tile); + } + } + + if (this.task == PetTasks.NEST || this.task == PetTasks.DOWN) { + if (this.levelHunger > 0) + this.levelHunger--; + + if (this.levelThirst > 0) + this.levelThirst--; + + this.addEnergy(5); + + this.addHappyness(1); + + if (this.energy == PetManager.maxEnergy(this.level)) { + this.roomUnit.removeStatus(RoomUnitStatus.LAY); + this.roomUnit.setCanWalk(true); + this.roomUnit.setGoalLocation(this.room.getRandomWalkableTile()); + this.task = null; + this.roomUnit.setStatus(RoomUnitStatus.GESTURE, PetGestures.ENERGY.getKey()); + this.gestureTickTimeout = time; + } + } else if (this.tickTimeout >= 5) { + if (this.levelHunger < 100) + this.levelHunger++; + + if (this.levelThirst < 100) + this.levelThirst++; + + if (this.energy < PetManager.maxEnergy(this.level)) + this.energy++; + + this.tickTimeout = time; + } + + if (this.task == PetTasks.STAY && Emulator.getIntUnixTimestamp() - this.stayStartedAt >= 120) { + this.task = null; + this.getRoomUnit().setCanWalk(true); + } + } else { + int timeout = Emulator.getRandom().nextInt(10) * 2; + this.roomUnit.setWalkTimeOut(timeout < 20 ? 20 + time : timeout + time); + + if (this.energy >= 2) + this.addEnergy(-1); + + if (this.levelHunger < 100) + this.levelHunger++; + + if (this.levelThirst < 100) + this.levelThirst++; + + if (this.happyness > 0 && time - this.happynessDelay >= 30) { + this.happyness--; + this.happynessDelay = time; + } + } + + if (time - this.gestureTickTimeout > 15) { + this.updateGesture(time); + } else if (time - this.randomActionTickTimeout > 30) { + this.randomAction(); + this.randomActionTickTimeout = time + (10 * Emulator.getRandom().nextInt(60)); + } + + if (!this.muted) { + if (this.chatTimeout <= time) { + if (this.energy <= 30) { + this.say(this.petData.randomVocal(PetVocalsType.TIRED)); + if (this.energy <= 10) + this.findNest(); + } else if (this.happyness > 85) { + this.say(this.petData.randomVocal(PetVocalsType.GENERIC_HAPPY)); + } else if (this.happyness < 15) { + this.say(this.petData.randomVocal(PetVocalsType.GENERIC_SAD)); + } else if (this.levelHunger > 50) { + this.say(this.petData.randomVocal(PetVocalsType.HUNGRY)); + this.eat(); + } else if (this.levelThirst > 50) { + this.say(this.petData.randomVocal(PetVocalsType.THIRSTY)); + this.drink(); + } + + int timeOut = Emulator.getRandom().nextInt(30); + this.chatTimeout = time + (timeOut < 3 ? 30 : timeOut); + } + } + } + } + + + public void handleCommand(PetCommand command, Habbo habbo, String[] data) { + this.idleCommandTicks = 0; + + if (this.task == PetTasks.STAY) { + this.stayStartedAt = 0; + this.task = null; + this.getRoomUnit().setCanWalk(true); + } + + command.handle(this, habbo, data); + + + } + + public boolean canWalk() { + if (this.task == null) + return true; + + switch (this.task) { + case DOWN: + case FLAT: + case HERE: + case SIT: + case BEG: + case PLAY: + case PLAY_FOOTBALL: + case PLAY_DEAD: + case FOLLOW: + case JUMP: + case STAND: + case NEST: + case RIDE: + + return false; + } + + return true; + } + + public void clearPosture() { + THashMap keys = new THashMap<>(); + + if (this.roomUnit.hasStatus(RoomUnitStatus.MOVE)) + keys.put(RoomUnitStatus.MOVE, this.roomUnit.getStatus(RoomUnitStatus.MOVE)); + + if (this.roomUnit.hasStatus(RoomUnitStatus.SIT)) + keys.put(RoomUnitStatus.SIT, this.roomUnit.getStatus(RoomUnitStatus.SIT)); + + if (this.roomUnit.hasStatus(RoomUnitStatus.LAY)) + keys.put(RoomUnitStatus.LAY, this.roomUnit.getStatus(RoomUnitStatus.LAY)); + + if (this.roomUnit.hasStatus(RoomUnitStatus.GESTURE)) + keys.put(RoomUnitStatus.GESTURE, this.roomUnit.getStatus(RoomUnitStatus.GESTURE)); + + if (this.task == null) { + boolean isDead = false; + if (this.roomUnit.hasStatus(RoomUnitStatus.RIP)) + isDead = true; + + this.roomUnit.clearStatus(); + + if (isDead) this.roomUnit.setStatus(RoomUnitStatus.RIP, ""); + for (Map.Entry entry : keys.entrySet()) { + this.roomUnit.setStatus(entry.getKey(), entry.getValue()); + } + + if (!keys.isEmpty()) this.packetUpdate = true; + } + } + + public void updateGesture(int time) { + this.gestureTickTimeout = time; + if (this.energy < 30) { + this.roomUnit.setStatus(RoomUnitStatus.GESTURE, PetGestures.TIRED.getKey()); + this.findNest(); + } else if (this.happyness == 100) { + this.roomUnit.setStatus(RoomUnitStatus.GESTURE, PetGestures.LOVE.getKey()); + } else if (this.happyness >= 90) { + this.randomHappyAction(); + this.roomUnit.setStatus(RoomUnitStatus.GESTURE, PetGestures.HAPPY.getKey()); + } else if (this.happyness <= 5) { + this.randomSadAction(); + this.roomUnit.setStatus(RoomUnitStatus.GESTURE, PetGestures.SAD.getKey()); + } else if (this.levelHunger > 80) { + this.roomUnit.setStatus(RoomUnitStatus.GESTURE, PetGestures.HUNGRY.getKey()); + this.eat(); + } else if (this.levelThirst > 80) { + this.roomUnit.setStatus(RoomUnitStatus.GESTURE, PetGestures.THIRSTY.getKey()); + this.drink(); + } else if (this.idleCommandTicks > 240) { + this.idleCommandTicks = 0; + + this.roomUnit.setStatus(RoomUnitStatus.GESTURE, PetGestures.QUESTION.getKey()); + } + } + + @Override + public void serialize(ServerMessage message) { + message.appendInt(this.id); + message.appendString(this.name); + if (this.petData != null) { + message.appendInt(this.petData.getType()); + } else { + message.appendInt(-1); + } + message.appendInt(this.race); + message.appendString(this.color); + message.appendInt(0); + message.appendInt(0); + message.appendInt(0); + } + + + public void findNest() { + HabboItem item = this.petData.randomNest(this.room.getRoomSpecialTypes().getNests()); + this.roomUnit.setCanWalk(true); + if (item != null) { + this.roomUnit.setGoalLocation(this.room.getLayout().getTile(item.getX(), item.getY())); + } else { + this.roomUnit.setStatus(RoomUnitStatus.LAY, this.room.getStackHeight(this.roomUnit.getX(), this.roomUnit.getY(), false) + ""); + this.say(this.petData.randomVocal(PetVocalsType.SLEEPING)); + this.task = PetTasks.DOWN; + } + } + + + public void drink() { + HabboItem item = this.petData.randomDrinkItem(this.room.getRoomSpecialTypes().getPetDrinks()); + if (item != null) { + this.roomUnit.setCanWalk(true); + this.roomUnit.setGoalLocation(this.room.getLayout().getTile(item.getX(), item.getY())); + } + } + + + public void eat() { + HabboItem item = this.petData.randomFoodItem(this.room.getRoomSpecialTypes().getPetFoods()); + { + if (item != null) { + this.roomUnit.setCanWalk(true); + this.roomUnit.setGoalLocation(this.room.getLayout().getTile(item.getX(), item.getY())); + } + } + } + + + public void findToy() { + HabboItem item = this.petData.randomToyItem(this.room.getRoomSpecialTypes().getPetToys()); + { + if (item != null) { + this.roomUnit.setCanWalk(true); + this.roomUnit.setGoalLocation(this.room.getLayout().getTile(item.getX(), item.getY())); + } + } + } + + + public void randomHappyAction() { + if (this.petData.actionsHappy.length > 0) { + this.roomUnit.setStatus(RoomUnitStatus.fromString(this.petData.actionsHappy[Emulator.getRandom().nextInt(this.petData.actionsHappy.length)]), ""); + } + } + + + public void randomSadAction() { + if (this.petData.actionsTired.length > 0) { + this.roomUnit.setStatus(RoomUnitStatus.fromString(this.petData.actionsTired[Emulator.getRandom().nextInt(this.petData.actionsTired.length)]), ""); + } + } + + + public void randomAction() { + if (this.petData.actionsRandom.length > 0) { + this.roomUnit.setStatus(RoomUnitStatus.fromString(this.petData.actionsRandom[Emulator.getRandom().nextInt(this.petData.actionsRandom.length)]), ""); + } + } + + + public void addExperience(int amount) { + this.experience += amount; + + if (this.room != null) { + this.room.sendComposer(new RoomPetExperienceComposer(this, amount).compose()); + + if(this.level < PetManager.experiences.length + 1 && this.experience >= PetManager.experiences[this.level - 1]) { + this.levelUp(); + } + } + } + + + protected void levelUp() { + if (this.level >= PetManager.experiences.length + 1) + return; + + if (this.experience > PetManager.experiences[this.level - 1]) { + this.experience = PetManager.experiences[this.level - 1]; + } + this.level++; + this.say(this.petData.randomVocal(PetVocalsType.LEVEL_UP)); + this.addHappyness(100); + this.roomUnit.setStatus(RoomUnitStatus.GESTURE, "exp"); + this.gestureTickTimeout = Emulator.getIntUnixTimestamp(); + AchievementManager.progressAchievement(Emulator.getGameEnvironment().getHabboManager().getHabbo(this.userId), Emulator.getGameEnvironment().getAchievementManager().getAchievement("PetLevelUp")); + this.room.sendComposer(new PetLevelUpdatedComposer(this).compose()); + } + + + public void addThirst(int amount) { + this.levelThirst += amount; + + if (this.levelThirst > 100) + this.levelThirst = 100; + + if (this.levelThirst < 0) + this.levelThirst = 0; + } + + + public void addHunger(int amount) { + this.levelHunger += amount; + + if (this.levelHunger > 100) + this.levelHunger = 100; + + if (this.levelHunger < 0) + this.levelHunger = 0; + } + + + public void freeCommand() { + this.task = null; + this.roomUnit.setGoalLocation(this.getRoomUnit().getCurrentLocation()); + this.roomUnit.clearStatus(); + this.roomUnit.setCanWalk(true); + this.say(this.petData.randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + } + + + public void scratched(Habbo habbo) { + this.addHappyness(10); + this.addExperience(10); + this.addRespect(); + this.needsUpdate = true; + + if (habbo != null) { + habbo.getHabboStats().petRespectPointsToGive--; + habbo.getHabboInfo().getCurrentRoom().sendComposer(new RoomPetRespectComposer(this).compose()); + + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("PetRespectGiver")); + } + + AchievementManager.progressAchievement(Emulator.getGameEnvironment().getHabboManager().getHabbo(this.userId), Emulator.getGameEnvironment().getAchievementManager().getAchievement("PetRespectReceiver")); + } + + + public int getId() { + return this.id; + } + + public int getUserId() { + return this.userId; + } + + public void setUserId(int userId) { + this.userId = userId; + } + + public Room getRoom() { + return this.room; + } + + public void setRoom(Room room) { + this.room = room; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public PetData getPetData() { + return this.petData; + } + + public void setPetData(PetData petData) { + this.petData = petData; + } + + public int getRace() { + return this.race; + } + + public void setRace(int race) { + this.race = race; + } + + public String getColor() { + return this.color; + } + + public void setColor(String color) { + this.color = color; + } + + public int getHappyness() { + return this.happyness; + } + + public void setHappyness(int happyness) { + this.happyness = happyness; + } + + public int getExperience() { + return this.experience; + } + + public void setExperience(int experience) { + this.experience = experience; + } + + public int getEnergy() { + return this.energy; + } + + public void setEnergy(int energy) { + this.energy = energy; + } + + public int getMaxEnergy() { + return this.level * 100; + } + + public int getCreated() { + return this.created; + } + + public void setCreated(int created) { + this.created = created; + } + + public int getLevel() { + return this.level; + } + + public void setLevel(int level) { + this.level = level; + } + + public RoomUnit getRoomUnit() { + return this.roomUnit; + } + + public void setRoomUnit(RoomUnit roomUnit) { + this.roomUnit = roomUnit; + } + + public PetTasks getTask() { + return this.task; + } + + public void setTask(PetTasks newTask) { + this.task = newTask; + } + + public boolean isMuted() { + return this.muted; + } + + public void setMuted(boolean muted) { + this.muted = muted; + } + + public int getLevelThirst() { + return this.levelThirst; + } + + public void setLevelThirst(int levelThirst) { + this.levelThirst = levelThirst; + } + + public int getLevelHunger() { + return this.levelHunger; + } + + public void setLevelHunger(int levelHunger) { + this.levelHunger = levelHunger; + } + + public void removeFromRoom() { + removeFromRoom(false); + } + + public void removeFromRoom(boolean dontSendPackets) { + + if (this.roomUnit != null && this.roomUnit.getCurrentLocation() != null) { + this.roomUnit.getCurrentLocation().removeUnit(this.roomUnit); + } + + if (!dontSendPackets) { + room.sendComposer(new RoomUserRemoveComposer(this.roomUnit).compose()); + room.removePet(this.id); + } + + this.roomUnit = null; + this.room = null; + this.needsUpdate = true; + } + + public int getStayStartedAt() { + return stayStartedAt; + } + + public void setStayStartedAt(int stayStartedAt) { + this.stayStartedAt = stayStartedAt; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetAction.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetAction.java new file mode 100644 index 0000000..919da87 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetAction.java @@ -0,0 +1,25 @@ +package com.eu.habbo.habbohotel.pets; + +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.util.ArrayList; +import java.util.List; + +public abstract class PetAction { + + public final PetTasks petTask; + public final boolean stopsPetWalking; + public final List statusToRemove = new ArrayList<>(); + public final List statusToSet = new ArrayList<>(); + public int minimumActionDuration = 500; + public String gestureToSet = null; + + protected PetAction(PetTasks petTask, boolean stopsPetWalking) { + this.petTask = petTask; + this.stopsPetWalking = stopsPetWalking; + } + + + public abstract boolean apply(Pet pet, Habbo habbo, String[] data); +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetBreedingReward.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetBreedingReward.java new file mode 100644 index 0000000..82720c5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetBreedingReward.java @@ -0,0 +1,21 @@ +package com.eu.habbo.habbohotel.pets; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class PetBreedingReward { + + public final int petType; + + + public final int rarityLevel; + + + public final int breed; + + public PetBreedingReward(ResultSet set) throws SQLException { + this.petType = set.getInt("pet_type"); + this.rarityLevel = set.getInt("rarity_level"); + this.breed = set.getInt("breed"); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetCommand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetCommand.java new file mode 100644 index 0000000..e2ca68a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetCommand.java @@ -0,0 +1,76 @@ +package com.eu.habbo.habbohotel.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class PetCommand implements Comparable { + + public final int id; + + + public final String key; + + + public final int level; + + + public final int xp; + + + public final int energyCost; + + + public final int happynessCost; + + + public final PetAction action; + + public PetCommand(ResultSet set, PetAction action) throws SQLException { + this.id = set.getInt("command_id"); + this.key = set.getString("text"); + this.level = set.getInt("required_level"); + this.xp = set.getInt("reward_xp"); + this.energyCost = set.getInt("cost_energy"); + this.happynessCost = set.getInt("cost_happyness"); + this.action = action; + } + + @Override + public int compareTo(PetCommand o) { + return this.level - o.level; + } + + public void handle(Pet pet, Habbo habbo, String[] data) { + if (Emulator.getRandom().nextInt((pet.level - this.level <= 0 ? 2 : pet.level - this.level) + 2) == 0) { + pet.say(pet.petData.randomVocal(PetVocalsType.DISOBEY)); + return; + } + + if (this.action != null) { + if (this.action.petTask != pet.getTask()) { + if (this.action.stopsPetWalking) { + pet.getRoomUnit().setGoalLocation(pet.getRoomUnit().getCurrentLocation()); + } + if (this.action.apply(pet, habbo, data)) { + for (RoomUnitStatus status : this.action.statusToRemove) { + pet.getRoomUnit().removeStatus(status); + } + + for (RoomUnitStatus status : this.action.statusToSet) { + pet.getRoomUnit().setStatus(status, "0"); + } + + pet.getRoomUnit().setStatus(RoomUnitStatus.GESTURE, this.action.gestureToSet); + + pet.addEnergy(-this.energyCost); + pet.addHappyness(-this.happynessCost); + pet.addExperience(this.xp); + } + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetData.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetData.java new file mode 100644 index 0000000..1eae8a4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetData.java @@ -0,0 +1,277 @@ +package com.eu.habbo.habbohotel.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionNest; +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetDrink; +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetFood; +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetToy; +import com.eu.habbo.habbohotel.users.HabboItem; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class PetData implements Comparable { + + public static final String BLINK = "eyb"; + public static final String SPEAK = "spk"; + public static final String EAT = "eat"; + public static final String PLAYFUL = "pla"; + public static final List generalDrinkItems = new ArrayList<>(); + public static final List generalFoodItems = new ArrayList<>(); + public static final List generalNestItems = new ArrayList<>(); + public static final List generalToyItems = new ArrayList<>(); + public static final THashMap> generalPetVocals = new THashMap<>(); + public String[] actionsHappy; + public String[] actionsTired; + public String[] actionsRandom; + public THashMap> petVocals; + public boolean canSwim; + private int type; + private String name; + private List petCommands; + private List nestItems; + private List foodItems; + private List drinkItems; + private List toyItems; + private int offspringType; + + public PetData(ResultSet set) throws SQLException { + this.load(set); + } + + public void load(ResultSet set) throws SQLException { + this.type = set.getInt("pet_type"); + this.name = set.getString("pet_name"); + this.offspringType = set.getInt("offspring_type"); + this.actionsHappy = set.getString("happy_actions").split(";"); + this.actionsTired = set.getString("tired_actions").split(";"); + this.actionsRandom = set.getString("random_actions").split(";"); + this.canSwim = set.getString("can_swim").equalsIgnoreCase("1"); + + this.reset(); + } + + public List getPetCommands() { + return this.petCommands; + } + + public void setPetCommands(List petCommands) { + this.petCommands = petCommands; + } + + public int getType() { + return this.type; + } + + + public String getName() { + return this.name; + } + + + public int getOffspringType() { + return this.offspringType; + } + + + public void addNest(Item nest) { + if (nest != null) + this.nestItems.add(nest); + } + + + public List getNests() { + return this.nestItems; + } + + + public boolean haveNest(HabboItem nest) { + return this.haveNest(nest.getBaseItem()); + } + + + boolean haveNest(Item nest) { + return PetData.generalNestItems.contains(nest) || this.nestItems.contains(nest); + } + + + public HabboItem randomNest(THashSet items) { + List nestList = new ArrayList<>(); + + for (InteractionNest nest : items) { + if (this.haveNest(nest)) { + nestList.add(nest); + } + } + + if (!nestList.isEmpty()) { + Collections.shuffle(nestList); + + return nestList.get(0); + } + + return null; + } + + + public void addFoodItem(Item food) { + this.foodItems.add(food); + } + + + public List getFoodItems() { + return this.foodItems; + } + + + public boolean haveFoodItem(HabboItem food) { + return this.haveFoodItem(food.getBaseItem()); + } + + + boolean haveFoodItem(Item food) { + return this.foodItems.contains(food) || PetData.generalFoodItems.contains(food); + } + + + public HabboItem randomFoodItem(THashSet items) { + List foodList = new ArrayList<>(); + + for (InteractionPetFood food : items) { + if (this.haveFoodItem(food)) { + foodList.add(food); + } + } + + if (!foodList.isEmpty()) { + Collections.shuffle(foodList); + return foodList.get(0); + } + + return null; + } + + + public void addDrinkItem(Item item) { + this.drinkItems.add(item); + } + + + public List getDrinkItems() { + return this.drinkItems; + } + + + public boolean haveDrinkItem(HabboItem item) { + return this.haveDrinkItem(item.getBaseItem()); + } + + + boolean haveDrinkItem(Item item) { + return this.drinkItems.contains(item) || PetData.generalDrinkItems.contains(item); + } + + + public HabboItem randomDrinkItem(THashSet items) { + List drinkList = new ArrayList<>(); + + for (InteractionPetDrink drink : items) { + if (this.haveDrinkItem(drink)) { + drinkList.add(drink); + } + } + + if (!drinkList.isEmpty()) { + Collections.shuffle(drinkList); + return drinkList.get(0); + } + + return null; + } + + + public void addToyItem(Item toy) { + this.toyItems.add(toy); + } + + + public List getToyItems() { + return this.toyItems; + } + + + public boolean haveToyItem(HabboItem toy) { + return this.haveToyItem(toy.getBaseItem()); + } + + + public boolean haveToyItem(Item toy) { + return this.toyItems.contains(toy) || PetData.generalToyItems.contains(toy); + } + + + public HabboItem randomToyItem(THashSet toys) { + List toyList = new ArrayList<>(); + + for (InteractionPetToy toy : toys) { + if (this.haveToyItem(toy)) { + toyList.add(toy); + } + } + + if (!toyList.isEmpty()) { + Collections.shuffle(toyList); + return toyList.get(0); + } + + return null; + } + + + public PetVocal randomVocal(PetVocalsType type) { + //TODO: Remove this useless copying. + List vocals = new ArrayList<>(); + + if (this.petVocals.get(type) != null) + vocals.addAll(this.petVocals.get(type)); + + if (PetData.generalPetVocals.get(type) != null) + vocals.addAll(PetData.generalPetVocals.get(type)); + + if (vocals.isEmpty()) + return null; + + return vocals.get(Emulator.getRandom().nextInt(vocals.size())); + } + + @Override + public int compareTo(PetData o) { + return this.getType() - o.getType(); + } + + public void reset() { + this.petCommands = new ArrayList<>(); + this.nestItems = new ArrayList<>(); + this.foodItems = new ArrayList<>(); + this.drinkItems = new ArrayList<>(); + this.toyItems = new ArrayList<>(); + + this.petVocals = new THashMap<>(); + + for (PetVocalsType type : PetVocalsType.values()) { + this.petVocals.put(type, new THashSet<>()); + } + + if (PetData.generalPetVocals.isEmpty()) { + for (PetVocalsType type : PetVocalsType.values()) { + PetData.generalPetVocals.put(type, new THashSet<>()); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetGestures.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetGestures.java new file mode 100644 index 0000000..61f0aed --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetGestures.java @@ -0,0 +1,25 @@ +package com.eu.habbo.habbohotel.pets; + +public enum PetGestures { + THIRSTY("thr"), + TIRED("trd"), + PLAYFULL("plf"), + HUNGRY("hng"), + SAD("sad"), + HAPPY("sml"), + QUESTION("que"), + LVLUP("exp"), + LOVE("lov"), + WARNING("und"), + ENERGY("nrg"); + + private final String key; + + PetGestures(String key) { + this.key = key; + } + + public String getKey() { + return this.key; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetManager.java new file mode 100644 index 0000000..109d7ce --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetManager.java @@ -0,0 +1,520 @@ +package com.eu.habbo.habbohotel.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionNest; +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetDrink; +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetFood; +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetToy; +import com.eu.habbo.habbohotel.pets.actions.*; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import gnu.trove.map.TIntIntMap; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntIntHashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.procedure.TIntObjectProcedure; +import gnu.trove.set.hash.THashSet; +import org.apache.commons.math3.distribution.NormalDistribution; +import lombok.extern.slf4j.Slf4j; +import java.sql.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; + +@Slf4j +public class PetManager { + public static int MAXIMUM_PET_INVENTORY_SIZE = 25; + public static final int[] experiences = new int[]{100, 200, 400, 600, 900, 1300, 1800, 2400, 3200, 4300, 5700, 7600, 10100, 13300, 17500, 23000, 30200, 39600, 51900}; + static int[] skins = new int[]{0, 1, 6, 7}; + public final THashMap petActions = new THashMap() { + { + this.put(0, new ActionFree()); + this.put(1, new ActionSit()); + this.put(2, new ActionDown()); + this.put(3, new ActionHere()); + this.put(4, new ActionBeg()); + this.put(5, new ActionPlayDead()); + this.put(6, new ActionStay()); + this.put(7, new ActionFollow()); + this.put(8, new ActionStand()); + this.put(9, new ActionJump()); + this.put(10, new ActionSpeak()); + this.put(11, new ActionPlay()); + this.put(12, new ActionSilent()); + this.put(13, new ActionNest()); + this.put(14, new ActionDrink()); + this.put(15, new ActionFollowLeft()); + this.put(16, new ActionFollowRight()); + this.put(17, new ActionPlayFootball()); + this.put(24, new ActionMoveForward()); + this.put(25, new ActionTurnLeft()); + this.put(26, new ActionTurnRight()); + this.put(27, new ActionRelax()); + this.put(28, new ActionCroak()); + this.put(29, new ActionDip()); + this.put(30, new ActionWave()); + this.put(35, new ActionWings()); + this.put(36, new ActionBreatheFire()); + this.put(38, new ActionTorch()); + this.put(43, new ActionEat()); + this.put(46, new ActionBreed()); + + } + }; + private final THashMap> petRaces; + private final THashMap petData; + private final TIntIntMap breedingPetType; + private final THashMap>> breedingReward; + + + public PetManager() { + long millis = System.currentTimeMillis(); + + this.petRaces = new THashMap<>(); + this.petData = new THashMap<>(); + this.breedingPetType = new TIntIntHashMap(); + this.breedingReward = new THashMap<>(); + + reloadPetData(); + + log.info("Pet Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)"); + } + + public static int getLevel(int experience) { + int index = -1; + + for (int i = 0; i < experiences.length; i++) { + if (experiences[i] > experience) { + index = i; + break; + } + } + + if(index == -1) { index = experiences.length; } + return index + 1; + } + + public static int maxEnergy(int level) { + //TODO: Add energy calculation. + return 100 * level; + } + + public static int randomBody(int minimumRarity, boolean isRare) { + int randomRarity = isRare ? random(Math.max(minimumRarity - 1, 0), (MonsterplantPet.bodyRarity.size() - minimumRarity) + (minimumRarity - 1), 2.0) : random(Math.max(minimumRarity - 1, 0), MonsterplantPet.bodyRarity.size(), 2.0); + + return MonsterplantPet.bodyRarity.get(MonsterplantPet.bodyRarity.keySet().toArray()[randomRarity]).getValue(); + } + + public static int randomColor(int minimumRarity, boolean isRare) { + int randomRarity = isRare ? random(Math.max(minimumRarity - 1, 0), (MonsterplantPet.colorRarity.size() - minimumRarity) + (minimumRarity - 1), 2.0) : random(Math.max(minimumRarity - 1, 0), MonsterplantPet.colorRarity.size(), 2.0); + + return MonsterplantPet.colorRarity.get(MonsterplantPet.colorRarity.keySet().toArray()[randomRarity]).getValue(); + } + + public static int random(int low, int high, double bias) { + double r = Math.random(); + r = Math.pow(r, bias); + return (int) (low + (high - low) * r); + } + + public static Pet loadPet(ResultSet set) throws SQLException { + if (set.getInt("type") == 15) + return new HorsePet(set); + else if (set.getInt("type") == 16) + return new MonsterplantPet(set); + else if (set.getInt("type") == 26 || set.getInt("type") == 27) + return new GnomePet(set); + else + return new Pet(set); + } + + public static NormalDistribution getNormalDistributionForBreeding(int levelOne, int levelTwo) { + return getNormalDistributionForBreeding((levelOne + levelTwo) / 2); + } + + public static NormalDistribution getNormalDistributionForBreeding(double avgLevel) { + return new NormalDistribution(avgLevel, (20 - (avgLevel / 2)) / 2); + } + + public void reloadPetData() { + this.petRaces.clear(); + this.petData.clear(); + this.breedingPetType.clear(); + this.breedingReward.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + this.loadRaces(connection); + this.loadPetData(connection); + this.loadPetCommands(connection); + this.loadPetBreeding(connection); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + log.error("Pet Manager -> Failed to load!"); + } + } + + private void loadRaces(Connection connection) { + this.petRaces.clear(); + + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM pet_breeds ORDER BY race, color_one, color_two ASC")) { + while (set.next()) { + if (this.petRaces.get(set.getInt("race")) == null) + this.petRaces.put(set.getInt("race"), new THashSet<>()); + + this.petRaces.get(set.getInt("race")).add(new PetRace(set)); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + private void loadPetData(Connection connection) { + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM pet_actions ORDER BY pet_type ASC")) { + while (set.next()) { + this.petData.put(set.getInt("pet_type"), new PetData(set)); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.loadPetItems(connection); + + this.loadPetVocals(connection); + } + + private void loadPetItems(Connection connection) { + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM pet_items")) { + while (set.next()) { + Item baseItem = Emulator.getGameEnvironment().getItemManager().getItem(set.getInt("item_id")); + + if (baseItem != null) { + if (set.getInt("pet_id") == -1) { + if (baseItem.getInteractionType().getType() == InteractionNest.class) + PetData.generalNestItems.add(baseItem); + else if (baseItem.getInteractionType().getType() == InteractionPetFood.class) + PetData.generalFoodItems.add(baseItem); + else if (baseItem.getInteractionType().getType() == InteractionPetDrink.class) + PetData.generalDrinkItems.add(baseItem); + else if (baseItem.getInteractionType().getType() == InteractionPetToy.class) + PetData.generalToyItems.add(baseItem); + } else { + PetData data = this.getPetData(set.getInt("pet_id")); + + if (data != null) { + if (baseItem.getInteractionType().getType() == InteractionNest.class) + data.addNest(baseItem); + else if (baseItem.getInteractionType().getType() == InteractionPetFood.class) + data.addFoodItem(baseItem); + else if (baseItem.getInteractionType().getType() == InteractionPetDrink.class) + data.addDrinkItem(baseItem); + else if (baseItem.getInteractionType().getType() == InteractionPetToy.class) + data.addToyItem(baseItem); + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + private void loadPetVocals(Connection connection) { + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM pet_vocals")) { + while (set.next()) { + if (set.getInt("pet_id") >= 0) { + if (this.petData.containsKey(set.getInt("pet_id"))) { + PetVocalsType petVocalsType = PetVocalsType.valueOf(set.getString("type").toUpperCase()); + + if (petVocalsType != null) { + this.petData.get(set.getInt("pet_id")).petVocals.get(petVocalsType).add(new PetVocal(set.getString("message"))); + } else { + log.error("Unknown pet vocal type " + set.getString("type")); + } + } else { + log.error("Missing pet_actions table entry for pet id " + set.getInt("pet_id")); + } + } else { + if (!PetData.generalPetVocals.containsKey(PetVocalsType.valueOf(set.getString("type").toUpperCase()))) + PetData.generalPetVocals.put(PetVocalsType.valueOf(set.getString("type").toUpperCase()), new THashSet<>()); + + PetData.generalPetVocals.get(PetVocalsType.valueOf(set.getString("type").toUpperCase())).add(new PetVocal(set.getString("message"))); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + private void loadPetCommands(Connection connection) { + THashMap commandsList = new THashMap<>(); + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM pet_commands_data")) { + while (set.next()) { + commandsList.put(set.getInt("command_id"), new PetCommand(set, this.petActions.get(set.getInt("command_id")))); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM pet_commands ORDER BY pet_id ASC")) { + while (set.next()) { + PetData data = this.petData.get(set.getInt("pet_id")); + + if (data != null) { + data.getPetCommands().add(commandsList.get(set.getInt("command_id"))); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + private void loadPetBreeding(Connection connection) { + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM pet_breeding")) { + while (set.next()) { + this.breedingPetType.put(set.getInt("pet_id"), set.getInt("offspring_id")); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM pet_breeding_races")) { + while (set.next()) { + PetBreedingReward reward = new PetBreedingReward(set); + if (!this.breedingReward.containsKey(reward.petType)) { + this.breedingReward.put(reward.petType, new TIntObjectHashMap<>()); + } + + if (!this.breedingReward.get(reward.petType).containsKey(reward.rarityLevel)) { + this.breedingReward.get(reward.petType).put(reward.rarityLevel, new ArrayList<>()); + } + + this.breedingReward.get(reward.petType).get(reward.rarityLevel).add(reward); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public THashSet getBreeds(String petName) { + if (!petName.startsWith("a0 pet")) { + log.error("Pet " + petName + " not found. Make sure it matches the pattern \"a0 pet\"!"); + return null; + } + + try { + int petId = Integer.valueOf(petName.split("t")[1]); + return this.petRaces.get(petId); + } catch (Exception e) { + log.error("Caught exception", e); + } + + return null; + } + + public TIntObjectHashMap> getBreedingRewards(int petType) { + return this.breedingReward.get(petType); + } + + public int getRarityForOffspring(Pet pet) { + final int[] rarityLevel = {0}; + + TIntObjectHashMap> offspringList = this.breedingReward.get(pet.getPetData().getType()); + + offspringList.forEachEntry(new TIntObjectProcedure>() { + @Override + public boolean execute(int i, ArrayList petBreedingRewards) { + for (PetBreedingReward reward : petBreedingRewards) { + if (reward.breed == pet.getRace()) { + rarityLevel[0] = i; + return false; + } + } + + return true; + } + }); + + return 4 - rarityLevel[0]; + } + + public PetData getPetData(int type) { + synchronized (this.petData) { + if (this.petData.containsKey(type)) { + return this.petData.get(type); + } else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + log.error("Missing petdata for type " + type + ". Adding this to the database..."); + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO pet_actions (pet_type) VALUES (?)")) { + statement.setInt(1, type); + statement.execute(); + } + + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM pet_actions WHERE pet_type = ? LIMIT 1")) { + statement.setInt(1, type); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + PetData petData = new PetData(set); + this.petData.put(type, petData); + log.error("Missing petdata for type " + type + " added to the database!"); + return petData; + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + return null; + } + + public PetData getPetData(String petName) { + synchronized (this.petData) { + for (Map.Entry entry : this.petData.entrySet()) { + if (entry.getValue().getName().equalsIgnoreCase(petName)) { + return entry.getValue(); + } + } + } + + return null; + } + + public Collection getPetData() { + return this.petData.values(); + } + + public Pet createPet(Item item, String name, String race, String color, GameClient client) { + int type = Integer.valueOf(item.getName().toLowerCase().replace("a0 pet", "")); + + if (this.petData.containsKey(type)) { + Pet pet; + if (type == 15) + pet = new HorsePet(type, Integer.valueOf(race), color, name, client.getHabbo().getHabboInfo().getId()); + else if (type == 16) + pet = this.createMonsterplant(null, client.getHabbo(), false, null, 0); + else + pet = new Pet(type, + Integer.valueOf(race), + color, + name, + client.getHabbo().getHabboInfo().getId() + ); + + pet.needsUpdate = true; + pet.run(); + return pet; + } + return null; + } + + public Pet createPet(int type, String name, GameClient client) { + return this.createPet(type, Emulator.getRandom().nextInt(this.petRaces.get(type).size() + 1), name, client); + } + + public Pet createPet(int type, int race, String name, GameClient client) { + if (this.petData.containsKey(type)) { + Pet pet = new Pet(type, race, "FFFFFF", name, client.getHabbo().getHabboInfo().getId()); + pet.needsUpdate = true; + pet.run(); + return pet; + } + return null; + } + + public MonsterplantPet createMonsterplant(Room room, Habbo habbo, boolean rare, RoomTile t, int minimumRarity) { + MonsterplantPet pet = new MonsterplantPet( + habbo.getHabboInfo().getId(), //Owner ID + randomBody(minimumRarity, rare), + randomColor(minimumRarity, rare), + Emulator.getRandom().nextInt(12) + 1, + Emulator.getRandom().nextInt(11), + Emulator.getRandom().nextInt(12) + 1, + Emulator.getRandom().nextInt(11), + Emulator.getRandom().nextInt(12) + 1, + Emulator.getRandom().nextInt(11) + ); + + pet.setUserId(habbo.getHabboInfo().getId()); + pet.setRoom(room); + pet.setRoomUnit(new RoomUnit()); + pet.getRoomUnit().setPathFinderRoom(room); + pet.needsUpdate = true; + pet.run(); + return pet; + } + + public Pet createGnome(String name, Room room, Habbo habbo) { + Pet pet = new GnomePet(26, 0, "FFFFFF", name, habbo.getHabboInfo().getId(), + "5 " + + "0 -1 " + this.randomGnomeSkinColor() + " " + + "1 10" + (1 + Emulator.getRandom().nextInt(2)) + " " + this.randomGnomeColor() + " " + + "2 201 " + this.randomGnomeColor() + " " + + "3 30" + (1 + Emulator.getRandom().nextInt(2)) + " " + this.randomGnomeColor() + " " + + "4 40" + Emulator.getRandom().nextInt(2) + " " + this.randomGnomeColor() + ); + + pet.setUserId(habbo.getHabboInfo().getId()); + pet.setRoom(room); + pet.setRoomUnit(new RoomUnit()); + pet.getRoomUnit().setPathFinderRoom(room); + pet.needsUpdate = true; + pet.run(); + + return pet; + } + + public Pet createLeprechaun(String name, Room room, Habbo habbo) { + Pet pet = new GnomePet(27, 0, "FFFFFF", name, habbo.getHabboInfo().getId(), + "5 " + + "0 -1 0 " + + "1 102 19 " + + "2 201 27 " + + "3 302 23 " + + "4 401 27" + ); + + pet.setUserId(habbo.getHabboInfo().getId()); + pet.setRoom(room); + pet.setRoomUnit(new RoomUnit()); + pet.getRoomUnit().setPathFinderRoom(room); + pet.needsUpdate = true; + pet.run(); + + return pet; + } + + private int randomGnomeColor() { + int color = 19; + + while (color == 19 || color == 27) { + color = Emulator.getRandom().nextInt(34); + } + + return color; + } + + private int randomLeprechaunColor() { + return Emulator.getRandom().nextInt(2) == 1 ? 19 : 27; + } + + private int randomGnomeSkinColor() { + return skins[Emulator.getRandom().nextInt(skins.length)]; + } + + public boolean deletePet(Pet pet) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM users_pets WHERE id = ? LIMIT 1")) { + statement.setInt(1, pet.getId()); + return statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return false; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetRace.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetRace.java new file mode 100644 index 0000000..c02d6a4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetRace.java @@ -0,0 +1,29 @@ +package com.eu.habbo.habbohotel.pets; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class PetRace { + + public final int race; + + + public final int colorOne; + + + public final int colorTwo; + + + public final boolean hasColorOne; + + + public final boolean hasColorTwo; + + public PetRace(ResultSet set) throws SQLException { + this.race = set.getInt("race"); + this.colorOne = set.getInt("color_one"); + this.colorTwo = set.getInt("color_two"); + this.hasColorOne = set.getString("has_color_one").equals("1"); + this.hasColorTwo = set.getString("has_color_two").equals("1"); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetTasks.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetTasks.java new file mode 100644 index 0000000..bdba8b2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetTasks.java @@ -0,0 +1,62 @@ +package com.eu.habbo.habbohotel.pets; + +public enum PetTasks { + NONE(""), + FREE(""), + SIT("sit"), + DOWN("lay"), + HERE(""), + BEG("beg"), + PLAY_DEAD("ded"), + STAY(""), + FOLLOW(""), + STAND("std"), + JUMP("jmp"), + SPEAK("spk"), + PLAY(""), + SILENT(""), + NEST(""), + DRINK(""), + FOLLOW_LEFT(""), + FOLLOW_RIGHT(""), + PLAY_FOOTBALL(""), + COME_HERE(""), + BOUNCE(""), + FLAT(""), + DANCE(""), + SPIN(""), + SWITCH_TV(""), + MOVE_FORWARD(""), + TURN_LEFT(""), + TURN_RIGHT(""), + RELAX(""), + CROAK(""), + DIP(""), + WAVE(""), + MAMBO(""), + HIGH_JUMP(""), + CHICKEN_DANCE(""), + TRIPLE_JUMP(""), + SPREAD_WINGS(""), + BREATHE_FIRE(""), + HANG(""), + TORCH(""), + SWING(""), + ROLL(""), + RING_OF_FIRE(""), + EAT("eat"), + WAG_TAIL(""), + COUNT(""), + BREED(""), + RIDE(""); + + private final String status; + + PetTasks(String status) { + this.status = status; + } + + public String getStatus() { + return this.status; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetVocal.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetVocal.java new file mode 100644 index 0000000..30cd7f9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetVocal.java @@ -0,0 +1,9 @@ +package com.eu.habbo.habbohotel.pets; + +public class PetVocal { + public final String message; + + public PetVocal(String message) { + this.message = message; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetVocalsType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetVocalsType.java new file mode 100644 index 0000000..0aad835 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/PetVocalsType.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.pets; + +public enum PetVocalsType { + DISOBEY, + DRINKING, + EATING, + GENERIC_HAPPY, + GENERIC_NEUTRAL, + GENERIC_SAD, + GREET_OWNER, + HUNGRY, + LEVEL_UP, + MUTED, + PLAYFUL, + SLEEPING, + THIRSTY, + TIRED, + UNKNOWN_COMMAND +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/RideablePet.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/RideablePet.java new file mode 100644 index 0000000..afdb4b3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/RideablePet.java @@ -0,0 +1,56 @@ +package com.eu.habbo.habbohotel.pets; + +import com.eu.habbo.habbohotel.users.Habbo; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class RideablePet extends Pet { + + private Habbo rider; + private boolean hasSaddle; + private boolean anyoneCanRide; + private int saddleItemId; + + public RideablePet(ResultSet set) throws SQLException { + super(set); + this.rider = null; + } + + public RideablePet(int type, int race, String color, String name, int userId) { + super(type, race, color, name, userId); + this.rider = null; + } + + public boolean hasSaddle() { + return this.hasSaddle; + } + + public void hasSaddle(boolean hasSaddle) { + this.hasSaddle = hasSaddle; + } + + public boolean anyoneCanRide() { + return this.anyoneCanRide; + } + + public void setAnyoneCanRide(boolean anyoneCanRide) { + this.anyoneCanRide = anyoneCanRide; + } + + public Habbo getRider() { + return this.rider; + } + + public void setRider(Habbo rider) { + this.rider = rider; + } + + public int getSaddleItemId() { + return saddleItemId; + } + + public void setSaddleItemId(int saddleItemId) { + this.saddleItemId = saddleItemId; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionBeg.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionBeg.java new file mode 100644 index 0000000..e2fb3e5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionBeg.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ActionBeg extends PetAction { + public ActionBeg() { + super(PetTasks.BEG, true); + this.statusToSet.add(RoomUnitStatus.BEG); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + pet.clearPosture(); + + if (pet.getHappyness() > 90) + pet.say(pet.getPetData().randomVocal(PetVocalsType.PLAYFUL)); + else + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionBreatheFire.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionBreatheFire.java new file mode 100644 index 0000000..e04a188 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionBreatheFire.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.threading.runnables.PetClearPosture; + +public class ActionBreatheFire extends PetAction { + public ActionBreatheFire() { + super(null, true); + this.minimumActionDuration = 1000; + this.statusToSet.add(RoomUnitStatus.FLAME); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + Emulator.getThreading().run(new PetClearPosture(pet, RoomUnitStatus.FLAME, null, false), this.minimumActionDuration); + + if (pet.getHappyness() > 50) + pet.say(pet.getPetData().randomVocal(PetVocalsType.PLAYFUL)); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionBreed.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionBreed.java new file mode 100644 index 0000000..83ec620 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionBreed.java @@ -0,0 +1,39 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetBreedingNest; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.rooms.pets.breeding.PetBreedingStartFailedComposer; +import org.apache.commons.lang3.StringUtils; + +public class ActionBreed extends PetAction { + public ActionBreed() { + super(PetTasks.BREED, true); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + InteractionPetBreedingNest nest = null; + for (HabboItem item : pet.getRoom().getRoomSpecialTypes().getItemsOfType(InteractionPetBreedingNest.class)) { + if (StringUtils.containsIgnoreCase(item.getBaseItem().getName(), pet.getPetData().getName())) { + if (!((InteractionPetBreedingNest) item).boxFull()) { + nest = (InteractionPetBreedingNest) item; + break; + } + } + } + + if (nest != null) { + pet.getRoomUnit().setGoalLocation(pet.getRoom().getLayout().getTile(nest.getX(), nest.getY())); + + return true; + } else { + habbo.getClient().sendResponse(new PetBreedingStartFailedComposer(PetBreedingStartFailedComposer.NO_NESTS)); + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionCroak.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionCroak.java new file mode 100644 index 0000000..6ad3b69 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionCroak.java @@ -0,0 +1,29 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.threading.runnables.PetClearPosture; + +public class ActionCroak extends PetAction { + public ActionCroak() { + super(PetTasks.SPEAK, false); + this.minimumActionDuration = 2000; + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + pet.getRoomUnit().setStatus(RoomUnitStatus.CROAK, "0"); + + Emulator.getThreading().run(new PetClearPosture(pet, RoomUnitStatus.CROAK, null, false), 2000); + + if (pet.getHappyness() > 80) + pet.say(pet.getPetData().randomVocal(PetVocalsType.PLAYFUL)); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionDip.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionDip.java new file mode 100644 index 0000000..8f47aad --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionDip.java @@ -0,0 +1,29 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionWater; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import gnu.trove.set.hash.THashSet; + +public class ActionDip extends PetAction { + public ActionDip() { + super(null, true); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + THashSet waterItems = pet.getRoom().getRoomSpecialTypes().getItemsOfType(InteractionWater.class); + + if (waterItems.isEmpty()) + return false; + + HabboItem waterPatch = (HabboItem) waterItems.toArray()[Emulator.getRandom().nextInt(waterItems.size())]; + + pet.getRoomUnit().setGoalLocation(pet.getRoom().getLayout().getTile(waterPatch.getX(), waterPatch.getY())); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionDown.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionDown.java new file mode 100644 index 0000000..2f601fb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionDown.java @@ -0,0 +1,28 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ActionDown extends PetAction { + public ActionDown() { + super(PetTasks.DOWN, true); + this.statusToRemove.add(RoomUnitStatus.MOVE); + this.statusToRemove.add(RoomUnitStatus.SIT); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + pet.getRoomUnit().setStatus(RoomUnitStatus.LAY, pet.getRoom().getStackHeight(pet.getRoomUnit().getX(), pet.getRoomUnit().getY(), false) + ""); + + if (pet.getHappyness() > 50) + pet.say(pet.getPetData().randomVocal(PetVocalsType.PLAYFUL)); + else + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionDrink.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionDrink.java new file mode 100644 index 0000000..7d56c1c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionDrink.java @@ -0,0 +1,28 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ActionDrink extends PetAction { + public ActionDrink() { + super(null, false); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + if (pet.getLevelThirst() > 40) { + pet.drink(); + + if (pet.getLevelThirst() > 65) + pet.say(pet.getPetData().randomVocal(PetVocalsType.THIRSTY)); + + return true; + } else { + pet.say(pet.getPetData().randomVocal(PetVocalsType.DISOBEY)); + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionEat.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionEat.java new file mode 100644 index 0000000..0b701c6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionEat.java @@ -0,0 +1,33 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.threading.runnables.PetClearPosture; + +public class ActionEat extends PetAction { + public ActionEat() { + super(null, true); + + this.statusToSet.add(RoomUnitStatus.EAT); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + //Eat + if (pet.getLevelHunger() > 40) { + pet.say(pet.getPetData().randomVocal(PetVocalsType.HUNGRY)); + Emulator.getThreading().run(new PetClearPosture(pet, RoomUnitStatus.EAT, null, false), 500); + pet.eat(); + + return true; + } else { + pet.say(pet.getPetData().randomVocal(PetVocalsType.DISOBEY)); + return false; + } + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionFollow.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionFollow.java new file mode 100644 index 0000000..767faa3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionFollow.java @@ -0,0 +1,33 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.threading.runnables.PetFollowHabbo; + +public class ActionFollow extends PetAction { + public ActionFollow() { + super(PetTasks.FOLLOW, true); + this.statusToRemove.add(RoomUnitStatus.MOVE); + this.statusToRemove.add(RoomUnitStatus.LAY); + this.statusToRemove.add(RoomUnitStatus.DEAD); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + pet.clearPosture(); + + Emulator.getThreading().run(new PetFollowHabbo(pet, habbo, 0)); + + if (pet.getHappyness() > 75) + pet.say(pet.getPetData().randomVocal(PetVocalsType.PLAYFUL)); + else + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionFollowLeft.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionFollowLeft.java new file mode 100644 index 0000000..84b16e6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionFollowLeft.java @@ -0,0 +1,30 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.threading.runnables.PetFollowHabbo; + +public class ActionFollowLeft extends PetAction { + public ActionFollowLeft() { + super(PetTasks.FOLLOW, true); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + //Follow left. + pet.clearPosture(); + + Emulator.getThreading().run(new PetFollowHabbo(pet, habbo, -2)); + + if (pet.getHappyness() > 75) + pet.say(pet.getPetData().randomVocal(PetVocalsType.PLAYFUL)); + else + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionFollowRight.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionFollowRight.java new file mode 100644 index 0000000..e00de02 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionFollowRight.java @@ -0,0 +1,30 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.threading.runnables.PetFollowHabbo; + +public class ActionFollowRight extends PetAction { + public ActionFollowRight() { + super(PetTasks.FOLLOW, true); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + //Follow right. + pet.clearPosture(); + + Emulator.getThreading().run(new PetFollowHabbo(pet, habbo, +2)); + + if (pet.getHappyness() > 75) + pet.say(pet.getPetData().randomVocal(PetVocalsType.PLAYFUL)); + else + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionFree.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionFree.java new file mode 100644 index 0000000..39fc50a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionFree.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ActionFree extends PetAction { + public ActionFree() { + super(PetTasks.FREE, false); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + pet.freeCommand(); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionHere.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionHere.java new file mode 100644 index 0000000..150249a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionHere.java @@ -0,0 +1,29 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ActionHere extends PetAction { + public ActionHere() { + super(PetTasks.HERE, false); + + this.statusToRemove.add(RoomUnitStatus.DEAD); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + pet.getRoomUnit().setGoalLocation(pet.getRoom().getLayout().getTileInFront(habbo.getRoomUnit().getCurrentLocation(), habbo.getRoomUnit().getBodyRotation().getValue())); + pet.getRoomUnit().setCanWalk(true); + + if (pet.getHappyness() > 75) + pet.say(pet.getPetData().randomVocal(PetVocalsType.PLAYFUL)); + else + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionJump.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionJump.java new file mode 100644 index 0000000..8e232d4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionJump.java @@ -0,0 +1,32 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.threading.runnables.PetClearPosture; + +public class ActionJump extends PetAction { + public ActionJump() { + super(PetTasks.JUMP, true); + this.minimumActionDuration = 2000; + this.statusToSet.add(RoomUnitStatus.JUMP); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + pet.clearPosture(); + + Emulator.getThreading().run(new PetClearPosture(pet, RoomUnitStatus.JUMP, null, false), 2000); + + if (pet.getHappyness() > 60) + pet.say(pet.getPetData().randomVocal(PetVocalsType.PLAYFUL)); + else + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionMoveForward.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionMoveForward.java new file mode 100644 index 0000000..abaac92 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionMoveForward.java @@ -0,0 +1,23 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ActionMoveForward extends PetAction { + public ActionMoveForward() { + super(null, true); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + + pet.getRoomUnit().setGoalLocation(pet.getRoom().getLayout().getTileInFront(pet.getRoomUnit().getCurrentLocation(), pet.getRoomUnit().getBodyRotation().getValue())); + pet.getRoomUnit().setCanWalk(true); + + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionNest.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionNest.java new file mode 100644 index 0000000..f7d994d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionNest.java @@ -0,0 +1,28 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ActionNest extends PetAction { + public ActionNest() { + super(null, false); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + if (pet.getEnergy() < 65) { + pet.findNest(); + + if (pet.getEnergy() < 30) + pet.say(pet.getPetData().randomVocal(PetVocalsType.TIRED)); + + return true; + } else { + pet.say(pet.getPetData().randomVocal(PetVocalsType.DISOBEY)); + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionPlay.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionPlay.java new file mode 100644 index 0000000..71a7a29 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionPlay.java @@ -0,0 +1,25 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ActionPlay extends PetAction { + public ActionPlay() { + super(null, false); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + //Play + //TODO Implement playing for pets. For example; go to ball, toy etc. + if (pet.getHappyness() > 75) + pet.say(pet.getPetData().randomVocal(PetVocalsType.PLAYFUL)); + else { + pet.say(pet.getPetData().randomVocal(PetVocalsType.DISOBEY)); + } + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionPlayDead.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionPlayDead.java new file mode 100644 index 0000000..53aae87 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionPlayDead.java @@ -0,0 +1,31 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ActionPlayDead extends PetAction { + public ActionPlayDead() { + super(PetTasks.PLAY_DEAD, true); + this.statusToRemove.add(RoomUnitStatus.MOVE); + this.statusToRemove.add(RoomUnitStatus.LAY); + this.statusToRemove.add(RoomUnitStatus.DEAD); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + pet.clearPosture(); + + pet.getRoomUnit().setStatus(RoomUnitStatus.DEAD, pet.getRoom().getStackHeight(pet.getRoomUnit().getX(), pet.getRoomUnit().getY(), false) + ""); + + if (pet.getHappyness() > 50) + pet.say(pet.getPetData().randomVocal(PetVocalsType.PLAYFUL)); + else + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionPlayFootball.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionPlayFootball.java new file mode 100644 index 0000000..3f11cdc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionPlayFootball.java @@ -0,0 +1,44 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.items.interactions.InteractionPushable; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class ActionPlayFootball extends PetAction { + public ActionPlayFootball() { + super(null, false); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + + Room room = pet.getRoom(); + + if(room == null || room.getLayout() == null) + return false; + + HabboItem foundBall = null; + + for(HabboItem item : room.getFloorItems()) { + if(item instanceof InteractionPushable) { + foundBall = item; + } + } + + if(foundBall == null) + return false; + + pet.getRoomUnit().setGoalLocation(room.getLayout().getTile(foundBall.getX(), foundBall.getY())); + + if (pet.getHappyness() > 75) + pet.say(pet.getPetData().randomVocal(PetVocalsType.PLAYFUL)); + else + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionRelax.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionRelax.java new file mode 100644 index 0000000..00f893e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionRelax.java @@ -0,0 +1,28 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ActionRelax extends PetAction { + public ActionRelax() { + super(null, true); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + //Relax + if (pet.getHappyness() > 75) + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_HAPPY)); + else if (pet.getHappyness() < 30) + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_SAD)); + else + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + + pet.getRoomUnit().setStatus(RoomUnitStatus.RELAX, "0"); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionSilent.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionSilent.java new file mode 100644 index 0000000..2625825 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionSilent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ActionSilent extends PetAction { + public ActionSilent() { + super(null, false); + + this.statusToRemove.add(RoomUnitStatus.SPEAK); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + pet.setMuted(true); + pet.say(pet.getPetData().randomVocal(PetVocalsType.MUTED)); + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionSit.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionSit.java new file mode 100644 index 0000000..52ef037 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionSit.java @@ -0,0 +1,30 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ActionSit extends PetAction { + public ActionSit() { + super(PetTasks.SIT, true); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + if (pet.getTask() != PetTasks.SIT && !pet.getRoomUnit().hasStatus(RoomUnitStatus.SIT)) { + pet.getRoomUnit().setStatus(RoomUnitStatus.SIT, pet.getRoom().getStackHeight(pet.getRoomUnit().getX(), pet.getRoomUnit().getY(), false) - 0.50 + ""); + + if (pet.getHappyness() > 75) + pet.say(pet.getPetData().randomVocal(PetVocalsType.PLAYFUL)); + else + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + + return true; + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionSpeak.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionSpeak.java new file mode 100644 index 0000000..be7eaea --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionSpeak.java @@ -0,0 +1,39 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.threading.runnables.PetClearPosture; + +public class ActionSpeak extends PetAction { + public ActionSpeak() { + super(PetTasks.SPEAK, false); + + this.statusToSet.add(RoomUnitStatus.SPEAK); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + pet.setMuted(false); + Emulator.getThreading().run(new PetClearPosture(pet, RoomUnitStatus.SPEAK, null, false), 2000); + + if (pet.getHappyness() > 70) + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_HAPPY)); + else if (pet.getHappyness() < 30) + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_SAD)); + else if (pet.getLevelHunger() > 65) + pet.say(pet.getPetData().randomVocal(PetVocalsType.HUNGRY)); + else if (pet.getLevelThirst() > 65) + pet.say(pet.getPetData().randomVocal(PetVocalsType.THIRSTY)); + else if (pet.getEnergy() < 25) + pet.say(pet.getPetData().randomVocal(PetVocalsType.TIRED)); + else if (pet.getTask() == PetTasks.NEST || pet.getTask() == PetTasks.DOWN) + pet.say(pet.getPetData().randomVocal(PetVocalsType.SLEEPING)); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionStand.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionStand.java new file mode 100644 index 0000000..598c66d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionStand.java @@ -0,0 +1,30 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ActionStand extends PetAction { + public ActionStand() { + super(PetTasks.STAND, true); + this.statusToRemove.add(RoomUnitStatus.MOVE); + this.statusToRemove.add(RoomUnitStatus.LAY); + this.statusToRemove.add(RoomUnitStatus.DEAD); + this.statusToRemove.add(RoomUnitStatus.LAY); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + pet.clearPosture(); + + if (pet.getHappyness() > 30) + pet.say(pet.getPetData().randomVocal(PetVocalsType.PLAYFUL)); + else + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionStay.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionStay.java new file mode 100644 index 0000000..7b3851c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionStay.java @@ -0,0 +1,29 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ActionStay extends PetAction { + public ActionStay() { + super(PetTasks.STAY, true); + + this.statusToRemove.remove(RoomUnitStatus.MOVE); + this.statusToRemove.remove(RoomUnitStatus.DEAD); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + pet.clearPosture(); + + pet.getRoomUnit().setCanWalk(false); + pet.setStayStartedAt(Emulator.getIntUnixTimestamp()); + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionTorch.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionTorch.java new file mode 100644 index 0000000..e6a7748 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionTorch.java @@ -0,0 +1,29 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.threading.runnables.PetClearPosture; + +public class ActionTorch extends PetAction { + public ActionTorch() { + super(null, true); + + this.minimumActionDuration = 1000; + this.statusToSet.add(RoomUnitStatus.EAT); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + if (pet.getHappyness() < 30) { + pet.say(pet.getPetData().randomVocal(PetVocalsType.DISOBEY)); + return false; + } + + Emulator.getThreading().run(new PetClearPosture(pet, RoomUnitStatus.EAT, null, false), this.minimumActionDuration); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionTurnLeft.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionTurnLeft.java new file mode 100644 index 0000000..de7a4d8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionTurnLeft.java @@ -0,0 +1,20 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ActionTurnLeft extends PetAction { + public ActionTurnLeft() { + super(null, true); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + pet.getRoomUnit().setBodyRotation(RoomUserRotation.values()[(pet.getRoomUnit().getBodyRotation().getValue() - 1 < 0 ? 7 : pet.getRoomUnit().getBodyRotation().getValue() - 1)]); + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionTurnRight.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionTurnRight.java new file mode 100644 index 0000000..3704172 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionTurnRight.java @@ -0,0 +1,20 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.habbohotel.users.Habbo; + +public class ActionTurnRight extends PetAction { + public ActionTurnRight() { + super(null, true); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + pet.getRoomUnit().setBodyRotation(RoomUserRotation.values()[(pet.getRoomUnit().getBodyRotation().getValue() + 1 > 7 ? 0 : pet.getRoomUnit().getBodyRotation().getValue() + 1)]); + pet.say(pet.getPetData().randomVocal(PetVocalsType.GENERIC_NEUTRAL)); + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionWave.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionWave.java new file mode 100644 index 0000000..23b8ebf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionWave.java @@ -0,0 +1,30 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.threading.runnables.PetClearPosture; + +public class ActionWave extends PetAction { + public ActionWave() { + super(PetTasks.WAVE, false); + + this.statusToSet.add(RoomUnitStatus.WAVE); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + //WAV + if (pet.getHappyness() > 65) { + pet.getRoomUnit().setStatus(RoomUnitStatus.WAVE, "0"); + + Emulator.getThreading().run(new PetClearPosture(pet, RoomUnitStatus.WAVE, null, false), 2000); + return true; + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionWings.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionWings.java new file mode 100644 index 0000000..07a1b22 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/pets/actions/ActionWings.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.pets.actions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetAction; +import com.eu.habbo.habbohotel.pets.PetVocalsType; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.threading.runnables.PetClearPosture; + +public class ActionWings extends PetAction { + public ActionWings() { + super(null, true); + + this.statusToSet.add(RoomUnitStatus.WINGS); + } + + @Override + public boolean apply(Pet pet, Habbo habbo, String[] data) { + Emulator.getThreading().run(new PetClearPosture(pet, RoomUnitStatus.WINGS, null, false), this.minimumActionDuration); + + if (pet.getHappyness() > 50) + pet.say(pet.getPetData().randomVocal(PetVocalsType.PLAYFUL)); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/polls/Poll.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/polls/Poll.java new file mode 100644 index 0000000..8e7927d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/polls/Poll.java @@ -0,0 +1,52 @@ +package com.eu.habbo.habbohotel.polls; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; + +public class Poll { + + public final int id; + + + public final String title; + + + public final String thanksMessage; + + + public final String badgeReward; + + public int lastQuestionId; + + private ArrayList questions; + + public Poll(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.title = set.getString("title"); + this.thanksMessage = set.getString("thanks_message"); + this.badgeReward = set.getString("reward_badge"); + this.questions = new ArrayList<>(); + } + + public ArrayList getQuestions() { + return this.questions; + } + + public PollQuestion getQuestion(int id) { + for (PollQuestion q : this.questions) { + if (q.id == id) { + return q; + } + } + + return null; + } + + public void addQuestion(PollQuestion question) { + this.questions.add(question); + + Collections.sort(this.questions); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/polls/PollManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/polls/PollManager.java new file mode 100644 index 0000000..c35acf1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/polls/PollManager.java @@ -0,0 +1,75 @@ +package com.eu.habbo.habbohotel.polls; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; +import java.sql.*; + +@Slf4j +public class PollManager { + private final THashMap activePolls = new THashMap<>(); + + public PollManager() { + this.loadPolls(); + } + + public static boolean donePoll(Habbo habbo, int pollId) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT NULL FROM polls_answers WHERE poll_id = ? AND user_id = ? LIMIT 1")) { + statement.setInt(1, pollId); + statement.setInt(2, habbo.getHabboInfo().getId()); + try (ResultSet set = statement.executeQuery()) { + if (set.isBeforeFirst()) { + return true; + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + return false; + } + + public void loadPolls() { + synchronized (this.activePolls) { + this.activePolls.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (Statement statement = connection.createStatement()) { + try (ResultSet set = statement.executeQuery("SELECT * FROM polls")) { + while (set.next()) { + this.activePolls.put(set.getInt("id"), new Poll(set)); + } + } + + try (ResultSet set = statement.executeQuery("SELECT * FROM polls_questions ORDER BY parent_id, `order` ASC")) { + while (set.next()) { + Poll poll = this.getPoll(set.getInt("poll_id")); + + if (poll != null) { + PollQuestion question = new PollQuestion(set); + + if (set.getInt("parent_id") <= 0) { + poll.addQuestion(question); + } else { + PollQuestion parentQuestion = poll.getQuestion(set.getInt("parent_id")); + + if (parentQuestion != null) { + parentQuestion.addSubQuestion(question); + } + } + + poll.lastQuestionId = question.id; + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public Poll getPoll(int pollId) { + return this.activePolls.get(pollId); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/polls/PollQuestion.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/polls/PollQuestion.java new file mode 100644 index 0000000..b1c159e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/polls/PollQuestion.java @@ -0,0 +1,93 @@ +package com.eu.habbo.habbohotel.polls; + +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; +import gnu.trove.map.hash.THashMap; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Map; + +public class PollQuestion implements ISerialize, Comparable { + + public final int id; + + + public final int parentId; + + + public final int type; + + + public final String question; + + + public final THashMap options; + + + public final int minSelections; + + + public final int order; + + private ArrayList subQuestions; + + public PollQuestion(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.parentId = set.getInt("parent_id"); + this.type = set.getInt("type"); + this.question = set.getString("question"); + this.minSelections = set.getInt("min_selections"); + this.order = set.getInt("order"); + + this.options = new THashMap<>(); + this.subQuestions = new ArrayList<>(); + + String opts = set.getString("options"); + + if (this.type == 1 || this.type == 2) { + for (int i = 0; i < opts.split(";").length; i++) { + this.options.put(i, new String[]{opts.split(";")[i].split(":")[0], opts.split(";")[i].split(":")[1]}); + } + } + } + + public void addSubQuestion(PollQuestion pollQuestion) { + this.subQuestions.add(pollQuestion); + } + + @Override + public void serialize(ServerMessage message) { + message.appendInt(this.id); + message.appendInt(this.order); + message.appendInt(this.type); + message.appendString(this.question); + message.appendInt(this.minSelections); + message.appendInt(0); + message.appendInt(this.options.size()); + + if (this.type == 1 || this.type == 2) { + for (Map.Entry set : this.options.entrySet()) { + message.appendString(set.getValue()[0]); + message.appendString(set.getValue()[1]); + message.appendInt(set.getKey()); + } + } + + if (this.parentId <= 0) { + Collections.sort(this.subQuestions); + message.appendInt(this.subQuestions.size()); + + for (PollQuestion q : this.subQuestions) { + q.serialize(message); + } + } + } + + @Override + public int compareTo(PollQuestion o) { + return this.order - o.order; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/CustomRoomLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/CustomRoomLayout.java new file mode 100644 index 0000000..f1285fd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/CustomRoomLayout.java @@ -0,0 +1,46 @@ +package com.eu.habbo.habbohotel.rooms; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class CustomRoomLayout extends RoomLayout implements Runnable { + private final int roomId; + private boolean needsUpdate; + + public CustomRoomLayout(ResultSet set, Room room) throws SQLException { + super(set, room); + + this.roomId = room.getId(); + } + + @Override + public void run() { + if (this.needsUpdate) { + this.needsUpdate = false; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE room_models_custom SET door_x = ?, door_y = ?, door_dir = ?, heightmap = ? WHERE id = ? LIMIT 1")) { + statement.setInt(1, this.getDoorX()); + statement.setInt(2, this.getDoorY()); + statement.setInt(3, this.getDoorDirection()); + statement.setString(4, this.getHeightmap()); + statement.setInt(5, this.roomId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public boolean needsUpdate() { + return this.needsUpdate; + } + + public void needsUpdate(boolean needsUpdate) { + this.needsUpdate = needsUpdate; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/FurnitureMovementError.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/FurnitureMovementError.java new file mode 100644 index 0000000..9c1ddb7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/FurnitureMovementError.java @@ -0,0 +1,25 @@ +package com.eu.habbo.habbohotel.rooms; + +public enum FurnitureMovementError { + NONE(""), + NO_RIGHTS("${room.error.cant_set_not_owner}"), + INVALID_MOVE("${room.error.cant_set_item}"), + CANT_STACK("${room.error.cant_set_item}"), + CANCEL_PLUGIN_PLACE("${room.error.plugin_place}"), + CANCEL_PLUGIN_MOVE("${room.error.plugin_move}"), + CANCEL_PLUGIN_ROTATE("${room.error.plugin_rotate}"), + TILE_HAS_HABBOS("${room.error.cant_set_item}"), + TILE_HAS_PETS("${room.error.cant_set_item}"), + TILE_HAS_BOTS("${room.error.cant_set_item}"), + MAX_DIMMERS("${room.error.max_dimmers}"), + MAX_SOUNDFURNI("${room.errors.max_soundfurni}"), + MAX_ITEMS("${room.error.max_furniture}"), + MAX_STICKIES("${room.error.max_stickies}"); + + + public final String errorCode; + + FurnitureMovementError(String errorCode) { + this.errorCode = errorCode; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java new file mode 100644 index 0000000..73d5d17 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java @@ -0,0 +1,4698 @@ +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.bots.VisitorBot; +import com.eu.habbo.habbohotel.commands.CommandHandler; +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.habbohotel.items.FurnitureType; +import com.eu.habbo.habbohotel.items.ICycleable; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.*; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameGate; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameScoreboard; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTimer; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiSphere; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiTeleporter; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeExitTile; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagField; +import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagPole; +import com.eu.habbo.habbohotel.items.interactions.pets.*; +import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredBlob; +import com.eu.habbo.habbohotel.messenger.MessengerBuddy; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.pets.HorsePet; +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.users.*; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.GenericAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.GenericErrorMessagesComposer; +import com.eu.habbo.messages.outgoing.guilds.GuildInfoComposer; +import com.eu.habbo.messages.outgoing.hotelview.HotelViewComposer; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.AddPetComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.polls.infobus.SimplePollAnswerComposer; +import com.eu.habbo.messages.outgoing.polls.infobus.SimplePollStartComposer; +import com.eu.habbo.messages.outgoing.rooms.*; +import com.eu.habbo.messages.outgoing.rooms.items.*; +import com.eu.habbo.messages.outgoing.rooms.pets.RoomPetComposer; +import com.eu.habbo.messages.outgoing.rooms.users.*; +import com.eu.habbo.messages.outgoing.users.MutedWhisperComposer; +import com.eu.habbo.plugin.Event; +import com.eu.habbo.plugin.PluginManager; +import com.eu.habbo.plugin.events.furniture.*; +import com.eu.habbo.plugin.events.rooms.RoomLoadedEvent; +import com.eu.habbo.plugin.events.rooms.RoomUnloadedEvent; +import com.eu.habbo.plugin.events.rooms.RoomUnloadingEvent; +import com.eu.habbo.plugin.events.users.*; +import com.eu.habbo.threading.runnables.YouAreAPirate; +import gnu.trove.TCollections; +import gnu.trove.iterator.TIntObjectIterator; +import gnu.trove.list.array.TIntArrayList; +import gnu.trove.map.TIntIntMap; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntIntHashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.set.hash.THashSet; +import io.netty.util.internal.ConcurrentSet; +import org.apache.commons.math3.util.Pair; +import lombok.extern.slf4j.Slf4j; + +import java.awt.*; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +@Slf4j +public class Room implements Comparable, ISerialize, Runnable { + + public static final Comparator SORT_SCORE = (o1, o2) -> o2.getScore() - o1.getScore(); + public static final Comparator SORT_ID = (o1, o2) -> o2.getId() - o1.getId(); + private static final TIntObjectHashMap defaultMoodData = new TIntObjectHashMap<>(); + //Configuration. Loaded from database & updated accordingly. + public static boolean HABBO_CHAT_DELAY = false; + public static int MAXIMUM_BOTS = 10; + public static int MAXIMUM_PETS = 10; + public static int MAXIMUM_FURNI = 3000; + public static int MAXIMUM_POSTITNOTES = 200; + public static int HAND_ITEM_TIME = 10; + public static int IDLE_CYCLES = 240; + 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; + public static final double MAXIMUM_FURNI_HEIGHT = 40d; + + static { + for (int i = 1; i <= 3; i++) { + RoomMoodlightData data = RoomMoodlightData.fromString(""); + data.setId(i); + defaultMoodData.put(i, data); + } + } + + public final Object roomUnitLock = new Object(); + public final ConcurrentHashMap> tileCache = new ConcurrentHashMap<>(); + public final List userVotes; + private final ConcurrentHashMap currentHabbos = new ConcurrentHashMap<>(3); + private final TIntObjectMap habboQueue = TCollections.synchronizedMap(new TIntObjectHashMap<>(0)); + private final TIntObjectMap currentBots = TCollections.synchronizedMap(new TIntObjectHashMap<>(0)); + private final TIntObjectMap currentPets = TCollections.synchronizedMap(new TIntObjectHashMap<>(0)); + private final THashSet activeTrades; + private final TIntArrayList rights; + private final TIntIntHashMap mutedHabbos; + private final TIntObjectHashMap bannedHabbos; + private final ConcurrentSet games; + private final TIntObjectMap furniOwnerNames; + private final TIntIntMap furniOwnerCount; + private final TIntObjectMap moodlightData; + private final THashSet wordFilterWords; + private final TIntObjectMap roomItems; + private final Object loadLock = new Object(); + //Use appropriately. Could potentially cause memory leaks when used incorrectly. + public volatile boolean preventUnloading = false; + public volatile boolean preventUncaching = false; + public final ConcurrentHashMap.KeySetView scheduledComposers = ConcurrentHashMap.newKeySet(); + public ConcurrentHashMap.KeySetView scheduledTasks = ConcurrentHashMap.newKeySet(); + public String wordQuiz = ""; + public int noVotes = 0; + public int yesVotes = 0; + public int wordQuizEnd = 0; + public ScheduledFuture roomCycleTask; + private int id; + private int ownerId; + private String ownerName; + private String name; + private String description; + private RoomLayout layout; + private boolean overrideModel; + private final String layoutName; + private String password; + private RoomState state; + private int usersMax; + private volatile int score; + private volatile int category; + private String floorPaint; + private String wallPaint; + private String backgroundPaint; + private int wallSize; + private int wallHeight; + private int floorSize; + private int guildId; + private String tags; + private volatile boolean publicRoom; + private volatile boolean staffPromotedRoom; + private volatile boolean allowPets; + private volatile boolean allowPetsEat; + private volatile boolean allowWalkthrough; + private volatile boolean allowBotsWalk; + private volatile boolean allowEffects; + private volatile boolean hideWall; + private volatile int chatMode; + private volatile int chatWeight; + private volatile int chatSpeed; + private volatile int chatDistance; + private volatile int chatProtection; + private volatile int muteOption; + private volatile int kickOption; + private volatile int banOption; + private volatile int pollId; + private volatile boolean promoted; + private volatile int tradeMode; + private volatile boolean moveDiagonally; + private volatile boolean jukeboxActive; + private volatile boolean hideWired; + private RoomPromotion promotion; + private volatile boolean needsUpdate; + private volatile boolean loaded; + private volatile boolean preLoaded; + private int idleCycles; + private volatile int unitCounter; + private volatile int rollerSpeed; + private final int muteTime = Emulator.getConfig().getInt("hotel.flood.mute.time", 30); + private long rollerCycle = System.currentTimeMillis(); + private volatile int lastTimerReset = Emulator.getIntUnixTimestamp(); + private volatile boolean muted; + private RoomSpecialTypes roomSpecialTypes; + private TraxManager traxManager; + private boolean cycleOdd; + private long cycleTimestamp; + public Map repeatersLastTick = new HashMap<>(); + + + + public Room(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.ownerId = set.getInt("owner_id"); + this.ownerName = set.getString("owner_name"); + this.name = set.getString("name"); + this.description = set.getString("description"); + this.password = set.getString("password"); + this.state = RoomState.valueOf(set.getString("state").toUpperCase()); + this.usersMax = set.getInt("users_max"); + this.score = set.getInt("score"); + this.category = set.getInt("category"); + this.floorPaint = set.getString("paper_floor"); + this.wallPaint = set.getString("paper_wall"); + this.backgroundPaint = set.getString("paper_landscape"); + this.wallSize = set.getInt("thickness_wall"); + this.wallHeight = set.getInt("wall_height"); + this.floorSize = set.getInt("thickness_floor"); + this.tags = set.getString("tags"); + this.publicRoom = set.getBoolean("is_public"); + this.staffPromotedRoom = set.getBoolean("is_staff_picked"); + this.allowPets = set.getBoolean("allow_other_pets"); + this.allowPetsEat = set.getBoolean("allow_other_pets_eat"); + this.allowWalkthrough = set.getBoolean("allow_walkthrough"); + this.hideWall = set.getBoolean("allow_hidewall"); + this.chatMode = set.getInt("chat_mode"); + this.chatWeight = set.getInt("chat_weight"); + this.chatSpeed = set.getInt("chat_speed"); + this.chatDistance = set.getInt("chat_hearing_distance"); + this.chatProtection = set.getInt("chat_protection"); + this.muteOption = set.getInt("who_can_mute"); + this.kickOption = set.getInt("who_can_kick"); + this.banOption = set.getInt("who_can_ban"); + this.pollId = set.getInt("poll_id"); + this.guildId = set.getInt("guild_id"); + this.rollerSpeed = set.getInt("roller_speed"); + this.overrideModel = set.getString("override_model").equals("1"); + this.layoutName = set.getString("model"); + this.promoted = set.getString("promoted").equals("1"); + this.jukeboxActive = set.getString("jukebox_active").equals("1"); + this.hideWired = set.getString("hidewired").equals("1"); + + this.bannedHabbos = new TIntObjectHashMap<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM room_promotions WHERE room_id = ? AND end_timestamp > ? LIMIT 1")) { + if (this.promoted) { + statement.setInt(1, this.id); + statement.setInt(2, Emulator.getIntUnixTimestamp()); + + try (ResultSet promotionSet = statement.executeQuery()) { + this.promoted = false; + if (promotionSet.next()) { + this.promoted = true; + this.promotion = new RoomPromotion(this, promotionSet); + } + } + } + + this.loadBans(connection); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.tradeMode = set.getInt("trade_mode"); + this.moveDiagonally = set.getString("move_diagonally").equals("1"); + + this.preLoaded = true; + this.allowBotsWalk = true; + this.allowEffects = true; + this.furniOwnerNames = TCollections.synchronizedMap(new TIntObjectHashMap<>(0)); + this.furniOwnerCount = TCollections.synchronizedMap(new TIntIntHashMap(0)); + this.roomItems = TCollections.synchronizedMap(new TIntObjectHashMap<>(0)); + this.wordFilterWords = new THashSet<>(0); + this.moodlightData = new TIntObjectHashMap<>(defaultMoodData); + + for (String s : set.getString("moodlight_data").split(";")) { + RoomMoodlightData data = RoomMoodlightData.fromString(s); + this.moodlightData.put(data.getId(), data); + } + + this.mutedHabbos = new TIntIntHashMap(); + this.games = new ConcurrentSet<>(); + + this.activeTrades = new THashSet<>(0); + this.rights = new TIntArrayList(); + this.userVotes = new ArrayList<>(); + } + + public synchronized void loadData() { + synchronized (this.loadLock) { + if (!this.preLoaded || this.loaded) + return; + + this.preLoaded = false; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + synchronized (this.roomUnitLock) { + this.unitCounter = 0; + this.currentHabbos.clear(); + this.currentPets.clear(); + this.currentBots.clear(); + } + + this.roomSpecialTypes = new RoomSpecialTypes(); + this.loadLayout(); + this.loadRights(connection); + this.loadItems(connection); + this.loadHeightmap(); + this.loadBots(connection); + this.loadPets(connection); + this.loadWordFilter(connection); + this.loadWiredData(connection); + + this.idleCycles = 0; + this.loaded = true; + + this.roomCycleTask = Emulator.getThreading().getService().scheduleAtFixedRate(this, 500, 500, TimeUnit.MILLISECONDS); + } catch (Exception e) { + log.error("Caught exception", e); + } + + this.traxManager = new TraxManager(this); + + if (this.jukeboxActive) { + this.traxManager.play(0); + for (HabboItem item : this.roomSpecialTypes.getItemsOfType(InteractionJukeBox.class)) { + item.setExtradata("1"); + this.updateItem(item); + } + } + + for (HabboItem item : this.roomSpecialTypes.getItemsOfType(InteractionFireworks.class)) { + item.setExtradata("1"); + this.updateItem(item); + } + } + + Emulator.getPluginManager().fireEvent(new RoomLoadedEvent(this)); + } + + private synchronized void loadLayout() { + try { + if (this.layout == null) { + if (this.overrideModel) { + this.layout = Emulator.getGameEnvironment().getRoomManager().loadCustomLayout(this); + } else { + this.layout = Emulator.getGameEnvironment().getRoomManager().loadLayout(this.layoutName, this); + } + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + private synchronized void loadHeightmap() { + try { + if (this.layout != null) { + for (short x = 0; x < this.layout.getMapSizeX(); x++) { + for (short y = 0; y < this.layout.getMapSizeY(); y++) { + RoomTile tile = this.layout.getTile(x, y); + if (tile != null) { + this.updateTile(tile); + } + } + } + } else { + log.error("Unknown Room Layout for Room (ID: {})", this.id); + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + private synchronized void loadItems(Connection connection) { + this.roomItems.clear(); + + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM items WHERE room_id = ?")) { + statement.setInt(1, this.id); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + this.addHabboItem(Emulator.getGameEnvironment().getItemManager().loadHabboItem(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } catch (Exception e) { + log.error("Caught exception", e); + } + + if (this.itemCount() > Room.MAXIMUM_FURNI) { + log.error("Room ID: {} has exceeded the furniture limit ({} > {}).", this.getId(), this.itemCount(), Room.MAXIMUM_FURNI); + } + } + + private synchronized void loadWiredData(Connection connection) { + try (PreparedStatement statement = connection.prepareStatement("SELECT id, wired_data FROM items WHERE room_id = ? AND wired_data<>''")) { + statement.setInt(1, this.id); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + try { + HabboItem item = this.getHabboItem(set.getInt("id")); + + if (item instanceof InteractionWired interactionWired) { + interactionWired.loadWiredData(set, this); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + private synchronized void loadBots(Connection connection) { + this.currentBots.clear(); + + try (PreparedStatement statement = connection.prepareStatement("SELECT users.username AS owner_name, bots.* FROM bots INNER JOIN users ON bots.user_id = users.id WHERE room_id = ?")) { + statement.setInt(1, this.id); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + Bot b = Emulator.getGameEnvironment().getBotManager().loadBot(set); + + if (b != null) { + b.setRoom(this); + b.setRoomUnit(new RoomUnit()); + b.getRoomUnit().setPathFinderRoom(this); + b.getRoomUnit().setLocation(this.layout.getTile((short) set.getInt("x"), (short) set.getInt("y"))); + if (b.getRoomUnit().getCurrentLocation() == null || b.getRoomUnit().getCurrentLocation().getState() == RoomTileState.INVALID) { + b.getRoomUnit().setZ(this.getLayout().getDoorTile().getStackHeight()); + b.getRoomUnit().setLocation(this.getLayout().getDoorTile()); + b.getRoomUnit().setRotation(RoomUserRotation.fromValue(this.getLayout().getDoorDirection())); + } else { + b.getRoomUnit().setZ(set.getDouble("z")); + b.getRoomUnit().setPreviousLocationZ(set.getDouble("z")); + b.getRoomUnit().setRotation(RoomUserRotation.values()[set.getInt("rot")]); + } + b.getRoomUnit().setRoomUnitType(RoomUnitType.BOT); + b.getRoomUnit().setDanceType(DanceType.values()[set.getInt("dance")]); + + b.getRoomUnit().setInRoom(true); + this.giveEffect(b.getRoomUnit(), set.getInt("effect"), Integer.MAX_VALUE); + this.addBot(b); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + private synchronized void loadPets(Connection connection) { + + this.currentPets.clear(); + + try (PreparedStatement statement = connection.prepareStatement("SELECT users.username as pet_owner_name, users_pets.* FROM users_pets INNER JOIN users ON users_pets.user_id = users.id WHERE room_id = ?")) { + statement.setInt(1, this.id); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + + Pet pet = PetManager.loadPet(set); + pet.setRoom(this); + pet.setRoomUnit(new RoomUnit()); + pet.getRoomUnit().setPathFinderRoom(this); + pet.getRoomUnit().setLocation(this.layout.getTile((short) set.getInt("x"), (short) set.getInt("y"))); + if (pet.getRoomUnit().getCurrentLocation() == null || pet.getRoomUnit().getCurrentLocation().getState() == RoomTileState.INVALID) { + pet.getRoomUnit().setZ(this.getLayout().getDoorTile().getStackHeight()); + pet.getRoomUnit().setLocation(this.getLayout().getDoorTile()); + pet.getRoomUnit().setRotation(RoomUserRotation.fromValue(this.getLayout().getDoorDirection())); + } else { + pet.getRoomUnit().setZ(set.getDouble("z")); + pet.getRoomUnit().setRotation(RoomUserRotation.values()[set.getInt("rot")]); + } + pet.getRoomUnit().setRoomUnitType(RoomUnitType.PET); + pet.getRoomUnit().setCanWalk(true); + this.addPet(pet); + this.getFurniOwnerNames().put(pet.getUserId(), set.getString("pet_owner_name")); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + private synchronized void loadWordFilter(Connection connection) { + this.wordFilterWords.clear(); + + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM room_wordfilter WHERE room_id = ?")) { + statement.setInt(1, this.id); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + this.wordFilterWords.add(set.getString("word")); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void updateTile(RoomTile tile) { + if (tile != null) { + tile.setStackHeight(this.getStackHeight(tile.x, tile.y, false)); + tile.setState(this.calculateTileState(tile)); + } + } + + public void updateTiles(THashSet tiles) { + for (RoomTile tile : tiles) { + if(tile == null) { + continue; + } + this.tileCache.remove(tile); + tile.setStackHeight(this.getStackHeight(tile.x, tile.y, false)); + tile.setState(this.calculateTileState(tile)); + } + + this.sendComposer(new UpdateStackHeightComposer(this, tiles).compose()); + } + + private RoomTileState calculateTileState(RoomTile tile) { + return this.calculateTileState(tile, null); + } + + private RoomTileState calculateTileState(RoomTile tile, HabboItem exclude) { + if (tile == null || tile.state == RoomTileState.INVALID) + return RoomTileState.INVALID; + + RoomTileState result = RoomTileState.OPEN; + + THashSet items = this.getItemsAt(tile); + + if (items == null) return RoomTileState.INVALID; + + HabboItem tallestItem = null; + + for (HabboItem item : items) { + if (exclude != null && item == exclude) continue; + + if(item.getBaseItem().allowLay()) { + return RoomTileState.LAY; + } + + if(tallestItem != null && tallestItem.getZ() + Item.getCurrentHeight(tallestItem) > item.getZ() + Item.getCurrentHeight(item)) + continue; + + result = this.checkStateForItem(item, tile); + tallestItem = item; + } + return result; + } + + private RoomTileState checkStateForItem(HabboItem item, RoomTile tile) { + RoomTileState result = RoomTileState.BLOCKED; + + if (item.isWalkable()) { + result = RoomTileState.OPEN; + } else if (item.getBaseItem().allowSit()) { + result = RoomTileState.SIT; + } else if (item.getBaseItem().allowLay()) { + result = RoomTileState.LAY; + } + + RoomTileState overriddenState = item.getOverrideTileState(tile, this); + if (overriddenState != null) { + result = overriddenState; + } + + return result; + } + + public boolean tileWalkable(RoomTile t) { + return this.tileWalkable(t.x, t.y); + } + + public boolean tileWalkable(short x, short y) { + boolean walkable = this.layout.tileWalkable(x, y); + RoomTile tile = this.getLayout().getTile(x, y); + + if ((walkable && tile != null) && (tile.hasUnits() && !this.allowWalkthrough)) { + walkable = false; + + } + + return walkable; + } + + public void pickUpItem(HabboItem item, Habbo picker) { + if (item == null) + return; + + if (Emulator.getPluginManager().isRegistered(FurniturePickedUpEvent.class, true)) { + Event furniturePickedUpEvent = new FurniturePickedUpEvent(item, picker); + Emulator.getPluginManager().fireEvent(furniturePickedUpEvent); + + if (furniturePickedUpEvent.isCancelled()) + return; + } + + this.removeHabboItem(item.getId()); + item.onPickUp(this); + item.setRoomId(0); + item.needsUpdate(true); + + if (item.getBaseItem().getType() == FurnitureType.FLOOR) { + this.sendComposer(new RemoveFloorItemComposer(item).compose()); + + THashSet updatedTiles = new THashSet<>(); + Rectangle rectangle = RoomLayout.getRectangle(item.getX(), item.getY(), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + + for (short x = (short) rectangle.x; x < rectangle.x + rectangle.getWidth(); x++) { + for (short y = (short) rectangle.y; y < rectangle.y + rectangle.getHeight(); y++) { + double stackHeight = this.getStackHeight(x, y, false); + RoomTile tile = this.layout.getTile(x, y); + + if (tile != null) { + tile.setStackHeight(stackHeight); + updatedTiles.add(tile); + } + } + } + this.sendComposer(new UpdateStackHeightComposer(this, updatedTiles).compose()); + this.updateTiles(updatedTiles); + updatedTiles.forEach(tile -> { + this.updateHabbosAt(tile.x, tile.y); + this.updateBotsAt(tile.x, tile.y); + }); + } else if (item.getBaseItem().getType() == FurnitureType.WALL) { + this.sendComposer(new RemoveWallItemComposer(item).compose()); + } + + Habbo habbo = (picker != null && picker.getHabboInfo().getId() == item.getId() ? picker : Emulator.getGameServer().getGameClientManager().getHabbo(item.getUserId())); + if (habbo != null) { + habbo.getInventory().getItemsComponent().addItem(item); + habbo.getClient().sendResponse(new AddHabboItemComposer(item)); + habbo.getClient().sendResponse(new InventoryRefreshComposer()); + } + Emulator.getThreading().run(item); + } + + public void updateHabbosAt(Rectangle rectangle) { + for (short i = (short) rectangle.x; i < rectangle.x + rectangle.width; i++) { + for (short j = (short) rectangle.y; j < rectangle.y + rectangle.height; j++) { + this.updateHabbosAt(i, j); + } + } + } + + public void updateHabbo(Habbo habbo) { + this.updateRoomUnit(habbo.getRoomUnit()); + } + + public void updateRoomUnit(RoomUnit roomUnit) { + HabboItem item = this.getTopItemAt(roomUnit.getX(), roomUnit.getY()); + + if ((item == null && !roomUnit.cmdSit) || (item != null && !item.getBaseItem().allowSit())) + roomUnit.removeStatus(RoomUnitStatus.SIT); + + double oldZ = roomUnit.getZ(); + + if (item != null) { + if (item.getBaseItem().allowSit()) { + roomUnit.setZ(item.getZ()); + } else { + roomUnit.setZ(item.getZ() + Item.getCurrentHeight(item)); + } + + if (oldZ != roomUnit.getZ()) { + this.scheduledTasks.add(() -> { + try { + item.onWalkOn(roomUnit, Room.this, null); + } catch (Exception e) { + + } + }); + } + } + + this.sendComposer(new RoomUserStatusComposer(roomUnit).compose()); + } + + public void updateHabbosAt(short x, short y) { + this.updateHabbosAt(x, y, this.getHabbosAt(x, y)); + } + + public void updateHabbosAt(short x, short y, List habbos) { + HabboItem item = this.getTopItemAt(x, y); + + for (Habbo habbo : habbos) { + + double oldZ = habbo.getRoomUnit().getZ(); + RoomUserRotation oldRotation = habbo.getRoomUnit().getBodyRotation(); + double z = habbo.getRoomUnit().getCurrentLocation().getStackHeight(); + boolean updated = false; + + if (habbo.getRoomUnit().hasStatus(RoomUnitStatus.SIT) && ((item == null && !habbo.getRoomUnit().cmdSit) || (item != null && !item.getBaseItem().allowSit()))) { + habbo.getRoomUnit().removeStatus(RoomUnitStatus.SIT); + updated = true; + } + + if (habbo.getRoomUnit().hasStatus(RoomUnitStatus.LAY) && ((item == null && !habbo.getRoomUnit().cmdLay) || (item != null && !item.getBaseItem().allowLay()))) { + habbo.getRoomUnit().removeStatus(RoomUnitStatus.LAY); + updated = true; + } + + if (item != null && (item.getBaseItem().allowSit() || item.getBaseItem().allowLay())) { + habbo.getRoomUnit().setZ(item.getZ()); + habbo.getRoomUnit().setPreviousLocationZ(item.getZ()); + habbo.getRoomUnit().setRotation(RoomUserRotation.fromValue(item.getRotation())); + } else { + habbo.getRoomUnit().setZ(z); + habbo.getRoomUnit().setPreviousLocationZ(z); + } + + if(habbo.getRoomUnit().getCurrentLocation().is(x, y) && (oldZ != z || updated || oldRotation != habbo.getRoomUnit().getBodyRotation())) { + habbo.getRoomUnit().statusUpdate(true); + } + } + } + + public void updateBotsAt(short x, short y) { + if(this.layout == null) { + return; + } + HabboItem topItem = this.getTopItemAt(x, y); + + THashSet roomUnits = new THashSet<>(); + + this.getBotsAt(this.layout.getTile(x, y)).forEach(bot -> { + if (topItem != null) { + if (topItem.getBaseItem().allowSit()) { + bot.getRoomUnit().setZ(topItem.getZ()); + bot.getRoomUnit().setPreviousLocationZ(topItem.getZ()); + bot.getRoomUnit().setRotation(RoomUserRotation.fromValue(topItem.getRotation())); + } else { + bot.getRoomUnit().setZ(topItem.getZ() + Item.getCurrentHeight(topItem)); + + if (topItem.getBaseItem().allowLay()) { + bot.getRoomUnit().setStatus(RoomUnitStatus.LAY, (topItem.getZ() + topItem.getBaseItem().getHeight()) + ""); + } + } + } else { + bot.getRoomUnit().setZ(bot.getRoomUnit().getCurrentLocation().getStackHeight()); + bot.getRoomUnit().setPreviousLocationZ(bot.getRoomUnit().getCurrentLocation().getStackHeight()); + } + roomUnits.add(bot.getRoomUnit()); + }); + + if (!roomUnits.isEmpty()) { + this.sendComposer(new RoomUserStatusComposer(roomUnits, true).compose()); + } + } + + public void pickupPetsForHabbo(Habbo habbo) { + THashSet pets = new THashSet<>(); + + synchronized (this.currentPets) { + for (Pet pet : this.currentPets.valueCollection()) { + if (pet.getUserId() == habbo.getHabboInfo().getId()) { + pets.add(pet); + } + } + } + + for (Pet pet : pets) { + pet.removeFromRoom(); + Emulator.getThreading().run(pet); + habbo.getInventory().getPetsComponent().addPet(pet); + habbo.getClient().sendResponse(new AddPetComposer(pet)); + this.currentPets.remove(pet.getId()); + } + + } + + public void startTrade(Habbo userOne, Habbo userTwo) { + RoomTrade trade = new RoomTrade(userOne, userTwo, this); + synchronized (this.activeTrades) { + this.activeTrades.add(trade); + } + + trade.start(); + } + + public void stopTrade(RoomTrade trade) { + synchronized (this.activeTrades) { + this.activeTrades.remove(trade); + } + } + + public RoomTrade getActiveTradeForHabbo(Habbo user) { + synchronized (this.activeTrades) { + for (RoomTrade trade : this.activeTrades) { + for (RoomTradeUser habbo : trade.getRoomTradeUsers()) { + if (habbo.getHabbo() == user) + return trade; + } + } + } + return null; + } + + public synchronized void dispose() { + synchronized (this.loadLock) { + if (this.preventUnloading) + return; + + if (Emulator.getPluginManager().fireEvent(new RoomUnloadingEvent(this)).isCancelled()) + return; + + if (this.loaded) { + try { + + if (this.traxManager != null && !this.traxManager.disposed()) { + this.traxManager.dispose(); + } + + this.roomCycleTask.cancel(false); + this.scheduledTasks.clear(); + this.scheduledComposers.clear(); + this.loaded = false; + + this.tileCache.clear(); + + synchronized (this.mutedHabbos) { + this.mutedHabbos.clear(); + } + + for (InteractionGameTimer timer : this.getRoomSpecialTypes().getGameTimers().values()) { + timer.setRunning(false); + } + + for (Game game : this.games) { + game.dispose(); + } + this.games.clear(); + + removeAllPets(ownerId); + + synchronized (this.roomItems) { + TIntObjectIterator iterator = this.roomItems.iterator(); + + for (int i = this.roomItems.size(); i-- > 0; ) { + try { + iterator.advance(); + + if (iterator.value().needsUpdate()) + iterator.value().run(); + } catch (NoSuchElementException e) { + break; + } + } + } + + if (this.roomSpecialTypes != null) { + this.roomSpecialTypes.dispose(); + } + + synchronized (this.roomItems) { + this.roomItems.clear(); + } + + synchronized (this.habboQueue) { + this.habboQueue.clear(); + } + + + for (Habbo habbo : this.currentHabbos.values()) { + Emulator.getGameEnvironment().getRoomManager().leaveRoom(habbo, this); + } + + this.sendComposer(new HotelViewComposer().compose()); + + this.currentHabbos.clear(); + + + TIntObjectIterator botIterator = this.currentBots.iterator(); + + for (int i = this.currentBots.size(); i-- > 0; ) { + try { + botIterator.advance(); + botIterator.value().needsUpdate(true); + Emulator.getThreading().run(botIterator.value()); + } catch (NoSuchElementException e) { + log.error("Caught exception", e); + break; + } + } + + this.currentBots.clear(); + this.currentPets.clear(); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + try { + this.wordQuiz = ""; + this.yesVotes = 0; + this.noVotes = 0; + this.updateDatabaseUserCount(); + this.preLoaded = true; + this.layout = null; + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + Emulator.getPluginManager().fireEvent(new RoomUnloadedEvent(this)); + } + + @Override + public int compareTo(Room o) { + if (o.getUserCountWithoutInvisibleHabbos() != this.getUserCountWithoutInvisibleHabbos()) { + return o.getUserCountWithoutInvisibleHabbos() - this.getUserCountWithoutInvisibleHabbos(); + } + + return this.id - o.id; + } + + @Override + public void serialize(ServerMessage message) { + message.appendInt(this.id); + message.appendString(this.name); + if (this.isPublicRoom()) { + message.appendInt(0); + message.appendString(""); + } else { + message.appendInt(this.ownerId); + message.appendString(this.ownerName); + } + message.appendInt(this.state.getState()); + message.appendInt(this.getUserCountWithoutInvisibleHabbos()); + message.appendInt(this.usersMax); + message.appendString(this.description); + message.appendInt(0); + message.appendInt(this.score); + message.appendInt(0); + message.appendInt(this.category); + + String[] tags = Arrays.stream(this.tags.split(";")).filter(t -> !t.isEmpty()).toArray(String[]::new); + message.appendInt(tags.length); + for (String s : tags) { + message.appendString(s); + } + + int base = 0; + + if (this.getGuildId() > 0) { + base = base | 2; + } + + if (this.isPromoted()) { + base = base | 4; + } + + if (!this.isPublicRoom()) { + base = base | 8; + } + + + message.appendInt(base); + + + if (this.getGuildId() > 0) { + Guild g = Emulator.getGameEnvironment().getGuildManager().getGuild(this.getGuildId()); + if (g != null) { + message.appendInt(g.getId()); + message.appendString(g.getName()); + message.appendString(g.getBadge()); + } else { + message.appendInt(0); + message.appendString(""); + message.appendString(""); + } + } + + if (this.promoted) { + message.appendString(this.promotion.getTitle()); + message.appendString(this.promotion.getDescription()); + message.appendInt((this.promotion.getEndTimestamp() - Emulator.getIntUnixTimestamp()) / 60); + } + + } + + @Override + public void run() { + synchronized (this.loadLock) { + if (this.loaded) { + try { + Emulator.getThreading().run( + Room.this::cycle); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + } + + this.save(); + } + + public void save() { + if (this.needsUpdate) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE rooms SET name = ?, description = ?, password = ?, state = ?, users_max = ?, category = ?, score = ?, paper_floor = ?, paper_wall = ?, paper_landscape = ?, thickness_wall = ?, wall_height = ?, thickness_floor = ?, moodlight_data = ?, tags = ?, allow_other_pets = ?, allow_other_pets_eat = ?, allow_walkthrough = ?, allow_hidewall = ?, chat_mode = ?, chat_weight = ?, chat_speed = ?, chat_hearing_distance = ?, chat_protection =?, who_can_mute = ?, who_can_kick = ?, who_can_ban = ?, poll_id = ?, guild_id = ?, roller_speed = ?, override_model = ?, is_staff_picked = ?, promoted = ?, trade_mode = ?, move_diagonally = ?, owner_id = ?, owner_name = ?, jukebox_active = ?, hidewired = ? WHERE id = ?")) { + statement.setString(1, this.name); + statement.setString(2, this.description); + statement.setString(3, this.password); + statement.setString(4, this.state.name().toLowerCase()); + statement.setInt(5, this.usersMax); + statement.setInt(6, this.category); + statement.setInt(7, this.score); + statement.setString(8, this.floorPaint); + statement.setString(9, this.wallPaint); + statement.setString(10, this.backgroundPaint); + statement.setInt(11, this.wallSize); + statement.setInt(12, this.wallHeight); + statement.setInt(13, this.floorSize); + StringBuilder moodLightData = new StringBuilder(); + + int id = 1; + for (RoomMoodlightData data : this.moodlightData.valueCollection()) { + data.setId(id); + moodLightData.append(data).append(";"); + id++; + } + + statement.setString(14, moodLightData.toString()); + statement.setString(15, this.tags); + statement.setString(16, this.allowPets ? "1" : "0"); + statement.setString(17, this.allowPetsEat ? "1" : "0"); + statement.setString(18, this.allowWalkthrough ? "1" : "0"); + statement.setString(19, this.hideWall ? "1" : "0"); + statement.setInt(20, this.chatMode); + statement.setInt(21, this.chatWeight); + statement.setInt(22, this.chatSpeed); + statement.setInt(23, this.chatDistance); + statement.setInt(24, this.chatProtection); + statement.setInt(25, this.muteOption); + statement.setInt(26, this.kickOption); + statement.setInt(27, this.banOption); + statement.setInt(28, this.pollId); + statement.setInt(29, this.guildId); + statement.setInt(30, this.rollerSpeed); + statement.setString(31, this.overrideModel ? "1" : "0"); + statement.setString(32, this.staffPromotedRoom ? "1" : "0"); + statement.setString(33, this.promoted ? "1" : "0"); + statement.setInt(34, this.tradeMode); + statement.setString(35, this.moveDiagonally ? "1" : "0"); + statement.setInt(36, this.ownerId); + statement.setString(37, this.ownerName); + statement.setString(38, this.jukeboxActive ? "1" : "0"); + statement.setString(39, this.hideWired ? "1" : "0"); + statement.setInt(40, this.id); + statement.executeUpdate(); + this.needsUpdate = false; + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + private void updateDatabaseUserCount() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE rooms SET users = ? WHERE id = ? LIMIT 1")) { + statement.setInt(1, this.currentHabbos.size()); + statement.setInt(2, this.id); + statement.executeUpdate(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + private void cycle() { + this.cycleOdd = !this.cycleOdd; + this.cycleTimestamp = System.currentTimeMillis(); + final boolean[] foundRightHolder = {false}; + + + boolean loaded; + synchronized (this.loadLock) { + loaded = this.loaded; + } + this.tileCache.clear(); + if (loaded) { + if (!this.scheduledTasks.isEmpty()) { + ConcurrentHashMap.KeySetView tasks = this.scheduledTasks; + this.scheduledTasks = ConcurrentHashMap.newKeySet(); + + for (Runnable runnable : tasks) { + Emulator.getThreading().run(runnable); + } + } + + for (ICycleable task : this.roomSpecialTypes.getCycleTasks()) { + task.cycle(this); + } + + if (!this.currentHabbos.isEmpty()) { + this.idleCycles = 0; + + THashSet updatedUnit = new THashSet<>(); + ArrayList toKick = new ArrayList<>(); + + final Room room = this; + + final long millis = System.currentTimeMillis(); + + for (Habbo habbo : this.currentHabbos.values()) { + if (!foundRightHolder[0]) { + foundRightHolder[0] = habbo.getRoomUnit().getRightsLevel() != RoomRightLevels.NONE; + } + + /* Habbo doesn't remove the handitem anymore, checked on February 25 2023 + if (habbo.getRoomUnit().getHandItem() > 0 && millis - habbo.getRoomUnit().getHandItemTimestamp() > (Room.HAND_ITEM_TIME * 1000L)) { + this.giveHandItem(habbo, 0); + } + */ + + if (habbo.getRoomUnit().getEffectId() > 0 && millis / 1000 > habbo.getRoomUnit().getEffectEndTimestamp()) { + this.giveEffect(habbo, 0, -1); + } + + if (habbo.getRoomUnit().isKicked) { + habbo.getRoomUnit().kickCount++; + + if (habbo.getRoomUnit().kickCount >= 5) { + this.scheduledTasks.add(() -> Emulator.getGameEnvironment().getRoomManager().leaveRoom(habbo, room)); + continue; + } + } + + if (Emulator.getConfig().getBoolean("hotel.rooms.auto.idle")) { + if (!habbo.getRoomUnit().isIdle()) { + habbo.getRoomUnit().increaseIdleTimer(); + + if (habbo.getRoomUnit().isIdle()) { + boolean danceIsNone = (habbo.getRoomUnit().getDanceType() == DanceType.NONE); + if (danceIsNone) + this.sendComposer(new RoomUnitIdleComposer(habbo.getRoomUnit()).compose()); + if (danceIsNone && !Emulator.getConfig().getBoolean("hotel.roomuser.idle.not_dancing.ignore.wired_idle")) + WiredHandler.handle(WiredTriggerType.IDLES, habbo.getRoomUnit(), this, new Object[]{habbo}); + } + } else { + habbo.getRoomUnit().increaseIdleTimer(); + + if (!this.isOwner(habbo) && habbo.getRoomUnit().getIdleTimer() >= Room.IDLE_CYCLES_KICK) { + UserExitRoomEvent event = new UserExitRoomEvent(habbo, UserExitRoomEvent.UserExitRoomReason.KICKED_IDLE); + Emulator.getPluginManager().fireEvent(event); + + if (!event.isCancelled()) { + toKick.add(habbo); + } + } + } + } + + if (Emulator.getConfig().getBoolean("hotel.rooms.deco_hosting") && this.ownerId != habbo.getHabboInfo().getId()) { + //Check if the time already have 1 minute (120 / 2 = 60s) + if (habbo.getRoomUnit().getTimeInRoom() >= 120) { + AchievementManager.progressAchievement(this.ownerId, Emulator.getGameEnvironment().getAchievementManager().getAchievement("RoomDecoHosting")); + habbo.getRoomUnit().resetTimeInRoom(); + } else { + habbo.getRoomUnit().increaseTimeInRoom(); + } + } + + + if (habbo.getHabboStats().mutedBubbleTracker && habbo.getHabboStats().allowTalk()) { + habbo.getHabboStats().mutedBubbleTracker = false; + this.sendComposer(new RoomUserIgnoredComposer(habbo, RoomUserIgnoredComposer.UNIGNORED).compose()); + } + + // Substract 1 from the chatCounter every odd cycle, which is every (500ms * 2). + if (this.cycleOdd && habbo.getHabboStats().chatCounter.get() > 0) { + habbo.getHabboStats().chatCounter.decrementAndGet(); + } + + if (this.cycleRoomUnit(habbo.getRoomUnit(), RoomUnitType.USER)) { + updatedUnit.add(habbo.getRoomUnit()); + } + } + + if (!toKick.isEmpty()) { + for (Habbo habbo : toKick) { + Emulator.getGameEnvironment().getRoomManager().leaveRoom(habbo, this); + } + } + + if (!this.currentBots.isEmpty()) { + TIntObjectIterator botIterator = this.currentBots.iterator(); + for (int i = this.currentBots.size(); i-- > 0; ) { + try { + final Bot bot; + try { + botIterator.advance(); + bot = botIterator.value(); + } catch (Exception e) { + break; + } + + if (!this.allowBotsWalk && bot.getRoomUnit().isWalking()) { + bot.getRoomUnit().stopWalking(); + updatedUnit.add(bot.getRoomUnit()); + continue; + } + + botIterator.value().cycle(this.allowBotsWalk); + + + if (this.cycleRoomUnit(bot.getRoomUnit(), RoomUnitType.BOT)) { + updatedUnit.add(bot.getRoomUnit()); + } + + + } catch (NoSuchElementException e) { + log.error("Caught exception", e); + break; + } + } + } + + if (!this.currentPets.isEmpty() && this.allowBotsWalk) { + TIntObjectIterator petIterator = this.currentPets.iterator(); + for (int i = this.currentPets.size(); i-- > 0; ) { + try { + petIterator.advance(); + } catch (NoSuchElementException e) { + log.error("Caught exception", e); + break; + } + + Pet pet = petIterator.value(); + if (this.cycleRoomUnit(pet.getRoomUnit(), RoomUnitType.PET)) { + updatedUnit.add(pet.getRoomUnit()); + } + + pet.cycle(); + + if (pet.packetUpdate) { + updatedUnit.add(pet.getRoomUnit()); + pet.packetUpdate = false; + } + + 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.rollerSpeed != -1 && this.rollerCycle >= this.rollerSpeed) { + 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 -> { + + HabboItem newRoller = null; + + RoomTile rollerTile = this.getLayout().getTile(roller.getX(), roller.getY()); + + if (rollerTile == null) + return true; + + THashSet itemsOnRoller = new THashSet<>(); + + for (HabboItem item : getItemsAt(rollerTile)) { + if (item.getZ() >= roller.getZ() + Item.getCurrentHeight(roller)) { + itemsOnRoller.add(item); + } + } + + itemsOnRoller.remove(roller); + + if (!rollerTile.hasUnits() && itemsOnRoller.isEmpty()) + return true; + + RoomTile tileInFront = Room.this.layout.getTileInFront(Room.this.layout.getTile(roller.getX(), roller.getY()), roller.getRotation()); + + if (tileInFront == null) + return true; + + if (!Room.this.layout.tileExists(tileInFront.x, tileInFront.y)) + return true; + + if (tileInFront.state == RoomTileState.INVALID) + return true; + + if (!tileInFront.getAllowStack() && !(tileInFront.isWalkable() || tileInFront.state == RoomTileState.SIT || tileInFront.state == RoomTileState.LAY)) + return true; + + if (tileInFront.hasUnits()) + return true; + + THashSet itemsNewTile = new THashSet<>(); + itemsNewTile.addAll(getItemsAt(tileInFront)); + itemsNewTile.removeAll(itemsOnRoller); + + itemsOnRoller.removeIf(item -> item.getX() != roller.getX() || item.getY() != roller.getY() || rollerFurniIds.contains(item.getId())); + + HabboItem topItem = Room.this.getTopItemAt(tileInFront.x, tileInFront.y); + + boolean allowUsers = true; + boolean allowFurniture = true; + boolean stackContainsRoller = false; + + for (HabboItem 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.getZ() != roller.getZ() || (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.z; + } + + if (allowUsers) { + Event roomUserRolledEvent = null; + + if (Emulator.getPluginManager().isRegistered(UserRolledEvent.class, true)) { + roomUserRolledEvent = new UserRolledEvent(null, null, null); + } + + ArrayList unitsOnTile = new ArrayList<>(rollerTile.getUnits()); + + for (RoomUnit unit : rollerTile.getUnits()) { + if (unit.getRoomUnitType() == RoomUnitType.PET) { + Pet pet = this.getPet(unit); + if (pet instanceof RideablePet && ((RideablePet) pet).getRider() != null) { + break; + } + } + } + + THashSet usersRolledThisTile = new THashSet<>(); + + for (RoomUnit unit : unitsOnTile) { + if (rolledUnitIds.contains(unit.getId())) continue; + + if (usersRolledThisTile.size() >= Room.ROLLERS_MAXIMUM_ROLL_AVATARS) break; + + if (unit.getRoomUnitType() == RoomUnitType.PET) { + break; + } + + if (stackContainsRoller && !allowFurniture && !(topItem != null && topItem.isWalkable())) + continue; + + if (unit.hasStatus(RoomUnitStatus.MOVE)) + continue; + + double newZ = unit.getZ() + zOffset; + + if (roomUserRolledEvent != null && unit.getRoomUnitType() == RoomUnitType.USER) { + roomUserRolledEvent = new UserRolledEvent(getHabbo(unit), roller, tileInFront); + Emulator.getPluginManager().fireEvent(roomUserRolledEvent); + + if (roomUserRolledEvent.isCancelled()) + continue; + } + + // horse riding + boolean isRiding = false; + if (unit.getRoomUnitType() == RoomUnitType.USER) { + Habbo rollingHabbo = this.getHabbo(unit); + if (rollingHabbo != null && rollingHabbo.getHabboInfo() != null) { + RideablePet riding = rollingHabbo.getHabboInfo().getRiding(); + if (riding != null) { + RoomUnit ridingUnit = riding.getRoomUnit(); + newZ = ridingUnit.getZ() + zOffset; + rolledUnitIds.add(ridingUnit.getId()); + updatedUnit.remove(ridingUnit); + messages.add(new RoomUnitOnRollerComposer(ridingUnit, roller, ridingUnit.getCurrentLocation(), ridingUnit.getZ(), tileInFront, newZ, room)); + isRiding = true; + } + } + } + + usersRolledThisTile.add(unit.getId()); + rolledUnitIds.add(unit.getId()); + updatedUnit.remove(unit); + messages.add(new RoomUnitOnRollerComposer(unit, roller, unit.getCurrentLocation(), unit.getZ() + (isRiding ? 1 : 0), tileInFront, newZ + (isRiding ? 1 : 0), room)); + if (itemsOnRoller.isEmpty()) { + HabboItem item = room.getTopItemAt(tileInFront.x, tileInFront.y); + + if (item != null && itemsNewTile.contains(item) && !itemsOnRoller.contains(item)) { + Emulator.getThreading().run(() -> { + if (unit.getGoal() == rollerTile) { + try { + item.onWalkOn(unit, room, new Object[] { rollerTile, tileInFront }); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + }, this.getRollerSpeed() == 0 ? 250 : InteractionRoller.DELAY); + } + } + + if (unit.hasStatus(RoomUnitStatus.SIT)) { + unit.sitUpdate = true; + } + } + } + + if (!messages.isEmpty()) { + for (MessageComposer message : messages) { + room.sendComposer(message.compose()); + } + messages.clear(); + } + + if (allowFurniture || !stackContainsRoller || InteractionRoller.NO_RULES) { + Event furnitureRolledEvent = null; + PluginManager pluginManager = Emulator.getPluginManager(); // Store the plugin manager + + if (pluginManager.isRegistered(FurnitureRolledEvent.class, true)) { + furnitureRolledEvent = new FurnitureRolledEvent(null, null, null); + } + + if (newRoller == null || topItem == newRoller) { + List sortedItems = new ArrayList<>(itemsOnRoller); + sortedItems.sort((o1, o2) -> Double.compare(o2.getZ(), o1.getZ())); + + for (HabboItem item : sortedItems) { + if ((item.getX() == roller.getX() && item.getY() == roller.getY() && zOffset <= 0) && (item != roller)) { + if (furnitureRolledEvent != null) { + furnitureRolledEvent = new FurnitureRolledEvent(item, roller, tileInFront); + pluginManager.fireEvent(furnitureRolledEvent); + + if (furnitureRolledEvent.isCancelled()) { + continue; + } + } + + final double currentZOffset = zOffset; + int delay = (getRollerSpeed() == 0) ? 250 : InteractionRoller.DELAY; // Calculate delay once + + Emulator.getThreading().run(() -> { + this.sendComposer(new FloorItemOnRollerComposer(item, roller, tileInFront, currentZOffset, room).compose()); + }, delay); + + rollerFurniIds.add(item.getId()); + } + } + } + } + + + if (!messages.isEmpty()) { + for (MessageComposer message : messages) { + room.sendComposer(message.compose()); + } + messages.clear(); + } + + return true; + }); + + int currentTime = (int) (this.cycleTimestamp / 1000); + for (HabboItem 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 RoomUserStatusComposer(updatedUnit, true).compose()); + } + + this.traxManager.cycle(); + } else { + + if (this.idleCycles < 60) + this.idleCycles++; + else + this.dispose(); + } + } + + synchronized (this.habboQueue) { + if (!this.habboQueue.isEmpty() && !foundRightHolder[0]) { + this.habboQueue.forEachEntry((a, b) -> { + if (b.isOnline() && b.getHabboInfo().getRoomQueueId() == Room.this.getId()) { + b.getClient().sendResponse(new RoomAccessDeniedComposer("")); + } + return true; + }); + this.habboQueue.clear(); + } + } + + if (!this.scheduledComposers.isEmpty()) { + for (ServerMessage message : this.scheduledComposers) { + this.sendComposer(message); + } + + this.scheduledComposers.clear(); + } + } + + + private boolean cycleRoomUnit(RoomUnit unit, RoomUnitType type) { + boolean update = unit.needsStatusUpdate(); + if (unit.hasStatus(RoomUnitStatus.SIGN)) { + this.sendComposer(new RoomUserStatusComposer(unit).compose()); + unit.removeStatus(RoomUnitStatus.SIGN); + } + + if (unit.isWalking() && unit.getPath() != null && !unit.getPath().isEmpty()) { + if (!unit.cycle(this)) { + return true; + } + } else { + if (unit.hasStatus(RoomUnitStatus.MOVE) && !unit.animateWalk) { + unit.removeStatus(RoomUnitStatus.MOVE); + + update = true; + } + + if (!unit.isWalking() && !unit.cmdSit) { + RoomTile thisTile = this.getLayout().getTile(unit.getX(), unit.getY()); + HabboItem topItem = this.getTallestChair(thisTile); + + if (topItem == null || !topItem.getBaseItem().allowSit()) { + if (unit.hasStatus(RoomUnitStatus.SIT)) { + unit.removeStatus(RoomUnitStatus.SIT); + update = true; + } + } else if (thisTile.state == RoomTileState.SIT && (!unit.hasStatus(RoomUnitStatus.SIT) || unit.sitUpdate)) { + this.dance(unit, DanceType.NONE); + //int tileHeight = this.layout.getTile(topItem.getX(), topItem.getY()).z; + unit.setStatus(RoomUnitStatus.SIT, (Item.getCurrentHeight(topItem)) + ""); + unit.setZ(topItem.getZ()); + unit.setRotation(RoomUserRotation.values()[topItem.getRotation()]); + unit.sitUpdate = false; + return true; + } + } + } + + if (!unit.isWalking() && !unit.cmdLay) { + HabboItem topItem = this.getTopItemAt(unit.getX(), unit.getY()); + + if (topItem == null || !topItem.getBaseItem().allowLay()) { + if (unit.hasStatus(RoomUnitStatus.LAY)) { + unit.removeStatus(RoomUnitStatus.LAY); + update = true; + } + } else { + if (!unit.hasStatus(RoomUnitStatus.LAY)) { + unit.setStatus(RoomUnitStatus.LAY, Item.getCurrentHeight(topItem) + ""); + unit.setRotation(RoomUserRotation.values()[topItem.getRotation() % 4]); + + if (topItem.getRotation() == 0 || topItem.getRotation() == 4) { + unit.setLocation(this.layout.getTile(unit.getX(), topItem.getY())); + //unit.setOldY(topItem.getY()); + } else { + unit.setLocation(this.layout.getTile(topItem.getX(), unit.getY())); + //unit.setOldX(topItem.getX()); + } + update = true; + } + } + } + + if (update) { + unit.statusUpdate(false); + } + + return update; + } + + public int getId() { + return this.id; + } + + public int getOwnerId() { + return this.ownerId; + } + + public void setOwnerId(int ownerId) { + this.ownerId = ownerId; + } + + public String getOwnerName() { + return this.ownerName; + } + + public void setOwnerName(String ownerName) { + this.ownerName = ownerName; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + + if (this.name.length() > 50) { + this.name = this.name.substring(0, 50); + } + + if (this.hasGuild()) { + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(this.guildId); + + if (guild != null) { + guild.setRoomName(name); + } + } + } + + public String getDescription() { + return this.description; + } + + public void setDescription(String description) { + this.description = description; + + if (this.description.length() > 250) { + this.description = this.description.substring(0, 250); + } + } + + public RoomLayout getLayout() { + return this.layout; + } + + public void setLayout(RoomLayout layout) { + this.layout = layout; + } + + public boolean hasCustomLayout() { + return this.overrideModel; + } + + public void setHasCustomLayout(boolean overrideModel) { + this.overrideModel = overrideModel; + } + + public String getPassword() { + return this.password; + } + + public void setPassword(String password) { + this.password = password; + + if (this.password.length() > 20) { + this.password = this.password.substring(0, 20); + } + } + + public RoomState getState() { + return this.state; + } + + public void setState(RoomState state) { + this.state = state; + } + + public int getUsersMax() { + return this.usersMax; + } + + public void setUsersMax(int usersMax) { + this.usersMax = usersMax; + } + + public int getScore() { + return this.score; + } + + public void setScore(int score) { + this.score = score; + } + + public int getCategory() { + return this.category; + } + + public void setCategory(int category) { + this.category = category; + } + + public String getFloorPaint() { + return this.floorPaint; + } + + public void setFloorPaint(String floorPaint) { + this.floorPaint = floorPaint; + } + + public String getWallPaint() { + return this.wallPaint; + } + + public void setWallPaint(String wallPaint) { + this.wallPaint = wallPaint; + } + + public String getBackgroundPaint() { + return this.backgroundPaint; + } + + public void setBackgroundPaint(String backgroundPaint) { + this.backgroundPaint = backgroundPaint; + } + + public int getWallSize() { + return this.wallSize; + } + + public void setWallSize(int wallSize) { + this.wallSize = wallSize; + } + + public int getWallHeight() { + return this.wallHeight; + } + + public void setWallHeight(int wallHeight) { + this.wallHeight = wallHeight; + } + + public int getFloorSize() { + return this.floorSize; + } + + public void setFloorSize(int floorSize) { + this.floorSize = floorSize; + } + + public String getTags() { + return this.tags; + } + + public void setTags(String tags) { + this.tags = tags; + } + + public int getTradeMode() { + return this.tradeMode; + } + + public void setTradeMode(int tradeMode) { + this.tradeMode = tradeMode; + } + + public boolean moveDiagonally() { + return this.moveDiagonally; + } + + public void moveDiagonally(boolean moveDiagonally) { + this.moveDiagonally = moveDiagonally; + this.layout.moveDiagonally(this.moveDiagonally); + this.needsUpdate = true; + } + + public int getGuildId() { + return this.guildId; + } + + public boolean hasGuild() { + return this.guildId != 0; + } + + public void setGuildId(int guildId) { + this.guildId = guildId; + } + + public String getGuildName() { + if (this.hasGuild()) { + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(this.guildId); + + if (guild != null) { + return guild.getName(); + } + } + + return ""; + } + + public boolean isPublicRoom() { + return this.publicRoom; + } + + public void setPublicRoom(boolean publicRoom) { + this.publicRoom = publicRoom; + } + + public boolean isStaffPromotedRoom() { + return this.staffPromotedRoom; + } + + public void setStaffPromotedRoom(boolean staffPromotedRoom) { + this.staffPromotedRoom = staffPromotedRoom; + } + + public boolean isAllowPets() { + return this.allowPets; + } + + public void setAllowPets(boolean allowPets) { + this.allowPets = allowPets; + if (!allowPets) { + removeAllPets(ownerId); + } + } + + public boolean isAllowPetsEat() { + return this.allowPetsEat; + } + + public void setAllowPetsEat(boolean allowPetsEat) { + this.allowPetsEat = allowPetsEat; + } + + public boolean isAllowWalkthrough() { + return this.allowWalkthrough; + } + + public void setAllowWalkthrough(boolean allowWalkthrough) { + this.allowWalkthrough = allowWalkthrough; + } + + public boolean isAllowBotsWalk() { + return this.allowBotsWalk; + } + + public void setAllowBotsWalk(boolean allowBotsWalk) { + this.allowBotsWalk = allowBotsWalk; + } + + public boolean isAllowEffects() { + return this.allowEffects; + } + + public void setAllowEffects(boolean allowEffects) { + this.allowEffects = allowEffects; + } + + public boolean isHideWall() { + return this.hideWall; + } + + public void setHideWall(boolean hideWall) { + this.hideWall = hideWall; + } + + public Color getBackgroundTonerColor() { + Color color = new Color(0, 0, 0); + TIntObjectIterator iterator = this.roomItems.iterator(); + + for (int i = this.roomItems.size(); i > 0; i--) { + try { + iterator.advance(); + HabboItem object = iterator.value(); + + if (object instanceof InteractionBackgroundToner) { + String[] extraData = object.getExtradata().split(":"); + + if (extraData.length == 4) { + if (extraData[0].equalsIgnoreCase("1")) { + return Color.getHSBColor(Integer.parseInt(extraData[1]), Integer.parseInt(extraData[2]), Integer.parseInt(extraData[3])); + } + } + } + } catch (Exception e) { + } + } + + return color; + } + + public int getChatMode() { + return this.chatMode; + } + + public void setChatMode(int chatMode) { + this.chatMode = chatMode; + } + + public int getChatWeight() { + return this.chatWeight; + } + + public void setChatWeight(int chatWeight) { + this.chatWeight = chatWeight; + } + + public int getChatSpeed() { + return this.chatSpeed; + } + + public void setChatSpeed(int chatSpeed) { + this.chatSpeed = chatSpeed; + } + + public int getChatDistance() { + return this.chatDistance; + } + + public void setChatDistance(int chatDistance) { + this.chatDistance = chatDistance; + } + + /** + * Removes all pets from the room except if the owner id is excludeUserId + * + * @param excludeUserId Habbo id to keep pets + */ + public void removeAllPets(int excludeUserId) { + ArrayList toRemovePets = new ArrayList<>(); + ArrayList removedPets = new ArrayList<>(); + synchronized (this.currentPets) { + for (Pet pet : this.currentPets.valueCollection()) { + try { + if (pet.getUserId() != excludeUserId) { + toRemovePets.add(pet); + } + + } catch (NoSuchElementException e) { + log.error("Caught exception", e); + break; + } + } + } + + for (Pet pet : toRemovePets) { + removedPets.add(pet); + + pet.removeFromRoom(); + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(pet.getUserId()); + if (habbo != null) { + habbo.getInventory().getPetsComponent().addPet(pet); + habbo.getClient().sendResponse(new AddPetComposer(pet)); + } + + pet.needsUpdate = true; + pet.run(); + } + + for (Pet pet : removedPets) { + this.currentPets.remove(pet.getId()); + } + } + + public int getChatProtection() { + return this.chatProtection; + } + + public void setChatProtection(int chatProtection) { + this.chatProtection = chatProtection; + } + + public int getMuteOption() { + return this.muteOption; + } + + public void setMuteOption(int muteOption) { + this.muteOption = muteOption; + } + + public int getKickOption() { + return this.kickOption; + } + + public void setKickOption(int kickOption) { + this.kickOption = kickOption; + } + + public int getBanOption() { + return this.banOption; + } + + public void setBanOption(int banOption) { + this.banOption = banOption; + } + + public int getPollId() { + return this.pollId; + } + + public void setPollId(int pollId) { + this.pollId = pollId; + } + + public int getRollerSpeed() { + return this.rollerSpeed; + } + + public void setRollerSpeed(int rollerSpeed) { + this.rollerSpeed = rollerSpeed; + this.rollerCycle = 0; + this.needsUpdate = true; + } + + public String[] filterAnything() { + return new String[]{this.getOwnerName(), this.getGuildName(), this.getDescription(), this.getPromotionDesc()}; + } + + public long getCycleTimestamp() { + return this.cycleTimestamp; + } + + public boolean isPromoted() { + this.promoted = this.promotion != null && this.promotion.getEndTimestamp() > Emulator.getIntUnixTimestamp(); + this.needsUpdate = true; + + return this.promoted; + } + + public RoomPromotion getPromotion() { + return this.promotion; + } + + public String getPromotionDesc() { + if (this.promotion != null) { + return this.promotion.getDescription(); + } + + return ""; + } + + public void createPromotion(String title, String description, int category) { + this.promoted = true; + + if (this.promotion == null) { + this.promotion = new RoomPromotion(this, title, description, Emulator.getIntUnixTimestamp() + (120 * 60), Emulator.getIntUnixTimestamp(), category); + } else { + this.promotion.setTitle(title); + this.promotion.setDescription(description); + this.promotion.setEndTimestamp(Emulator.getIntUnixTimestamp() + (120 * 60)); + this.promotion.setCategory(category); + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO room_promotions (room_id, title, description, end_timestamp, start_timestamp, category) VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE title = ?, description = ?, end_timestamp = ?, category = ?")) { + statement.setInt(1, this.id); + statement.setString(2, title); + statement.setString(3, description); + statement.setInt(4, this.promotion.getEndTimestamp()); + statement.setInt(5, this.promotion.getStartTimestamp()); + statement.setInt(6, category); + statement.setString(7, this.promotion.getTitle()); + statement.setString(8, this.promotion.getDescription()); + statement.setInt(9, this.promotion.getEndTimestamp()); + statement.setInt(10, this.promotion.getCategory()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.needsUpdate = true; + } + + public boolean addGame(Game game) { + synchronized (this.games) { + return this.games.add(game); + } + } + + public boolean deleteGame(Game game) { + game.stop(); + game.dispose(); + synchronized (this.games) { + return this.games.remove(game); + } + } + + public Game getGame(Class gameType) { + if (gameType == null) return null; + + synchronized (this.games) { + for (Game game : this.games) { + if (gameType.isInstance(game)) { + return game; + } + } + } + + return null; + } + + public Game getGameOrCreate(Class gameType) { + Game game = this.getGame(gameType); + if(game == null) { + try { + game = gameType.getDeclaredConstructor(Room.class).newInstance(this); + this.addGame(game); + } catch (Exception e) { + log.error("Error getting game " + gameType.getName(), e); + } + } + + return game; + } + + public ConcurrentSet getGames() { + return this.games; + } + + public int getUserCount() { + return this.currentHabbos.size(); + } + + /** + * Get all users but without the players that are invisible. + * + * @return the amount of visible players. + */ + public int getUserCountWithoutInvisibleHabbos() { + return (int) this.currentHabbos.values() + .stream() + .filter((habbo -> !habbo.getHabboInfo().isInvisibleInRooms())) + .count(); + } + + public ConcurrentHashMap getCurrentHabbos() { + return this.currentHabbos; + } + + public Collection getHabbos() { + return this.currentHabbos.values(); + } + + public TIntObjectMap getHabboQueue() { + return this.habboQueue; + } + + public TIntObjectMap getFurniOwnerNames() { + return this.furniOwnerNames; + } + + public String getFurniOwnerName(int userId) { + return this.furniOwnerNames.get(userId); + } + + public TIntIntMap getFurniOwnerCount() { + return this.furniOwnerCount; + } + + public TIntObjectMap getMoodlightData() { + return this.moodlightData; + } + + public int getLastTimerReset() { + return this.lastTimerReset; + } + + public void setLastTimerReset(int lastTimerReset) { + this.lastTimerReset = lastTimerReset; + } + + public void addToQueue(Habbo habbo) { + synchronized (this.habboQueue) { + this.habboQueue.put(habbo.getHabboInfo().getId(), habbo); + } + } + + public boolean removeFromQueue(Habbo habbo) { + try { + this.sendComposer(new HideDoorbellComposer(habbo.getHabboInfo().getUsername()).compose()); + + synchronized (this.habboQueue) { + return this.habboQueue.remove(habbo.getHabboInfo().getId()) != null; + } + } catch (Exception e) { + log.error("Caught exception", e); + } + + return true; + } + + public TIntObjectMap getCurrentBots() { + return this.currentBots; + } + + public TIntObjectMap getCurrentPets() { + return this.currentPets; + } + + public THashSet getWordFilterWords() { + return this.wordFilterWords; + } + + public RoomSpecialTypes getRoomSpecialTypes() { + return this.roomSpecialTypes; + } + + public boolean isPreLoaded() { + return this.preLoaded; + } + + public boolean isLoaded() { + return this.loaded; + } + + public void setNeedsUpdate(boolean needsUpdate) { + this.needsUpdate = needsUpdate; + } + + public TIntArrayList getRights() { + return this.rights; + } + + public boolean isMuted() { + return this.muted; + } + + public void setMuted(boolean muted) { + this.muted = muted; + } + + public TraxManager getTraxManager() { + return this.traxManager; + } + + public void addHabboItem(HabboItem item) { + if (item == null) + return; + + synchronized (this.roomItems) { + try { + this.roomItems.put(item.getId(), item); + } catch (Exception e) { + + } + } + + synchronized (this.furniOwnerCount) { + this.furniOwnerCount.put(item.getUserId(), this.furniOwnerCount.get(item.getUserId()) + 1); + } + + synchronized (this.furniOwnerNames) { + if (!this.furniOwnerNames.containsKey(item.getUserId())) { + HabboInfo habbo = HabboManager.getOfflineHabboInfo(item.getUserId()); + + if (habbo != null) { + this.furniOwnerNames.put(item.getUserId(), habbo.getUsername()); + } else { + log.error("Failed to find username for item (ID: {}, UserID: {})", item.getId(), item.getUserId()); + } + } + } + + //TODO: Move this list + synchronized (this.roomSpecialTypes) { + if (item instanceof ICycleable) { + this.roomSpecialTypes.addCycleTask((ICycleable) item); + } + + if (item instanceof InteractionWiredTrigger) { + this.roomSpecialTypes.addTrigger((InteractionWiredTrigger) item); + } else if (item instanceof InteractionWiredEffect) { + this.roomSpecialTypes.addEffect((InteractionWiredEffect) item); + } else if (item instanceof InteractionWiredCondition) { + this.roomSpecialTypes.addCondition((InteractionWiredCondition) item); + } else if (item instanceof InteractionWiredExtra) { + this.roomSpecialTypes.addExtra((InteractionWiredExtra) item); + } else if (item instanceof InteractionWiredHighscore) { + this.roomSpecialTypes.addHighscore((InteractionWiredHighscore) item); + } else if (item instanceof InteractionBattleBanzaiTeleporter) { + this.roomSpecialTypes.addBanzaiTeleporter((InteractionBattleBanzaiTeleporter) item); + } else if (item instanceof InteractionRoller) { + this.roomSpecialTypes.addRoller((InteractionRoller) item); + } else if (item instanceof InteractionGameScoreboard) { + this.roomSpecialTypes.addGameScoreboard((InteractionGameScoreboard) item); + } else if (item instanceof InteractionGameGate) { + this.roomSpecialTypes.addGameGate((InteractionGameGate) item); + } else if (item instanceof InteractionGameTimer) { + this.roomSpecialTypes.addGameTimer((InteractionGameTimer) item); + } else if (item instanceof InteractionFreezeExitTile) { + this.roomSpecialTypes.addFreezeExitTile((InteractionFreezeExitTile) item); + } else if (item instanceof InteractionNest) { + this.roomSpecialTypes.addNest((InteractionNest) item); + } else if (item instanceof InteractionPetDrink) { + this.roomSpecialTypes.addPetDrink((InteractionPetDrink) item); + } else if (item instanceof InteractionPetFood) { + this.roomSpecialTypes.addPetFood((InteractionPetFood) item); + } else if (item instanceof InteractionMoodLight) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionPyramid) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionMusicDisc) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionBattleBanzaiSphere) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionTalkingFurniture) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionWater) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionWaterItem) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionMuteArea) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionBuildArea) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionTagPole) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionTagField) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionJukeBox) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionPetBreedingNest) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionBlackHole) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionStickyPole) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof WiredBlob) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionTent) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionSnowboardSlope) { + this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionFireworks) { + this.roomSpecialTypes.addUndefined(item); + } + + } + } + + public HabboItem getHabboItem(int id) { + if (this.roomItems == null || this.roomSpecialTypes == null) + return null; // room not loaded completely + + HabboItem item; + synchronized (this.roomItems) { + item = this.roomItems.get(id); + } + + if (item == null) + item = this.roomSpecialTypes.getBanzaiTeleporter(id); + + if (item == null) + item = this.roomSpecialTypes.getTrigger(id); + + if (item == null) + item = this.roomSpecialTypes.getEffect(id); + + if (item == null) + item = this.roomSpecialTypes.getCondition(id); + + if (item == null) + item = this.roomSpecialTypes.getGameGate(id); + + if (item == null) + item = this.roomSpecialTypes.getGameScorebord(id); + + if (item == null) + item = this.roomSpecialTypes.getGameTimer(id); + + if (item == null) + item = this.roomSpecialTypes.getFreezeExitTiles().get(id); + + if (item == null) + item = this.roomSpecialTypes.getRoller(id); + + if (item == null) + item = this.roomSpecialTypes.getNest(id); + + if (item == null) + item = this.roomSpecialTypes.getPetDrink(id); + + if (item == null) + item = this.roomSpecialTypes.getPetFood(id); + + return item; + } + + void removeHabboItem(int id) { + this.removeHabboItem(this.getHabboItem(id)); + } + + + public void removeHabboItem(HabboItem item) { + if (item != null) { + + HabboItem i; + synchronized (this.roomItems) { + i = this.roomItems.remove(item.getId()); + } + + if (i != null) { + synchronized (this.furniOwnerCount) { + synchronized (this.furniOwnerNames) { + int count = this.furniOwnerCount.get(i.getUserId()); + + if (count > 1) + this.furniOwnerCount.put(i.getUserId(), count - 1); + else { + this.furniOwnerCount.remove(i.getUserId()); + this.furniOwnerNames.remove(i.getUserId()); + } + } + } + + if (item instanceof ICycleable) { + this.roomSpecialTypes.removeCycleTask((ICycleable) item); + } + + if (item instanceof InteractionBattleBanzaiTeleporter) { + this.roomSpecialTypes.removeBanzaiTeleporter((InteractionBattleBanzaiTeleporter) item); + } else if (item instanceof InteractionWiredTrigger) { + this.roomSpecialTypes.removeTrigger((InteractionWiredTrigger) item); + } else if (item instanceof InteractionWiredEffect) { + this.roomSpecialTypes.removeEffect((InteractionWiredEffect) item); + } else if (item instanceof InteractionWiredCondition) { + this.roomSpecialTypes.removeCondition((InteractionWiredCondition) item); + } else if (item instanceof InteractionWiredExtra) { + this.roomSpecialTypes.removeExtra((InteractionWiredExtra) item); + } else if (item instanceof InteractionRoller) { + this.roomSpecialTypes.removeRoller((InteractionRoller) item); + } else if (item instanceof InteractionGameScoreboard) { + this.roomSpecialTypes.removeScoreboard((InteractionGameScoreboard) item); + } else if (item instanceof InteractionGameGate) { + this.roomSpecialTypes.removeGameGate((InteractionGameGate) item); + } else if (item instanceof InteractionGameTimer) { + this.roomSpecialTypes.removeGameTimer((InteractionGameTimer) item); + } else if (item instanceof InteractionFreezeExitTile) { + this.roomSpecialTypes.removeFreezeExitTile((InteractionFreezeExitTile) item); + } else if (item instanceof InteractionNest) { + this.roomSpecialTypes.removeNest((InteractionNest) item); + } else if (item instanceof InteractionPetDrink) { + this.roomSpecialTypes.removePetDrink((InteractionPetDrink) item); + } else if (item instanceof InteractionPetFood) { + this.roomSpecialTypes.removePetFood((InteractionPetFood) item); + } else if (item instanceof InteractionMoodLight) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof InteractionPyramid) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof InteractionMusicDisc) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof InteractionBattleBanzaiSphere) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof InteractionTalkingFurniture) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof InteractionWaterItem) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof InteractionWater) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof InteractionMuteArea) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof InteractionTagPole) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof InteractionTagField) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof InteractionJukeBox) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof InteractionPetBreedingNest) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof InteractionBlackHole) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof InteractionWiredHighscore) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof InteractionStickyPole) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof WiredBlob) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof InteractionTent) { + this.roomSpecialTypes.removeUndefined(item); + } else if (item instanceof InteractionSnowboardSlope) { + this.roomSpecialTypes.removeUndefined(item); + } + } + } + } + + public THashSet getFloorItems() { + THashSet items = new THashSet<>(); + TIntObjectIterator iterator = this.roomItems.iterator(); + + for (int i = this.roomItems.size(); i-- > 0; ) { + try { + iterator.advance(); + } catch (Exception e) { + break; + } + + if (iterator.value().getBaseItem().getType() == FurnitureType.FLOOR) + items.add(iterator.value()); + } + return items; + } + + public THashSet getWallItems() { + THashSet items = new THashSet<>(); + TIntObjectIterator iterator = this.roomItems.iterator(); + + for (int i = this.roomItems.size(); i-- > 0; ) { + try { + iterator.advance(); + } catch (Exception e) { + break; + } + if (iterator.value().getBaseItem().getType() == FurnitureType.WALL) + items.add(iterator.value()); + } + return items; + } + + public List getPostItNotes() { + return roomItems.valueCollection().stream().filter(i -> i.getBaseItem().getInteractionType().getType() == InteractionPostIt.class).toList(); + } + + public void addHabbo(Habbo habbo) { + synchronized (this.roomUnitLock) { + habbo.getRoomUnit().setId(this.unitCounter); + this.currentHabbos.put(habbo.getHabboInfo().getId(), habbo); + this.unitCounter++; + // don't update the db if the user is invisible + if (!habbo.getHabboInfo().isInvisibleInRooms()) { + this.updateDatabaseUserCount(); + } + } + } + + public void kickHabbo(Habbo habbo, boolean alert) { + if (alert) { + habbo.getClient().sendResponse(new GenericErrorMessagesComposer(GenericErrorMessagesComposer.KICKED_OUT_OF_THE_ROOM)); + } + + habbo.getRoomUnit().isKicked = true; + habbo.getRoomUnit().setGoalLocation(this.layout.getDoorTile()); + + if (habbo.getRoomUnit().getPath() == null || habbo.getRoomUnit().getPath().size() <= 1 || this.isPublicRoom()) { + habbo.getRoomUnit().setCanWalk(true); + Emulator.getGameEnvironment().getRoomManager().leaveRoom(habbo, this); + } + } + + public void removeHabbo(Habbo habbo) { + removeHabbo(habbo, false); + } + + public void removeHabbo(Habbo habbo, boolean sendRemovePacket) { + if (habbo.getRoomUnit() != null && habbo.getRoomUnit().getCurrentLocation() != null) { + habbo.getRoomUnit().getCurrentLocation().removeUnit(habbo.getRoomUnit()); + } + + synchronized (this.roomUnitLock) { + this.currentHabbos.remove(habbo.getHabboInfo().getId()); + } + + if (sendRemovePacket && habbo.getRoomUnit() != null && !habbo.getRoomUnit().isTeleporting) { + this.sendComposer(new RoomUserRemoveComposer(habbo.getRoomUnit()).compose()); + } + + if (habbo.getRoomUnit().getCurrentLocation() != null) { + HabboItem item = this.getTopItemAt(habbo.getRoomUnit().getX(), habbo.getRoomUnit().getY()); + + if (item != null) { + try { + item.onWalkOff(habbo.getRoomUnit(), this, new Object[]{}); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + } + + if (habbo.getHabboInfo().getCurrentGame() != null && this.getGame(habbo.getHabboInfo().getCurrentGame()) != null) { + this.getGame(habbo.getHabboInfo().getCurrentGame()).removeHabbo(habbo); + + } + + RoomTrade trade = this.getActiveTradeForHabbo(habbo); + + if (trade != null) { + trade.stopTrade(habbo); + } + + if (habbo.getHabboInfo().getId() != this.ownerId) { + this.pickupPetsForHabbo(habbo); + } + + this.updateDatabaseUserCount(); + } + + public void addBot(Bot bot) { + synchronized (this.roomUnitLock) { + bot.getRoomUnit().setId(this.unitCounter); + this.currentBots.put(bot.getId(), bot); + this.unitCounter++; + } + } + + public void addPet(Pet pet) { + synchronized (this.roomUnitLock) { + pet.getRoomUnit().setId(this.unitCounter); + this.currentPets.put(pet.getId(), pet); + this.unitCounter++; + + Habbo habbo = this.getHabbo(pet.getUserId()); + if (habbo != null) { + this.furniOwnerNames.put(pet.getUserId(), this.getHabbo(pet.getUserId()).getHabboInfo().getUsername()); + } + } + } + + public Bot getBot(int botId) { + return this.currentBots.get(botId); + } + + public Bot getBot(RoomUnit roomUnit) { + synchronized (this.currentBots) { + TIntObjectIterator iterator = this.currentBots.iterator(); + + for (int i = this.currentBots.size(); i-- > 0; ) { + try { + iterator.advance(); + } catch (NoSuchElementException e) { + log.error("Caught exception", e); + break; + } + + if (iterator.value().getRoomUnit() == roomUnit) + return iterator.value(); + } + } + + return null; + } + + public Bot getBotByRoomUnitId(int id) { + synchronized (this.currentBots) { + return currentBots.valueCollection().stream().filter(b -> b.getRoomUnit().getId() == id).findFirst().orElse(null); + } + } + + public List getBots(String name) { + synchronized (this.currentBots) { + return currentBots.valueCollection().stream().filter(b -> b.getName().equalsIgnoreCase(name)).toList(); + } + } + + public boolean hasBotsAt(final int x, final int y) { + final boolean[] result = {false}; + + synchronized (this.currentBots) { + this.currentBots.forEachValue(object -> { + if (object.getRoomUnit().getX() == x && object.getRoomUnit().getY() == y) { + result[0] = true; + return false; + } + return true; + }); + } + return result[0]; + } + + public Pet getPet(int petId) { + return this.currentPets.get(petId); + } + + public Pet getPet(RoomUnit roomUnit) { + return currentPets.valueCollection().stream().filter(p -> p.getRoomUnit() == roomUnit).findFirst().orElse(null); + } + + public boolean removeBot(Bot bot) { + synchronized (this.currentBots) { + if (this.currentBots.containsKey(bot.getId())) { + if (bot.getRoomUnit() != null && bot.getRoomUnit().getCurrentLocation() != null) { + bot.getRoomUnit().getCurrentLocation().removeUnit(bot.getRoomUnit()); + } + + this.currentBots.remove(bot.getId()); + bot.getRoomUnit().setInRoom(false); + bot.setRoom(null); + this.sendComposer(new RoomUserRemoveComposer(bot.getRoomUnit()).compose()); + bot.setRoomUnit(null); + return true; + } + } + + return false; + } + + public void placePet(Pet pet, short x, short y, double z, int rot) { + synchronized (this.currentPets) { + RoomTile tile = this.layout.getTile(x, y); + + if (tile == null) { + tile = this.layout.getDoorTile(); + } + + pet.setRoomUnit(new RoomUnit()); + pet.setRoom(this); + pet.getRoomUnit().setGoalLocation(tile); + pet.getRoomUnit().setLocation(tile); + pet.getRoomUnit().setRoomUnitType(RoomUnitType.PET); + pet.getRoomUnit().setCanWalk(true); + pet.getRoomUnit().setPathFinderRoom(this); + pet.getRoomUnit().setPreviousLocationZ(z); + pet.getRoomUnit().setZ(z); + if (pet.getRoomUnit().getCurrentLocation() == null) { + pet.getRoomUnit().setLocation(this.getLayout().getDoorTile()); + pet.getRoomUnit().setRotation(RoomUserRotation.fromValue(this.getLayout().getDoorDirection())); + } + + pet.needsUpdate = true; + this.furniOwnerNames.put(pet.getUserId(), this.getHabbo(pet.getUserId()).getHabboInfo().getUsername()); + this.addPet(pet); + this.sendComposer(new RoomPetComposer(pet).compose()); + } + } + + public Pet removePet(int petId) { + return this.currentPets.remove(petId); + } + + public boolean hasHabbosAt(int x, int y) { + return getHabbos().stream().anyMatch(h -> h.getRoomUnit().getX() == x && h.getRoomUnit().getY() == y); + } + + public boolean hasPetsAt(int x, int y) { + synchronized (this.currentPets) { + TIntObjectIterator petIterator = this.currentPets.iterator(); + + for (int i = this.currentPets.size(); i-- > 0; ) { + try { + petIterator.advance(); + } catch (NoSuchElementException e) { + log.error("Caught exception", e); + break; + } + + if (petIterator.value().getRoomUnit().getX() == x && petIterator.value().getRoomUnit().getY() == y) + return true; + } + } + + return false; + } + + public List getBotsAt(RoomTile tile) { + synchronized (this.currentBots) { + return currentBots.valueCollection().stream().filter(b -> b.getRoomUnit().getCurrentLocation().equals(tile)).toList(); + } + } + + public List getHabbosAt(short x, short y) { + if(this.layout == null) { + return new ArrayList<>(); + } + return this.getHabbosAt(this.layout.getTile(x, y)); + } + + public List getHabbosAt(RoomTile tile) { + if(this.layout == null) { + return new ArrayList<>(); + } + return getHabbos().stream().filter(h -> h.getRoomUnit().getCurrentLocation().equals(tile)).toList(); + } + + public THashSet getHabbosAndBotsAt(short x, short y) { + return this.getHabbosAndBotsAt(this.layout.getTile(x, y)); + } + + public THashSet getHabbosAndBotsAt(RoomTile tile) { + THashSet list = new THashSet<>(); + + list.addAll(getBotsAt(tile).stream().map(Bot::getRoomUnit).toList()); + list.addAll(getHabbosAt(tile).stream().map(Habbo::getRoomUnit).toList()); + + return list; + } + + public THashSet getHabbosOnItem(HabboItem item) { + THashSet habbos = new THashSet<>(); + for (short x = item.getX(); x < item.getX() + item.getBaseItem().getLength(); x++) { + for (short y = item.getY(); y < item.getY() + item.getBaseItem().getWidth(); y++) { + habbos.addAll(this.getHabbosAt(x, y)); + } + } + + return habbos; + } + + public THashSet getBotsOnItem(HabboItem item) { + THashSet bots = new THashSet<>(); + for (short x = item.getX(); x < item.getX() + item.getBaseItem().getLength(); x++) { + for (short y = item.getY(); y < item.getY() + item.getBaseItem().getWidth(); y++) { + bots.addAll(this.getBotsAt(this.getLayout().getTile(x, y))); + } + } + + return bots; + } + + public void teleportHabboToItem(Habbo habbo, HabboItem item) { + this.teleportRoomUnitToLocation(habbo.getRoomUnit(), item.getX(), item.getY(), item.getZ() + Item.getCurrentHeight(item)); + } + + public void teleportHabboToLocation(Habbo habbo, short x, short y) { + this.teleportRoomUnitToLocation(habbo.getRoomUnit(), x, y, 0.0); + } + + public void teleportRoomUnitToItem(RoomUnit roomUnit, HabboItem item) { + this.teleportRoomUnitToLocation(roomUnit, item.getX(), item.getY(), item.getZ() + Item.getCurrentHeight(item)); + } + + public void teleportRoomUnitToLocation(RoomUnit roomUnit, short x, short y) { + this.teleportRoomUnitToLocation(roomUnit, x, y, 0.0); + } + + public void teleportRoomUnitToLocation(RoomUnit roomUnit, short x, short y, double z) { + if (this.loaded) { + RoomTile tile = this.layout.getTile(x, y); + + if (z < tile.z) { + z = tile.z; + } + + roomUnit.setLocation(tile); + roomUnit.setGoalLocation(tile); + roomUnit.setZ(z); + roomUnit.setPreviousLocationZ(z); + this.updateRoomUnit(roomUnit); + + + } + } + + public void muteHabbo(Habbo habbo, int minutes) { + synchronized (this.mutedHabbos) { + this.mutedHabbos.put(habbo.getHabboInfo().getId(), Emulator.getIntUnixTimestamp() + (minutes * 60)); + } + } + + public boolean isMuted(Habbo habbo) { + if (this.isOwner(habbo) || this.hasRights(habbo)) + return false; + + if (this.mutedHabbos.containsKey(habbo.getHabboInfo().getId())) { + boolean time = this.mutedHabbos.get(habbo.getHabboInfo().getId()) > Emulator.getIntUnixTimestamp(); + + if (!time) { + this.mutedHabbos.remove(habbo.getHabboInfo().getId()); + } + + return time; + } + + return false; + } + + public void habboEntered(Habbo habbo) { + habbo.getRoomUnit().animateWalk = false; + + synchronized (this.currentBots) { + if (habbo.getHabboInfo().getId() != this.getOwnerId()) + return; + + TIntObjectIterator botIterator = this.currentBots.iterator(); + + for (int i = this.currentBots.size(); i-- > 0; ) { + try { + botIterator.advance(); + + if (botIterator.value() instanceof VisitorBot) { + ((VisitorBot) botIterator.value()).onUserEnter(habbo); + break; + } + } catch (Exception e) { + break; + } + } + } + + HabboItem doorTileTopItem = this.getTopItemAt(habbo.getRoomUnit().getX(), habbo.getRoomUnit().getY()); + if (doorTileTopItem != null && !(doorTileTopItem instanceof InteractionTeleportTile)) { + try { + doorTileTopItem.onWalkOn(habbo.getRoomUnit(), this, new Object[]{}); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + } + + public void floodMuteHabbo(Habbo habbo, int timeOut) { + habbo.getHabboStats().mutedCount++; + timeOut += (timeOut * (int) Math.ceil(Math.pow(habbo.getHabboStats().mutedCount, 2))); + habbo.getHabboStats().chatCounter.set(0); + habbo.mute(timeOut, true); + } + + public void talk(Habbo habbo, RoomChatMessage roomChatMessage, RoomChatType chatType) { + this.talk(habbo, roomChatMessage, chatType, false); + } + + public void talk(final Habbo habbo, final RoomChatMessage roomChatMessage, RoomChatType chatType, boolean ignoreWired) { + if (!habbo.getHabboStats().allowTalk()) + return; + + if (habbo.getHabboInfo().getCurrentRoom() != this) + return; + + long millis = System.currentTimeMillis(); + + if (HABBO_CHAT_DELAY && millis - habbo.getHabboStats().lastChat < 750) { + return; + + } + + habbo.getHabboStats().lastChat = millis; + if (roomChatMessage != null && Emulator.getConfig().getBoolean("easter_eggs.enabled") && roomChatMessage.getMessage().equalsIgnoreCase("i am a pirate")) { + habbo.getHabboStats().chatCounter.addAndGet(1); + Emulator.getThreading().run(new YouAreAPirate(habbo, this)); + return; + } + + UserIdleEvent event = new UserIdleEvent(habbo, UserIdleEvent.IdleReason.TALKED, false); + Emulator.getPluginManager().fireEvent(event); + + if (!event.isCancelled() && !event.idle) { + this.unIdle(habbo); + } + + this.sendComposer(new RoomUserTypingComposer(habbo.getRoomUnit(), false).compose()); + + if (roomChatMessage == null || roomChatMessage.getMessage() == null || roomChatMessage.getMessage().equals("")) + 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; + } + } + } + + if (!this.wordFilterWords.isEmpty() && !habbo.hasPermission(Permission.ACC_CHAT_NO_FILTER)) { + for (String string : this.wordFilterWords) { + roomChatMessage.setMessage(roomChatMessage.getMessage().replaceAll("(?i)" + Pattern.quote(string), "bobba")); + } + } + + if (!habbo.hasPermission(Permission.ACC_NOMUTE)) { + if (this.isMuted() && !this.hasRights(habbo)) { + return; + } + + if (this.isMuted(habbo)) { + habbo.getClient().sendResponse(new MutedWhisperComposer(this.mutedHabbos.get(habbo.getHabboInfo().getId()) - Emulator.getIntUnixTimestamp())); + return; + } + } + + if (!habbo.hasPermission(Permission.ACC_CHAT_NO_FLOOD)) { + final int chatCounter = habbo.getHabboStats().chatCounter.addAndGet(1); + + if (chatCounter > 3) { + final boolean floodRights = Emulator.getConfig().getBoolean("flood.with.rights"); + final boolean hasRights = this.hasRights(habbo); + + if (floodRights || !hasRights) { + this.floodMuteHabbo(habbo, muteTime); + return; + + /*if (this.chatProtection == 0) { + this.floodMuteHabbo(habbo, muteTime); + return; + } else if (this.chatProtection == 1 && chatCounter > 4) { + this.floodMuteHabbo(habbo, muteTime); + return; + } else if (this.chatProtection == 2 && chatCounter > 5) { + this.floodMuteHabbo(habbo, muteTime); + return; + }*/ + } + } + } + + if (chatType != RoomChatType.WHISPER) { + if (CommandHandler.handleCommand(habbo.getClient(), roomChatMessage.getUnfilteredMessage())) { + WiredHandler.handle(WiredTriggerType.SAY_COMMAND, habbo.getRoomUnit(), habbo.getHabboInfo().getCurrentRoom(), new Object[]{roomChatMessage.getMessage()}); + roomChatMessage.isCommand = true; + return; + } + + if (!ignoreWired) { + if (WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, habbo.getRoomUnit(), habbo.getHabboInfo().getCurrentRoom(), new Object[]{roomChatMessage.getMessage()})) { + habbo.getClient().sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(roomChatMessage.getMessage(), habbo, habbo, roomChatMessage.getBubble()))); + return; + } + } + } + + ServerMessage prefixMessage = null; + + if (Emulator.getPluginManager().isRegistered(UsernameTalkEvent.class, true)) { + UsernameTalkEvent usernameTalkEvent = Emulator.getPluginManager().fireEvent(new UsernameTalkEvent(habbo, roomChatMessage, chatType)); + if (usernameTalkEvent.hasCustomComposer()) { + prefixMessage = usernameTalkEvent.getCustomComposer(); + } + } + + if(prefixMessage == null) { + prefixMessage = roomChatMessage.getHabbo().getHabboInfo().getRank().hasPrefix() ? new RoomUserNameChangedComposer(habbo, true).compose() : null; + } + ServerMessage clearPrefixMessage = prefixMessage != null ? new RoomUserNameChangedComposer(habbo).compose() : null; + + Rectangle tentRectangle = this.roomSpecialTypes.tentAt(habbo.getRoomUnit().getCurrentLocation()); + + String trimmedMessage = roomChatMessage.getMessage().replaceAll("\\s+$",""); + + if (trimmedMessage.isEmpty()) trimmedMessage = " "; + + roomChatMessage.setMessage(trimmedMessage); + + if (chatType == RoomChatType.WHISPER) { + if (roomChatMessage.getTargetHabbo() == null) { + return; + } + + RoomChatMessage staffChatMessage = new RoomChatMessage(roomChatMessage); + staffChatMessage.setMessage("To " + staffChatMessage.getTargetHabbo().getHabboInfo().getUsername() + ": " + staffChatMessage.getMessage()); + + final ServerMessage message = new RoomUserWhisperComposer(roomChatMessage).compose(); + final ServerMessage staffMessage = new RoomUserWhisperComposer(staffChatMessage).compose(); + + for (Habbo h : this.getHabbos()) { + if (h == roomChatMessage.getTargetHabbo() || h == habbo) { + if (!h.getHabboStats().userIgnored(habbo.getHabboInfo().getId())) { + if (prefixMessage != null) { + h.getClient().sendResponse(prefixMessage); + } + h.getClient().sendResponse(message); + + if (clearPrefixMessage != null) { + h.getClient().sendResponse(clearPrefixMessage); + } + } + + continue; + } + if (h.hasPermission(Permission.ACC_SEE_WHISPERS)) { + h.getClient().sendResponse(staffMessage); + } + } + } else if (chatType == RoomChatType.TALK) { + ServerMessage message = new RoomUserTalkComposer(roomChatMessage).compose(); + boolean noChatLimit = habbo.hasPermission(Permission.ACC_CHAT_NO_LIMIT); + + for (Habbo h : this.getHabbos()) { + if ((h.getRoomUnit().getCurrentLocation().distance(habbo.getRoomUnit().getCurrentLocation()) <= this.chatDistance || + h.equals(habbo) || + this.hasRights(h) || + noChatLimit) && (tentRectangle == null || RoomLayout.tileInSquare(tentRectangle, h.getRoomUnit().getCurrentLocation()))) { + if (!h.getHabboStats().userIgnored(habbo.getHabboInfo().getId())) { + if (prefixMessage != null && !h.getHabboStats().preferOldChat) { + h.getClient().sendResponse(prefixMessage); + } + h.getClient().sendResponse(message); + if (clearPrefixMessage != null && !h.getHabboStats().preferOldChat) { + h.getClient().sendResponse(clearPrefixMessage); + } + } + continue; + } + // Staff should be able to see the tent chat anyhow + showTentChatMessageOutsideTentIfPermitted(h, roomChatMessage, tentRectangle); + } + } else if (chatType == RoomChatType.SHOUT) { + ServerMessage message = new RoomUserShoutComposer(roomChatMessage).compose(); + + for (Habbo h : this.getHabbos()) { + // Show the message + // If the receiving Habbo has not ignored the sending Habbo + // AND the sending Habbo is NOT in a tent OR the receiving Habbo is in the same tent as the sending Habbo + if (!h.getHabboStats().userIgnored(habbo.getHabboInfo().getId()) && (tentRectangle == null || RoomLayout.tileInSquare(tentRectangle, h.getRoomUnit().getCurrentLocation()))) { + if (prefixMessage != null && !h.getHabboStats().preferOldChat) { + h.getClient().sendResponse(prefixMessage); + } + h.getClient().sendResponse(message); + if (clearPrefixMessage != null && !h.getHabboStats().preferOldChat) { + h.getClient().sendResponse(clearPrefixMessage); + } + continue; + } + // Staff should be able to see the tent chat anyhow, even when not in the same tent + showTentChatMessageOutsideTentIfPermitted(h, roomChatMessage, tentRectangle); + } + } + + if (chatType == RoomChatType.TALK || chatType == RoomChatType.SHOUT) { + synchronized (this.currentBots) { + TIntObjectIterator botIterator = this.currentBots.iterator(); + + for (int i = this.currentBots.size(); i-- > 0; ) { + try { + botIterator.advance(); + Bot bot = botIterator.value(); + bot.onUserSay(roomChatMessage); + + } catch (NoSuchElementException e) { + log.error("Caught exception", e); + break; + } + } + } + + if (roomChatMessage.getBubble().triggersTalkingFurniture()) { + THashSet items = this.roomSpecialTypes.getItemsOfType(InteractionTalkingFurniture.class); + + for (HabboItem item : items) { + if (this.layout.getTile(item.getX(), item.getY()).distance(habbo.getRoomUnit().getCurrentLocation()) <= Emulator.getConfig().getInt("furniture.talking.range")) { + int count = Emulator.getConfig().getInt(item.getBaseItem().getName() + ".message.count", 0); + + if (count > 0) { + int randomValue = Emulator.getRandom().nextInt(count + 1); + + RoomChatMessage itemMessage = new RoomChatMessage(Emulator.getTexts().getValue(item.getBaseItem().getName() + ".message." + randomValue, item.getBaseItem().getName() + ".message." + randomValue + " not found!"), habbo, RoomChatMessageBubbles.getBubble(Emulator.getConfig().getInt(item.getBaseItem().getName() + ".message.bubble", RoomChatMessageBubbles.PARROT.getType()))); + + this.sendComposer(new RoomUserTalkComposer(itemMessage).compose()); + + try { + item.onClick(habbo.getClient(), this, new Object[0]); + item.setExtradata("1"); + updateItemState(item); + + Emulator.getThreading().run(() -> { + item.setExtradata("0"); + updateItemState(item); + }, 2000); + + break; + } catch (Exception e) { + log.error("Caught exception", e); + } + } + } + } + } + } + } + + /** + * Sends the given message to the receiving Habbo if the Habbo has the ACC_SEE_TENTCHAT permission and is not within the tent + * @param receivingHabbo The receiving Habbo + * @param roomChatMessage The message to receive + * @param tentRectangle The whole tent area from where the sending Habbo is saying something + */ + private void showTentChatMessageOutsideTentIfPermitted(Habbo receivingHabbo, RoomChatMessage roomChatMessage, Rectangle tentRectangle) { + if (receivingHabbo != null && receivingHabbo.hasPermission(Permission.ACC_SEE_TENTCHAT) && tentRectangle != null && !RoomLayout.tileInSquare(tentRectangle, receivingHabbo.getRoomUnit().getCurrentLocation())) { + RoomChatMessage staffChatMessage = new RoomChatMessage(roomChatMessage); + staffChatMessage.setMessage("[" + Emulator.getTexts().getValue("hotel.room.tent.prefix") + "] " + staffChatMessage.getMessage()); + final ServerMessage staffMessage = new RoomUserWhisperComposer(staffChatMessage).compose(); + receivingHabbo.getClient().sendResponse(staffMessage); + } + } + + public THashSet getLockedTiles() { + THashSet lockedTiles = new THashSet<>(); + + TIntObjectIterator iterator = this.roomItems.iterator(); + + for (int i = this.roomItems.size(); i-- > 0; ) { + HabboItem item; + try { + iterator.advance(); + item = iterator.value(); + } catch (Exception e) { + break; + } + + if (item.getBaseItem().getType() != FurnitureType.FLOOR) + continue; + + boolean found = lockedTiles.stream().anyMatch(tile -> tile.x == item.getX() && tile.y == item.getY()); + + if (!found) { + if (item.getRotation() == 0 || item.getRotation() == 4) { + for (short y = 0; y < item.getBaseItem().getLength(); y++) { + for (short x = 0; x < item.getBaseItem().getWidth(); x++) { + RoomTile tile = this.layout.getTile((short) (item.getX() + x), (short) (item.getY() + y)); + + if (tile != null) { + lockedTiles.add(tile); + } + } + } + } else { + for (short y = 0; y < item.getBaseItem().getWidth(); y++) { + for (short x = 0; x < item.getBaseItem().getLength(); x++) { + RoomTile tile = this.layout.getTile((short) (item.getX() + x), (short) (item.getY() + y)); + + if (tile != null) { + lockedTiles.add(tile); + } + } + } + } + } + } + + return lockedTiles; + } + + @Deprecated + public THashSet getItemsAt(int x, int y) { + if (this.getLayout() == null) { + return null; + } + RoomTile tile = this.getLayout().getTile((short) x, (short) y); + + if (tile != null) { + return this.getItemsAt(tile); + } + + return new THashSet<>(0); + } + + public THashSet getItemsAt(RoomTile tile) { + return getItemsAt(tile, false); + } + + public THashSet getItemsAt(RoomTile tile, boolean returnOnFirst) { + THashSet items = new THashSet<>(0); + + if (tile == null) + return items; + + if (this.loaded) { + THashSet cachedItems = this.tileCache.get(tile); + if(cachedItems != null) + return cachedItems; + } + + TIntObjectIterator iterator = this.roomItems.iterator(); + + for (int i = this.roomItems.size(); i-- > 0; ) { + HabboItem item; + try { + iterator.advance(); + item = iterator.value(); + } catch (Exception e) { + break; + } + + if (item == null) + continue; + + if (item.getBaseItem().getType() != FurnitureType.FLOOR) + continue; + + int width, length; + + if (item.getRotation() != 2 && item.getRotation() != 6) { + width = item.getBaseItem().getWidth() > 0 ? item.getBaseItem().getWidth() : 1; + length = item.getBaseItem().getLength() > 0 ? item.getBaseItem().getLength() : 1; + } + else { + width = item.getBaseItem().getLength() > 0 ? item.getBaseItem().getLength() : 1; + length = item.getBaseItem().getWidth() > 0 ? item.getBaseItem().getWidth() : 1; + } + + if (!(tile.x >= item.getX() && tile.x <= item.getX() + width - 1 && tile.y >= item.getY() && tile.y <= item.getY() + length - 1)) + continue; + + items.add(item); + + if(returnOnFirst) { + return items; + } + } + + if (this.loaded) { + this.tileCache.put(tile, items); + } + + return items; + } + + public THashSet getItemsAt(int x, int y, double minZ) { + THashSet items = new THashSet<>(); + + for (HabboItem item : this.getItemsAt(x, y)) { + if (item.getZ() < minZ) + continue; + + items.add(item); + } + return items; + } + + public THashSet getItemsAt(Class type, int x, int y) { + THashSet items = new THashSet<>(); + + for (HabboItem item : this.getItemsAt(x, y)) { + if (!item.getClass().equals(type)) + continue; + + items.add(item); + } + return items; + } + + public boolean hasItemsAt(int x, int y) { + RoomTile tile = this.getLayout().getTile((short) x, (short) y); + + if(tile == null) + return false; + + return this.getItemsAt(tile, true).size() > 0; + } + + public HabboItem getTopItemAt(int x, int y) { + return this.getTopItemAt(x, y, null); + } + + public HabboItem getTopItemAt(int x, int y, HabboItem exclude) { + RoomTile tile = this.getLayout().getTile((short) x, (short) y); + + if(tile == null) + return null; + + HabboItem highestItem = null; + + for (HabboItem item : this.getItemsAt(x, y)) { + if(exclude != null && exclude == item) + continue; + + if (highestItem != null && highestItem.getZ() + Item.getCurrentHeight(highestItem) > item.getZ() + Item.getCurrentHeight(item)) + continue; + + highestItem = item; + } + + return highestItem; + } + + public HabboItem getTopItemAt(THashSet tiles, HabboItem exclude) { + HabboItem highestItem = null; + for(RoomTile tile : tiles) { + + if (tile == null) + continue; + + for (HabboItem item : this.getItemsAt(tile.x, tile.y)) { + if (exclude != null && exclude == item) + continue; + + if (highestItem != null && highestItem.getZ() + Item.getCurrentHeight(highestItem) > item.getZ() + Item.getCurrentHeight(item)) + continue; + + highestItem = item; + } + } + + return highestItem; + } + + public double getTopHeightAt(int x, int y) { + HabboItem item = this.getTopItemAt(x, y); + + if (item != null) { + return (item.getZ() + Item.getCurrentHeight(item) - (item.getBaseItem().allowSit() ? 1 : 0)); + } else { + return this.layout.getHeightAtSquare(x, y); + } + } + + public HabboItem getLowestChair(RoomTile tile) { + HabboItem lowestChair = null; + + THashSet items = this.getItemsAt(tile); + if (items != null && !items.isEmpty()) { + for (HabboItem item : items) { + + if(!item.getBaseItem().allowSit()) + continue; + + if(lowestChair != null && lowestChair.getZ() < item.getZ()) + continue; + + lowestChair = item; + } + } + + return lowestChair; + } + + public HabboItem getTallestChair(RoomTile tile) { + HabboItem lowestChair = null; + + THashSet items = this.getItemsAt(tile); + if (items != null && !items.isEmpty()) { + for (HabboItem item : items) { + + if(!item.getBaseItem().allowSit()) + continue; + + if(lowestChair != null && lowestChair.getZ() + Item.getCurrentHeight(lowestChair) > item.getZ() + Item.getCurrentHeight(item)) + continue; + + lowestChair = item; + } + } + + return lowestChair; + } + + public double getStackHeight(short x, short y, boolean calculateHeightmap, HabboItem exclude) { + + if (x < 0 || y < 0 || this.layout == null) + return calculateHeightmap ? Short.MAX_VALUE : 0.0; + + if (Emulator.getPluginManager().isRegistered(FurnitureStackHeightEvent.class, true)) { + FurnitureStackHeightEvent event = Emulator.getPluginManager().fireEvent(new FurnitureStackHeightEvent(x, y, this)); + if(event.hasPluginHelper()) { + return calculateHeightmap ? event.getHeight() * 256.0D : event.getHeight(); + } + } + + double height = this.layout.getHeightAtSquare(x, y); + boolean canStack = true; + + THashSet stackHelpers = this.getItemsAt(InteractionStackHelper.class, x, y); + + if(stackHelpers.size() > 0) { + for(HabboItem item : stackHelpers) { + if (item == exclude) continue; + return calculateHeightmap ? item.getZ() * 256.0D : item.getZ(); + } + } + + HabboItem item = this.getTopItemAt(x, y, exclude); + if (item != null) { + canStack = item.getBaseItem().allowStack(); + height = item.getZ() + (item.getBaseItem().allowSit() ? 0 : Item.getCurrentHeight(item)); + } + + if (calculateHeightmap) { + return (canStack ? height * 256.0D : Short.MAX_VALUE); + } + + return canStack ? height : -1; + } + + public double getStackHeight(short x, short y, boolean calculateHeightmap) { + return this.getStackHeight(x, y, calculateHeightmap, null); + } + + public boolean hasObjectTypeAt(Class type, int x, int y) { + THashSet items = this.getItemsAt(x, y); + + for (HabboItem item : items) { + if (item.getClass() == type) { + return true; + } + } + + return false; + } + + public boolean canSitOrLayAt(int x, int y) { + if (this.hasHabbosAt(x, y)) + return false; + + THashSet items = this.getItemsAt(x, y); + + return this.canSitAt(items) || this.canLayAt(items); + } + + public boolean canSitAt(int x, int y) { + if (this.hasHabbosAt(x, y)) + return false; + + return this.canSitAt(this.getItemsAt(x, y)); + } + + boolean canWalkAt(RoomTile roomTile) { + if (roomTile == null) { + return false; + } + + if (roomTile.state == RoomTileState.INVALID) + return false; + + HabboItem topItem = null; + boolean canWalk = true; + THashSet items = this.getItemsAt(roomTile); + if (items != null) { + for (HabboItem item : items) { + if (topItem == null) { + topItem = item; + } + + if (item.getZ() > topItem.getZ()) { + topItem = item; + canWalk = topItem.isWalkable() || topItem.getBaseItem().allowWalk(); + } else if (item.getZ() == topItem.getZ() && canWalk) { + if ((!topItem.isWalkable() && !topItem.getBaseItem().allowWalk()) || (!item.getBaseItem().allowWalk() && !item.isWalkable())) { + canWalk = false; + } + } + } + } + + return canWalk; + } + + boolean canSitAt(THashSet items) { + if (items == null) + return false; + + HabboItem tallestItem = null; + + for (HabboItem item : items) { + if(tallestItem != null && tallestItem.getZ() + Item.getCurrentHeight(tallestItem) > item.getZ() + Item.getCurrentHeight(item)) + continue; + + tallestItem = item; + } + + if (tallestItem == null) + return false; + + return tallestItem.getBaseItem().allowSit(); + } + + public boolean canLayAt(int x, int y) { + return this.canLayAt(this.getItemsAt(x, y)); + } + + boolean canLayAt(THashSet items) { + if (items == null || items.isEmpty()) + return true; + + HabboItem topItem = null; + + for (HabboItem item : items) { + if ((topItem == null || item.getZ() > topItem.getZ())) { + topItem = item; + } + } + + return (topItem == null || topItem.getBaseItem().allowLay()); + } + + public RoomTile getRandomWalkableTile() { + for (int i = 0; i < 10; i++) { + RoomTile tile = this.layout.getTile((short) (Math.random() * this.layout.getMapSizeX()), (short) (Math.random() * this.layout.getMapSizeY())); + if (tile != null && tile.getState() != RoomTileState.BLOCKED && tile.getState() != RoomTileState.INVALID) { + return tile; + } + } + + return null; + } + + public Habbo getHabbo(String username) { + for (Habbo habbo : this.getHabbos()) { + if (habbo.getHabboInfo().getUsername().equalsIgnoreCase(username) && !habbo.getHabboInfo().isInvisibleInRooms()) + return habbo; + } + return null; + } + + public Habbo getHabbo(RoomUnit roomUnit) { + for (Habbo habbo : this.getHabbos()) { + if (habbo.getRoomUnit() == roomUnit) + return habbo; + } + return null; + } + + public HorsePet getHabboHorse(final RoomUnit roomUnit) { + final AtomicReference result = new AtomicReference<>(); + + this.currentPets.forEachEntry((i, pet) -> { + if (!(pet instanceof HorsePet)) { + return true; + } + + final HorsePet horsePet = (HorsePet) pet; + + if (horsePet.getRider() == null || horsePet.getRider().getRoomUnit() != roomUnit) { + return true; + } + + result.set((HorsePet) pet); + return false; + }); + + return result.get(); + } + + public Habbo getHabbo(int userId) { + return this.currentHabbos.get(userId); + } + + public Habbo getHabboByRoomUnitId(int roomUnitId) { + for (Habbo habbo : this.getHabbos()) { + if (habbo.getRoomUnit().getId() == roomUnitId) + return habbo; + } + + return null; + } + + public void sendComposer(ServerMessage message) { + for (Habbo habbo : this.getHabbos()) { + if (habbo.getClient() == null) continue; + + habbo.getClient().sendResponse(message); + } + } + + public void sendComposerToHabbosWithRights(ServerMessage message) { + for (Habbo habbo : this.getHabbos()) { + if (this.hasRights(habbo)) { + habbo.getClient().sendResponse(message); + } + } + } + + public void petChat(ServerMessage message) { + for (Habbo habbo : this.getHabbos()) { + if (!habbo.getHabboStats().ignorePets) + habbo.getClient().sendResponse(message); + } + } + + public void botChat(ServerMessage message) { + if (message == null) { + return; + } + + for (Habbo habbo : this.getHabbos()) { + if (!habbo.getHabboStats().ignoreBots) + habbo.getClient().sendResponse(message); + } + } + + private void loadRights(Connection connection) { + this.rights.clear(); + try (PreparedStatement statement = connection.prepareStatement("SELECT user_id FROM room_rights WHERE room_id = ?")) { + statement.setInt(1, this.id); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + this.rights.add(set.getInt("user_id")); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + private void loadBans(Connection connection) { + this.bannedHabbos.clear(); + + try (PreparedStatement statement = connection.prepareStatement("SELECT users.username, users.id, room_bans.* FROM room_bans INNER JOIN users ON room_bans.user_id = users.id WHERE ends > ? AND room_bans.room_id = ?")) { + statement.setInt(1, Emulator.getIntUnixTimestamp()); + statement.setInt(2, this.id); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + if (this.bannedHabbos.containsKey(set.getInt("user_id"))) + continue; + + this.bannedHabbos.put(set.getInt("user_id"), new RoomBan(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public RoomRightLevels getGuildRightLevel(Habbo habbo) { + if (this.guildId > 0 && habbo.getHabboStats().hasGuild(this.guildId)) { + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(this.guildId); + + if (Emulator.getGameEnvironment().getGuildManager().getOnlyAdmins(guild).get(habbo.getHabboInfo().getId()) != null) + return RoomRightLevels.GUILD_ADMIN; + + if (guild.getRights()) { + return RoomRightLevels.GUILD_RIGHTS; + } + } + + return RoomRightLevels.NONE; + } + + /** + * @deprecated Deprecated since 2.5.0. Use {@link #getGuildRightLevel(Habbo)} instead. + */ + @Deprecated + public int guildRightLevel(Habbo habbo) { + return this.getGuildRightLevel(habbo).level; + } + + public boolean isOwner(Habbo habbo) { + return habbo.getHabboInfo().getId() == this.ownerId || habbo.hasPermission(Permission.ACC_ANYROOMOWNER); + } + + public boolean hasRights(Habbo habbo) { + return this.isOwner(habbo) || this.rights.contains(habbo.getHabboInfo().getId()) || (habbo.getRoomUnit().getRightsLevel() != RoomRightLevels.NONE && this.currentHabbos.containsKey(habbo.getHabboInfo().getId())); + } + + public void giveRights(Habbo habbo) { + if (habbo != null) { + this.giveRights(habbo.getHabboInfo().getId()); + } + } + + public void giveRights(int userId) { + if (this.rights.contains(userId)) + return; + + if (this.rights.add(userId)) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO room_rights VALUES (?, ?)")) { + statement.setInt(1, this.id); + statement.setInt(2, userId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + Habbo habbo = this.getHabbo(userId); + + if (habbo != null) { + this.refreshRightsForHabbo(habbo); + + this.sendComposer(new RoomAddRightsListComposer(this, habbo.getHabboInfo().getId(), habbo.getHabboInfo().getUsername()).compose()); + } else { + Habbo owner = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.ownerId); + + if (owner != null) { + MessengerBuddy buddy = owner.getMessenger().getFriend(userId); + + if (buddy != null) { + this.sendComposer(new RoomAddRightsListComposer(this, userId, buddy.getUsername()).compose()); + } + } + } + } + + public void removeRights(int userId) { + Habbo habbo = this.getHabbo(userId); + + if (Emulator.getPluginManager().fireEvent(new UserRightsTakenEvent(this.getHabbo(this.getOwnerId()), userId, habbo)).isCancelled()) + return; + + this.sendComposer(new RoomRemoveRightsListComposer(this, userId).compose()); + + if (this.rights.remove(userId)) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM room_rights WHERE room_id = ? AND user_id = ?")) { + statement.setInt(1, this.id); + statement.setInt(2, userId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + if (habbo != null) { + this.ejectUserFurni(habbo.getHabboInfo().getId()); + habbo.getRoomUnit().setRightsLevel(RoomRightLevels.NONE); + habbo.getRoomUnit().removeStatus(RoomUnitStatus.FLAT_CONTROL); + this.refreshRightsForHabbo(habbo); + } + } + + public void removeAllRights() { + for (int userId : rights.toArray()) { + this.ejectUserFurni(userId); + } + + this.rights.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM room_rights WHERE room_id = ?")) { + statement.setInt(1, this.id); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.refreshRightsInRoom(); + } + + void refreshRightsInRoom() { + Room room = this; + for (Habbo habbo : this.getHabbos()) { + if (habbo.getHabboInfo().getCurrentRoom() == room) { + this.refreshRightsForHabbo(habbo); + } + } + } + + public void refreshRightsForHabbo(Habbo habbo) { + HabboItem item; + RoomRightLevels flatCtrl = RoomRightLevels.NONE; + if (habbo.getHabboStats().isRentingSpace()) { + item = this.getHabboItem(habbo.getHabboStats().getRentedItemId()); + + if (item != null) { + return; + } + } + + if (habbo.hasPermission(Permission.ACC_ANYROOMOWNER)) { + habbo.getClient().sendResponse(new RoomOwnerComposer()); + flatCtrl = RoomRightLevels.MODERATOR; + } else if (this.isOwner(habbo)) { + habbo.getClient().sendResponse(new RoomOwnerComposer()); + flatCtrl = RoomRightLevels.MODERATOR; + } else if (this.hasRights(habbo) && !this.hasGuild()) { + flatCtrl = RoomRightLevels.RIGHTS; + } else if (this.hasGuild()) { + flatCtrl = this.getGuildRightLevel(habbo); + } + + habbo.getClient().sendResponse(new RoomRightsComposer(flatCtrl)); + habbo.getRoomUnit().setStatus(RoomUnitStatus.FLAT_CONTROL, flatCtrl.level + ""); + habbo.getRoomUnit().setRightsLevel(flatCtrl); + habbo.getRoomUnit().statusUpdate(true); + + if (flatCtrl.equals(RoomRightLevels.MODERATOR)) { + habbo.getClient().sendResponse(new RoomRightsListComposer(this)); + } + } + + public THashMap getUsersWithRights() { + THashMap rightsMap = new THashMap<>(); + + if (!this.rights.isEmpty()) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.username AS username, users.id as user_id FROM room_rights INNER JOIN users ON room_rights.user_id = users.id WHERE room_id = ?")) { + statement.setInt(1, this.id); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + rightsMap.put(set.getInt("user_id"), set.getString("username")); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + return rightsMap; + } + + public void unbanHabbo(int userId) { + RoomBan ban = this.bannedHabbos.remove(userId); + + if (ban != null) { + ban.delete(); + } + + this.sendComposer(new RoomUserUnbannedComposer(this, userId).compose()); + } + + public boolean isBanned(Habbo habbo) { + RoomBan ban = this.bannedHabbos.get(habbo.getHabboInfo().getId()); + + boolean banned = ban != null && ban.endTimestamp > Emulator.getIntUnixTimestamp() && !habbo.hasPermission(Permission.ACC_ANYROOMOWNER) && !habbo.hasPermission("acc_enteranyroom"); + + if (!banned && ban != null) { + this.unbanHabbo(habbo.getHabboInfo().getId()); + } + + return banned; + } + + public TIntObjectHashMap getBannedHabbos() { + return this.bannedHabbos; + } + + public void addRoomBan(RoomBan roomBan) { + this.bannedHabbos.put(roomBan.userId, roomBan); + } + + public void makeSit(Habbo habbo) { + if (habbo.getRoomUnit() == null) return; + + if (habbo.getRoomUnit().hasStatus(RoomUnitStatus.SIT) || !habbo.getRoomUnit().canForcePosture()) { + return; + } + + this.dance(habbo, DanceType.NONE); + habbo.getRoomUnit().cmdSit = true; + habbo.getRoomUnit().setBodyRotation(RoomUserRotation.values()[habbo.getRoomUnit().getBodyRotation().getValue() - habbo.getRoomUnit().getBodyRotation().getValue() % 2]); + habbo.getRoomUnit().setStatus(RoomUnitStatus.SIT, 0.5 + ""); + this.sendComposer(new RoomUserStatusComposer(habbo.getRoomUnit()).compose()); + } + + public void makeStand(Habbo habbo) { + if (habbo.getRoomUnit() == null) return; + + HabboItem item = this.getTopItemAt(habbo.getRoomUnit().getX(), habbo.getRoomUnit().getY()); + if (item == null || !item.getBaseItem().allowSit() || !item.getBaseItem().allowLay()) { + habbo.getRoomUnit().cmdStand = true; + habbo.getRoomUnit().setBodyRotation(RoomUserRotation.values()[habbo.getRoomUnit().getBodyRotation().getValue() - habbo.getRoomUnit().getBodyRotation().getValue() % 2]); + habbo.getRoomUnit().removeStatus(RoomUnitStatus.SIT); + this.sendComposer(new RoomUserStatusComposer(habbo.getRoomUnit()).compose()); + } + } + + public void giveEffect(Habbo habbo, int effectId, int duration) { + if (habbo != null && habbo.getRoomUnit() != null && this.currentHabbos.containsKey(habbo.getHabboInfo().getId())) { + this.giveEffect(habbo.getRoomUnit(), effectId, duration, false); + } + } + + public void giveEffect(RoomUnit roomUnit, int effectId, int duration) { + this.giveEffect(roomUnit, effectId, duration, false); + } + + public void giveEffect(RoomUnit roomUnit, int effectId, int duration, boolean ignoreChecks) { + if (roomUnit == null || roomUnit.getRoom() == null) return; + + Habbo habbo = roomUnit.getRoom().getHabbo(roomUnit); + + if (roomUnit.getRoomUnitType() == RoomUnitType.USER && (habbo == null || habbo.getHabboInfo().isInGame() && !ignoreChecks)) { return; } + if (duration == -1 || duration == Integer.MAX_VALUE) { + duration = Integer.MAX_VALUE; + } else { + duration += Emulator.getIntUnixTimestamp(); + } + + if (this.allowEffects && roomUnit != null) { + roomUnit.setEffectId(effectId, duration); + this.sendComposer(new RoomUserEffectComposer(roomUnit).compose()); + } + } + + public void giveHandItem(Habbo habbo, int handItem) { + this.giveHandItem(habbo.getRoomUnit(), handItem); + } + + public void giveHandItem(RoomUnit roomUnit, int handItem) { + roomUnit.setHandItem(handItem); + this.sendComposer(new RoomUserHandItemComposer(roomUnit).compose()); + } + + public void updateItem(HabboItem item) { + if (!this.isLoaded()) { + return; + } + if (item != null && item.getRoomId() == this.id && item.getBaseItem() != null) { + if (item.getBaseItem().getType() == FurnitureType.FLOOR) { + this.sendComposer(new FloorItemUpdateComposer(item).compose()); + this.updateTiles(this.getLayout().getTilesAt(this.layout.getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation())); + } else if (item.getBaseItem().getType() == FurnitureType.WALL) { + this.sendComposer(new WallItemUpdateComposer(item).compose()); + } + } + } + + public void updateItemState(HabboItem item) { + if (!item.isLimited()) { + this.sendComposer(new ItemStateComposer(item).compose()); + } else { + this.sendComposer(new FloorItemUpdateComposer(item).compose()); + } + + if (item.getBaseItem().getType() == FurnitureType.FLOOR) { + if (this.layout == null) return; + + this.updateTiles(this.getLayout().getTilesAt(this.layout.getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation())); + + if(item instanceof InteractionMultiHeight) { + ((InteractionMultiHeight)item).updateUnitsOnItem(this); + } + } + } + + public int getUserFurniCount(int userId) { + return this.furniOwnerCount.get(userId); + } + + public int getUserUniqueFurniCount(int userId) { + THashSet items = new THashSet<>(); + + for (HabboItem item : this.roomItems.valueCollection()) { + if (!items.contains(item.getBaseItem()) && item.getUserId() == userId) items.add(item.getBaseItem()); + } + + return items.size(); + } + + public void ejectUserFurni(int userId) { + THashSet items = new THashSet<>(); + + TIntObjectIterator iterator = this.roomItems.iterator(); + + for (int i = this.roomItems.size(); i-- > 0; ) { + try { + iterator.advance(); + } catch (Exception e) { + break; + } + + if (iterator.value().getUserId() == userId) { + items.add(iterator.value()); + iterator.value().setRoomId(0); + } + } + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + + if (habbo != null) { + habbo.getInventory().getItemsComponent().addItems(items); + habbo.getClient().sendResponse(new AddHabboItemComposer(items)); + } + + for (HabboItem i : items) { + this.pickUpItem(i, null); + } + } + + public void ejectUserItem(HabboItem item) { + this.pickUpItem(item, null); + } + + + public void ejectAll() { + this.ejectAll(null); + } + + + public void ejectAll(Habbo habbo) { + THashMap> userItemsMap = new THashMap<>(); + + synchronized (this.roomItems) { + TIntObjectIterator iterator = this.roomItems.iterator(); + + for (int i = this.roomItems.size(); i-- > 0; ) { + try { + iterator.advance(); + } catch (Exception e) { + break; + } + + if (habbo != null && iterator.value().getUserId() == habbo.getHabboInfo().getId()) + continue; + + if (iterator.value() instanceof InteractionPostIt) + continue; + + userItemsMap.computeIfAbsent(iterator.value().getUserId(), k -> new THashSet<>()).add(iterator.value()); + } + } + + for (Map.Entry> entrySet : userItemsMap.entrySet()) { + for (HabboItem i : entrySet.getValue()) { + this.pickUpItem(i, null); + } + + Habbo user = Emulator.getGameEnvironment().getHabboManager().getHabbo(entrySet.getKey()); + + if (user != null) { + user.getInventory().getItemsComponent().addItems(entrySet.getValue()); + user.getClient().sendResponse(new AddHabboItemComposer(entrySet.getValue())); + } + } + } + + public void refreshGuild(Guild guild) { + if (guild.getRoomId() == this.id) { + THashSet members = Emulator.getGameEnvironment().getGuildManager().getGuildMembers(guild.getId()); + + for (Habbo habbo : this.getHabbos()) { + Optional member = members.stream().filter(m -> m.getUserId() == habbo.getHabboInfo().getId()).findAny(); + + if (!member.isPresent()) continue; + + habbo.getClient().sendResponse(new GuildInfoComposer(guild, habbo.getClient(), false, member.get())); + } + } + + this.refreshGuildRightsInRoom(); + } + + public void refreshGuildColors(Guild guild) { + if (guild.getRoomId() == this.id) { + TIntObjectIterator iterator = this.roomItems.iterator(); + + for (int i = this.roomItems.size(); i-- > 0; ) { + try { + iterator.advance(); + } catch (Exception e) { + break; + } + + HabboItem habboItem = iterator.value(); + + if (habboItem instanceof InteractionGuildFurni) { + if (((InteractionGuildFurni) habboItem).getGuildId() == guild.getId()) + this.updateItem(habboItem); + } + } + } + } + + public void refreshGuildRightsInRoom() { + for (Habbo habbo : this.getHabbos()) { + if ((habbo.getHabboInfo().getCurrentRoom() == this && habbo.getHabboInfo().getId() != this.ownerId) + && (!(habbo.hasPermission(Permission.ACC_ANYROOMOWNER) || habbo.hasPermission(Permission.ACC_MOVEROTATE)))) + this.refreshRightsForHabbo(habbo); + } + } + + public void idle(Habbo habbo) { + habbo.getRoomUnit().setIdle(); + + if (habbo.getRoomUnit().getDanceType() != DanceType.NONE) { + this.dance(habbo, DanceType.NONE); + } + + this.sendComposer(new RoomUnitIdleComposer(habbo.getRoomUnit()).compose()); + WiredHandler.handle(WiredTriggerType.IDLES, habbo.getRoomUnit(), this, new Object[]{habbo}); + } + + public void unIdle(Habbo habbo) { + if (habbo == null || habbo.getRoomUnit() == null) return; + habbo.getRoomUnit().resetIdleTimer(); + this.sendComposer(new RoomUnitIdleComposer(habbo.getRoomUnit()).compose()); + WiredHandler.handle(WiredTriggerType.UNIDLES, habbo.getRoomUnit(), this, new Object[]{habbo}); + } + + public void dance(Habbo habbo, DanceType danceType) { + this.dance(habbo.getRoomUnit(), danceType); + } + + public void dance(RoomUnit unit, DanceType danceType) { + if(unit.getDanceType() != danceType) { + boolean isDancing = !unit.getDanceType().equals(DanceType.NONE); + unit.setDanceType(danceType); + this.sendComposer(new RoomUserDanceComposer(unit).compose()); + + if (danceType.equals(DanceType.NONE) && isDancing) { + WiredHandler.handle(WiredTriggerType.STOPS_DANCING, unit, this, new Object[]{unit}); + } else if (!danceType.equals(DanceType.NONE) && !isDancing) { + WiredHandler.handle(WiredTriggerType.STARTS_DANCING, unit, this, new Object[]{unit}); + } + } + } + + public void addToWordFilter(String word) { + synchronized (this.wordFilterWords) { + if (this.wordFilterWords.contains(word)) + return; + + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT IGNORE INTO room_wordfilter VALUES (?, ?)")) { + statement.setInt(1, this.getId()); + statement.setString(2, word); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + return; + } + + this.wordFilterWords.add(word); + } + } + + public void removeFromWordFilter(String word) { + synchronized (this.wordFilterWords) { + this.wordFilterWords.remove(word); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM room_wordfilter WHERE room_id = ? AND word = ?")) { + statement.setInt(1, this.getId()); + statement.setString(2, word); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public void handleWordQuiz(Habbo habbo, String answer) { + synchronized (this.userVotes) { + if (!this.wordQuiz.isEmpty() && !this.hasVotedInWordQuiz(habbo)) { + answer = answer.replace(":", ""); + + if (answer.equals("0")) { + this.noVotes++; + } else if (answer.equals("1")) { + this.yesVotes++; + } + + this.sendComposer(new SimplePollAnswerComposer(habbo.getHabboInfo().getId(), answer, this.noVotes, this.yesVotes).compose()); + this.userVotes.add(habbo.getHabboInfo().getId()); + } + } + } + + public void startWordQuiz(String question, int duration) { + if (!this.hasActiveWordQuiz()) { + this.wordQuiz = question; + this.noVotes = 0; + this.yesVotes = 0; + this.userVotes.clear(); + this.wordQuizEnd = Emulator.getIntUnixTimestamp() + (duration / 1000); + this.sendComposer(new SimplePollStartComposer(duration, question).compose()); + } + } + + public boolean hasActiveWordQuiz() { + return Emulator.getIntUnixTimestamp() < this.wordQuizEnd; + } + + public boolean hasVotedInWordQuiz(Habbo habbo) { + return this.userVotes.contains(habbo.getHabboInfo().getId()); + } + + public void alert(String message) { + this.sendComposer(new GenericAlertComposer(message).compose()); + } + + public int itemCount() { + return this.roomItems.size(); + } + + public void setJukeBoxActive(boolean jukeBoxActive) { + this.jukeboxActive = jukeBoxActive; + this.needsUpdate = true; + } + + public boolean isHideWired() { + return this.hideWired; + } + + public void setHideWired(boolean hideWired) { + this.hideWired = hideWired; + + if (this.hideWired) { + + for (HabboItem item : this.roomSpecialTypes.getTriggers()) { + this.sendComposer(new RemoveFloorItemComposer(item).compose()); + } + + for (HabboItem item : this.roomSpecialTypes.getEffects()) { + this.sendComposer(new RemoveFloorItemComposer(item).compose()); + } + + for (HabboItem item : this.roomSpecialTypes.getConditions()) { + this.sendComposer(new RemoveFloorItemComposer(item).compose()); + } + + for (HabboItem item : this.roomSpecialTypes.getExtras()) { + this.sendComposer(new RemoveFloorItemComposer(item).compose()); + } + } else { + this.sendComposer(new RoomFloorItemsComposer(this.furniOwnerNames, this.roomSpecialTypes.getTriggers()).compose()); + this.sendComposer(new RoomFloorItemsComposer(this.furniOwnerNames, this.roomSpecialTypes.getEffects()).compose()); + this.sendComposer(new RoomFloorItemsComposer(this.furniOwnerNames, this.roomSpecialTypes.getConditions()).compose()); + this.sendComposer(new RoomFloorItemsComposer(this.furniOwnerNames, this.roomSpecialTypes.getExtras()).compose()); + } + } + + public FurnitureMovementError canPlaceFurnitureAt(HabboItem item, Habbo habbo, RoomTile tile, int rotation) { + if (this.itemCount() >= Room.MAXIMUM_FURNI) { + return FurnitureMovementError.MAX_ITEMS; + } + + if (tile == null || tile.state == RoomTileState.INVALID) { + return FurnitureMovementError.INVALID_MOVE; + } + + rotation %= 8; + if (this.hasRights(habbo) || this.getGuildRightLevel(habbo).isEqualOrGreaterThan(RoomRightLevels.GUILD_RIGHTS) || habbo.hasPermission(Permission.ACC_MOVEROTATE)) { + return FurnitureMovementError.NONE; + } + + if (habbo.getHabboStats().isRentingSpace()) { + HabboItem rentSpace = this.getHabboItem(habbo.getHabboStats().rentedItemId); + + if (rentSpace != null) { + if (!RoomLayout.squareInSquare(RoomLayout.getRectangle(rentSpace.getX(), rentSpace.getY(), rentSpace.getBaseItem().getWidth(), rentSpace.getBaseItem().getLength(), rentSpace.getRotation()), RoomLayout.getRectangle(tile.x, tile.y, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), rotation))) { + return FurnitureMovementError.NO_RIGHTS; + } else { + return FurnitureMovementError.NONE; + } + } + } + + for (HabboItem area : this.getRoomSpecialTypes().getItemsOfType(InteractionBuildArea.class)) { + if (((InteractionBuildArea) area).inSquare(tile) && ((InteractionBuildArea) area).isBuilder(habbo.getHabboInfo().getUsername())) { + return FurnitureMovementError.NONE; + } + } + + return FurnitureMovementError.NO_RIGHTS; + } + + public FurnitureMovementError furnitureFitsAt(RoomTile tile, HabboItem item, int rotation) { + return furnitureFitsAt(tile, item, rotation, true); + } + + public FurnitureMovementError furnitureFitsAt(RoomTile tile, HabboItem item, int rotation, boolean checkForUnits) { + if (!this.layout.fitsOnMap(tile, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), rotation)) + return FurnitureMovementError.INVALID_MOVE; + + if (item instanceof InteractionStackHelper) return FurnitureMovementError.NONE; + + THashSet occupiedTiles = this.layout.getTilesAt(tile, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), rotation); + for (RoomTile t : occupiedTiles) { + if(t.state == RoomTileState.INVALID) return FurnitureMovementError.INVALID_MOVE; + if(!Emulator.getConfig().getBoolean("wired.place.under", false) || (Emulator.getConfig().getBoolean("wired.place.under", false) && !item.isWalkable() && !item.getBaseItem().allowSit() && !item.getBaseItem().allowLay())) { + if (checkForUnits && this.hasHabbosAt(t.x, t.y)) return FurnitureMovementError.TILE_HAS_HABBOS; + if (checkForUnits && this.hasBotsAt(t.x, t.y)) return FurnitureMovementError.TILE_HAS_BOTS; + if (checkForUnits && this.hasPetsAt(t.x, t.y)) return FurnitureMovementError.TILE_HAS_PETS; + } + } + + List>> tileFurniList = new ArrayList<>(); + for (RoomTile t : occupiedTiles) { + tileFurniList.add(Pair.create(t, this.getItemsAt(t))); + + HabboItem topItem = this.getTopItemAt(t.x, t.y, item); + if (topItem != null && !topItem.getBaseItem().allowStack() && !t.getAllowStack()) { + return FurnitureMovementError.CANT_STACK; + } + } + + if (!item.canStackAt(this, tileFurniList)) { + return FurnitureMovementError.CANT_STACK; + } + + return FurnitureMovementError.NONE; + } + + public FurnitureMovementError placeFloorFurniAt(HabboItem item, RoomTile tile, int rotation, Habbo owner) { + boolean pluginHelper = false; + if (Emulator.getPluginManager().isRegistered(FurniturePlacedEvent.class, true)) { + FurniturePlacedEvent event = Emulator.getPluginManager().fireEvent(new FurniturePlacedEvent(item, owner, tile)); + + if (event.isCancelled()) { + return FurnitureMovementError.CANCEL_PLUGIN_PLACE; + } + + pluginHelper = event.hasPluginHelper(); + } + + THashSet occupiedTiles = this.layout.getTilesAt(tile, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), rotation); + + FurnitureMovementError fits = furnitureFitsAt(tile, item, rotation); + + if (!fits.equals(FurnitureMovementError.NONE) && !pluginHelper) { + return fits; + } + + double height = tile.getStackHeight(); + + for(RoomTile tile2 : occupiedTiles) { + double sHeight = tile2.getStackHeight(); + if(sHeight > height) { + height = sHeight; + } + } + + if (Emulator.getPluginManager().isRegistered(FurnitureBuildheightEvent.class, true)) { + FurnitureBuildheightEvent event = Emulator.getPluginManager().fireEvent(new FurnitureBuildheightEvent(item, owner, 0.00, height)); + if (event.hasChangedHeight()) { + height = event.getUpdatedHeight(); + } + } + + item.setZ(height); + item.setX(tile.x); + item.setY(tile.y); + item.setRotation(rotation); + if (!this.furniOwnerNames.containsKey(item.getUserId()) && owner != null) { + this.furniOwnerNames.put(item.getUserId(), owner.getHabboInfo().getUsername()); + } + + item.needsUpdate(true); + this.addHabboItem(item); + item.setRoomId(this.id); + item.onPlace(this); + this.updateTiles(occupiedTiles); + this.sendComposer(new AddFloorItemComposer(item, this.getFurniOwnerName(item.getUserId())).compose()); + + for (RoomTile t : occupiedTiles) { + this.updateHabbosAt(t.x, t.y); + this.updateBotsAt(t.x, t.y); + } + + Emulator.getThreading().run(item); + return FurnitureMovementError.NONE; + } + + public FurnitureMovementError placeWallFurniAt(HabboItem item, String wallPosition, Habbo owner) { + if (!(this.hasRights(owner) || this.getGuildRightLevel(owner).isEqualOrGreaterThan(RoomRightLevels.GUILD_RIGHTS))) { + return FurnitureMovementError.NO_RIGHTS; + } + + if (Emulator.getPluginManager().isRegistered(FurniturePlacedEvent.class, true)) { + Event furniturePlacedEvent = new FurniturePlacedEvent(item, owner, null); + Emulator.getPluginManager().fireEvent(furniturePlacedEvent); + + if (furniturePlacedEvent.isCancelled()) + return FurnitureMovementError.CANCEL_PLUGIN_PLACE; + } + + item.setWallPosition(wallPosition); + if (!this.furniOwnerNames.containsKey(item.getUserId()) && owner != null) { + this.furniOwnerNames.put(item.getUserId(), owner.getHabboInfo().getUsername()); + } + this.sendComposer(new AddWallItemComposer(item, this.getFurniOwnerName(item.getUserId())).compose()); + item.needsUpdate(true); + this.addHabboItem(item); + item.setRoomId(this.id); + item.onPlace(this); + Emulator.getThreading().run(item); + return FurnitureMovementError.NONE; + } + + public FurnitureMovementError moveFurniTo(HabboItem item, RoomTile tile, int rotation, Habbo actor) { + return moveFurniTo(item, tile, rotation, actor, true, true); + } + + public FurnitureMovementError moveFurniTo(HabboItem item, RoomTile tile, int rotation, Habbo actor, boolean sendUpdates) { + return moveFurniTo(item, tile, rotation, actor, sendUpdates, true); + } + + public FurnitureMovementError moveFurniTo(HabboItem item, RoomTile tile, int rotation, Habbo actor, boolean sendUpdates, boolean checkForUnits) { + RoomTile oldLocation = this.layout.getTile(item.getX(), item.getY()); + + boolean pluginHelper = false; + if (Emulator.getPluginManager().isRegistered(FurnitureMovedEvent.class, true)) { + FurnitureMovedEvent event = Emulator.getPluginManager().fireEvent(new FurnitureMovedEvent(item, actor, oldLocation, tile)); + if(event.isCancelled()) { + return FurnitureMovementError.CANCEL_PLUGIN_MOVE; + } + pluginHelper = event.hasPluginHelper(); + } + + boolean magicTile = item instanceof InteractionStackHelper; + + Optional stackHelper = this.getItemsAt(tile).stream().filter(InteractionStackHelper.class::isInstance).findAny(); + + //Check if can be placed at new position + THashSet occupiedTiles = this.layout.getTilesAt(tile, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), rotation); + THashSet newOccupiedTiles = this.layout.getTilesAt(tile, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), rotation); + + HabboItem topItem = this.getTopItemAt(occupiedTiles, null); + + if ((!stackHelper.isPresent() && !pluginHelper) || item.getBaseItem().getInteractionType().getType() == InteractionWater.class) { + if (oldLocation != tile) { + for (RoomTile t : occupiedTiles) { + HabboItem tileTopItem = this.getTopItemAt(t.x, t.y); + if (!magicTile && ((tileTopItem != null && tileTopItem != item ? (t.state.equals(RoomTileState.INVALID) || + !t.getAllowStack() || !tileTopItem.getBaseItem().allowStack() || + (tileTopItem.getBaseItem().getInteractionType().getType() == InteractionWater.class && (item.getBaseItem().getInteractionType().getType() != InteractionWaterItem.class || + item.getBaseItem().getInteractionType().getType() == InteractionWater.class))) : this.calculateTileState(t, item).equals(RoomTileState.INVALID)) || + stackHelper.isPresent() && item.getBaseItem().getInteractionType().getType() == InteractionWater.class)) { + return FurnitureMovementError.CANT_STACK; + } + + if(!Emulator.getConfig().getBoolean("wired.place.under", false) || (Emulator.getConfig().getBoolean("wired.place.under", false) && !item.isWalkable() && !item.getBaseItem().allowSit() && !item.getBaseItem().allowLay())) { + if (checkForUnits) { + if (!magicTile && this.hasHabbosAt(t.x, t.y)) return FurnitureMovementError.TILE_HAS_HABBOS; + if (!magicTile && this.hasBotsAt(t.x, t.y)) return FurnitureMovementError.TILE_HAS_BOTS; + if (!magicTile && this.hasPetsAt(t.x, t.y)) return FurnitureMovementError.TILE_HAS_PETS; + } + } + } + } + + List>> tileFurniList = new ArrayList<>(); + for (RoomTile t : occupiedTiles) { + tileFurniList.add(Pair.create(t, this.getItemsAt(t))); + } + + if (!magicTile && !item.canStackAt(this, tileFurniList)) { + return FurnitureMovementError.CANT_STACK; + } + } + + THashSet oldOccupiedTiles = new THashSet<>(); + if(oldLocation != null) { + oldOccupiedTiles.addAll(this.layout.getTilesAt(oldLocation, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation())); + } + + int oldRotation = item.getRotation(); + + if (oldRotation != rotation) { + item.setRotation(rotation); + if (Emulator.getPluginManager().isRegistered(FurnitureRotatedEvent.class, true)) { + Event furnitureRotatedEvent = new FurnitureRotatedEvent(item, actor, oldRotation); + Emulator.getPluginManager().fireEvent(furnitureRotatedEvent); + + if (furnitureRotatedEvent.isCancelled()) { + item.setRotation(oldRotation); + return FurnitureMovementError.CANCEL_PLUGIN_ROTATE; + } + } + + if((!stackHelper.isPresent() && topItem != null && topItem != item && !topItem.getBaseItem().allowStack())|| (topItem != null && topItem != item && topItem.getZ() + Item.getCurrentHeight(topItem) + Item.getCurrentHeight(item) > MAXIMUM_FURNI_HEIGHT)) + { + item.setRotation(oldRotation); + return FurnitureMovementError.CANT_STACK; + } + + // ) + } + //Place at new position + + double height; + + if (stackHelper.isPresent()) { + height = stackHelper.get().getExtradata().isEmpty() ? Double.parseDouble("0.0") : (Double.parseDouble(stackHelper.get().getExtradata()) / 100); + } else if (item == topItem) { + height = item.getZ(); + } else { + height = this.getStackHeight(tile.x, tile.y, false, item); + for(RoomTile til : occupiedTiles) { + double sHeight = this.getStackHeight(til.x, til.y, false, item); + if(sHeight > height) { + height = sHeight; + } + } + } + + if(height > MAXIMUM_FURNI_HEIGHT) return FurnitureMovementError.CANT_STACK; + if(height < this.getLayout().getHeightAtSquare(tile.x, tile.y)) return FurnitureMovementError.CANT_STACK; //prevent furni going under the floor + + if (Emulator.getPluginManager().isRegistered(FurnitureBuildheightEvent.class, true)) { + FurnitureBuildheightEvent event = Emulator.getPluginManager().fireEvent(new FurnitureBuildheightEvent(item, actor, 0.00, height)); + if (event.hasChangedHeight()) { + height = event.getUpdatedHeight(); + } + } + + item.setX(tile.x); + item.setY(tile.y); + item.setZ(height); + if (magicTile) { + item.setZ(tile.z); + item.setExtradata("" + item.getZ() * 100); + } + if (item.getZ() > MAXIMUM_FURNI_HEIGHT) { + item.setZ(MAXIMUM_FURNI_HEIGHT); + } + + + //Update Furniture + item.onMove(this, oldLocation, tile); + item.needsUpdate(true); + Emulator.getThreading().run(item); + + if(sendUpdates) { + this.sendComposer(new FloorItemUpdateComposer(item).compose()); + } + + //Update old & new tiles + occupiedTiles.removeAll(oldOccupiedTiles); + occupiedTiles.addAll(oldOccupiedTiles); + this.updateTiles(occupiedTiles); + + //Update Habbos at old position + for (RoomTile t : occupiedTiles) { + this.updateHabbosAt( + t.x, + t.y, + this.getHabbosAt(t.x, t.y) + /*.stream() + .filter(h -> !h.getRoomUnit().hasStatus(RoomUnitStatus.MOVE) || h.getRoomUnit().getGoal() == t) + .collect(Collectors.toCollection(THashSet::new))*/ + ); + this.updateBotsAt(t.x, t.y); + } + if(Emulator.getConfig().getBoolean("wired.place.under", false)) { + for(RoomTile t : newOccupiedTiles) { + for(Habbo h : this.getHabbosAt(t.x, t.y)) { + try { + item.onWalkOn(h.getRoomUnit(), this, null); + } + catch(Exception e) { + + } + } + } + } + return FurnitureMovementError.NONE; + } + + public FurnitureMovementError slideFurniTo(HabboItem item, RoomTile tile, int rotation) { + RoomTile oldLocation = this.layout.getTile(item.getX(), item.getY()); + + HabboItem topItem = this.getTopItemAt(tile.x, tile.y); + + boolean magicTile = item instanceof InteractionStackHelper; + + //Check if can be placed at new position + THashSet occupiedTiles = this.layout.getTilesAt(tile, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), rotation); + + List>> tileFurniList = new ArrayList<>(); + for (RoomTile t : occupiedTiles) { + tileFurniList.add(Pair.create(t, this.getItemsAt(t))); + } + + if (!magicTile && !item.canStackAt(this, tileFurniList)) { + return FurnitureMovementError.CANT_STACK; + } + + THashSet oldOccupiedTiles = this.layout.getTilesAt(this.layout.getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + + int oldRotation = item.getRotation(); + item.setRotation(rotation); + + //Place at new position + if (magicTile) { + item.setZ(tile.z); + item.setExtradata("" + item.getZ() * 100); + } + if (item.getZ() > MAXIMUM_FURNI_HEIGHT) { + item.setZ(MAXIMUM_FURNI_HEIGHT); + } + double offset = this.getStackHeight(tile.x, tile.y, false, item) - item.getZ(); + this.sendComposer(new FloorItemOnRollerComposer(item, null, tile, offset, this).compose()); + + //Update Habbos at old position + for (RoomTile t : occupiedTiles) { + this.updateHabbosAt(t.x, t.y); + this.updateBotsAt(t.x, t.y); + } + return FurnitureMovementError.NONE; + } + + public THashSet getRoomUnits() { + return getRoomUnits(null); + } + + public THashSet getRoomUnits(RoomTile atTile) { + THashSet units = new THashSet<>(); + + for (Habbo habbo : this.currentHabbos.values()) { + if (habbo != null && habbo.getRoomUnit() != null && habbo.getRoomUnit().getRoom() != null && habbo.getRoomUnit().getRoom().getId() == this.getId() && (atTile == null || habbo.getRoomUnit().getCurrentLocation() == atTile)) { + units.add(habbo.getRoomUnit()); + } + } + + for (Pet pet : this.currentPets.valueCollection()) { + if (pet != null && pet.getRoomUnit() != null && pet.getRoomUnit().getRoom() != null && pet.getRoomUnit().getRoom().getId() == this.getId() && (atTile == null || pet.getRoomUnit().getCurrentLocation() == atTile)) { + units.add(pet.getRoomUnit()); + } + } + + for (Bot bot : this.currentBots.valueCollection()) { + if (bot != null && bot.getRoomUnit() != null && bot.getRoomUnit().getRoom() != null && bot.getRoomUnit().getRoom().getId() == this.getId() && (atTile == null || bot.getRoomUnit().getCurrentLocation() == atTile)) { + units.add(bot.getRoomUnit()); + } + } + + return units; + } + + public Collection getRoomUnitsAt(RoomTile tile) { + THashSet roomUnits = getRoomUnits(); + return roomUnits.stream().filter(unit -> unit.getCurrentLocation() == tile).collect(Collectors.toSet()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomBan.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomBan.java new file mode 100644 index 0000000..8cb79b7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomBan.java @@ -0,0 +1,55 @@ +package com.eu.habbo.habbohotel.rooms; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class RoomBan { + + public final int roomId; + public final int userId; + public final String username; + public final int endTimestamp; + + public RoomBan(int roomId, int userId, String username, int endTimestamp) { + this.roomId = roomId; + this.userId = userId; + this.username = username; + this.endTimestamp = endTimestamp; + } + + public RoomBan(ResultSet set) throws SQLException { + this.roomId = set.getInt("room_id"); + this.userId = set.getInt("user_id"); + this.username = set.getString("username"); + this.endTimestamp = set.getInt("ends"); + } + + + public void insert() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO room_bans (room_id, user_id, ends) VALUES (?, ?, ?)")) { + statement.setInt(1, this.roomId); + statement.setInt(2, this.userId); + statement.setInt(3, this.endTimestamp); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + + public void delete() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM room_bans WHERE room_id = ? AND user_id = ?")) { + statement.setInt(1, this.roomId); + statement.setInt(2, this.userId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomCategory.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomCategory.java new file mode 100644 index 0000000..59b7b92 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomCategory.java @@ -0,0 +1,73 @@ +package com.eu.habbo.habbohotel.rooms; + +import com.eu.habbo.habbohotel.navigation.ListMode; + +import java.sql.ResultSet; +import java.sql.SQLException; + +@SuppressWarnings("NullableProblems") +public class RoomCategory implements Comparable { + + private int id; + private int minRank; + private String caption; + private String captionSave; + private boolean canTrade; + private int maxUserCount; + private boolean official; + private ListMode displayMode; + private int order; + + public RoomCategory(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.minRank = set.getInt("min_rank"); + this.caption = set.getString("caption"); + this.captionSave = set.getString("caption_save"); + this.canTrade = set.getBoolean("can_trade"); + this.maxUserCount = set.getInt("max_user_count"); + this.official = set.getString("public").equals("1"); + this.displayMode = ListMode.fromType(set.getInt("list_type")); + this.order = set.getInt("order_num"); + } + + public int getId() { + return this.id; + } + + public int getMinRank() { + return this.minRank; + } + + public String getCaption() { + return this.caption; + } + + public String getCaptionSave() { + return this.captionSave; + } + + public boolean isCanTrade() { + return this.canTrade; + } + + public int getMaxUserCount() { + return this.maxUserCount; + } + + public boolean isPublic() { + return this.official; + } + + public ListMode getDisplayMode() { + return this.displayMode; + } + + public int getOrder() { + return this.order; + } + + @Override + public int compareTo(RoomCategory o) { + return o.getId() - this.getId(); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatMessage.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatMessage.java new file mode 100644 index 0000000..d90d83a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatMessage.java @@ -0,0 +1,267 @@ +package com.eu.habbo.habbohotel.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.core.DatabaseLoggable; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.Incoming; +import com.eu.habbo.messages.incoming.MessageHandler; +import lombok.extern.slf4j.Slf4j; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.List; + +@Slf4j +public class RoomChatMessage implements Runnable, ISerialize, DatabaseLoggable { + + private static final String QUERY = "INSERT INTO chatlogs_room (user_from_id, user_to_id, message, timestamp, room_id) VALUES (?, ?, ?, ?, ?)"; + private static final List chatColors = Arrays.asList("@red@", "@cyan@", "@blue@", "@green@", "@purple@"); + public static int MAXIMUM_LENGTH = 100; + //Configuration. Loaded from database & updated accordingly. + public static boolean SAVE_ROOM_CHATS = false; + public static int[] BANNED_BUBBLES = {}; + private final Habbo habbo; + public int roomId; + public boolean isCommand = false; + public boolean filtered = false; + private int roomUnitId; + private String message; + private String unfilteredMessage; + private int timestamp = 0; + private RoomChatMessageBubbles bubble; + private Habbo targetHabbo; + private byte emotion; + private String RoomChatColour; //Added ChatColor + + + public RoomChatMessage(MessageHandler message) { + + if (message.packet.getMessageId() == Incoming.RoomUserWhisperEvent) { + String data = message.packet.readString(); + this.targetHabbo = message.client.getHabbo().getHabboInfo().getCurrentRoom().getHabbo(data.split(" ")[0]); + this.message = data.substring(data.split(" ")[0].length() + 1); + } else { + this.message = message.packet.readString(); + } + + try { + this.bubble = RoomChatMessageBubbles.getBubble(message.packet.readInt()); + } catch (Exception e) { + this.bubble = RoomChatMessageBubbles.NORMAL; + } + + this.RoomChatColour = message.packet.readString(); // Added for Room Chat Colour + + if (!message.client.getHabbo().hasPermission(Permission.ACC_ANYCHATCOLOR)) { + for (Integer i : RoomChatMessage.BANNED_BUBBLES) { + if (i.equals(this.bubble.getType())) { + this.bubble = RoomChatMessageBubbles.NORMAL; + break; + } + } + } + + this.habbo = message.client.getHabbo(); + this.roomUnitId = this.habbo.getRoomUnit().getId(); + this.unfilteredMessage = this.message; + this.timestamp = Emulator.getIntUnixTimestamp(); + + this.checkEmotion(); + + this.filter(); + } + + public RoomChatMessage(RoomChatMessage chatMessage) { + this.message = chatMessage.getMessage(); + this.unfilteredMessage = chatMessage.getUnfilteredMessage(); + this.habbo = chatMessage.getHabbo(); + this.targetHabbo = chatMessage.getTargetHabbo(); + this.bubble = chatMessage.getBubble(); + this.roomUnitId = chatMessage.roomUnitId; + this.emotion = (byte) chatMessage.getEmotion(); + } + + public RoomChatMessage(String message, RoomUnit roomUnit, RoomChatMessageBubbles bubble) { + this.message = message; + this.unfilteredMessage = message; + this.habbo = null; + this.bubble = bubble; + this.roomUnitId = roomUnit.getId(); + } + + public RoomChatMessage(String message, Habbo habbo, RoomChatMessageBubbles bubble) { + this.message = message; + this.unfilteredMessage = message; + this.habbo = habbo; + this.bubble = bubble; + this.checkEmotion(); + this.roomUnitId = habbo.getRoomUnit().getId(); + this.message = this.message.replace("\r", "").replace("\n", ""); + + if (this.bubble.isOverridable() && this.getHabbo().getHabboStats().chatColor != RoomChatMessageBubbles.NORMAL) + this.bubble = this.getHabbo().getHabboStats().chatColor; + } + + public RoomChatMessage(String message, Habbo habbo, Habbo targetHabbo, RoomChatMessageBubbles bubble) { + this.message = message; + this.unfilteredMessage = message; + this.habbo = habbo; + this.targetHabbo = targetHabbo; + this.bubble = bubble; + this.checkEmotion(); + this.roomUnitId = this.habbo.getRoomUnit().getId(); + this.message = this.message.replace("\r", "").replace("\n", ""); + + if (this.bubble.isOverridable() && this.getHabbo().getHabboStats().chatColor != RoomChatMessageBubbles.NORMAL) + this.bubble = this.getHabbo().getHabboStats().chatColor; + } + + private void checkEmotion() { + if (this.message.contains(":)") || this.message.contains(":-)") || this.message.contains(":]")) { + this.emotion = 1; + } else if (this.message.contains(":@") || this.message.contains(">:(")) { + this.emotion = 2; + } else if (this.message.contains(":o") || this.message.contains(":O") || this.message.contains(":0") || this.message.contains("O.o") || this.message.contains("o.O") || this.message.contains("O.O")) { + this.emotion = 3; + } else if (this.message.contains(":(") || this.message.contains(":-(") || this.message.contains(":[")) { + this.emotion = 4; + } + } + + @Override + public void run() { + if (this.habbo == null) + return; + + if (this.message.length() > RoomChatMessage.MAXIMUM_LENGTH) { + try { + this.message = this.message.substring(0, RoomChatMessage.MAXIMUM_LENGTH - 1); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + Emulator.getDatabaseLogger().store(this); + } + + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getUnfilteredMessage() { + return this.unfilteredMessage; + } + + public RoomChatMessageBubbles getBubble() { + return this.bubble; + } + + public Habbo getHabbo() { + return this.habbo; + } + + public Habbo getTargetHabbo() { + return this.targetHabbo; + } + + public int getEmotion() { + return this.emotion; + } + + @Override + public void serialize(ServerMessage message) { + + + if (this.habbo != null && this.bubble.isOverridable()) { + if (!this.habbo.hasPermission(Permission.ACC_ANYCHATCOLOR)) { + for (Integer i : RoomChatMessage.BANNED_BUBBLES) { + if (i == this.bubble.getType()) { + this.bubble = RoomChatMessageBubbles.NORMAL; + break; + } + } + } + } + + if (!this.getBubble().getPermission().isEmpty()) { + if (this.habbo != null && !this.habbo.hasPermission(this.getBubble().getPermission())) { + this.bubble = RoomChatMessageBubbles.NORMAL; + } + } + + try { + message.appendInt(this.roomUnitId); + message.appendString(this.getMessage()); + message.appendInt(this.getEmotion()); + message.appendInt(this.getBubble().getType()); + message.appendInt(0); + message.appendString(this.RoomChatColour); //Added packet for Room Chat Color + message.appendInt(this.getMessage().length()); + + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + public void filter() { + if (!this.habbo.getHabboStats().hasActiveClub()) { + for (String chatColor : chatColors) { + this.message = this.message.replace(chatColor, ""); + } + } + + if (Emulator.getConfig().getBoolean("hotel.wordfilter.enabled") && Emulator.getConfig().getBoolean("hotel.wordfilter.rooms")) { + if (!this.habbo.hasPermission(Permission.ACC_CHAT_NO_FILTER)) { + if (!Emulator.getGameEnvironment().getWordFilter().autoReportCheck(this)) { + if (!Emulator.getGameEnvironment().getWordFilter().hideMessageCheck(this.message)) { + Emulator.getGameEnvironment().getWordFilter().filter(this, this.habbo); + return; + } + } else { + int muteTime = Emulator.getConfig().getInt("hotel.wordfilter.automute"); + if (muteTime > 0) { + this.habbo.mute(muteTime, false); + } else { + log.error("Invalid hotel.wordfilter.automute defined in emulator_settings ({}).", muteTime); + } + } + + this.message = ""; + } + } + } + + @Override + public String getQuery() { + return QUERY; + } + + @Override + public void log(PreparedStatement statement) throws SQLException { + statement.setInt(1, this.habbo.getHabboInfo().getId()); + + if (this.targetHabbo != null) + statement.setInt(2, this.targetHabbo.getHabboInfo().getId()); + else + statement.setInt(2, 0); + + statement.setString(3, this.unfilteredMessage); + statement.setInt(4, this.timestamp); + + if (this.habbo.getHabboInfo().getCurrentRoom() != null) { + statement.setInt(5, this.habbo.getHabboInfo().getCurrentRoom().getId()); + } else { + statement.setInt(5, 0); + } + + statement.addBatch(); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatMessageBubbles.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatMessageBubbles.java new file mode 100644 index 0000000..befeea8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatMessageBubbles.java @@ -0,0 +1,94 @@ +package com.eu.habbo.habbohotel.rooms; + +public enum RoomChatMessageBubbles { + NORMAL(0, "", true, true), + ALERT(1, "", true, true), + BOT(2, "", true, true), + RED(3, "", true, true), + BLUE(4, "", true, true), + YELLOW(5, "", true, true), + GREEN(6, "", true, true), + BLACK(7, "", true, true), + FORTUNE_TELLER(8, "", false, false), + ZOMBIE_ARM(9, "", true, false), + SKELETON(10, "", true, false), + LIGHT_BLUE(11, "", true, true), + PINK(12, "", true, true), + PURPLE(13, "", true, true), + DARK_YEWLLOW(14, "", true, true), + DARK_BLUE(15, "", true, true), + HEARTS(16, "", true, true), + ROSES(17, "", true, true), + UNUSED(18, "", true, true), //? + PIG(19, "", true, true), + DOG(20, "", true, true), + BLAZE_IT(21, "", true, true), + DRAGON(22, "", true, true), + STAFF(23, "", false, true), + BATS(24, "", true, false), + MESSENGER(25, "", true, false), + STEAMPUNK(26, "", true, false), + THUNDER(27, "", true, true), + PARROT(28, "", false, false), + PIRATE(29, "", false, false), + BOT_GUIDE(30, "", true, true), + BOT_RENTABLE(31, "", true, true), + SCARY_THING(32, "", true, false), + FRANK(33, "", true, false), + WIRED(34, "", false, true), + GOAT(35, "", true, false), + SANTA(36, "", true, false), + AMBASSADOR(37, "acc_ambassador", false, true), + RADIO(38, "", true, false), + UNKNOWN_39(39, "", true, false), + UNKNOWN_40(40, "", true, false), + UNKNOWN_41(41, "", true, false), + UNKNOWN_42(42, "", true, false), + UNKNOWN_43(43, "", true, false), + UNKNOWN_44(44, "", true, false), + UNKNOWN_45(45, "", true, false), + UNKNOWN_46(46, "", true, false), + UNKNOWN_47(47, "", true, false), + UNKNOWN_48(48, "", true, false), + UNKNOWN_49(49, "", true, false), + UNKNOWN_50(50, "", true, false), + UNKNOWN_51(51, "", true, false), + UNKNOWN_52(52, "", true, false), + UNKNOWN_53(53, "", true, false); + + private final int type; + private final String permission; + private final boolean overridable; + private final boolean triggersTalkingFurniture; + + RoomChatMessageBubbles(int type, String permission, boolean overridable, boolean triggersTalkingFurniture) { + this.type = type; + this.permission = permission; + this.overridable = overridable; + this.triggersTalkingFurniture = triggersTalkingFurniture; + } + + public static RoomChatMessageBubbles getBubble(int bubbleId) { + try { + return values()[bubbleId]; + } catch (Exception e) { + return NORMAL; + } + } + + public int getType() { + return this.type; + } + + public String getPermission() { + return this.permission; + } + + public boolean isOverridable() { + return this.overridable; + } + + public boolean triggersTalkingFurniture() { + return this.triggersTalkingFurniture; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatType.java new file mode 100644 index 0000000..cb252f5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatType.java @@ -0,0 +1,7 @@ +package com.eu.habbo.habbohotel.rooms; + +public enum RoomChatType { + TALK, + SHOUT, + WHISPER +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomLayout.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomLayout.java new file mode 100644 index 0000000..2c488d1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomLayout.java @@ -0,0 +1,668 @@ +package com.eu.habbo.habbohotel.rooms; + +import com.eu.habbo.Emulator; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; + +import java.awt.*; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; + +@Slf4j +public class RoomLayout { + protected static final int BASICMOVEMENTCOST = 10; + protected static final int DIAGONALMOVEMENTCOST = 14; + public static double MAXIMUM_STEP_HEIGHT = 1.1; + public static boolean ALLOW_FALLING = true; + public boolean CANMOVEDIAGONALY = true; + private String name; + private short doorX; + private short doorY; + private short doorZ; + private int doorDirection; + private String heightmap; + private int mapSize; + private int mapSizeX; + private int mapSizeY; + private RoomTile[][] roomTiles; + private RoomTile doorTile; + private Room room; + + public RoomLayout(ResultSet set, Room room) throws SQLException { + this.room = room; + try { + this.name = set.getString("name"); + this.doorX = set.getShort("door_x"); + this.doorY = set.getShort("door_y"); + + this.doorDirection = set.getInt("door_dir"); + this.heightmap = set.getString("heightmap"); + + this.parse(); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + public static boolean squareInSquare(Rectangle outerSquare, Rectangle innerSquare) { + if (outerSquare.x > innerSquare.x) + return false; + + if (outerSquare.y > innerSquare.y) + return false; + + if (outerSquare.x + outerSquare.width < innerSquare.x + innerSquare.width) + return false; + + if (outerSquare.y + outerSquare.height < innerSquare.y + innerSquare.height) + return false; + + return true; + } + + public static boolean tileInSquare(Rectangle square, RoomTile tile) { + return (square.contains(tile.x, tile.y)); + } + + public static boolean pointInSquare(int x1, int y1, int x2, int y2, int pointX, int pointY) { + return (pointX >= x1 && pointY >= y1) && (pointX <= x2 && pointY <= y2); + } + + public static boolean tilesAdjecent(RoomTile one, RoomTile two) { + return !(one == null || two == null) && !(Math.abs(one.x - two.x) > 1) && !(Math.abs(one.y - two.y) > 1); + } + + public static Rectangle getRectangle(int x, int y, int width, int length, int rotation) { + rotation = (rotation % 8); + + if (rotation == 2 || rotation == 6) { + return new Rectangle(x, y, length, width); + } + + return new Rectangle(x, y, width, length); + } + + public static boolean tilesAdjecent(RoomTile tile, RoomTile comparator, int width, int length, int rotation) { + Rectangle rectangle = getRectangle(comparator.x, comparator.y, width, length, rotation); + rectangle = new Rectangle(rectangle.x - 1, rectangle.y - 1, rectangle.width + 2, rectangle.height + 2); + + return rectangle.contains(tile.x, tile.y); + } + + public void parse() { + String[] modelTemp = this.heightmap.replace("\n", "").split(Character.toString('\r')); + + this.mapSize = 0; + this.mapSizeX = modelTemp[0].length(); + this.mapSizeY = modelTemp.length; + this.roomTiles = new RoomTile[this.mapSizeX][this.mapSizeY]; + + for (short y = 0; y < this.mapSizeY; y++) { + if (modelTemp[y].isEmpty() || modelTemp[y].equalsIgnoreCase("\r")) { + continue; + } + + for (short x = 0; x < this.mapSizeX; x++) { + if (modelTemp[y].length() != this.mapSizeX) { + break; + } + + String square = modelTemp[y].substring(x, x + 1).trim().toLowerCase(); + RoomTileState state = RoomTileState.OPEN; + short height = 0; + if (square.equalsIgnoreCase("x")) { + state = RoomTileState.INVALID; + } else { + if (square.isEmpty()) { + height = 0; + } else if (Emulator.isNumeric(square)) { + height = Short.parseShort(square); + } else { + height = (short) (10 + "ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(square.toUpperCase())); + } + } + this.mapSize += 1; + + this.roomTiles[x][y] = new RoomTile(x, y, height, state, true); + } + } + + this.doorTile = this.roomTiles[this.doorX][this.doorY]; + + if (this.doorTile != null) { + this.doorTile.setAllowStack(false); + RoomTile doorFrontTile = this.getTileInFront(this.doorTile, this.doorDirection); + + if (doorFrontTile != null && this.tileExists(doorFrontTile.x, doorFrontTile.y)) { + if (this.roomTiles[doorFrontTile.x][doorFrontTile.y].state != RoomTileState.INVALID) { + if (this.doorZ != this.roomTiles[doorFrontTile.x][doorFrontTile.y].z || this.roomTiles[this.doorX][this.doorY].state != this.roomTiles[doorFrontTile.x][doorFrontTile.y].state) { + this.doorZ = this.roomTiles[doorFrontTile.x][doorFrontTile.y].z; + this.roomTiles[this.doorX][this.doorY].state = RoomTileState.OPEN; + } + } + } + } + } + + public String getName() { + return this.name; + } + + public short getDoorX() { + return this.doorX; + } + + public void setDoorX(short doorX) { + this.doorX = doorX; + } + + public short getDoorY() { + return this.doorY; + } + + public void setDoorY(short doorY) { + this.doorY = doorY; + } + + public int getDoorZ() { + return this.doorZ; + } + + public RoomTile getDoorTile() { + return this.doorTile; + } + + public int getDoorDirection() { + return this.doorDirection; + } + + public void setDoorDirection(int doorDirection) { + this.doorDirection = doorDirection; + } + + public String getHeightmap() { + return this.heightmap; + } + + public void setHeightmap(String heightMap) { + this.heightmap = heightMap; + } + + public int getMapSize() { + return this.mapSize; + } + + public int getMapSizeX() { + return this.mapSizeX; + } + + public int getMapSizeY() { + return this.mapSizeY; + } + + public short getHeightAtSquare(int x, int y) { + if (x < 0 || + y < 0 || + x >= this.getMapSizeX() || + y >= this.getMapSizeY()) + return 0; + + return this.roomTiles[x][y].z; + } + + public double getStackHeightAtSquare(int x, int y) { + if (x < 0 || + y < 0 || + x >= this.getMapSizeX() || + y >= this.getMapSizeY()) + return 0; + + return this.roomTiles[x][y].getStackHeight(); + } + + public double getRelativeHeightAtSquare(int x, int y) { + if (x < 0 || + y < 0 || + x >= this.getMapSizeX() || + y >= this.getMapSizeY()) + return 0; + + return this.roomTiles[x][y].relativeHeight(); + } + + public RoomTile getTile(short x, short y) { + if (this.tileExists(x, y)) { + return this.roomTiles[x][y]; + } + + return null; + } + + public boolean tileExists(short x, short y) { + return !(x < 0 || y < 0 || x >= this.getMapSizeX() || y >= this.getMapSizeY()); + } + + public boolean tileWalkable(short x, short y) { + return this.tileExists(x, y) && this.roomTiles[x][y].state == RoomTileState.OPEN && this.roomTiles[x][y].isWalkable(); + } + + public boolean isVoidTile(short x, short y) { + if (!this.tileExists(x, y)) return true; + return this.roomTiles[x][y].state == RoomTileState.INVALID; + } + + public String getRelativeMap() { + return this.heightmap.replace("\r\n", "\r"); + }//re + + public final Deque findPath(RoomTile oldTile, RoomTile newTile, RoomTile goalLocation, RoomUnit roomUnit) { + return this.findPath(oldTile, newTile, goalLocation, roomUnit, false); + } + + /// Pathfinder Reworked By Quadral, thanks buddy!! You Saved Morningstar <3 + public final Deque findPath(RoomTile oldTile, RoomTile newTile, RoomTile goalLocation, RoomUnit roomUnit, boolean isWalktroughRetry) { + if (this.room == null || !this.room.isLoaded() || oldTile == null || newTile == null || oldTile.equals(newTile) || newTile.state == RoomTileState.INVALID) + return new LinkedList<>(); + + LinkedList openList = new LinkedList<>(); + List closedList = new LinkedList<>(); + openList.add(oldTile.copy()); + + RoomTile doorTile = this.room.getLayout().getDoorTile(); + + long startMillis = System.currentTimeMillis(); + + while (!openList.isEmpty()) { + if (System.currentTimeMillis() - startMillis > Emulator.getConfig().getInt("pathfinder.execution_time.milli", 25) && Emulator.getConfig().getBoolean("pathfinder.max_execution_time.enabled", false)) { + return null; + } + RoomTile current = this.lowestFInOpen(openList); + if (current.x == newTile.x && current.y == newTile.y) { + return this.calcPath(this.findTile(openList, oldTile.x, oldTile.y), current); + } + + closedList.add(current); + openList.remove(current); + + List adjacentNodes = this.getAdjacent(openList, current, newTile, roomUnit); + for (RoomTile currentAdj : adjacentNodes) { + if (closedList.contains(currentAdj)) continue; + + if (roomUnit.canOverrideTile(currentAdj)) { + currentAdj.setPrevious(current); + currentAdj.sethCosts(this.findTile(openList, newTile.x, newTile.y)); + currentAdj.setgCosts(current); + openList.add(currentAdj); + continue; + } + + if (currentAdj.state == RoomTileState.BLOCKED || ((currentAdj.state == RoomTileState.SIT || currentAdj.state == RoomTileState.LAY) && !currentAdj.equals(goalLocation))) { + closedList.add(currentAdj); + openList.remove(currentAdj); + continue; + } + + double height = currentAdj.getStackHeight() - current.getStackHeight(); + + if ((!ALLOW_FALLING && height < -MAXIMUM_STEP_HEIGHT) || (currentAdj.state == RoomTileState.OPEN && height > MAXIMUM_STEP_HEIGHT)) { + closedList.add(currentAdj); + openList.remove(currentAdj); + continue; + } + + if (currentAdj.hasUnits() && doorTile.distance(currentAdj) > 2 && (!isWalktroughRetry || !this.room.isAllowWalkthrough() || currentAdj.equals(goalLocation))) { + closedList.add(currentAdj); + openList.remove(currentAdj); + continue; + } + + if (!openList.contains(currentAdj)) { + currentAdj.setPrevious(current); + currentAdj.sethCosts(this.findTile(openList, newTile.x, newTile.y)); + currentAdj.setgCosts(current); + openList.add(currentAdj); + } else if (currentAdj.getgCosts() > currentAdj.calculategCosts(current)) { + currentAdj.setPrevious(current); + currentAdj.setgCosts(current); + } + } + } + + if (this.room.isAllowWalkthrough() && !isWalktroughRetry) { + return this.findPath(oldTile, newTile, goalLocation, roomUnit, true); + } + + return null; + } + + private RoomTile findTile(List tiles, short x, short y) { + for (RoomTile tile : tiles) { + if (x == tile.x && y == tile.y) { + return tile; + } + } + + RoomTile tile = this.getTile(x, y); + + if (tile != null) { + return tile.copy(); + } + return null; + } + + public Deque calcPath(RoomTile start, RoomTile goal) { + LinkedList path = new LinkedList<>(); + if (start == null) + return path; + + RoomTile curr = goal; + while (curr != null) { + path.addFirst(this.getTile(curr.x, curr.y)); + curr = curr.getPrevious(); + if ((curr != null) && (curr.equals(start))) { + return path; + } + } + return path; + } + + private RoomTile lowestFInOpen(List openList) { + if (openList == null) + return null; + + RoomTile cheapest = openList.get(0); + for (RoomTile anOpenList : openList) { + if (anOpenList.getfCosts() < cheapest.getfCosts()) { + cheapest = anOpenList; + } + } + return cheapest; + } + + private List getAdjacent(List openList, RoomTile node, RoomTile nextTile, RoomUnit unit) { + short x = node.x; + short y = node.y; + List adj = new LinkedList<>(); + if (x > 0) { + RoomTile temp = this.findTile(openList, (short) (x - 1), y); + if (this.canWalkOn(temp, unit)) { + if (temp.state != RoomTileState.SIT || nextTile.getStackHeight() - node.getStackHeight() <= 2.0) { + temp.isDiagonally(false); + if (!adj.contains(temp)) + adj.add(temp); + } + } + } + if (x < this.mapSizeX) { + RoomTile temp = this.findTile(openList, (short) (x + 1), y); + if (this.canWalkOn(temp, unit)) { + if (temp.state != RoomTileState.SIT || nextTile.getStackHeight() - node.getStackHeight() <= 2.0) { + temp.isDiagonally(false); + if (!adj.contains(temp)) + adj.add(temp); + } + } + } + if (y > 0) { + RoomTile temp = this.findTile(openList, x, (short) (y - 1)); + if (this.canWalkOn(temp, unit)) { + if (temp.state != RoomTileState.SIT || nextTile.getStackHeight() - node.getStackHeight() <= 2.0) { + temp.isDiagonally(false); + if (!adj.contains(temp)) + adj.add(temp); + } + } + } + if (y < this.mapSizeY) { + RoomTile temp = this.findTile(openList, x, (short) (y + 1)); + if (this.canWalkOn(temp, unit)) { + if (temp.state != RoomTileState.SIT || nextTile.getStackHeight() - node.getStackHeight() <= 2.0) { + temp.isDiagonally(false); + if (!adj.contains(temp)) + adj.add(temp); + } + } + } + if (this.CANMOVEDIAGONALY) { + if ((x < this.mapSizeX) && (y < this.mapSizeY)) { + RoomTile offX = this.findTile(openList, (short) (x + 1), y); + RoomTile offY = this.findTile(openList, x, (short) (y + 1)); + if (offX != null && offY != null && (offX.isWalkable() || offY.isWalkable())) { + RoomTile temp = this.findTile(openList, (short) (x + 1), (short) (y + 1)); + if (this.canWalkOn(temp, unit)) { + if (temp.state != RoomTileState.SIT || nextTile.getStackHeight() - node.getStackHeight() <= 2.0) { + temp.isDiagonally(true); + if (!adj.contains(temp)) + adj.add(temp); + } + } + } + } + if ((x > 0) && (y > 0)) { + RoomTile offX = this.findTile(openList, (short) (x - 1), y); + RoomTile offY = this.findTile(openList, x, (short) (y - 1)); + if (offX != null && offY != null && (offX.isWalkable() || offY.isWalkable())) { + RoomTile temp = this.findTile(openList, (short) (x - 1), (short) (y - 1)); + if (this.canWalkOn(temp, unit)) { + if (temp.state != RoomTileState.SIT || nextTile.getStackHeight() - node.getStackHeight() <= 2.0) { + temp.isDiagonally(true); + if (!adj.contains(temp)) + adj.add(temp); + } + } + } + } + if ((x > 0) && (y < this.mapSizeY)) { + RoomTile offX = this.findTile(openList, (short) (x - 1), y); + RoomTile offY = this.findTile(openList, x, (short) (y + 1)); + if (offX != null && offY != null && (offX.isWalkable() || offY.isWalkable())) { + RoomTile temp = this.findTile(openList, (short) (x - 1), (short) (y + 1)); + if (this.canWalkOn(temp, unit)) { + if (temp.state != RoomTileState.SIT || nextTile.getStackHeight() - node.getStackHeight() <= 2.0) { + temp.isDiagonally(true); + if (!adj.contains(temp)) + adj.add(temp); + } + } + } + } + if ((x < this.mapSizeX) && (y > 0)) { + RoomTile offX = this.findTile(openList, (short) (x + 1), y); + RoomTile offY = this.findTile(openList, x, (short) (y - 1)); + if (offX != null && offY != null && (offX.isWalkable() || offY.isWalkable())) { + RoomTile temp = this.findTile(openList, (short) (x + 1), (short) (y - 1)); + if (this.canWalkOn(temp, unit)) { + if (temp.state != RoomTileState.SIT || nextTile.getStackHeight() - node.getStackHeight() <= 2.0) { + temp.isDiagonally(true); + if (!adj.contains(temp)) + adj.add(temp); + } + } + } + } + } + return adj; + } + + private boolean canWalkOn(RoomTile tile, RoomUnit unit) { + return tile != null && (unit.canOverrideTile(tile) || (tile.state != RoomTileState.BLOCKED && tile.state != RoomTileState.INVALID)); + } + + public void moveDiagonally(boolean value) { + this.CANMOVEDIAGONALY = value; + } + + public RoomTile getTileInFront(RoomTile tile, int rotation) { + return this.getTileInFront(tile, rotation, 0); + } + + public RoomTile getTileInFront(RoomTile tile, int rotation, int offset) { + int offsetX = 0; + int offsetY = 0; + + rotation = rotation % 8; + switch (rotation) { + case 0: + offsetY--; + break; + case 1: + offsetX++; + offsetY--; + break; + case 2: + offsetX++; + break; + case 3: + offsetX++; + offsetY++; + break; + case 4: + offsetY++; + break; + case 5: + offsetX--; + offsetY++; + break; + case 6: + offsetX--; + break; + case 7: + offsetX--; + offsetY--; + break; + } + + short x = tile.x; + short y = tile.y; + + for (int i = 0; i <= offset; i++) { + x += offsetX; + y += offsetY; + } + + return this.getTile(x, y); + } + + public List getTilesInFront(RoomTile tile, int rotation, int amount) { + List tiles = new ArrayList<>(amount); + RoomTile previous = tile; + for (int i = 0; i < amount; i++) { + RoomTile t = this.getTileInFront(previous, rotation, i); + + if (t != null) { + tiles.add(t); + } else { + break; + } + } + + return tiles; + } + + public List getTilesAround(RoomTile tile) { + return getTilesAround(tile, 0); + } + + public List getTilesAround(RoomTile tile, int directionOffset) { + return getTilesAround(tile, directionOffset, true); + } + + public List getTilesAround(RoomTile tile, int directionOffset, boolean diagonal) { + List tiles = new ArrayList<>(diagonal ? 8 : 4); + + if (tile != null) { + for (int i = 0; i < 8; i += (diagonal ? 1 : 2)) { + RoomTile t = this.getTileInFront(tile, (i + directionOffset) % 8); + if (t != null) { + tiles.add(t); + } + } + } + + return tiles; + } + + public List getWalkableTilesAround(RoomTile tile) { + return getWalkableTilesAround(tile, 0); + } + + public List getWalkableTilesAround(RoomTile tile, int directionOffset) { + List availableTiles = new ArrayList<>(this.getTilesAround(tile, directionOffset)); + + List toRemove = new ArrayList<>(); + + for (RoomTile t : availableTiles) { + if (t == null || t.state != RoomTileState.OPEN || !t.isWalkable()) { + toRemove.add(t); + } + } + + for (RoomTile t : toRemove) { + availableTiles.remove(t); + } + + return availableTiles; + } + + public boolean fitsOnMap(RoomTile tile, int width, int length, int rotation) { + if (tile != null) { + if (rotation == 0 || rotation == 4) { + for (short i = tile.x; i <= (tile.x + (width - 1)); i++) { + for (short j = tile.y; j <= (tile.y + (length - 1)); j++) { + RoomTile t = this.getTile(i, j); + + if (t == null || t.state == RoomTileState.INVALID) { + return false; + } + } + } + } else if (rotation == 2 || rotation == 6) { + for (short i = tile.x; i <= (tile.x + (length - 1)); i++) { + for (short j = tile.y; j <= (tile.y + (width - 1)); j++) { + RoomTile t = this.getTile(i, j); + + if (t == null || t.state == RoomTileState.INVALID) { + return false; + } + } + } + } + } + + return true; + } + + public THashSet getTilesAt(RoomTile tile, int width, int length, int rotation) { + THashSet pointList = new THashSet<>(width * length, 0.1f); + + if (tile != null) { + if (rotation == 0 || rotation == 4) { + for (short i = tile.x; i <= (tile.x + (width - 1)); i++) { + for (short j = tile.y; j <= (tile.y + (length - 1)); j++) { + RoomTile t = this.getTile(i, j); + + if (t != null) { + pointList.add(t); + } + } + } + } else if (rotation == 2 || rotation == 6) { + for (short i = tile.x; i <= (tile.x + (length - 1)); i++) { + for (short j = tile.y; j <= (tile.y + (width - 1)); j++) { + RoomTile t = this.getTile(i, j); + + if (t != null) { + pointList.add(t); + } + } + } + } + } + + return pointList; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomManager.java new file mode 100644 index 0000000..972b001 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomManager.java @@ -0,0 +1,1574 @@ +package com.eu.habbo.habbohotel.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.core.RoomUserPetComposer; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.games.battlebanzai.BattleBanzaiGame; +import com.eu.habbo.habbohotel.games.football.FootballGame; +import com.eu.habbo.habbohotel.games.freeze.FreezeGame; +import com.eu.habbo.habbohotel.games.tag.BunnyrunGame; +import com.eu.habbo.habbohotel.games.tag.IceTagGame; +import com.eu.habbo.habbohotel.games.tag.RollerskateGame; +import com.eu.habbo.habbohotel.games.wired.WiredGame; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.items.interactions.InteractionWired; +import com.eu.habbo.habbohotel.messenger.MessengerBuddy; +import com.eu.habbo.habbohotel.navigation.NavigatorFilterComparator; +import com.eu.habbo.habbohotel.navigation.NavigatorFilterField; +import com.eu.habbo.habbohotel.navigation.NavigatorManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetData; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.polls.Poll; +import com.eu.habbo.habbohotel.polls.PollManager; +import com.eu.habbo.habbohotel.users.*; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.incoming.users.UserNuxEvent; +import com.eu.habbo.messages.outgoing.generic.alerts.GenericErrorMessagesComposer; +import com.eu.habbo.messages.outgoing.hotelview.HotelViewComposer; +import com.eu.habbo.messages.outgoing.polls.PollStartComposer; +import com.eu.habbo.messages.outgoing.polls.infobus.SimplePollAnswersComposer; +import com.eu.habbo.messages.outgoing.polls.infobus.SimplePollStartComposer; +import com.eu.habbo.messages.outgoing.rooms.*; +import com.eu.habbo.messages.outgoing.rooms.items.RoomFloorItemsComposer; +import com.eu.habbo.messages.outgoing.rooms.items.RoomWallItemsComposer; +import com.eu.habbo.messages.outgoing.rooms.pets.RoomPetComposer; +import com.eu.habbo.messages.outgoing.rooms.promotions.RoomPromotionMessageComposer; +import com.eu.habbo.messages.outgoing.rooms.users.*; +import com.eu.habbo.messages.outgoing.users.MutedWhisperComposer; +import com.eu.habbo.plugin.events.navigator.NavigatorRoomCreatedEvent; +import com.eu.habbo.plugin.events.rooms.RoomFloorItemsLoadEvent; +import com.eu.habbo.plugin.events.rooms.RoomUncachedEvent; +import com.eu.habbo.plugin.events.rooms.UserVoteRoomEvent; +import com.eu.habbo.plugin.events.users.HabboAddedToRoomEvent; +import com.eu.habbo.plugin.events.users.UserEnterRoomEvent; +import com.eu.habbo.plugin.events.users.UserExitRoomEvent; +import gnu.trove.iterator.TIntObjectIterator; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TIntProcedure; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; + +import java.sql.*; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +@Slf4j +public class RoomManager { + + private static final int page = 0; + //Configuration. Loaded from database & updated accordingly. + public static int MAXIMUM_ROOMS_USER = 25; + public static int MAXIMUM_ROOMS_HC = 35; + public static int HOME_ROOM_ID = 0; + public static boolean SHOW_PUBLIC_IN_POPULAR_TAB = false; + private final THashMap roomCategories; + private final List mapNames; + private final ConcurrentHashMap activeRooms; + private final ArrayList> gameTypes; + + public RoomManager() { + long millis = System.currentTimeMillis(); + this.roomCategories = new THashMap<>(); + this.mapNames = new ArrayList<>(); + this.activeRooms = new ConcurrentHashMap<>(); + this.loadRoomCategories(); + this.loadRoomModels(); + + this.gameTypes = new ArrayList<>(); + + registerGameType(BattleBanzaiGame.class); + registerGameType(FreezeGame.class); + registerGameType(WiredGame.class); + registerGameType(FootballGame.class); + registerGameType(BunnyrunGame.class); + registerGameType(IceTagGame.class); + registerGameType(RollerskateGame.class); + + log.info("Room Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)"); + } + + public void loadRoomModels() { + this.mapNames.clear(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM room_models")) { + while (set.next()) { + this.mapNames.add(set.getString("name")); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public CustomRoomLayout loadCustomLayout(Room room) { + CustomRoomLayout layout = null; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM room_models_custom WHERE id = ? LIMIT 1")) { + statement.setInt(1, room.getId()); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + layout = new CustomRoomLayout(set, room); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return layout; + } + + private void loadRoomCategories() { + this.roomCategories.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM navigator_flatcats")) { + while (set.next()) { + this.roomCategories.put(set.getInt("id"), new RoomCategory(set)); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void loadPublicRooms() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM rooms WHERE is_public = ? OR is_staff_picked = ? ORDER BY id DESC")) { + statement.setString(1, "1"); + statement.setString(2, "1"); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + Room room = new Room(set); + room.preventUncaching = true; + this.activeRooms.put(set.getInt("id"), room); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public THashMap> findRooms(NavigatorFilterField filterField, String value, int category, boolean showInvisible) { + THashMap> rooms = new THashMap<>(); + String query = filterField.databaseQuery + " AND rooms.state NOT LIKE " + (showInvisible ? "''" : "'invisible'") + (category >= 0 ? "AND rooms.category = '" + category + "'" : "") + " ORDER BY rooms.users, rooms.id DESC LIMIT " + (page * NavigatorManager.MAXIMUM_RESULTS_PER_PAGE) + "" + ((page * NavigatorManager.MAXIMUM_RESULTS_PER_PAGE) + NavigatorManager.MAXIMUM_RESULTS_PER_PAGE); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement(query)) { + statement.setString(1, (filterField.comparator == NavigatorFilterComparator.EQUALS ? value : "%" + value + "%")); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + Room room = this.activeRooms.get(set.getInt("id")); + + if (room == null) { + room = new Room(set); + this.activeRooms.put(set.getInt("id"), room); + } + + if (!rooms.containsKey(set.getInt("category"))) { + rooms.put(set.getInt("category"), new ArrayList<>()); + } + + rooms.get(set.getInt("category")).add(room); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return rooms; + } + + public RoomCategory getCategory(int id) { + for (RoomCategory category : this.roomCategories.values()) { + if (category.getId() == id) + return category; + } + + return null; + } + + public RoomCategory getCategory(String name) { + for (RoomCategory category : this.roomCategories.values()) { + if (category.getCaption().equalsIgnoreCase(name)) { + return category; + } + } + + return null; + } + + public RoomCategory getCategoryBySafeCaption(String safeCaption) { + for (RoomCategory category : this.roomCategories.values()) { + if (category.getCaptionSave().equalsIgnoreCase(safeCaption)) { + return category; + } + } + + return null; + } + + public List roomCategoriesForHabbo(Habbo habbo) { + List categories = new ArrayList<>(); + for (RoomCategory category : this.roomCategories.values()) { + if (category.getMinRank() <= habbo.getHabboInfo().getRank().getId()) + categories.add(category); + } + + Collections.sort(categories); + + return categories; + } + + public boolean hasCategory(int categoryId, Habbo habbo) { + for (RoomCategory category : this.roomCategories.values()) { + if (category.getId() == categoryId) { + if (category.getMinRank() <= habbo.getHabboInfo().getRank().getId()) { + return true; + } + } + } + + return false; + } + + public THashMap getRoomCategories() { + return this.roomCategories; + } + + public List getRoomsByScore() { + List rooms = new ArrayList<>(this.activeRooms.values()); + rooms.sort(Room.SORT_SCORE); + + return rooms; + } + + public List getActiveRooms(int categoryId) { + List rooms = new ArrayList<>(); + for (Room room : this.activeRooms.values()) { + if (categoryId == room.getCategory() || categoryId == -1) + rooms.add(room); + } + Collections.sort(rooms); + return rooms; + } + + //TODO Move to HabboInfo class. + public List getRoomsForHabbo(Habbo habbo) { + List rooms = new ArrayList<>(); + for (Room room : this.activeRooms.values()) { + if (room.getOwnerId() == habbo.getHabboInfo().getId()) + rooms.add(room); + } + rooms.sort(Room.SORT_ID); + return rooms; + } + + public List getRoomsForHabbo(String username) { + Habbo h = Emulator.getGameEnvironment().getHabboManager().getHabbo(username); + if (h != null) { + return this.getRoomsForHabbo(h); + } + + List rooms = new ArrayList<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM rooms WHERE owner_name = ? ORDER BY id DESC LIMIT 25")) { + statement.setString(1, username); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + rooms.add(this.loadRoom(set.getInt("id"))); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return rooms; + } + + public Room loadRoom(int id) { + return loadRoom(id, false); + } + + public Room loadRoom(int id, boolean loadData) { + Room room = null; + + if (this.activeRooms.containsKey(id)) { + room = this.activeRooms.get(id); + + if (loadData) { + if (room.isPreLoaded() && !room.isLoaded()) { + room.loadData(); + } + } + + return room; + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM rooms WHERE id = ? LIMIT 1")) { + statement.setInt(1, id); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + room = new Room(set); + if (loadData) { + room.loadData(); + } + } + } + + if (room != null) { + this.activeRooms.put(room.getId(), room); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return room; + } + + + public Room createRoom(int ownerId, String ownerName, String name, String description, String modelName, int usersMax, int categoryId, int tradeType) { + Room room = null; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO rooms (owner_id, owner_name, name, description, model, users_max, category, trade_mode) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, ownerId); + statement.setString(2, ownerName); + statement.setString(3, name); + statement.setString(4, description); + statement.setString(5, modelName); + statement.setInt(6, usersMax); + statement.setInt(7, categoryId); + statement.setInt(8, tradeType); + statement.execute(); + try (ResultSet set = statement.getGeneratedKeys()) { + if (set.next()) + room = this.loadRoom(set.getInt(1)); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return room; + } + + + public Room createRoomForHabbo(Habbo habbo, String name, String description, String modelName, int usersMax, int categoryId, int tradeType) { + Room room = this.createRoom(habbo.getHabboInfo().getId(), habbo.getHabboInfo().getUsername(), name, description, modelName, usersMax, categoryId, tradeType); + + Emulator.getPluginManager().fireEvent(new NavigatorRoomCreatedEvent(habbo, room)); + + return room; + } + + public void loadRoomsForHabbo(Habbo habbo) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM rooms WHERE owner_id = ?")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + if (!this.activeRooms.containsKey(set.getInt("id"))) + this.activeRooms.put(set.getInt("id"), new Room(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void unloadRoomsForHabbo(Habbo habbo) { + List roomsToDispose = new ArrayList<>(); + for (Room room : this.activeRooms.values()) { + if (!room.isPublicRoom() && !room.isStaffPromotedRoom() && room.getOwnerId() == habbo.getHabboInfo().getId() && room.getUserCount() == 0 && (this.roomCategories.get(room.getCategory()) == null || !this.roomCategories.get(room.getCategory()).isPublic())) { + roomsToDispose.add(room); + } + } + + for (Room room : roomsToDispose) { + if (Emulator.getPluginManager().fireEvent(new RoomUncachedEvent(room)).isCancelled()) + continue; + + room.dispose(); + this.activeRooms.remove(room.getId()); + } + } + + public void clearInactiveRooms() { + THashSet roomsToDispose = new THashSet<>(); + for (Room room : this.activeRooms.values()) { + if (!room.isPublicRoom() && !room.isStaffPromotedRoom() && !Emulator.getGameServer().getGameClientManager().containsHabbo(room.getOwnerId()) && room.isPreLoaded()) { + roomsToDispose.add(room); + } + } + + for (Room room : roomsToDispose) { + room.dispose(); + if (room.getUserCount() == 0) + this.activeRooms.remove(room.getId()); + } + } + + public boolean layoutExists(String name) { + return this.mapNames.contains(name); + } + + public RoomLayout loadLayout(String name, Room room) { + RoomLayout layout = null; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM room_models WHERE name LIKE ? LIMIT 1")) { + statement.setString(1, name); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + layout = new RoomLayout(set, room); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return layout; + } + + public void unloadRoom(Room room) { + room.dispose(); + } + + public void uncacheRoom(Room room) { + this.activeRooms.remove(room.getId()); + } + + public void voteForRoom(Habbo habbo, Room room) { + if (habbo.getHabboInfo().getCurrentRoom() != null && room != null && habbo.getHabboInfo().getCurrentRoom() == room) { + if (this.hasVotedForRoom(habbo, room)) + return; + + UserVoteRoomEvent event = new UserVoteRoomEvent(room, habbo); + if (Emulator.getPluginManager().fireEvent(event).isCancelled()) return; + + room.setScore(room.getScore() + 1); + room.setNeedsUpdate(true); + habbo.getHabboStats().votedRooms.push(room.getId()); + for (Habbo h : room.getHabbos()) { + h.getClient().sendResponse(new RoomScoreComposer(room.getScore(), !this.hasVotedForRoom(h, room))); + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO room_votes VALUES (?, ?)")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + statement.setInt(2, room.getId()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + boolean hasVotedForRoom(Habbo habbo, Room room) { + if (room.getOwnerId() == habbo.getHabboInfo().getId()) + return true; + + for (int i : habbo.getHabboStats().votedRooms.toArray()) { + if (i == room.getId()) + return true; + } + + return false; + } + + public Room getRoom(int roomId) { + return this.activeRooms.get(roomId); + } + + public ArrayList getActiveRooms() { + return new ArrayList<>(this.activeRooms.values()); + } + + public int loadedRoomsCount() { + return this.activeRooms.size(); + } + + public void enterRoom(Habbo habbo, int roomId, String password) { + this.enterRoom(habbo, roomId, password, false, null); + } + + public void enterRoom(Habbo habbo, int roomId, String password, boolean overrideChecks) { + this.enterRoom(habbo, roomId, password, overrideChecks, null); + } + + public void enterRoom(Habbo habbo, int roomId, String password, boolean overrideChecks, RoomTile doorLocation) { + Room room = this.loadRoom(roomId, true); + + if (room == null) + return; + + if (habbo.getHabboInfo().getLoadingRoom() != 0 && room.getId() != habbo.getHabboInfo().getLoadingRoom()) { + habbo.getClient().sendResponse(new HotelViewComposer()); + habbo.getHabboInfo().setLoadingRoom(0); + return; + } + + if (Emulator.getPluginManager().fireEvent(new UserEnterRoomEvent(habbo, room)).isCancelled()) { + if (habbo.getHabboInfo().getCurrentRoom() == null) { + habbo.getClient().sendResponse(new HotelViewComposer()); + habbo.getHabboInfo().setLoadingRoom(0); + return; + } + } + + if (room.isBanned(habbo) && !habbo.hasPermission(Permission.ACC_ANYROOMOWNER) && !habbo.hasPermission(Permission.ACC_ENTERANYROOM)) { + habbo.getClient().sendResponse(new RoomEnterErrorComposer(RoomEnterErrorComposer.ROOM_ERROR_BANNED)); + return; + } + + if (habbo.getHabboInfo().getRoomQueueId() != roomId) { + Room queRoom = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId); + + if (queRoom != null) { + queRoom.removeFromQueue(habbo); + } + } + + if (overrideChecks || + room.isOwner(habbo) || + room.getState() == RoomState.OPEN || + habbo.hasPermission(Permission.ACC_ANYROOMOWNER) || + habbo.hasPermission(Permission.ACC_ENTERANYROOM) || + room.hasRights(habbo) || + (room.getState().equals(RoomState.INVISIBLE) && room.hasRights(habbo)) || + (room.hasGuild() && room.getGuildRightLevel(habbo).isGreaterThan(RoomRightLevels.GUILD_RIGHTS))) { + this.openRoom(habbo, room, doorLocation); + } else if (room.getState() == RoomState.LOCKED) { + boolean rightsFound = false; + + synchronized (room.roomUnitLock) { + for (Habbo current : room.getHabbos()) { + if (room.hasRights(current) || current.getHabboInfo().getId() == room.getOwnerId() || (room.hasGuild() && room.getGuildRightLevel(current).isEqualOrGreaterThan(RoomRightLevels.GUILD_RIGHTS))) { + current.getClient().sendResponse(new DoorbellAddUserComposer(habbo.getHabboInfo().getUsername())); + rightsFound = true; + } + } + } + + if (!rightsFound) { + habbo.getClient().sendResponse(new RoomAccessDeniedComposer("")); + habbo.getClient().sendResponse(new HotelViewComposer()); + habbo.getHabboInfo().setLoadingRoom(0); + return; + } + + habbo.getHabboInfo().setRoomQueueId(roomId); + habbo.getClient().sendResponse(new DoorbellAddUserComposer("")); + room.addToQueue(habbo); + } else if (room.getState() == RoomState.PASSWORD) { + if (room.getPassword().equalsIgnoreCase(password)) + this.openRoom(habbo, room, doorLocation); + else { + habbo.getClient().sendResponse(new GenericErrorMessagesComposer(GenericErrorMessagesComposer.WRONG_PASSWORD_USED)); + habbo.getClient().sendResponse(new HotelViewComposer()); + habbo.getHabboInfo().setLoadingRoom(0); + } + } else { + habbo.getClient().sendResponse(new HotelViewComposer()); + habbo.getHabboInfo().setLoadingRoom(0); + } + } + + void openRoom(Habbo habbo, Room room, RoomTile doorLocation) { + if (room == null || room.getLayout() == null) + return; + + if (Emulator.getConfig().getBoolean("hotel.room.enter.logs")) { + this.logEnter(habbo, room); + } + + if (habbo.getHabboInfo().getRoomQueueId() > 0) { + Room r = Emulator.getGameEnvironment().getRoomManager().getRoom(habbo.getHabboInfo().getRoomQueueId()); + + if (r != null) { + r.removeFromQueue(habbo); + } + } + + habbo.getHabboInfo().setRoomQueueId(0); + habbo.getClient().sendResponse(new HideDoorbellComposer("")); + + if (habbo.getRoomUnit() != null) { + RoomUnit existingRoom = habbo.getRoomUnit(); + if (existingRoom.getRoom() != null) { + if (existingRoom.getCurrentLocation() != null) + existingRoom.getCurrentLocation().removeUnit(existingRoom); + existingRoom.getRoom().sendComposer(new RoomUserRemoveComposer(existingRoom).compose()); + } + habbo.getRoomUnit().setRoom(null); + } + + habbo.setRoomUnit(new RoomUnit()); + + habbo.getRoomUnit().clearStatus(); + if (habbo.getRoomUnit().getCurrentLocation() == null) { + habbo.getRoomUnit().setLocation(doorLocation != null ? doorLocation : room.getLayout().getDoorTile()); + if (habbo.getRoomUnit().getCurrentLocation() != null) habbo.getRoomUnit().setZ(habbo.getRoomUnit().getCurrentLocation().getStackHeight()); + + if (doorLocation == null) { + habbo.getRoomUnit().setBodyRotation(RoomUserRotation.values()[room.getLayout().getDoorDirection()]); + habbo.getRoomUnit().setHeadRotation(RoomUserRotation.values()[room.getLayout().getDoorDirection()]); + } else { + habbo.getRoomUnit().setCanLeaveRoomByDoor(false); + habbo.getRoomUnit().isTeleporting = true; + HabboItem topItem = room.getTopItemAt(doorLocation.x, doorLocation.y); + if (topItem != null) { + habbo.getRoomUnit().setRotation(RoomUserRotation.values()[topItem.getRotation()]); + } + } + } + + habbo.getRoomUnit().setRoomUnitType(RoomUnitType.USER); + if (room.isBanned(habbo)) { + habbo.getClient().sendResponse(new RoomEnterErrorComposer(RoomEnterErrorComposer.ROOM_ERROR_BANNED)); + return; + } + + if (room.getUserCountWithoutInvisibleHabbos() >= room.getUsersMax() && !habbo.hasPermission(Permission.ACC_FULLROOMS) && !room.hasRights(habbo)) { + habbo.getClient().sendResponse(new RoomEnterErrorComposer(RoomEnterErrorComposer.ROOM_ERROR_GUESTROOM_FULL)); + return; + } + + habbo.getRoomUnit().clearStatus(); + habbo.getRoomUnit().cmdTeleport = false; + + habbo.getClient().sendResponse(new RoomOpenComposer()); + + habbo.getRoomUnit().setInRoom(true); + if (habbo.getHabboInfo().getCurrentRoom() != room && habbo.getHabboInfo().getCurrentRoom() != null) { + habbo.getHabboInfo().getCurrentRoom().removeHabbo(habbo, true); + } else if (!habbo.getHabboStats().blockFollowing && habbo.getHabboInfo().getCurrentRoom() == null) { + habbo.getMessenger().connectionChanged(habbo, true, true); + } + + if (habbo.getHabboInfo().getLoadingRoom() != 0) { + Room oldRoom = Emulator.getGameEnvironment().getRoomManager().getRoom(habbo.getHabboInfo().getLoadingRoom()); + if (oldRoom != null) { + oldRoom.removeFromQueue(habbo); + } + } + + habbo.getHabboInfo().setLoadingRoom(room.getId()); + + habbo.getClient().sendResponse(new RoomModelComposer(room)); + + if (!room.getWallPaint().equals("0.0")) + habbo.getClient().sendResponse(new RoomPaintComposer("wallpaper", room.getWallPaint())); + + if (!room.getFloorPaint().equals("0.0")) + habbo.getClient().sendResponse(new RoomPaintComposer("floor", room.getFloorPaint())); + + habbo.getClient().sendResponse(new RoomPaintComposer("landscape", room.getBackgroundPaint())); + + room.refreshRightsForHabbo(habbo); + + habbo.getClient().sendResponse(new RoomScoreComposer(room.getScore(), !this.hasVotedForRoom(habbo, room))); + + habbo.getRoomUnit().setFastWalk(habbo.getRoomUnit().isFastWalk() && habbo.hasPermission("cmd_fastwalk", room.hasRights(habbo))); + + if (room.isPromoted()) { + habbo.getClient().sendResponse(new RoomPromotionMessageComposer(room, room.getPromotion())); + } else { + habbo.getClient().sendResponse(new RoomPromotionMessageComposer(null, null)); + } + + if (room.getOwnerId() != habbo.getHabboInfo().getId() && !habbo.getHabboStats().visitedRoom(room.getId())) { + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("RoomEntry")); + } + } + + public void enterRoom(final Habbo habbo, final Room room) { + if (habbo.getHabboInfo().getLoadingRoom() != room.getId()) { + if (habbo.getHabboInfo().getLoadingRoom() != 0) { + habbo.getClient().sendResponse(new HotelViewComposer()); + } + return; + } + + habbo.getRoomUnit().removeStatus(RoomUnitStatus.FLAT_CONTROL); + habbo.getHabboInfo().setLoadingRoom(0); + habbo.getHabboInfo().setCurrentRoom(room); + habbo.getRoomUnit().setPathFinderRoom(room); + habbo.getRoomUnit().setHandItem(0); + + habbo.getRoomUnit().setRightsLevel(RoomRightLevels.NONE); + room.refreshRightsForHabbo(habbo); + if (habbo.getRoomUnit().isKicked && !habbo.getRoomUnit().canWalk()) { + habbo.getRoomUnit().setCanWalk(true); + } + habbo.getRoomUnit().isKicked = false; + + if (habbo.getRoomUnit().getCurrentLocation() == null && !habbo.getRoomUnit().isTeleporting) { + RoomTile doorTile = room.getLayout().getTile(room.getLayout().getDoorX(), room.getLayout().getDoorY()); + + if (doorTile != null) { + habbo.getRoomUnit().setLocation(doorTile); + habbo.getRoomUnit().setZ(doorTile.getStackHeight()); + } + + habbo.getRoomUnit().setBodyRotation(RoomUserRotation.values()[room.getLayout().getDoorDirection()]); + habbo.getRoomUnit().setHeadRotation(RoomUserRotation.values()[room.getLayout().getDoorDirection()]); + } + + habbo.getRoomUnit().setPathFinderRoom(room); + habbo.getRoomUnit().resetIdleTimer(); + + room.addHabbo(habbo); + + List habbos = new ArrayList<>(); + if (!room.getCurrentHabbos().isEmpty()) { + + Collection habbosToSendEnter = room.getCurrentHabbos().values(); + Collection visibleHabbos = room.getHabbos(); + + if (Emulator.getPluginManager().isRegistered(HabboAddedToRoomEvent.class, false)) { + HabboAddedToRoomEvent event = Emulator.getPluginManager().fireEvent(new HabboAddedToRoomEvent(habbo, room, habbosToSendEnter, visibleHabbos)); + habbosToSendEnter = event.habbosToSendEnter; + visibleHabbos = event.visibleHabbos; + } + + // + if (!habbo.getHabboInfo().isInvisibleInRooms()) { + for (Habbo habboToSendEnter : habbosToSendEnter) { + GameClient client = habboToSendEnter.getClient(); + if (client != null) { + client.sendResponse(new RoomUsersComposer(habbo).compose()); + client.sendResponse(new RoomUserStatusComposer(habbo.getRoomUnit()).compose()); + } + } + } + + for (Habbo h : visibleHabbos) { + if (!h.getHabboInfo().isInvisibleInRooms()) { + habbos.add(h); + } + } + + synchronized (room.roomUnitLock) { + habbo.getClient().sendResponse(new RoomUsersComposer(habbos)); + habbo.getClient().sendResponse(new RoomUserStatusComposer(habbos)); + } + + if (habbo.getHabboStats().guild != 0) { + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(habbo.getHabboStats().guild); + + if (guild != null) { + room.sendComposer(new RoomUsersAddGuildBadgeComposer(guild).compose()); + } + } + + int effect = habbo.getInventory().getEffectsComponent().activatedEffect; + room.giveEffect(habbo.getRoomUnit(), effect, -1); + } + + + habbo.getClient().sendResponse(new RoomUsersComposer(room.getCurrentBots().valueCollection(), true)); + if (!room.getCurrentBots().isEmpty()) { + TIntObjectIterator botIterator = room.getCurrentBots().iterator(); + for (int i = room.getCurrentBots().size(); i-- > 0; ) { + try { + botIterator.advance(); + } catch (NoSuchElementException e) { + break; + } + Bot bot = botIterator.value(); + if (!bot.getRoomUnit().getDanceType().equals(DanceType.NONE)) { + habbo.getClient().sendResponse(new RoomUserDanceComposer(bot.getRoomUnit())); + } + + habbo.getClient().sendResponse(new RoomUserStatusComposer(bot.getRoomUnit(), bot.getRoomUnit().getZ())); + } + } + + habbo.getClient().sendResponse(new RoomPaneComposer(room, room.isOwner(habbo))); + + habbo.getClient().sendResponse(new RoomThicknessComposer(room)); + + habbo.getClient().sendResponse(new RoomDataComposer(room, habbo.getClient().getHabbo(), false, true)); + + habbo.getClient().sendResponse(new RoomWallItemsComposer(room)); + { + final THashSet floorItems = new THashSet<>(); + + THashSet allFloorItems = new THashSet<>(room.getFloorItems()); + + if (Emulator.getPluginManager().isRegistered(RoomFloorItemsLoadEvent.class, true)) { + RoomFloorItemsLoadEvent roomFloorItemsLoadEvent = Emulator.getPluginManager().fireEvent(new RoomFloorItemsLoadEvent(habbo, allFloorItems)); + if (roomFloorItemsLoadEvent.hasChangedFloorItems()) { + allFloorItems = roomFloorItemsLoadEvent.getFloorItems(); + } + } + + allFloorItems.forEach(new TObjectProcedure() { + @Override + public boolean execute(HabboItem object) { + if (room.isHideWired() && object instanceof InteractionWired) + return true; + + floorItems.add(object); + if (floorItems.size() == 250) { + habbo.getClient().sendResponse(new RoomFloorItemsComposer(room.getFurniOwnerNames(), floorItems)); + floorItems.clear(); + } + + return true; + } + }); + + habbo.getClient().sendResponse(new RoomFloorItemsComposer(room.getFurniOwnerNames(), floorItems)); + floorItems.clear(); + } + + if (!room.getCurrentPets().isEmpty()) { + habbo.getClient().sendResponse(new RoomPetComposer(room.getCurrentPets())); + for (Pet pet : room.getCurrentPets().valueCollection()) { + habbo.getClient().sendResponse(new RoomUserStatusComposer(pet.getRoomUnit())); + } + } + + if (!habbo.getHabboStats().allowTalk()) { + habbo.getHabboStats().mutedBubbleTracker = true; + int remainingMuteTime = habbo.getHabboStats().remainingMuteTime(); + habbo.getClient().sendResponse(new FloodCounterComposer(remainingMuteTime)); + habbo.getClient().sendResponse(new MutedWhisperComposer(remainingMuteTime)); + room.sendComposer(new RoomUserIgnoredComposer(habbo, RoomUserIgnoredComposer.MUTED).compose()); + } else if (habbo.getHabboStats().mutedBubbleTracker) { + habbo.getHabboStats().mutedBubbleTracker = false; + } + + THashMap guildBadges = new THashMap<>(); + for (Habbo roomHabbo : habbos) { + { + if (roomHabbo.getRoomUnit().getDanceType().getType() > 0) { + habbo.getClient().sendResponse(new RoomUserDanceComposer(roomHabbo.getRoomUnit())); + } + + if (roomHabbo.getRoomUnit().getHandItem() > 0) { + habbo.getClient().sendResponse(new RoomUserHandItemComposer(roomHabbo.getRoomUnit())); + } + + if (roomHabbo.getRoomUnit().getEffectId() > 0) { + habbo.getClient().sendResponse(new RoomUserEffectComposer(roomHabbo.getRoomUnit())); + } + + if (roomHabbo.getRoomUnit().isIdle()) { + habbo.getClient().sendResponse(new RoomUnitIdleComposer(roomHabbo.getRoomUnit())); + } + + if (roomHabbo.getHabboStats().userIgnored(habbo.getHabboInfo().getId())) { + roomHabbo.getClient().sendResponse(new RoomUserIgnoredComposer(habbo, RoomUserIgnoredComposer.IGNORED)); + } + + if (!roomHabbo.getHabboStats().allowTalk()) { + habbo.getClient().sendResponse(new RoomUserIgnoredComposer(roomHabbo, RoomUserIgnoredComposer.MUTED)); + } else if (habbo.getHabboStats().userIgnored(roomHabbo.getHabboInfo().getId())) { + habbo.getClient().sendResponse(new RoomUserIgnoredComposer(roomHabbo, RoomUserIgnoredComposer.IGNORED)); + } + + if (roomHabbo.getHabboStats().guild != 0 && !guildBadges.containsKey(roomHabbo.getHabboStats().guild)) { + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(roomHabbo.getHabboStats().guild); + + if (guild != null) { + guildBadges.put(roomHabbo.getHabboStats().guild, guild.getBadge()); + } + } + + if (roomHabbo.getRoomUnit().getRoomUnitType().equals(RoomUnitType.PET)) { + try { + habbo.getClient().sendResponse(new RoomUserRemoveComposer(roomHabbo.getRoomUnit())); + habbo.getClient().sendResponse(new RoomUserPetComposer(((PetData) roomHabbo.getHabboStats().cache.get("pet_type")).getType(), (Integer) roomHabbo.getHabboStats().cache.get("pet_race"), (String) roomHabbo.getHabboStats().cache.get("pet_color"), roomHabbo)); + } catch (Exception e) { + + } + } + } + } + + habbo.getClient().sendResponse(new RoomUsersGuildBadgesComposer(guildBadges)); + + if (room.hasRights(habbo) || (room.hasGuild() && room.getGuildRightLevel(habbo).isEqualOrGreaterThan(RoomRightLevels.GUILD_RIGHTS))) { + if (!room.getHabboQueue().isEmpty()) { + for (Habbo waiting : room.getHabboQueue().valueCollection()) { + habbo.getClient().sendResponse(new DoorbellAddUserComposer(waiting.getHabboInfo().getUsername())); + } + } + } + + if (room.getPollId() > 0) { + if (!PollManager.donePoll(habbo.getClient().getHabbo(), room.getPollId())) { + Poll poll = Emulator.getGameEnvironment().getPollManager().getPoll(room.getPollId()); + + if (poll != null) { + habbo.getClient().sendResponse(new PollStartComposer(poll)); + } + } + } + + if (room.hasActiveWordQuiz()) { + habbo.getClient().sendResponse(new SimplePollStartComposer((Emulator.getIntUnixTimestamp() - room.wordQuizEnd) * 1000, room.wordQuiz)); + + if (room.hasVotedInWordQuiz(habbo)) { + habbo.getClient().sendResponse(new SimplePollAnswersComposer(room.noVotes, room.yesVotes)); + } + } + + WiredHandler.handle(WiredTriggerType.ENTER_ROOM, habbo.getRoomUnit(), room, null); + room.habboEntered(habbo); + + if (!habbo.getHabboStats().nux && (room.isOwner(habbo) || room.isPublicRoom())) { + UserNuxEvent.handle(habbo); + } + } + + void logEnter(Habbo habbo, Room room) { + habbo.getHabboStats().roomEnterTimestamp = Emulator.getIntUnixTimestamp(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO room_enter_log (room_id, user_id, timestamp) VALUES(?, ?, ?)")) { + statement.setInt(1, room.getId()); + statement.setInt(2, habbo.getHabboInfo().getId()); + statement.setInt(3, (int) (habbo.getHabboStats().roomEnterTimestamp)); + statement.execute(); + + if (!habbo.getHabboStats().visitedRoom(room.getId())) + habbo.getHabboStats().addVisitRoom(room.getId()); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void leaveRoom(Habbo habbo, Room room) { + this.leaveRoom(habbo, room, true); + } + + public void leaveRoom(Habbo habbo, Room room, boolean redirectToHotelView) { + if (habbo.getHabboInfo().getCurrentRoom() != null && habbo.getHabboInfo().getCurrentRoom() == room) { + habbo.getRoomUnit().setPathFinderRoom(null); + + this.logExit(habbo); + room.removeHabbo(habbo, true); + + if (redirectToHotelView) { + habbo.getClient().sendResponse(new HotelViewComposer()); + } + habbo.getHabboInfo().setCurrentRoom(null); + habbo.getRoomUnit().isKicked = false; + + if (room.getOwnerId() != habbo.getHabboInfo().getId()) { + AchievementManager.progressAchievement(room.getOwnerId(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("RoomDecoHosting"), (int) Math.floor((Emulator.getIntUnixTimestamp() - habbo.getHabboStats().roomEnterTimestamp) / 60000)); + } + + habbo.getMessenger().connectionChanged(habbo, habbo.isOnline(), false); + } + } + + public void logExit(Habbo habbo) { + Emulator.getPluginManager().fireEvent(new UserExitRoomEvent(habbo, UserExitRoomEvent.UserExitRoomReason.DOOR)); + if (habbo.getRoomUnit().getCacheable().containsKey("control")) { + Habbo control = (Habbo) habbo.getRoomUnit().getCacheable().remove("control"); + control.getRoomUnit().getCacheable().remove("controller"); + } + + if (habbo.getHabboInfo().getRiding() != null) { + if (habbo.getHabboInfo().getRiding().getRoomUnit() != null) { + habbo.getHabboInfo().getRiding().getRoomUnit().setGoalLocation(habbo.getHabboInfo().getRiding().getRoomUnit().getCurrentLocation()); + } + habbo.getHabboInfo().getRiding().setTask(PetTasks.FREE); + habbo.getHabboInfo().getRiding().setRider(null); + habbo.getHabboInfo().setRiding(null); + } + + Room room = habbo.getHabboInfo().getCurrentRoom(); + if (room != null) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE room_enter_log SET exit_timestamp = ? WHERE user_id = ? AND room_id = ? ORDER BY timestamp DESC LIMIT 1")) { + statement.setInt(1, Emulator.getIntUnixTimestamp()); + statement.setInt(2, habbo.getHabboInfo().getId()); + statement.setInt(3, room.getId()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public Set getTags() { + Map tagCount = new HashMap<>(); + + for (Room room : this.activeRooms.values()) { + for (String s : room.getTags().split(";")) { + int i = 0; + if (tagCount.get(s) != null) + i++; + + tagCount.put(s, i++); + } + } + return new TreeMap<>(tagCount).keySet(); + } + + public ArrayList getPublicRooms() { + ArrayList rooms = new ArrayList<>(); + + for (Room room : this.activeRooms.values()) { + if (room.isPublicRoom()) { + rooms.add(room); + } + } + rooms.sort(Room.SORT_ID); + return rooms; + } + + public ArrayList getPopularRooms(int count) { + ArrayList rooms = new ArrayList<>(); + + for (Room room : this.activeRooms.values()) { + if (room.getUserCountWithoutInvisibleHabbos() > 0) { + if (!room.isPublicRoom() || RoomManager.SHOW_PUBLIC_IN_POPULAR_TAB) rooms.add(room); + } + } + + if (rooms.isEmpty()) { + return rooms; + } + + Collections.sort(rooms); + + return new ArrayList<>(rooms.subList(0, (rooms.size() < count ? rooms.size() : count))); + } + + public ArrayList getPopularRooms(int count, int category) { + ArrayList rooms = new ArrayList<>(); + + for (Room room : this.activeRooms.values()) { + if (!room.isPublicRoom() && room.getCategory() == category) { + rooms.add(room); + } + } + + if (rooms.isEmpty()) { + return rooms; + } + + Collections.sort(rooms); + + return new ArrayList<>(rooms.subList(0, (rooms.size() < count ? rooms.size() : count))); + } + + public Map> getPopularRoomsByCategory(int count) { + Map> rooms = new HashMap<>(); + + for (Room room : this.activeRooms.values()) { + if (!room.isPublicRoom() && room.getUserCount() > 0) { /* Changed do not show rooms that are empty */ + if (!rooms.containsKey(room.getCategory())) { + rooms.put(room.getCategory(), new ArrayList<>()); + } + + rooms.get(room.getCategory()).add(room); + } + } + + Map> result = new HashMap<>(); + + for (Map.Entry> set : rooms.entrySet()) { + if (set.getValue().isEmpty()) + continue; + + Collections.sort(set.getValue()); + + result.put(set.getKey(), new ArrayList<>(set.getValue().subList(0, (set.getValue().size() < count ? set.getValue().size() : count)))); + } + + return result; + } + + public ArrayList getRoomsWithName(String name) { + ArrayList rooms = new ArrayList<>(); + + for (Room room : this.activeRooms.values()) { + if (room.getName().toLowerCase().contains(name.toLowerCase())) { + rooms.add(room); + } + } + + if (rooms.size() < 25) { + rooms.addAll(this.getOfflineRoomsWithName(name)); + } + + Collections.sort(rooms); + + return rooms; + } + + private ArrayList getOfflineRoomsWithName(String name) { + ArrayList rooms = new ArrayList<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.username AS owner_name, rooms.* FROM rooms INNER JOIN users ON owner_id = users.id WHERE name LIKE ? ORDER BY id DESC LIMIT 25")) { + statement.setString(1, "%" + name + "%"); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + if (this.activeRooms.containsKey(set.getInt("id"))) + continue; + + Room r = new Room(set); + rooms.add(r); + this.activeRooms.put(r.getId(), r); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return rooms; + } + + public ArrayList getRoomsWithTag(String tag) { + ArrayList rooms = new ArrayList<>(); + + for (Room room : this.activeRooms.values()) { + for (String s : room.getTags().split(";")) { + if (s.toLowerCase().equals(tag.toLowerCase())) { + rooms.add(room); + break; + } + } + } + + Collections.sort(rooms); + + return rooms; + } + + public ArrayList getGroupRoomsWithName(String name) { + ArrayList rooms = new ArrayList<>(); + + for (Room room : this.activeRooms.values()) { + if (room.getGuildId() == 0) + continue; + + if (room.getName().toLowerCase().contains(name.toLowerCase())) + rooms.add(room); + } + + if (rooms.size() < 25) { + rooms.addAll(this.getOfflineGroupRoomsWithName(name)); + } + + Collections.sort(rooms); + + return rooms; + } + + private ArrayList getOfflineGroupRoomsWithName(String name) { + ArrayList rooms = new ArrayList<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.username AS owner_name, rooms.* FROM rooms INNER JOIN users ON rooms.owner_id = users.id WHERE name LIKE ? AND guild_id != 0 ORDER BY id DESC LIMIT 25")) { + statement.setString(1, "%" + name + "%"); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + if (this.activeRooms.containsKey(set.getInt("id"))) + continue; + + Room r = new Room(set); + rooms.add(r); + + this.activeRooms.put(r.getId(), r); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return rooms; + } + + public ArrayList getRoomsFriendsNow(Habbo habbo) { + ArrayList rooms = new ArrayList<>(); + + for (MessengerBuddy buddy : habbo.getMessenger().getFriends().values()) { + if (buddy.getOnline() == 0) + continue; + + Habbo friend = Emulator.getGameEnvironment().getHabboManager().getHabbo(buddy.getId()); + if (friend == null || friend.getHabboInfo().getCurrentRoom() == null) + continue; + + rooms.add(friend.getHabboInfo().getCurrentRoom()); + } + + Collections.sort(rooms); + + return rooms; + } + + public ArrayList getRoomsFriendsOwn(Habbo habbo) { + ArrayList rooms = new ArrayList<>(); + + for (MessengerBuddy buddy : habbo.getMessenger().getFriends().values()) { + if (buddy.getOnline() == 0) + continue; + + Habbo friend = Emulator.getGameEnvironment().getHabboManager().getHabbo(buddy.getId()); + + if (friend == null) + continue; + + rooms.addAll(this.getRoomsForHabbo(friend)); + } + + Collections.sort(rooms); + + return rooms; + } + + public ArrayList getRoomsVisited(Habbo habbo, boolean includeSelf, int limit) { + ArrayList rooms = new ArrayList<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT rooms.* FROM room_enter_log INNER JOIN rooms ON room_enter_log.room_id = rooms.id WHERE user_id = ? AND timestamp >= ? AND rooms.owner_id != ? GROUP BY rooms.id ORDER BY timestamp DESC LIMIT " + limit)) { + statement.setInt(1, habbo.getHabboInfo().getId()); + statement.setInt(2, Emulator.getIntUnixTimestamp() - 259200); + statement.setInt(3, (includeSelf ? 0 : habbo.getHabboInfo().getId())); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + Room room = this.activeRooms.get(set.getInt("id")); + + if (room == null) { + room = new Room(set); + + this.activeRooms.put(room.getId(), room); + } + + rooms.add(room); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + Collections.sort(rooms); + + return rooms; + } + + public ArrayList getRoomsFavourite(Habbo habbo) { + final ArrayList rooms = new ArrayList<>(); + + habbo.getHabboStats().getFavoriteRooms().forEach(new TIntProcedure() { + @Override + public boolean execute(int value) { + Room room = RoomManager.this.getRoom(value); + + if (room != null) { + if (room.getState() == RoomState.INVISIBLE) { + room.loadData(); + if (!room.hasRights(habbo)) return true; + } + rooms.add(room); + } + return true; + } + }); + + return rooms; + } + + public List getGroupRooms(Habbo habbo, int limit) { + final ArrayList rooms = new ArrayList<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("SELECT rooms.* FROM rooms INNER JOIN guilds_members ON guilds_members.guild_id = rooms.guild_id WHERE guilds_members.user_id = ? AND level_id != 3")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + if (this.activeRooms.containsKey(set.getInt("id"))) { + rooms.add(this.activeRooms.get(set.getInt("id"))); + } else { + rooms.add(new Room(set)); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + Collections.sort(rooms); + + return rooms.subList(0, (rooms.size() > limit ? limit : rooms.size())); + } + + public ArrayList getRoomsWithRights(Habbo habbo) { + ArrayList rooms = new ArrayList<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT rooms.* FROM rooms INNER JOIN room_rights ON room_rights.room_id = rooms.id WHERE room_rights.user_id = ? ORDER BY rooms.id DESC LIMIT 30")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + if (this.activeRooms.containsKey(set.getInt("id"))) { + rooms.add(this.activeRooms.get(set.getInt("id"))); + } else { + rooms.add(new Room(set)); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return rooms; + } + + public ArrayList getRoomsWithFriendsIn(Habbo habbo, int limit) { + final ArrayList rooms = new ArrayList<>(); + + for (MessengerBuddy buddy : habbo.getMessenger().getFriends().values()) { + Habbo friend = Emulator.getGameEnvironment().getHabboManager().getHabbo(buddy.getId()); + + if (friend == null || friend.getHabboInfo() == null) continue; + + if (friend.getHabboInfo().isInvisibleInRooms()) { + continue; + } + + Room room = friend.getHabboInfo().getCurrentRoom(); + if (room != null && !rooms.contains(room) && room.hasRights(habbo)) rooms.add(room); + + if (rooms.size() >= limit) break; + } + + Collections.sort(rooms); + + return rooms; + } + + public List getTopRatedRooms(int limit) { + final ArrayList rooms = new ArrayList<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("SELECT * FROM rooms ORDER BY score DESC LIMIT ?")) { + statement.setInt(1, limit); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + if (this.activeRooms.containsKey(set.getInt("id"))) { + rooms.add(this.activeRooms.get(set.getInt("id"))); + } else { + rooms.add(new Room(set)); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return rooms; + } + + public ArrayList getRoomsWithAdminRights(Habbo habbo) { + ArrayList rooms = new ArrayList<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("SELECT * FROM rooms INNER JOIN guilds_members ON guilds_members.guild_id = rooms.guild_id WHERE guilds_members.user_id = ? AND level_id = 0")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + if (this.activeRooms.containsKey(set.getInt("id"))) { + rooms.add(this.activeRooms.get(set.getInt("id"))); + } else { + rooms.add(new Room(set)); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return rooms; + } + + public ArrayList getRoomsInGroup(Habbo habbo) { + return new ArrayList<>(); + } + + public ArrayList getRoomsPromoted() { + ArrayList r = new ArrayList<>(); + + for (Room room : this.getActiveRooms()) { + if (room.isPromoted()) { + r.add(room); + } + } + + return r; + } + + public ArrayList getRoomsStaffPromoted() { + ArrayList r = new ArrayList<>(); + + for (Room room : this.getActiveRooms()) { + if (room.isStaffPromotedRoom()) { + r.add(room); + } + } + + return r; + } + + public List filterRoomsByOwner(List rooms, String filter) { + ArrayList r = new ArrayList<>(); + + for (Room room : rooms) { + if (room.getOwnerName().equalsIgnoreCase(filter)) + r.add(room); + } + + return r; + } + + public List filterRoomsByName(List rooms, String filter) { + ArrayList r = new ArrayList<>(); + + for (Room room : rooms) { + if (room.getName().toLowerCase().contains(filter.toLowerCase())) + r.add(room); + } + + return r; + } + + public List filterRoomsByNameAndDescription(List rooms, String filter) { + ArrayList r = new ArrayList<>(); + + for (Room room : rooms) { + if (room.getName().toLowerCase().contains(filter.toLowerCase()) || room.getDescription().toLowerCase().contains(filter.toLowerCase())) + r.add(room); + } + + return r; + } + + public List filterRoomsByTag(List rooms, String filter) { + ArrayList r = new ArrayList<>(); + + for (Room room : rooms) { + if (room.getTags().split(";").length == 0) + continue; + + for (String s : room.getTags().split(";")) { + if (s.equalsIgnoreCase(filter)) + r.add(room); + } + } + + return r; + } + + public List filterRoomsByGroup(List rooms, String filter) { + ArrayList r = new ArrayList<>(); + + for (Room room : rooms) { + if (room.getGuildId() == 0) + continue; + + if (Emulator.getGameEnvironment().getGuildManager().getGuild(room.getGuildId()).getName().toLowerCase().contains(filter.toLowerCase())) + r.add(room); + } + + return r; + } + + public synchronized void dispose() { + for (Room room : this.activeRooms.values()) { + room.dispose(); + } + + this.activeRooms.clear(); + + log.info("Room Manager -> Disposed!"); + } + + public CustomRoomLayout insertCustomLayout(Room room, String map, int doorX, int doorY, int doorDirection) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO room_models_custom (id, name, door_x, door_y, door_dir, heightmap) VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE door_x = ?, door_y = ?, door_dir = ?, heightmap = ?")) { + statement.setInt(1, room.getId()); + statement.setString(2, "custom_" + room.getId()); + statement.setInt(3, doorX); + statement.setInt(4, doorY); + statement.setInt(5, doorDirection); + statement.setString(6, map); + statement.setInt(7, doorX); + statement.setInt(8, doorY); + statement.setInt(9, doorDirection); + statement.setString(10, map); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return this.loadCustomLayout(room); + } + + public void banUserFromRoom(Habbo rights, int userId, int roomId, RoomBanTypes length) { + Room room = this.getRoom(roomId); + + if (room == null) + return; + + if (rights != null && !room.hasRights(rights)) + return; + + String name = ""; + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + if (habbo != null) { + if (habbo.hasPermission(Permission.ACC_UNKICKABLE)) { + return; + } + + name = habbo.getHabboInfo().getUsername(); + } else { + HabboInfo info = HabboManager.getOfflineHabboInfo(userId); + + if (info != null) { + if (info.getRank().hasPermission(Permission.ACC_UNKICKABLE, false)) { + return; + } + name = info.getUsername(); + } + } + + if (name.isEmpty()) { + return; + } + + RoomBan roomBan = new RoomBan(roomId, userId, name, Emulator.getIntUnixTimestamp() + length.duration); + roomBan.insert(); + + room.addRoomBan(roomBan); + + if (habbo != null) { + if (habbo.getHabboInfo().getCurrentRoom() == room) { + room.removeHabbo(habbo, true); + habbo.getClient().sendResponse(new RoomEnterErrorComposer(RoomEnterErrorComposer.ROOM_ERROR_BANNED)); + } + } + } + + public void registerGameType(Class gameClass) { + gameTypes.add(gameClass); + } + + public void unregisterGameType(Class gameClass) { + gameTypes.remove(gameClass); + } + + public ArrayList> getGameTypes() { + return gameTypes; + } + + public enum RoomBanTypes { + RWUAM_BAN_USER_HOUR(60 * 60), + RWUAM_BAN_USER_DAY(24 * 60 * 60), + RWUAM_BAN_USER_PERM(10 * 365 * 24 * 60 * 60); + + public int duration; + + RoomBanTypes(int duration) { + this.duration = duration; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomMoodlightData.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomMoodlightData.java new file mode 100644 index 0000000..54e12e6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomMoodlightData.java @@ -0,0 +1,75 @@ +package com.eu.habbo.habbohotel.rooms; + +public class RoomMoodlightData { + private int id; + private boolean enabled; + private boolean backgroundOnly; + private String color; + private int intensity; + + public RoomMoodlightData(int id, boolean enabled, boolean backgroundOnly, String color, int intensity) { + this.id = id; + this.enabled = enabled; + this.backgroundOnly = backgroundOnly; + this.color = color; + this.intensity = intensity; + } + + public static RoomMoodlightData fromString(String s) { + String[] data = s.split(","); + + if (data.length == 5) { + return new RoomMoodlightData(Integer.valueOf(data[1]), data[0].equalsIgnoreCase("2"), data[2].equalsIgnoreCase("2"), data[3], Integer.valueOf(data[4])); + } else { + return new RoomMoodlightData(1, true, true, "#000000", 255); + } + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public boolean isEnabled() { + return this.enabled; + } + + public void enable() { + this.enabled = true; + } + + public void disable() { + this.enabled = false; + } + + public boolean isBackgroundOnly() { + return this.backgroundOnly; + } + + public void setBackgroundOnly(boolean backgroundOnly) { + this.backgroundOnly = backgroundOnly; + } + + public String getColor() { + return this.color; + } + + public void setColor(String color) { + this.color = color; + } + + public int getIntensity() { + return this.intensity; + } + + public void setIntensity(int intensity) { + this.intensity = intensity; + } + + public String toString() { + return (this.enabled ? 2 : 1) + "," + this.id + "," + (this.backgroundOnly ? 2 : 1) + "," + this.color + "," + this.intensity; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomPromotion.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomPromotion.java new file mode 100644 index 0000000..992db7f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomPromotion.java @@ -0,0 +1,102 @@ +package com.eu.habbo.habbohotel.rooms; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class RoomPromotion { + private final Room room; + public boolean needsUpdate; + private String title; + private String description; + private int endTimestamp; + private int startTimestamp; + private int category; + + public RoomPromotion(Room room, String title, String description, int endTimestamp, int startTimestamp, int category) { + this.room = room; + this.title = title; + this.description = description; + this.endTimestamp = endTimestamp; + this.startTimestamp = startTimestamp; + this.category = category; + } + + public RoomPromotion(Room room, ResultSet set) throws SQLException { + this.room = room; + this.title = set.getString("title"); + this.description = set.getString("description"); + this.endTimestamp = set.getInt("end_timestamp"); + this.startTimestamp = set.getInt("start_timestamp"); + this.category = set.getInt("category"); + } + + public void save() { + if (this.needsUpdate) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE room_promotions SET title = ?, description = ?, category = ? WHERE room_id = ?")) { + statement.setString(1, this.title); + statement.setString(2, this.description); + statement.setInt(3, this.category); + statement.setInt(4, this.room.getId()); + statement.executeUpdate(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.needsUpdate = false; + } + } + + public Room getRoom() { + return this.room; + } + + public String getTitle() { + return this.title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDescription() { + return this.description; + } + + public void setDescription(String description) { + this.description = description; + } + + public int getEndTimestamp() { + return this.endTimestamp; + } + + public void setEndTimestamp(int endTimestamp) { + this.endTimestamp = endTimestamp; + } + + public void addEndTimestamp(int time) { + this.endTimestamp += time; + } + + public int getStartTimestamp() { + return startTimestamp; + } + + public void setStartTimestamp(int startTimestamp) { + this.startTimestamp = startTimestamp; + } + + public int getCategory() { + return category; + } + + public void setCategory(int category) { + this.category = category; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomRightLevels.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomRightLevels.java new file mode 100644 index 0000000..fef685a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomRightLevels.java @@ -0,0 +1,55 @@ +package com.eu.habbo.habbohotel.rooms; + +public enum RoomRightLevels { + + NONE(0), + + + RIGHTS(1), + + + GUILD_RIGHTS(2), + + + GUILD_ADMIN(3), + + + OWNER(4), + + + MODERATOR(5), + + + SIX(6), + + + SEVEN(7), + + + EIGHT(8), + + + NINE(9); + + public final int level; + + RoomRightLevels(int level) { + this.level = level; + } + + public boolean equals(RoomRightLevels level) { + return this.level == level.level; + } + + public boolean isEqualOrGreaterThan(RoomRightLevels level) { + return this.level >= level.level; + } + + public boolean isGreaterThan(RoomRightLevels level) { + return this.level > level.level; + } + + public boolean isLessThan(RoomRightLevels level) { + return this.level < level.level; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomSpecialTypes.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomSpecialTypes.java new file mode 100644 index 0000000..ff9667d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomSpecialTypes.java @@ -0,0 +1,762 @@ +package com.eu.habbo.habbohotel.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.ICycleable; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.*; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameGate; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameScoreboard; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTimer; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiTeleporter; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.gates.InteractionBattleBanzaiGate; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.scoreboards.InteractionBattleBanzaiScoreboard; +import com.eu.habbo.habbohotel.items.interactions.games.football.scoreboards.InteractionFootballScoreboard; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeExitTile; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.gates.InteractionFreezeGate; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.scoreboards.InteractionFreezeScoreboard; +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionNest; +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetDrink; +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetFood; +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetToy; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.wired.WiredConditionType; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + +import java.awt.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class RoomSpecialTypes { + private final THashMap banzaiTeleporters; + private final THashMap nests; + private final THashMap petDrinks; + private final THashMap petFoods; + private final THashMap petToys; + private final THashMap rollers; + + private final THashMap> wiredTriggers; + private final THashMap> wiredEffects; + private final THashMap> wiredConditions; + private final THashMap wiredExtras; + private final THashMap wiredHighscore; + + private final THashMap gameScoreboards; + private final THashMap gameGates; + private final THashMap gameTimers; + + private final THashMap freezeExitTile; + private final THashMap undefined; + private final THashSet cycleTasks; + + public RoomSpecialTypes() { + this.banzaiTeleporters = new THashMap<>(0); + this.nests = new THashMap<>(0); + this.petDrinks = new THashMap<>(0); + this.petFoods = new THashMap<>(0); + this.petToys = new THashMap<>(0); + this.rollers = new THashMap<>(0); + + this.wiredTriggers = new THashMap<>(0); + this.wiredEffects = new THashMap<>(0); + this.wiredConditions = new THashMap<>(0); + this.wiredExtras = new THashMap<>(0); + this.wiredHighscore = new THashMap<>(0); + + this.gameScoreboards = new THashMap<>(0); + this.gameGates = new THashMap<>(0); + this.gameTimers = new THashMap<>(0); + + this.freezeExitTile = new THashMap<>(0); + this.undefined = new THashMap<>(0); + this.cycleTasks = new THashSet<>(0); + } + + + public InteractionBattleBanzaiTeleporter getBanzaiTeleporter(int itemId) { + return this.banzaiTeleporters.get(itemId); + } + + public void addBanzaiTeleporter(InteractionBattleBanzaiTeleporter item) { + this.banzaiTeleporters.put(item.getId(), item); + } + + public void removeBanzaiTeleporter(InteractionBattleBanzaiTeleporter item) { + this.banzaiTeleporters.remove(item.getId()); + } + + public THashSet getBanzaiTeleporters() { + synchronized (this.banzaiTeleporters) { + THashSet battleBanzaiTeleporters = new THashSet<>(); + battleBanzaiTeleporters.addAll(this.banzaiTeleporters.values()); + + return battleBanzaiTeleporters; + } + } + + public InteractionBattleBanzaiTeleporter getRandomTeleporter(Item baseItem, InteractionBattleBanzaiTeleporter exclude) { + List teleporterList = new ArrayList<>(); + for (InteractionBattleBanzaiTeleporter teleporter : this.banzaiTeleporters.values()) { + if (baseItem == null || teleporter.getBaseItem() == baseItem) { + teleporterList.add(teleporter); + } + } + + teleporterList.remove(exclude); + + if (!teleporterList.isEmpty()) { + Collections.shuffle(teleporterList); + return teleporterList.get(0); + } + + return null; + } + + + public InteractionNest getNest(int itemId) { + return this.nests.get(itemId); + } + + public void addNest(InteractionNest item) { + this.nests.put(item.getId(), item); + } + + public void removeNest(InteractionNest item) { + this.nests.remove(item.getId()); + } + + public THashSet getNests() { + synchronized (this.nests) { + THashSet nests = new THashSet<>(); + nests.addAll(this.nests.values()); + + return nests; + } + } + + + public InteractionPetDrink getPetDrink(int itemId) { + return this.petDrinks.get(itemId); + } + + public void addPetDrink(InteractionPetDrink item) { + this.petDrinks.put(item.getId(), item); + } + + public void removePetDrink(InteractionPetDrink item) { + this.petDrinks.remove(item.getId()); + } + + public THashSet getPetDrinks() { + synchronized (this.petDrinks) { + THashSet petDrinks = new THashSet<>(); + petDrinks.addAll(this.petDrinks.values()); + + return petDrinks; + } + } + + + public InteractionPetFood getPetFood(int itemId) { + return this.petFoods.get(itemId); + } + + public void addPetFood(InteractionPetFood item) { + this.petFoods.put(item.getId(), item); + } + + public void removePetFood(InteractionPetFood petFood) { + this.petFoods.remove(petFood.getId()); + } + + public THashSet getPetFoods() { + synchronized (this.petFoods) { + THashSet petFoods = new THashSet<>(); + petFoods.addAll(this.petFoods.values()); + + return petFoods; + } + } + + + public InteractionPetToy getPetToy(int itemId) { + return this.petToys.get(itemId); + } + + public void addPetToy(InteractionPetToy item) { + this.petToys.put(item.getId(), item); + } + + public void removePetToy(InteractionPetToy petToy) { + this.petToys.remove(petToy.getId()); + } + + public THashSet getPetToys() { + synchronized (this.petToys) { + THashSet petToys = new THashSet<>(); + petToys.addAll(this.petToys.values()); + + return petToys; + } + } + + + public InteractionRoller getRoller(int itemId) { + synchronized (this.rollers) { + return this.rollers.get(itemId); + } + } + + public void addRoller(InteractionRoller item) { + synchronized (this.rollers) { + this.rollers.put(item.getId(), item); + } + } + + public void removeRoller(InteractionRoller roller) { + synchronized (this.rollers) { + this.rollers.remove(roller.getId()); + } + } + + public THashMap getRollers() { + return this.rollers; + } + + + public InteractionWiredTrigger getTrigger(int itemId) { + synchronized (this.wiredTriggers) { + for (Map.Entry> map : this.wiredTriggers.entrySet()) { + for (InteractionWiredTrigger trigger : map.getValue()) { + if (trigger.getId() == itemId) + return trigger; + } + } + + return null; + } + } + + public THashSet getTriggers() { + synchronized (this.wiredTriggers) { + THashSet triggers = new THashSet<>(); + + for (Map.Entry> map : this.wiredTriggers.entrySet()) { + triggers.addAll(map.getValue()); + } + + return triggers; + } + } + + public THashSet getTriggers(WiredTriggerType type) { + return this.wiredTriggers.get(type); + } + + public THashSet getTriggers(int x, int y) { + synchronized (this.wiredTriggers) { + THashSet triggers = new THashSet<>(); + + for (Map.Entry> map : this.wiredTriggers.entrySet()) { + for (InteractionWiredTrigger trigger : map.getValue()) { + if (trigger.getX() == x && trigger.getY() == y) + triggers.add(trigger); + } + } + + return triggers; + } + } + + public void addTrigger(InteractionWiredTrigger trigger) { + synchronized (this.wiredTriggers) { + if (!this.wiredTriggers.containsKey(trigger.getType())) + this.wiredTriggers.put(trigger.getType(), new THashSet<>()); + + this.wiredTriggers.get(trigger.getType()).add(trigger); + } + } + + public void removeTrigger(InteractionWiredTrigger trigger) { + synchronized (this.wiredTriggers) { + this.wiredTriggers.get(trigger.getType()).remove(trigger); + + if (this.wiredTriggers.get(trigger.getType()).isEmpty()) { + this.wiredTriggers.remove(trigger.getType()); + } + } + } + + + public InteractionWiredEffect getEffect(int itemId) { + synchronized (this.wiredEffects) { + for (Map.Entry> map : this.wiredEffects.entrySet()) { + for (InteractionWiredEffect effect : map.getValue()) { + if (effect.getId() == itemId) + return effect; + } + } + } + + return null; + } + + public THashSet getEffects() { + synchronized (this.wiredEffects) { + THashSet effects = new THashSet<>(); + + for (Map.Entry> map : this.wiredEffects.entrySet()) { + effects.addAll(map.getValue()); + } + + return effects; + } + } + + public THashSet getEffects(WiredEffectType type) { + return this.wiredEffects.get(type); + } + + public THashSet getEffects(int x, int y) { + synchronized (this.wiredEffects) { + THashSet effects = new THashSet<>(); + + for (Map.Entry> map : this.wiredEffects.entrySet()) { + for (InteractionWiredEffect effect : map.getValue()) { + if (effect.getX() == x && effect.getY() == y) + effects.add(effect); + } + } + + return effects; + } + } + + public void addEffect(InteractionWiredEffect effect) { + synchronized (this.wiredEffects) { + if (!this.wiredEffects.containsKey(effect.getType())) + this.wiredEffects.put(effect.getType(), new THashSet<>()); + + this.wiredEffects.get(effect.getType()).add(effect); + } + } + + public void removeEffect(InteractionWiredEffect effect) { + synchronized (this.wiredEffects) { + this.wiredEffects.get(effect.getType()).remove(effect); + + if (this.wiredEffects.get(effect.getType()).isEmpty()) { + this.wiredEffects.remove(effect.getType()); + } + } + } + + + public InteractionWiredCondition getCondition(int itemId) { + synchronized (this.wiredConditions) { + for (Map.Entry> map : this.wiredConditions.entrySet()) { + for (InteractionWiredCondition condition : map.getValue()) { + if (condition.getId() == itemId) + return condition; + } + } + } + + return null; + } + + public THashSet getConditions() { + synchronized (this.wiredConditions) { + THashSet conditions = new THashSet<>(); + + for (Map.Entry> map : this.wiredConditions.entrySet()) { + conditions.addAll(map.getValue()); + } + + return conditions; + } + } + + public THashSet getConditions(WiredConditionType type) { + synchronized (this.wiredConditions) { + return this.wiredConditions.get(type); + } + } + + public THashSet getConditions(int x, int y) { + synchronized (this.wiredConditions) { + THashSet conditions = new THashSet<>(); + + for (Map.Entry> map : this.wiredConditions.entrySet()) { + for (InteractionWiredCondition condition : map.getValue()) { + if (condition.getX() == x && condition.getY() == y) + conditions.add(condition); + } + } + + return conditions; + } + } + + public void addCondition(InteractionWiredCondition condition) { + synchronized (this.wiredConditions) { + if (!this.wiredConditions.containsKey(condition.getType())) + this.wiredConditions.put(condition.getType(), new THashSet<>()); + + this.wiredConditions.get(condition.getType()).add(condition); + } + } + + public void removeCondition(InteractionWiredCondition condition) { + synchronized (this.wiredConditions) { + this.wiredConditions.get(condition.getType()).remove(condition); + + if (this.wiredConditions.get(condition.getType()).isEmpty()) { + this.wiredConditions.remove(condition.getType()); + } + } + } + + + public THashSet getExtras() { + synchronized (this.wiredExtras) { + THashSet conditions = new THashSet<>(); + + for (Map.Entry map : this.wiredExtras.entrySet()) { + conditions.add(map.getValue()); + } + + return conditions; + } + } + + public THashSet getExtras(int x, int y) { + synchronized (this.wiredExtras) { + THashSet extras = new THashSet<>(); + + for (Map.Entry map : this.wiredExtras.entrySet()) { + if (map.getValue().getX() == x && map.getValue().getY() == y) { + extras.add(map.getValue()); + } + } + + return extras; + } + } + + public void addExtra(InteractionWiredExtra extra) { + synchronized (this.wiredExtras) { + this.wiredExtras.put(extra.getId(), extra); + } + } + + public void removeExtra(InteractionWiredExtra extra) { + synchronized (this.wiredExtras) { + this.wiredExtras.remove(extra.getId()); + } + } + + public void addHighscore(InteractionWiredHighscore highscore) { + synchronized (this.wiredHighscore) { + this.wiredHighscore.put(highscore.getId(), highscore); + } + } + + public THashSet getWiredHighscores() { + synchronized (this.wiredHighscore) { + THashSet highscores = new THashSet<>(); + + for (Map.Entry map : this.wiredHighscore.entrySet()) { + highscores.add(map.getValue()); + } + + return highscores; + } + } + + public boolean hasExtraType(short x, short y, Class type) { + synchronized (this.wiredExtras) { + for (Map.Entry map : this.wiredExtras.entrySet()) { + if (map.getValue().getX() == x && map.getValue().getY() == y && map.getValue().getClass().isAssignableFrom(type)) { + return true; + } + } + } + + return false; + } + + public InteractionGameScoreboard getGameScorebord(int itemId) { + return this.gameScoreboards.get(itemId); + } + + public void addGameScoreboard(InteractionGameScoreboard scoreboard) { + this.gameScoreboards.put(scoreboard.getId(), scoreboard); + } + + public void removeScoreboard(InteractionGameScoreboard scoreboard) { + this.gameScoreboards.remove(scoreboard.getId()); + } + + public THashMap getFreezeScoreboards() { + synchronized (this.gameScoreboards) { + THashMap boards = new THashMap<>(); + + for (Map.Entry set : this.gameScoreboards.entrySet()) { + if (set.getValue() instanceof InteractionFreezeScoreboard) { + boards.put(set.getValue().getId(), (InteractionFreezeScoreboard) set.getValue()); + } + } + + return boards; + } + } + + public THashMap getFreezeScoreboards(GameTeamColors teamColor) { + synchronized (this.gameScoreboards) { + THashMap boards = new THashMap<>(); + + for (Map.Entry set : this.gameScoreboards.entrySet()) { + if (set.getValue() instanceof InteractionFreezeScoreboard) { + if (((InteractionFreezeScoreboard) set.getValue()).teamColor.equals(teamColor)) + boards.put(set.getValue().getId(), (InteractionFreezeScoreboard) set.getValue()); + } + } + + return boards; + } + } + + public THashMap getBattleBanzaiScoreboards() { + synchronized (this.gameScoreboards) { + THashMap boards = new THashMap<>(); + + for (Map.Entry set : this.gameScoreboards.entrySet()) { + if (set.getValue() instanceof InteractionBattleBanzaiScoreboard) { + boards.put(set.getValue().getId(), (InteractionBattleBanzaiScoreboard) set.getValue()); + } + } + + return boards; + } + } + + public THashMap getBattleBanzaiScoreboards(GameTeamColors teamColor) { + synchronized (this.gameScoreboards) { + THashMap boards = new THashMap<>(); + + for (Map.Entry set : this.gameScoreboards.entrySet()) { + if (set.getValue() instanceof InteractionBattleBanzaiScoreboard) { + if (((InteractionBattleBanzaiScoreboard) set.getValue()).teamColor.equals(teamColor)) + boards.put(set.getValue().getId(), (InteractionBattleBanzaiScoreboard) set.getValue()); + } + } + + return boards; + } + } + + public THashMap getFootballScoreboards() { + synchronized (this.gameScoreboards) { + THashMap boards = new THashMap<>(); + + for (Map.Entry set : this.gameScoreboards.entrySet()) { + if (set.getValue() instanceof InteractionFootballScoreboard) { + boards.put(set.getValue().getId(), (InteractionFootballScoreboard) set.getValue()); + } + } + + return boards; + } + } + + public THashMap getFootballScoreboards(GameTeamColors teamColor) { + synchronized (this.gameScoreboards) { + THashMap boards = new THashMap<>(); + + for (Map.Entry set : this.gameScoreboards.entrySet()) { + if (set.getValue() instanceof InteractionFootballScoreboard) { + if (((InteractionFootballScoreboard) set.getValue()).teamColor.equals(teamColor)) + boards.put(set.getValue().getId(), (InteractionFootballScoreboard) set.getValue()); + } + } + + return boards; + } + } + + + public InteractionGameGate getGameGate(int itemId) { + return this.gameGates.get(itemId); + } + + public void addGameGate(InteractionGameGate gameGate) { + this.gameGates.put(gameGate.getId(), gameGate); + } + + public void removeGameGate(InteractionGameGate gameGate) { + this.gameGates.remove(gameGate.getId()); + } + + public THashMap getFreezeGates() { + synchronized (this.gameGates) { + THashMap gates = new THashMap<>(); + + for (Map.Entry set : this.gameGates.entrySet()) { + if (set.getValue() instanceof InteractionFreezeGate) { + gates.put(set.getValue().getId(), (InteractionFreezeGate) set.getValue()); + } + } + + return gates; + } + } + + public THashMap getBattleBanzaiGates() { + synchronized (this.gameGates) { + THashMap gates = new THashMap<>(); + + for (Map.Entry set : this.gameGates.entrySet()) { + if (set.getValue() instanceof InteractionBattleBanzaiGate) { + gates.put(set.getValue().getId(), (InteractionBattleBanzaiGate) set.getValue()); + } + } + + return gates; + } + } + + + public InteractionGameTimer getGameTimer(int itemId) { + return this.gameTimers.get(itemId); + } + + public void addGameTimer(InteractionGameTimer gameTimer) { + this.gameTimers.put(gameTimer.getId(), gameTimer); + } + + public void removeGameTimer(InteractionGameTimer gameTimer) { + this.gameTimers.remove(gameTimer.getId()); + } + + public THashMap getGameTimers() { + return this.gameTimers; + } + + public InteractionFreezeExitTile getFreezeExitTile() { + for (InteractionFreezeExitTile t : this.freezeExitTile.values()) { + return t; + } + + return null; + } + + public InteractionFreezeExitTile getRandomFreezeExitTile() { + synchronized (this.freezeExitTile) { + return (InteractionFreezeExitTile) this.freezeExitTile.values().toArray()[Emulator.getRandom().nextInt(this.freezeExitTile.size())]; + } + } + + public void addFreezeExitTile(InteractionFreezeExitTile freezeExitTile) { + this.freezeExitTile.put(freezeExitTile.getId(), freezeExitTile); + } + + public THashMap getFreezeExitTiles() { + return this.freezeExitTile; + } + + public void removeFreezeExitTile(InteractionFreezeExitTile freezeExitTile) { + this.freezeExitTile.remove(freezeExitTile.getId()); + } + + public boolean hasFreezeExitTile() { + return !this.freezeExitTile.isEmpty(); + } + + public void addUndefined(HabboItem item) { + synchronized (this.undefined) { + this.undefined.put(item.getId(), item); + } + } + + public void removeUndefined(HabboItem item) { + synchronized (this.undefined) { + this.undefined.remove(item.getId()); + } + } + + public THashSet getItemsOfType(Class type) { + THashSet items = new THashSet<>(); + synchronized (this.undefined) { + for (HabboItem item : this.undefined.values()) { + if (item.getClass() == type) + items.add(item); + } + } + + return items; + } + + public HabboItem getLowestItemsOfType(Class type) { + HabboItem i = null; + synchronized (this.undefined) { + for (HabboItem item : this.undefined.values()) { + if (i == null || item.getZ() < i.getZ()) { + if (item.getClass().isAssignableFrom(type)) { + i = item; + } + } + } + } + + return i; + } + + public THashSet getCycleTasks() { + return this.cycleTasks; + } + + public void addCycleTask(ICycleable task) { + this.cycleTasks.add(task); + } + + public void removeCycleTask(ICycleable task) { + this.cycleTasks.remove(task); + } + + public synchronized void dispose() { + this.banzaiTeleporters.clear(); + this.nests.clear(); + this.petDrinks.clear(); + this.petFoods.clear(); + this.rollers.clear(); + + this.wiredTriggers.clear(); + this.wiredEffects.clear(); + this.wiredConditions.clear(); + + this.gameScoreboards.clear(); + this.gameGates.clear(); + this.gameTimers.clear(); + + this.freezeExitTile.clear(); + this.undefined.clear(); + this.cycleTasks.clear(); + } + + public Rectangle tentAt(RoomTile location) { + for (HabboItem item : this.getItemsOfType(InteractionTent.class)) { + Rectangle rectangle = RoomLayout.getRectangle(item.getX(), item.getY(), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + if (RoomLayout.tileInSquare(rectangle, location)) { + return rectangle; + } + } + + return null; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomState.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomState.java new file mode 100644 index 0000000..d6962bf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomState.java @@ -0,0 +1,18 @@ +package com.eu.habbo.habbohotel.rooms; + +public enum RoomState { + OPEN(0), + LOCKED(1), + PASSWORD(2), + INVISIBLE(3); + + private final int state; + + RoomState(int state) { + this.state = state; + } + + public int getState() { + return this.state; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTile.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTile.java new file mode 100644 index 0000000..d3978d8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTile.java @@ -0,0 +1,216 @@ +package com.eu.habbo.habbohotel.rooms; + +import com.eu.habbo.habbohotel.items.Item; +import gnu.trove.set.hash.THashSet; + +import java.util.ArrayList; +import java.util.List; + +public class RoomTile { + public final short x; + public final short y; + public final short z; + private final THashSet units; + public RoomTileState state; + private double stackHeight; + private boolean allowStack = true; + private RoomTile previous = null; + private boolean diagonally; + private short gCosts; + private short hCosts; + + + public RoomTile(short x, short y, short z, RoomTileState state, boolean allowStack) { + this.x = x; + this.y = y; + this.z = z; + this.stackHeight = z; + this.state = state; + this.setAllowStack(allowStack); + this.units = new THashSet<>(); + } + + public RoomTile(RoomTile tile) { + this.x = tile.x; + this.y = tile.y; + this.z = tile.z; + this.stackHeight = tile.stackHeight; + this.state = tile.state; + this.allowStack = tile.allowStack; + this.diagonally = tile.diagonally; + this.gCosts = tile.gCosts; + this.hCosts = tile.hCosts; + + if (this.state == RoomTileState.INVALID) { + this.allowStack = false; + } + this.units = tile.units; + } + + public RoomTile() + { + x = 0; + y = 0; + z = 0; + this.stackHeight = 0; + this.state = RoomTileState.INVALID; + this.allowStack = false; + this.diagonally = false; + this.gCosts = 0; + this.hCosts = 0; + this.units = null; + } + + public double getStackHeight() { + return this.stackHeight; + } + + public void setStackHeight(double stackHeight) { + if (this.state == RoomTileState.INVALID) { + this.stackHeight = Short.MAX_VALUE; + this.allowStack = false; + return; + } + + if (stackHeight >= 0 && stackHeight != Short.MAX_VALUE) { + this.stackHeight = stackHeight; + this.allowStack = true; + } else { + this.allowStack = false; + this.stackHeight = this.z; + } + } + + public boolean getAllowStack() { + if (this.state == RoomTileState.INVALID) { + return false; + } + + return this.allowStack; + } + + public void setAllowStack(boolean allowStack) { + this.allowStack = allowStack; + } + + public short relativeHeight() { + if (this.state == RoomTileState.INVALID) { + return Short.MAX_VALUE; + } else if (!this.allowStack && (this.state == RoomTileState.BLOCKED || this.state == RoomTileState.SIT)) { + return 64 * 256; + } + + return this.allowStack ? (short) (this.getStackHeight() * 256.0) : 64 * 256; + } + + @Override + public boolean equals(Object o) { + return o instanceof RoomTile && + ((RoomTile) o).x == this.x && + ((RoomTile) o).y == this.y; + } + + public RoomTile copy() { + return new RoomTile(this); + } + + public double distance(RoomTile roomTile) { + double x = this.x - roomTile.x; + double y = this.y - roomTile.y; + return Math.sqrt(x * x + y * y); + } + + public void isDiagonally(boolean isDiagonally) { + this.diagonally = isDiagonally; + } + + public RoomTile getPrevious() { + return this.previous; + } + + public void setPrevious(RoomTile previous) { + this.previous = previous; + } + + public int getfCosts() { + return this.gCosts + this.hCosts; + } + + public int getgCosts() { + return this.gCosts; + } + + public void setgCosts(RoomTile previousRoomTile) { + this.setgCosts(previousRoomTile, this.diagonally ? RoomLayout.DIAGONALMOVEMENTCOST : RoomLayout.BASICMOVEMENTCOST); + } + + private void setgCosts(short gCosts) { + this.gCosts = gCosts; + } + + void setgCosts(RoomTile previousRoomTile, int basicCost) { + this.setgCosts((short) (previousRoomTile.getgCosts() + basicCost)); + } + + public int calculategCosts(RoomTile previousRoomTile) { + if (this.diagonally) { + return previousRoomTile.getgCosts() + 14; + } + + return previousRoomTile.getgCosts() + 10; + } + + public void sethCosts(RoomTile parent) { + this.hCosts = (short) ((Math.abs(this.x - parent.x) + Math.abs(this.y - parent.y)) * (parent.diagonally ? RoomLayout.DIAGONALMOVEMENTCOST : RoomLayout.BASICMOVEMENTCOST)); + } + + public String toString() { + return "RoomTile (" + this.x + ", " + this.y + ", " + this.z + "): h: " + this.hCosts + " g: " + this.gCosts + " f: " + this.getfCosts(); + } + + public boolean isWalkable() { + return this.state == RoomTileState.OPEN; + } + + public RoomTileState getState() { + return this.state; + } + + public void setState(RoomTileState state) { + this.state = state; + } + + public boolean is(short x, short y) { + return this.x == x && this.y == y; + } + + public List getUnits() { + synchronized (this.units) { + return new ArrayList(this.units); + } + } + + public void addUnit(RoomUnit unit) { + synchronized (this.units) { + if (!this.units.contains(unit)) { + this.units.add(unit); + } + } + } + + public void removeUnit(RoomUnit unit) { + synchronized (this.units) { + this.units.remove(unit); + } + } + + public boolean hasUnits() { + synchronized (this.units) { + return this.units.size() > 0; + } + } + + public boolean unitIsOnFurniOnTile(RoomUnit unit, Item item) { + return (unit.getX() >= this.x && unit.getX() < this.x + item.getLength()) && (unit.getY() >= this.y && unit.getY() < this.y + item.getWidth()); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTileState.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTileState.java new file mode 100644 index 0000000..634ae4c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTileState.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.rooms; + + +public enum RoomTileState { + + OPEN, + + + BLOCKED, + + + INVALID, + + + SIT, + + + LAY +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTrade.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTrade.java new file mode 100644 index 0000000..c79e0fb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTrade.java @@ -0,0 +1,340 @@ +package com.eu.habbo.habbohotel.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import com.eu.habbo.messages.outgoing.trading.*; +import com.eu.habbo.plugin.events.furniture.FurnitureRedeemedEvent; +import com.eu.habbo.plugin.events.trading.TradeConfirmEvent; +import com.eu.habbo.threading.runnables.QueryDeleteHabboItem; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; + +import java.sql.*; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +public class RoomTrade { + //Configuration. Loaded from database & updated accordingly. + public static boolean TRADING_ENABLED = true; + public static boolean TRADING_REQUIRES_PERK = true; + + private final List users; + private final Room room; + private boolean tradeCompleted; + + public RoomTrade(Habbo userOne, Habbo userTwo, Room room) { + this.users = new ArrayList<>(); + this.tradeCompleted = false; + + this.users.add(new RoomTradeUser(userOne)); + this.users.add(new RoomTradeUser(userTwo)); + this.room = room; + } + + public void start() { + this.initializeTradeStatus(); + this.openTrade(); + } + + protected void initializeTradeStatus() { + for (RoomTradeUser roomTradeUser : this.users) { + if (!roomTradeUser.getHabbo().getRoomUnit().hasStatus(RoomUnitStatus.TRADING)) { + roomTradeUser.getHabbo().getRoomUnit().setStatus(RoomUnitStatus.TRADING, ""); + if (!roomTradeUser.getHabbo().getRoomUnit().isWalking()) + this.room.sendComposer(new RoomUserStatusComposer(roomTradeUser.getHabbo().getRoomUnit()).compose()); + } + } + } + + protected void openTrade() { + this.sendMessageToUsers(new TradeStartComposer(this)); + } + + public void offerItem(Habbo habbo, HabboItem item) { + RoomTradeUser user = this.getRoomTradeUserForHabbo(habbo); + + if (user.getItems().contains(item)) + return; + + habbo.getInventory().getItemsComponent().removeHabboItem(item); + user.getItems().add(item); + + this.clearAccepted(); + this.updateWindow(); + } + + public void offerMultipleItems(Habbo habbo, THashSet items) { + RoomTradeUser user = this.getRoomTradeUserForHabbo(habbo); + + for (HabboItem item : items) { + if (!user.getItems().contains(item)) { + habbo.getInventory().getItemsComponent().removeHabboItem(item); + user.getItems().add(item); + } + } + + this.clearAccepted(); + this.updateWindow(); + } + + public void removeItem(Habbo habbo, HabboItem item) { + RoomTradeUser user = this.getRoomTradeUserForHabbo(habbo); + + if (!user.getItems().contains(item)) + return; + + habbo.getInventory().getItemsComponent().addItem(item); + user.getItems().remove(item); + + this.clearAccepted(); + this.updateWindow(); + } + + public void accept(Habbo habbo, boolean value) { + RoomTradeUser user = this.getRoomTradeUserForHabbo(habbo); + + user.setAccepted(value); + + this.sendMessageToUsers(new TradeAcceptedComposer(user)); + boolean accepted = true; + for (RoomTradeUser roomTradeUser : this.users) { + if (!roomTradeUser.getAccepted()) + accepted = false; + } + if (accepted) { + this.sendMessageToUsers(new TradingWaitingConfirmComposer()); + } + } + + public void confirm(Habbo habbo) { + RoomTradeUser user = this.getRoomTradeUserForHabbo(habbo); + + user.confirm(); + + this.sendMessageToUsers(new TradeAcceptedComposer(user)); + boolean accepted = true; + for (RoomTradeUser roomTradeUser : this.users) { + if (!roomTradeUser.getConfirmed()) + accepted = false; + } + if (accepted) { + if (this.tradeItems()) { + this.closeWindow(); + this.sendMessageToUsers(new TradeCompleteComposer()); + } + + this.room.stopTrade(this); + } + } + + boolean tradeItems() { + for (RoomTradeUser roomTradeUser : this.users) { + for (HabboItem item : roomTradeUser.getItems()) { + if (roomTradeUser.getHabbo().getInventory().getItemsComponent().getHabboItem(item.getId()) != null) { + this.sendMessageToUsers(new TradeClosedComposer(roomTradeUser.getHabbo().getRoomUnit().getId(), TradeClosedComposer.ITEMS_NOT_FOUND)); + return false; + } + } + } + + RoomTradeUser userOne = this.users.get(0); + RoomTradeUser userTwo = this.users.get(1); + + boolean tradeConfirmEventRegistered = Emulator.getPluginManager().isRegistered(TradeConfirmEvent.class, true); + TradeConfirmEvent tradeConfirmEvent = new TradeConfirmEvent(userOne, userTwo); + if (tradeConfirmEventRegistered) { + Emulator.getPluginManager().fireEvent(tradeConfirmEvent); + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + + int tradeId = 0; + + boolean logTrades = Emulator.getConfig().getBoolean("hotel.log.trades"); + if (logTrades) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO room_trade_log (user_one_id, user_two_id, user_one_ip, user_two_ip, timestamp, user_one_item_count, user_two_item_count) VALUES (?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, userOne.getHabbo().getHabboInfo().getId()); + statement.setInt(2, userTwo.getHabbo().getHabboInfo().getId()); + statement.setString(3, userOne.getHabbo().getHabboInfo().getIpLogin()); + statement.setString(4, userTwo.getHabbo().getHabboInfo().getIpLogin()); + statement.setInt(5, Emulator.getIntUnixTimestamp()); + statement.setInt(6, userOne.getItems().size()); + statement.setInt(7, userTwo.getItems().size()); + statement.executeUpdate(); + try (ResultSet generatedKeys = statement.getGeneratedKeys()) { + if (generatedKeys.next()) { + tradeId = generatedKeys.getInt(1); + } + } + } + } + + int userOneId = userOne.getHabbo().getHabboInfo().getId(); + int userTwoId = userTwo.getHabbo().getHabboInfo().getId(); + + try (PreparedStatement statement = connection.prepareStatement("UPDATE items SET user_id = ? WHERE id = ? LIMIT 1")) { + try (PreparedStatement stmt = connection.prepareStatement("INSERT INTO room_trade_log_items (id, item_id, user_id) VALUES (?, ?, ?)")) { + for (HabboItem item : userOne.getItems()) { + item.setUserId(userTwoId); + statement.setInt(1, userTwoId); + statement.setInt(2, item.getId()); + statement.addBatch(); + + if (logTrades) { + stmt.setInt(1, tradeId); + stmt.setInt(2, item.getId()); + stmt.setInt(3, userOneId); + stmt.addBatch(); + } + } + + for (HabboItem item : userTwo.getItems()) { + item.setUserId(userOneId); + statement.setInt(1, userOneId); + statement.setInt(2, item.getId()); + statement.addBatch(); + + if (logTrades) { + stmt.setInt(1, tradeId); + stmt.setInt(2, item.getId()); + stmt.setInt(3, userTwoId); + stmt.addBatch(); + } + } + + if (logTrades) { + stmt.executeBatch(); + } + } + + statement.executeBatch(); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + THashSet itemsUserOne = new THashSet<>(userOne.getItems()); + THashSet itemsUserTwo = new THashSet<>(userTwo.getItems()); + + userOne.clearItems(); + userTwo.clearItems(); + + int creditsForUserTwo = 0; + THashSet creditFurniUserOne = new THashSet<>(); + for (HabboItem item : itemsUserOne) { + int worth = RoomTrade.getCreditsByItem(item); + if (worth > 0) { + creditsForUserTwo += worth; + creditFurniUserOne.add(item); + new QueryDeleteHabboItem(item).run(); + } + } + itemsUserOne.removeAll(creditFurniUserOne); + + int creditsForUserOne = 0; + THashSet creditFurniUserTwo = new THashSet<>(); + for (HabboItem item : itemsUserTwo) { + int worth = RoomTrade.getCreditsByItem(item); + if (worth > 0) { + creditsForUserOne += worth; + creditFurniUserTwo.add(item); + new QueryDeleteHabboItem(item).run(); + } + } + itemsUserTwo.removeAll(creditFurniUserTwo); + + userOne.getHabbo().giveCredits(creditsForUserOne); + userTwo.getHabbo().giveCredits(creditsForUserTwo); + + userOne.getHabbo().getInventory().getItemsComponent().addItems(itemsUserTwo); + userTwo.getHabbo().getInventory().getItemsComponent().addItems(itemsUserOne); + + userOne.getHabbo().getClient().sendResponse(new AddHabboItemComposer(itemsUserTwo)); + userTwo.getHabbo().getClient().sendResponse(new AddHabboItemComposer(itemsUserOne)); + + userOne.getHabbo().getClient().sendResponse(new InventoryRefreshComposer()); + userTwo.getHabbo().getClient().sendResponse(new InventoryRefreshComposer()); + return true; + } + + protected void clearAccepted() { + for (RoomTradeUser user : this.users) { + user.setAccepted(false); + } + } + + protected void updateWindow() { + this.sendMessageToUsers(new TradeUpdateComposer(this)); + } + + private void returnItems() { + for (RoomTradeUser user : this.users) { + user.putItemsIntoInventory(); + } + } + + private void closeWindow() { + this.removeStatusses(); + this.sendMessageToUsers(new TradeCloseWindowComposer()); + } + + public void stopTrade(Habbo habbo) { + this.removeStatusses(); + this.clearAccepted(); + this.returnItems(); + for (RoomTradeUser user : this.users) { + user.clearItems(); + } + this.updateWindow(); + this.sendMessageToUsers(new TradeClosedComposer(habbo.getHabboInfo().getId(), TradeClosedComposer.USER_CANCEL_TRADE)); + this.room.stopTrade(this); + } + + private void removeStatusses() { + for (RoomTradeUser user : this.users) { + Habbo habbo = user.getHabbo(); + + if (habbo == null) + continue; + + habbo.getRoomUnit().removeStatus(RoomUnitStatus.TRADING); + this.room.sendComposer(new RoomUserStatusComposer(habbo.getRoomUnit()).compose()); + } + } + + public RoomTradeUser getRoomTradeUserForHabbo(Habbo habbo) { + for (RoomTradeUser roomTradeUser : this.users) { + if (roomTradeUser.getHabbo() == habbo) + return roomTradeUser; + } + return null; + } + + public void sendMessageToUsers(MessageComposer message) { + for (RoomTradeUser roomTradeUser : this.users) { + roomTradeUser.getHabbo().getClient().sendResponse(message); + } + } + + public List getRoomTradeUsers() { + return this.users; + } + + public static int getCreditsByItem(HabboItem item) { + if (!Emulator.getConfig().getBoolean("redeem.currency.trade")) return 0; + + if (!item.getBaseItem().getName().startsWith("CF_") && !item.getBaseItem().getName().startsWith("CFC_")) return 0; + + try { + return Integer.valueOf(item.getBaseItem().getName().split("_")[1]); + } catch (Exception e) { + return 0; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTradeUser.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTradeUser.java new file mode 100644 index 0000000..6b222e3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomTradeUser.java @@ -0,0 +1,80 @@ +package com.eu.habbo.habbohotel.rooms; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import gnu.trove.set.hash.THashSet; + +public class RoomTradeUser { + private final Habbo habbo; + private final THashSet items; + private int userId; + private boolean accepted; + private boolean confirmed; + + public RoomTradeUser(Habbo habbo) { + this.habbo = habbo; + + if (this.habbo != null) { + this.userId = this.habbo.getHabboInfo().getId(); + } + + this.accepted = false; + this.confirmed = false; + this.items = new THashSet<>(); + } + + public int getUserId() { + return this.userId; + } + + public void setUserId(int userId) { + this.userId = userId; + } + + public Habbo getHabbo() { + return this.habbo; + } + + public boolean getAccepted() { + return this.accepted; + } + + public void setAccepted(boolean value) { + this.accepted = value; + } + + public boolean getConfirmed() { + return this.confirmed; + } + + public void confirm() { + this.confirmed = true; + } + + public void addItem(HabboItem item) { + this.items.add(item); + } + + public HabboItem getItem(int itemId) { + for (HabboItem item : this.items) { + if (item.getId() == itemId) { + return item; + } + } + + return null; + } + + public THashSet getItems() { + return this.items; + } + + public void putItemsIntoInventory() { + this.habbo.getInventory().getItemsComponent().addItems(this.items); + } + + public void clearItems() { + this.items.clear(); + } +} + diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnit.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnit.java new file mode 100644 index 0000000..233c131 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnit.java @@ -0,0 +1,809 @@ +package com.eu.habbo.habbohotel.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.*; +import com.eu.habbo.habbohotel.items.interactions.interfaces.ConditionalGate; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.RideablePet; +import com.eu.habbo.habbohotel.users.DanceType; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import com.eu.habbo.plugin.Event; +import com.eu.habbo.plugin.events.roomunit.RoomUnitLookAtPointEvent; +import com.eu.habbo.plugin.events.roomunit.RoomUnitSetGoalEvent; +import com.eu.habbo.plugin.events.users.UserIdleEvent; +import com.eu.habbo.plugin.events.users.UserTakeStepEvent; +import com.eu.habbo.threading.runnables.RoomUnitKick; +import com.eu.habbo.util.pathfinding.Rotation; +import gnu.trove.map.TMap; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledFuture; +import java.util.stream.Collectors; + +public class RoomUnit { + + private static final Logger LOGGER = LoggerFactory.getLogger(RoomUnit.class); + + public boolean isWiredTeleporting = false; + public boolean isLeavingTeleporter = false; + private final ConcurrentHashMap status; + private final THashMap cacheable; + public boolean canRotate = true; + public boolean animateWalk = false; + public boolean cmdTeleport = false; + public boolean cmdSit = false; + public boolean cmdStand = false; + public boolean cmdLay = false; + public boolean sitUpdate = false; + public boolean isTeleporting = false; + public boolean isKicked; + public int kickCount = 0; + private int id; + private RoomTile startLocation; + private RoomTile previousLocation; + private double previousLocationZ; + private RoomTile currentLocation; + private RoomTile goalLocation; + private double z; + private int tilesWalked; + private boolean inRoom; + private boolean canWalk; + private boolean fastWalk = false; + private boolean statusUpdate = false; + private boolean invisible = false; + private boolean lastCycleStatus = false; + private boolean canLeaveRoomByDoor = true; + private RoomUserRotation bodyRotation = RoomUserRotation.NORTH; + private RoomUserRotation headRotation = RoomUserRotation.NORTH; + private DanceType danceType; + private RoomUnitType roomUnitType; + private Deque path = new LinkedList<>(); + private int handItem; + private long handItemTimestamp; + private int walkTimeOut; + private int effectId; + private int effectEndTimestamp; + private ScheduledFuture moveBlockingTask; + private int timeInRoom; + + private int idleTimer; + private Room room; + private RoomRightLevels rightsLevel = RoomRightLevels.NONE; + private THashSet overridableTiles; + + public RoomUnit() { + this.id = 0; + this.inRoom = false; + this.canWalk = true; + this.status = new ConcurrentHashMap<>(); + this.cacheable = new THashMap<>(); + this.roomUnitType = RoomUnitType.UNKNOWN; + this.danceType = DanceType.NONE; + this.handItem = 0; + this.handItemTimestamp = 0; + this.walkTimeOut = Emulator.getIntUnixTimestamp(); + this.effectId = 0; + this.isKicked = false; + this.overridableTiles = new THashSet<>(); + this.timeInRoom = 0; + } + + public void clearWalking() { + this.goalLocation = null; + this.startLocation = this.currentLocation; + this.inRoom = false; + + this.status.clear(); + + this.cacheable.clear(); + } + + public void stopWalking() { + synchronized (this.status) { + this.status.remove(RoomUnitStatus.MOVE); + this.setGoalLocation(this.currentLocation); + } + } + + public boolean cycle(Room room) { + try { + Habbo rider = null; + if (this.getRoomUnitType() == RoomUnitType.PET) { + Pet pet = room.getPet(this); + if (pet instanceof RideablePet) { + rider = ((RideablePet) pet).getRider(); + } + } + + if (rider != null) { + // copy things from rider + if (this.status.containsKey(RoomUnitStatus.MOVE) && !rider.getRoomUnit().getStatusMap().containsKey(RoomUnitStatus.MOVE)) { + this.status.remove(RoomUnitStatus.MOVE); + } + + if (rider.getRoomUnit().getCurrentLocation().x != this.getX() || rider.getRoomUnit().getCurrentLocation().y != this.getY()) { + this.status.put(RoomUnitStatus.MOVE, rider.getRoomUnit().getCurrentLocation().x + "," + rider.getRoomUnit().getCurrentLocation().y + "," + (rider.getRoomUnit().getCurrentLocation().getStackHeight())); + this.setPreviousLocation(rider.getRoomUnit().getPreviousLocation()); + this.setPreviousLocationZ(rider.getRoomUnit().getPreviousLocation().getStackHeight()); + this.setCurrentLocation(rider.getRoomUnit().getCurrentLocation()); + this.setZ(rider.getRoomUnit().getCurrentLocation().getStackHeight()); + } + + return this.statusUpdate; + } + + + if (!this.isWalking() && !this.isKicked) { + if (this.status.remove(RoomUnitStatus.MOVE) == null) { + Habbo habboT = room.getHabbo(this); + if (habboT != null) { + habboT.getHabboInfo().getRiding().getRoomUnit().status.remove(RoomUnitStatus.MOVE); + + } + return true; + } + } + + if (this.status.remove(RoomUnitStatus.SIT) != null) this.statusUpdate = true; + if (this.status.remove(RoomUnitStatus.MOVE) != null) this.statusUpdate = true; + if (this.status.remove(RoomUnitStatus.LAY) != null) this.statusUpdate = true; + + for (Map.Entry set : this.status.entrySet()) { + if (set.getKey().removeWhenWalking) { + this.status.remove(set.getKey()); + } + } + + if (this.path == null || this.path.isEmpty()) + return true; + + boolean canfastwalk = true; + Habbo habboT = room.getHabbo(this); + if (habboT != null) { + if (habboT.getHabboInfo().getRiding() != null) + canfastwalk = false; + } + + RoomTile next = this.path.poll(); + boolean overrideChecks = next != null && this.canOverrideTile(next); + + if (this.path.isEmpty()) { + this.sitUpdate = true; + + if (next != null && next.hasUnits() && !overrideChecks) { + return false; + } + } + + Deque peekPath = room.getLayout().findPath(this.currentLocation, this.path.peek(), this.goalLocation, this); + + if (peekPath == null) peekPath = new LinkedList<>(); + + if (peekPath.size() >= 3) { + if (path.isEmpty()) return true; + + path.pop(); + //peekPath.pop(); //Start + peekPath.removeLast(); //End + + if (peekPath.peek() != next) { + next = peekPath.poll(); + for (int i = 0; i < peekPath.size(); i++) { + this.path.addFirst(peekPath.removeLast()); + } + } + } + + if (canfastwalk && this.fastWalk) { + if (this.path.size() > 1) { + next = this.path.poll(); + } + } + + if (next == null) + return true; + + Habbo habbo = room.getHabbo(this); + + this.status.remove(RoomUnitStatus.DEAD); + + if (habbo != null) { + if (this.isIdle()) { + UserIdleEvent event = new UserIdleEvent(habbo, UserIdleEvent.IdleReason.WALKED, false); + Emulator.getPluginManager().fireEvent(event); + + if (!event.isCancelled()) { + if (!event.idle) { + room.unIdle(habbo); + this.idleTimer = 0; + } + } + } + + if (Emulator.getPluginManager().isRegistered(UserTakeStepEvent.class, false)) { + Event e = new UserTakeStepEvent(habbo, room.getLayout().getTile(this.getX(), this.getY()), next); + Emulator.getPluginManager().fireEvent(e); + + if (e.isCancelled()) + return true; + } + } + + HabboItem item = room.getTopItemAt(next.x, next.y); + + //if(!(this.path.size() == 0 && canSitNextTile)) + { + double height = next.getStackHeight() - this.currentLocation.getStackHeight(); + if (!room.tileWalkable(next) || (!RoomLayout.ALLOW_FALLING && height < -RoomLayout.MAXIMUM_STEP_HEIGHT) || (next.state == RoomTileState.OPEN && height > RoomLayout.MAXIMUM_STEP_HEIGHT)) { + this.room = room; + this.path.clear(); + this.findPath(); + + if (this.path.isEmpty()) { + this.status.remove(RoomUnitStatus.MOVE); + return false; + } + next = (RoomTile)this.path.pop(); + + } + } + + boolean canSitNextTile = room.canSitAt(next.x, next.y); + + if (canSitNextTile) { + HabboItem tallestChair = room.getTallestChair(next); + + if (tallestChair != null) + item = tallestChair; + } + + if (next.equals(this.goalLocation) && next.state == RoomTileState.SIT && !overrideChecks) { + if (item == null || item.getZ() - this.getZ() > RoomLayout.MAXIMUM_STEP_HEIGHT) { + this.status.remove(RoomUnitStatus.MOVE); + return false; + } + } + + double zHeight = 0.0D; + + /*if (((habbo != null && habbo.getHabboInfo().getRiding() != null) || isRiding) && next.equals(this.goalLocation) && (next.state == RoomTileState.SIT || next.state == RoomTileState.LAY)) { + this.status.remove(RoomUnitStatus.MOVE); + return false; + }*/ + + if (habbo != null) { + if (habbo.getHabboInfo().getRiding() != null) { + zHeight += 1.0D; + } + } + + HabboItem habboItem = room.getTopItemAt(this.getX(), this.getY()); + if (habboItem != null) { + if (habboItem != item || !RoomLayout.pointInSquare(habboItem.getX(), habboItem.getY(), habboItem.getX() + habboItem.getBaseItem().getWidth() - 1, habboItem.getY() + habboItem.getBaseItem().getLength() - 1, next.x, next.y)) + habboItem.onWalkOff(this, room, new Object[]{this.getCurrentLocation(), next}); + } + + this.tilesWalked++; + + RoomUserRotation oldRotation = this.getBodyRotation(); + this.setRotation(RoomUserRotation.values()[Rotation.Calculate(this.getX(), this.getY(), next.x, next.y)]); + if (item != null) { + if (item != habboItem || !RoomLayout.pointInSquare(item.getX(), item.getY(), item.getX() + item.getBaseItem().getWidth() - 1, item.getY() + item.getBaseItem().getLength() - 1, this.getX(), this.getY())) { + if (item.canWalkOn(this, room, null)) { + item.onWalkOn(this, room, new Object[]{this.getCurrentLocation(), next}); + } else if (item instanceof ConditionalGate) { + this.setRotation(oldRotation); + this.tilesWalked--; + this.setGoalLocation(this.currentLocation); + this.status.remove(RoomUnitStatus.MOVE); + room.sendComposer(new RoomUserStatusComposer(this).compose()); + + if (habbo != null) { + ((ConditionalGate) item).onRejected(this, this.getRoom(), new Object[]{}); + } + return false; + } + } else { + item.onWalk(this, room, new Object[]{this.getCurrentLocation(), next}); + } + + zHeight += item.getZ(); + + if (!item.getBaseItem().allowSit() && !item.getBaseItem().allowLay()) { + zHeight += Item.getCurrentHeight(item); + } + } else { + zHeight += room.getLayout().getHeightAtSquare(next.x, next.y); + } + + + this.setPreviousLocation(this.getCurrentLocation()); + + this.setStatus(RoomUnitStatus.MOVE, next.x + "," + next.y + "," + zHeight); + if (habbo != null) { + if (habbo.getHabboInfo().getRiding() != null) { + RoomUnit ridingUnit = habbo.getHabboInfo().getRiding().getRoomUnit(); + + if (ridingUnit != null) { + ridingUnit.setPreviousLocationZ(this.getZ()); + this.setZ(zHeight - 1.0); + ridingUnit.setRotation(RoomUserRotation.values()[Rotation.Calculate(this.getX(), this.getY(), next.x, next.y)]); + ridingUnit.setPreviousLocation(this.getCurrentLocation()); + ridingUnit.setGoalLocation(this.getGoal()); + ridingUnit.setStatus(RoomUnitStatus.MOVE, next.x + "," + next.y + "," + (zHeight - 1.0)); + room.sendComposer(new RoomUserStatusComposer(ridingUnit).compose()); + //ridingUnit.setZ(zHeight - 1.0); + } + } + } + //room.sendComposer(new RoomUserStatusComposer(this).compose()); + + this.setZ(zHeight); + this.setCurrentLocation(room.getLayout().getTile(next.x, next.y)); + this.resetIdleTimer(); + + if (habbo != null) { + HabboItem topItem = room.getTopItemAt(next.x, next.y); + + boolean isAtDoor = next.x == room.getLayout().getDoorX() && next.y == room.getLayout().getDoorY(); + boolean publicRoomKicks = !room.isPublicRoom() || Emulator.getConfig().getBoolean("hotel.room.public.doortile.kick"); + boolean invalidated = topItem != null && topItem.invalidatesToRoomKick(); + + if (this.canLeaveRoomByDoor && isAtDoor && publicRoomKicks && !invalidated) { + Emulator.getThreading().run(new RoomUnitKick(habbo, room, false), 500); + } + } + + return false; + + } catch (Exception e) { + LOGGER.error("Caught exception", e); + return false; + } + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public RoomTile getCurrentLocation() { + return this.currentLocation; + } + + public void setCurrentLocation(RoomTile location) { + if (location != null) { + if (this.currentLocation != null) { + this.currentLocation.removeUnit(this); + } + this.currentLocation = location; + location.addUnit(this); + } + } + + public short getX() { + return this.currentLocation.x; + } + + public short getY() { + return this.currentLocation.y; + } + + public double getZ() { + return this.z; + } + + public void setZ(double z) { + this.z = z; + + if (this.room != null) { + Bot bot = this.room.getBot(this); + if (bot != null) { + bot.needsUpdate(true); + } + } + } + + public boolean isInRoom() { + return this.inRoom; + } + + public synchronized void setInRoom(boolean inRoom) { + this.inRoom = inRoom; + } + + public RoomUnitType getRoomUnitType() { + return this.roomUnitType; + } + + public synchronized void setRoomUnitType(RoomUnitType roomUnitType) { + this.roomUnitType = roomUnitType; + } + + public void setRotation(RoomUserRotation rotation) { + this.bodyRotation = rotation; + this.headRotation = rotation; + } + + public RoomUserRotation getBodyRotation() { + return this.bodyRotation; + } + + public void setBodyRotation(RoomUserRotation bodyRotation) { + this.bodyRotation = bodyRotation; + } + + public RoomUserRotation getHeadRotation() { + return this.headRotation; + } + + public void setHeadRotation(RoomUserRotation headRotation) { + this.headRotation = headRotation; + } + + public DanceType getDanceType() { + return this.danceType; + } + + public synchronized void setDanceType(DanceType danceType) { + this.danceType = danceType; + } + + public void setCanWalk(boolean value) { + this.canWalk = value; + } + + public boolean canWalk() { + return this.canWalk; + } + + public boolean isFastWalk() { + return this.fastWalk; + } + + public void setFastWalk(boolean fastWalk) { + this.fastWalk = fastWalk; + } + + public RoomTile getStartLocation() { + return this.startLocation; + } + + public int tilesWalked() { + return this.tilesWalked; + } + + public RoomTile getGoal() { + return this.goalLocation; + } + + public void setGoalLocation(RoomTile goalLocation) { + if (goalLocation != null) { + // if (goalLocation.state != RoomTileState.INVALID) { + this.setGoalLocation(goalLocation, false); + } + //} + } + + public void setGoalLocation(RoomTile goalLocation, boolean noReset) { + if (Emulator.getPluginManager().isRegistered(RoomUnitSetGoalEvent.class, false)) + { + Event event = new RoomUnitSetGoalEvent(this.room, this, goalLocation); + Emulator.getPluginManager().fireEvent(event); + + if (event.isCancelled()) + return; + } + + /// Set start location + this.startLocation = this.currentLocation; + + if (goalLocation != null && !noReset) { + boolean isWalking = this.hasStatus(RoomUnitStatus.MOVE); + this.goalLocation = goalLocation; + this.findPath(); ///< Quadral: this is where we start formulating a path + if (!this.path.isEmpty()) { + this.tilesWalked = isWalking ? this.tilesWalked : 0; + this.cmdSit = false; + } else { + this.goalLocation = this.currentLocation; + } + } + } + + public void setLocation(RoomTile location) { + if (location != null) { + this.startLocation = location; + setPreviousLocation(location); + setCurrentLocation(location); + this.goalLocation = location; + } + } + + public RoomTile getPreviousLocation() { + return this.previousLocation; + } + + public void setPreviousLocation(RoomTile previousLocation) { + this.previousLocation = previousLocation; + this.previousLocationZ = this.z; + } + + public double getPreviousLocationZ() { + return this.previousLocationZ; + } + + public void setPreviousLocationZ(double z) { + this.previousLocationZ = z; + } + + public void setPathFinderRoom(Room room) { + this.room = room; + } + + public void findPath() + { + if (this.room != null && this.room.getLayout() != null && this.goalLocation != null && (this.goalLocation.isWalkable() || this.room.canSitOrLayAt(this.goalLocation.x, this.goalLocation.y) || this.canOverrideTile(this.goalLocation))) { + Deque path = this.room.getLayout().findPath(this.currentLocation, this.goalLocation, this.goalLocation, this); + if (path != null) this.path = path; + } + } + + public boolean isAtGoal() { + return this.currentLocation.equals(this.goalLocation); + } + + public boolean isWalking() { + return !this.isAtGoal() && this.canWalk; + } + + public String getStatus(RoomUnitStatus key) { + return this.status.get(key); + } + + public ConcurrentHashMap getStatusMap() { + return this.status; + } + + public void removeStatus(RoomUnitStatus key) { + this.status.remove(key); + } + + public void setStatus(RoomUnitStatus key, String value) { + if (key != null && value != null) { + this.status.put(key, value); + } + } + + public boolean hasStatus(RoomUnitStatus key) { + return this.status.containsKey(key); + } + + public void clearStatus() { + this.status.clear(); + } + + public void statusUpdate(boolean update) { + this.statusUpdate = update; + } + + public boolean needsStatusUpdate() { + return this.statusUpdate; + } + + public TMap getCacheable() { + return this.cacheable; + } + + public int getHandItem() { + return this.handItem; + } + + public void setHandItem(int handItem) { + this.handItem = handItem; + this.handItemTimestamp = System.currentTimeMillis(); + } + + public long getHandItemTimestamp() { + return this.handItemTimestamp; + } + + public int getEffectId() { + return this.effectId; + } + + public void setEffectId(int effectId, int endTimestamp) { + this.effectId = effectId; + this.effectEndTimestamp = endTimestamp; + } + + public int getEffectEndTimestamp() { + return this.effectEndTimestamp; + } + + public int getWalkTimeOut() { + return this.walkTimeOut; + } + + public void setWalkTimeOut(int walkTimeOut) { + this.walkTimeOut = walkTimeOut; + } + + public void increaseTimeInRoom() { + this.timeInRoom++; + } + + public int getTimeInRoom() { + return this.timeInRoom; + } + + public void resetTimeInRoom() { + this.timeInRoom = 0; + } + + public void increaseIdleTimer() { + this.idleTimer++; + } + + public boolean isIdle() { + return this.idleTimer > Room.IDLE_CYCLES; //Amount of room cycles / 2 = seconds. + } + + public int getIdleTimer() { + return this.idleTimer; + } + + public void resetIdleTimer() { + this.idleTimer = 0; + } + + public void setIdle() { + this.idleTimer = Room.IDLE_CYCLES + 1; + } + + public void lookAtPoint(RoomTile location) { + if (!this.canRotate) return; + + if (Emulator.getPluginManager().isRegistered(RoomUnitLookAtPointEvent.class, false)) { + Event lookAtPointEvent = new RoomUnitLookAtPointEvent(this.room, this, location); + Emulator.getPluginManager().fireEvent(lookAtPointEvent); + + if (lookAtPointEvent.isCancelled()) + return; + } + + if (this.status.containsKey(RoomUnitStatus.LAY)) { + return; + } + + if (!this.status.containsKey(RoomUnitStatus.SIT)) { + this.bodyRotation = (RoomUserRotation.values()[Rotation.Calculate(this.getX(), this.getY(), location.x, location.y)]); + } + + RoomUserRotation rotation = (RoomUserRotation.values()[Rotation.Calculate(this.getX(), this.getY(), location.x, location.y)]); + + if (Math.abs(rotation.getValue() - this.bodyRotation.getValue()) <= 1) { + this.headRotation = rotation; + } + } + + public Deque getPath() { + return this.path; + } + + public void setPath(Deque path) { + this.path = path; + } + + public RoomRightLevels getRightsLevel() { + return this.rightsLevel; + } + + public void setRightsLevel(RoomRightLevels rightsLevel) { + this.rightsLevel = rightsLevel; + } + + public Room getRoom() { + return room; + } + + public void setRoom(Room room) { + this.room = room; + } + + public boolean canOverrideTile(RoomTile tile) { + if (tile == null || room == null || room.getLayout() == null) return false; + + if (room.getItemsAt(tile).stream().anyMatch(i -> i.canOverrideTile(this, room, tile))) + return true; + + int tileIndex = (tile.x & 0xFF) | (tile.y << 12); + return this.overridableTiles.contains(tileIndex); + } + + public void addOverrideTile(RoomTile tile) { + int tileIndex = (tile.x & 0xFF) | (tile.y << 12); + if (!this.overridableTiles.contains(tileIndex)) { + this.overridableTiles.add(tileIndex); + } + } + + public void removeOverrideTile(RoomTile tile) { + if (room == null || room.getLayout() == null) return; + + int tileIndex = (tile.x & 0xFF) | (tile.y << 12); + this.overridableTiles.remove(tileIndex); + } + + public void clearOverrideTiles() { + this.overridableTiles.clear(); + } + + public boolean canLeaveRoomByDoor() { + return canLeaveRoomByDoor; + } + + public void setCanLeaveRoomByDoor(boolean canLeaveRoomByDoor) { + this.canLeaveRoomByDoor = canLeaveRoomByDoor; + } + + public boolean canForcePosture() { + if (this.room == null) return false; + + HabboItem topItem = this.room.getTopItemAt(this.getX(), this.getY()); + + return topItem == null || (!(topItem instanceof InteractionWater) && !(topItem instanceof InteractionWaterItem)); + } + + public RoomTile getClosestTile(List tiles) { + return tiles.stream().min(Comparator.comparingDouble(a -> a.distance(this.getCurrentLocation()))).orElse(null); + } + + public RoomTile getClosestAdjacentTile(short x, short y, boolean diagonal) { + if(room == null) return null; + + RoomTile baseTile = room.getLayout().getTile(x, y); + + if (baseTile == null) return null; + + List rotations = new ArrayList<>(); + rotations.add(RoomUserRotation.SOUTH.getValue()); + rotations.add(RoomUserRotation.NORTH.getValue()); + rotations.add(RoomUserRotation.EAST.getValue()); + rotations.add(RoomUserRotation.WEST.getValue()); + + if (diagonal) { + rotations.add(RoomUserRotation.NORTH_EAST.getValue()); + rotations.add(RoomUserRotation.NORTH_WEST.getValue()); + rotations.add(RoomUserRotation.SOUTH_EAST.getValue()); + rotations.add(RoomUserRotation.SOUTH_WEST.getValue()); + } + + return this.getClosestTile( + rotations.stream() + .map(rotation -> room.getLayout().getTileInFront(baseTile, rotation)) + .filter(t -> t != null && t.isWalkable() && (this.getCurrentLocation().equals(t) || !room.hasHabbosAt(t.x, t.y))) + .collect(Collectors.toList()) + ); + } + + public ScheduledFuture getMoveBlockingTask() { + return moveBlockingTask; + } + + public void setMoveBlockingTask(ScheduledFuture moveBlockingTask) { + this.moveBlockingTask = moveBlockingTask; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitEffect.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitEffect.java new file mode 100644 index 0000000..3be40d2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitEffect.java @@ -0,0 +1,226 @@ +package com.eu.habbo.habbohotel.rooms; + +public enum RoomUnitEffect { + //(\w+)\s(\w+)\s(\w+) + //\2\(\1\), + NONE(0), + SPOTLIGHT(1), + HOVERBOARD(2), + UFOBLUE(3), + TWINKLE(4), + TORCH(5), + JETPACK(6), + BUTTERFLIES(7), + FIREFLIES(8), + LOVE(9), + FLIES(10), + XRAY(11), + ICE(12), + GHOST(13), + HOVERBOARDPINK(14), + HOVERBOARDYELLOW(15), + MICROPHONE(16), + UFOPINK(17), + UFOYELLOW(18), + CARPOLICE(19), + CARAMBULANCE(20), + CARDOLLAR(21), + CARTOPFUEL(22), + TOTEMMAN(23), + TOTEMMERDRAGON(24), + TOTEMEAGLE(25), + TOTEMMIX(26), + VIKING(27), + SPLASH(28), + SWIMMING(29), + WADE(30), + CHEETOS(31), + DESPICABLEME(32), + BBRED(33), + BBGREEN(34), + BBBLUE(35), + BBYELLOW(36), + WADEINSWAMP(37), + ICESKATINGBOYS(38), + ICESKATINGGIRLS(39), + ESRED(40), + ESGREEN(41), + ESBLUE(42), + ESYELLOW(43), + SIMS(44), + TAGGEDICESKATINGBOYS(45), + TAGGEDICESKATINGGIRLS(46), + MEGAMIND(47), + CARDOGGY(48), + ESREDUNTOUCHABLE(49), + ESGREENUNTOUCHABLE(50), + ESBLUEUNTOUCHABLE(51), + ESYELLOWUNTOUCHABLE(52), + EASTERCHICKS(53), + EASTERBUNNY(54), + ROLLERSKATINGBOYS(55), + ROLLERSKATINGGIRLS(56), + TAGGEDROLLERSKATINGBOYS(57), + TAGGEDROLLERSKATINGGIRLS(58), + SUNNYDELIGHT(59), + RANGO(60), + DISNEYCHANNELEFFECT1(61), + DISNEYCHANNELEFFECT2(62), + DISNEYCHANNELEFFECT3(63), + CANDLE(64), + MOBILE0800(65), + DISNEYWIZARDSOFWAVERLY(66), + RIOPARROT(67), + EASTERTAGGING(68), + VOLKSWAGEN(69), + KUNGFUPANDA(70), + SKATEBOARD1(71), + SKATEBOARD2(72), + CHUPACHUPS(73), + LEI1(74), + LEI2(75), + LEI3(76), + RIDING(77), + PERRY(78), + ALIENMASK(79), + GIANTMOUTH(80), + SWAMPCREATUREMASK(81), + INKBLOTMASK(82), + MIMEMASK(83), + MUMMYMASK(84), + PUMPKINMASK(85), + SCARECROWMASK(86), + WOLFMASK(87), + ZOMBIEMASK(88), + BACKKNIFE(89), + BUTTERYFLYWINGS1(90), + FAIRYWINGS1(91), + GHOSTSHEET(92), + HEADLESS(93), + LIISUTRUCK(94), + SNOWWARRED(95), + SNOWWARBLUE(96), + SNOWBOARDPLCH(97), + SNOWSTORMCROSSHAIR(98), + NIKO(99), + DRAGON(100), + BANGGUN(101), + STAFF(102), + RIDINGSADDLE2(103), + PIE(104), + DUBBELFRISSS(105), + BLUETORCH(106), + PLASTOPODCHAIR(107), + NINJADISAPPEAR(108), + MEDAL1(109), + MEDAL2(110), + MEDAL3(111), + SPIDERMAN(112), + RAINCLOUD(113), + STRONGARMS(114), + RINGMASTER(115), + FLY(116), + EXECUTIONER(117), + EVILCLOWN(118), + DARKALIENMASK(119), + GIANTMOUTH2(120), + SWAMPCREATUREMASK2(121), + INKBLOTMASK2(122), + MIMEMASK2(123), + MUMMY2MASK(124), + FROSTPUMPKINMASK(125), + SCARECROWMASK2(126), + EVILWOLFMASK(127), + ZOMBIEMASK2(128), + BACKKNIFE2(129), + BUTTERYFLYWINGS2(130), + FAIRYWINGS2(131), + GLOWINGGHOSTSHEET(132), + HEADLESS2(133), + SNAKEBODY(134), + PUPPETMASTER(135), + BACKWALKINGSHOES(136), + GOLDSPOTLIGHT(137), + GOLDENGLASSES(138), + GOLDMICROPHONE(139), + HABNAMDANCE(140), + FLOWERMASK(141), + GOATMASK(142), + FEATHERMASK1(143), + FEATHERMASK2(144), + FEATHERMASK3(145), + FEATHERMASK4(146), + PEACOCK1MASK(147), + PEACOCK2MASK(148), + PEACOCK3MASK(149), + PEACOCK4MASK(150), + GOATMASK2(151), + GOATMASK3(152), + FLOWERMASK2(153), + MASSIVEEGG(154), + BCRYSTAL(155), + GCRYSTAL(156), + PIMPLE(157), + PINATA(158), + BARREL(159), + PIRATECAPTAIN(160), + PIRATECREW(161), + PIRATESWORD(162), + HEADONTHEGROUND(163), + PIRATEGUN(164), + SPINNINGTHUMBSUP(165), + GOBLIN(166), + MUTANT(167), + SPINNINGHEATS(168), + SLIMED(169), + DUCK(170), + SPACEBUNNY(171), + REDVIKING(172), + GREENVIKING(173), + HOVERBOARDGREEN(174), + REDAIRPLANE(175), + BLUEAIRPLANE(176), + TARANDFEATHER(177), + AMBASSADOR(178), + LUCHADOR(179), + DAYOFTHEDEAD(180), + DAYOFTHEDEAD2(181), + CYBERPUNKGUN(182), + FOSSILHAMMER(183), + SPLASHEVIL(184), + SWIMEVIL(185), + MAGICWAND(186), + BOT(187), + CAMERABOT(188), + MOBILEDISCO(189), + MOBILEDISCO2(190), + HOVERPLANK(191), + WATERINGCAN(192), + TRAMPOLINEJUMP(193), + TREADMILL(194), + CROSSTRAINER(195), + STARWARS(196), + FLYINGCARPET(197), + YELLOWDUCK(198), + FLYNGTURTLE(199); + + private int id; + + RoomUnitEffect(int id) { + this.id = id; + } + + public static RoomUnitEffect fromId(int id) { + for (RoomUnitEffect effect : RoomUnitEffect.values()) { + if (effect.id == id) { + return effect; + } + } + + return RoomUnitEffect.NONE; + } + + public int getId() { + return this.id; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitStatus.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitStatus.java new file mode 100644 index 0000000..7319176 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitStatus.java @@ -0,0 +1,96 @@ +package com.eu.habbo.habbohotel.rooms; + +public enum RoomUnitStatus { + MOVE("mv", true), + + SIT_IN("sit-in"), + SIT("sit", true), + SIT_OUT("sit-out"), + + LAY_IN("lay-in"), + LAY("lay", true), + LAY_OUT("lay-out"), + + FLAT_CONTROL("flatctrl"), + SIGN("sign"), + GESTURE("gst"), + WAVE("wav"), + TRADING("trd"), + + DIP("dip"), + + EAT_IN("eat-in"), + EAT("eat"), + EAT_OUT("eat-out"), + + BEG("beg", true), + + DEAD_IN("ded-in"), + DEAD("ded", true), + DEAD_OUT("ded-out"), + + JUMP_IN("jmp-in"), + JUMP("jmp", true), + JUMP_OUT("jmp-out"), + + PLAY_IN("pla-in"), + PLAY("pla", true), + PLAY_OUT("pla-out"), + + SPEAK("spk"), + CROAK("crk"), + RELAX("rlx"), + WINGS("wng", true), + FLAME("flm"), + RIP("rip"), + GROW("grw"), + GROW_1("grw1"), + GROW_2("grw2"), + GROW_3("grw3"), + GROW_4("grw4"), + GROW_5("grw5"), + GROW_6("grw6"), + GROW_7("grw7"), + + KICK("kck"), + WAG_TAIL("wag"), + DANCE("dan"), + AMS("ams"), + SWIM("swm"), + TURN("trn"), + + SRP("srp"), + SRP_IN("srp-in"), + + SLEEP_IN("slp-in"), + SLEEP("slp", true), + SLEEP_OUT("slp-out"); + + public final String key; + public final boolean removeWhenWalking; + + RoomUnitStatus(String key) { + this.key = key; + this.removeWhenWalking = false; + } + + RoomUnitStatus(String key, boolean removeWhenWalking) { + this.key = key; + this.removeWhenWalking = removeWhenWalking; + } + + public static RoomUnitStatus fromString(String key) { + for (RoomUnitStatus status : values()) { + if (status.key.equalsIgnoreCase(key)) { + return status; + } + } + + return null; + } + + @Override + public String toString() { + return this.key; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitType.java new file mode 100644 index 0000000..83d3902 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUnitType.java @@ -0,0 +1,18 @@ +package com.eu.habbo.habbohotel.rooms; + +public enum RoomUnitType { + USER(1), + BOT(4), + PET(2), + UNKNOWN(3); + + private final int typeId; + + RoomUnitType(int typeId) { + this.typeId = typeId; + } + + public int getTypeId() { + return this.typeId; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUserAction.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUserAction.java new file mode 100644 index 0000000..03f257b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUserAction.java @@ -0,0 +1,32 @@ +package com.eu.habbo.habbohotel.rooms; + +public enum RoomUserAction { + NONE(0), + WAVE(1), + BLOW_KISS(2), + LAUGH(3), + UNKNOWN(4), + IDLE(5), + JUMP(6), + THUMB_UP(7); + + private final int action; + + RoomUserAction(int action) { + this.action = action; + } + + public static RoomUserAction fromValue(int value) { + for (RoomUserAction action : RoomUserAction.values()) { + if (action.getAction() == value) { + return action; + } + } + + return NONE; + } + + public int getAction() { + return this.action; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUserRotation.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUserRotation.java new file mode 100644 index 0000000..11f9f77 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomUserRotation.java @@ -0,0 +1,63 @@ +package com.eu.habbo.habbohotel.rooms; + +public enum RoomUserRotation { + NORTH(0), + NORTH_EAST(1), + EAST(2), + SOUTH_EAST(3), + SOUTH(4), + SOUTH_WEST(5), + WEST(6), + NORTH_WEST(7); + + private final int direction; + + RoomUserRotation(int direction) { + this.direction = direction; + } + + public static RoomUserRotation fromValue(int rotation) { + rotation %= 8; + for (RoomUserRotation rot : values()) { + if (rot.getValue() == rotation) { + return rot; + } + } + + return NORTH; + } + + public static RoomUserRotation counterClockwise(RoomUserRotation rotation) { + return fromValue(rotation.getValue() + 7); + } + + public static RoomUserRotation clockwise(RoomUserRotation rotation) { + return fromValue(rotation.getValue() + 9); + } + + public int getValue() { + return this.direction; + } + + public RoomUserRotation getOpposite() { + switch (this) { + case NORTH: + return RoomUserRotation.SOUTH; + case NORTH_EAST: + return RoomUserRotation.SOUTH_WEST; + case EAST: + return RoomUserRotation.WEST; + case SOUTH_EAST: + return RoomUserRotation.NORTH_WEST; + case SOUTH: + return RoomUserRotation.NORTH; + case SOUTH_WEST: + return RoomUserRotation.NORTH_EAST; + case WEST: + return RoomUserRotation.EAST; + case NORTH_WEST: + return RoomUserRotation.SOUTH_EAST; + } + return null; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/TraxManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/TraxManager.java new file mode 100644 index 0000000..e719bdf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/TraxManager.java @@ -0,0 +1,443 @@ +package com.eu.habbo.habbohotel.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.core.Disposable; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.SoundTrack; +import com.eu.habbo.habbohotel.items.interactions.InteractionJukeBox; +import com.eu.habbo.habbohotel.items.interactions.InteractionMusicDisc; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.inventory.RemoveHabboItemComposer; +import com.eu.habbo.messages.outgoing.rooms.items.jukebox.JukeBoxMySongsComposer; +import com.eu.habbo.messages.outgoing.rooms.items.jukebox.JukeBoxNowPlayingMessageComposer; +import com.eu.habbo.messages.outgoing.rooms.items.jukebox.JukeBoxPlayListComposer; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@Slf4j +public class TraxManager implements Disposable { + public static int NORMAL_JUKEBOX_LIMIT = 10; + public static int LARGE_JUKEBOX_LIMIT = 20; + private final Room room; + private InteractionJukeBox jukeBox; + private final List songs = new ArrayList<>(0); + private int totalLength = 0; + private int startedTimestamp = 0; + private InteractionMusicDisc currentlyPlaying = null; + private int playingIndex = 0; + private int cycleStartedTimestamp = 0; + private Habbo starter = null; + private int songsLimit = 0; + + private boolean disposed = false; + + public TraxManager(Room room) { + this.room = room; + + //Check if room has a Jukebox already on DB + this.jukeBox = this.loadRoomJukebox(); + + if (this.jukeBox == null) { + //Check again if there's a jukebox on room but has not been saved on DB before + for (HabboItem item : room.getRoomSpecialTypes().getItemsOfType(InteractionJukeBox.class)) + { + this.jukeBox = (InteractionJukeBox) item; + } + + if(this.jukeBox != null) + { + this.loadPlaylist(); + this.songsLimit = this.getSongsLimit(this.jukeBox); + } + } else { + this.loadPlaylist(); + this.songsLimit = this.getSongsLimit(this.jukeBox); + } + } + + public InteractionJukeBox loadRoomJukebox() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM room_trax WHERE room_id = ?")) { + statement.setInt(1, this.room.getId()); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + HabboItem jukebox = Emulator.getGameEnvironment().getItemManager().loadHabboItem(set.getInt("trax_item_id")); + if(jukebox != null) { + if (!(jukebox instanceof InteractionJukeBox)) { + return null; + } else { + return (InteractionJukeBox) jukebox; + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return null; + } + + public void loadPlaylist() { + if(this.jukeBox == null) return; + + this.songs.clear(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM trax_playlist WHERE trax_item_id = ?")) { + statement.setInt(1, this.jukeBox.getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + HabboItem musicDisc = Emulator.getGameEnvironment().getItemManager().loadHabboItem(set.getInt("item_id")); + if(musicDisc != null) { + if (!(musicDisc instanceof InteractionMusicDisc) || musicDisc.getRoomId() != -1) { + deleteSongFromPlaylist(this.jukeBox.getId(), musicDisc.getId()); + } else { + SoundTrack track = Emulator.getGameEnvironment().getItemManager().getSoundTrack(((InteractionMusicDisc) musicDisc).getSongId()); + + if (track != null) { + this.songs.add((InteractionMusicDisc) musicDisc); + this.totalLength += track.getLength(); + } + } + } + + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public static void deleteSongFromPlaylist(int jukebox_id, int song_id) + { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM trax_playlist WHERE trax_item_id = ? AND item_id = ? LIMIT 1")) { + statement.setInt(1, jukebox_id); + statement.setInt(2, song_id); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void addTraxOnRoom(InteractionJukeBox jukeBox) { + if(this.jukeBox != null) return; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement_1 = connection.prepareStatement("INSERT INTO room_trax (room_id, trax_item_id) VALUES (?, ?)")) + { + statement_1.setInt(1, this.room.getId()); + statement_1.setInt(2, jukeBox.getId()); + statement_1.execute(); + } + catch (SQLException e) { + log.error("Caught SQL exception", e); + return; + } + + this.jukeBox = jukeBox; + this.loadPlaylist(); + this.songsLimit = this.getSongsLimit(this.jukeBox); + } + + public void removeTraxOnRoom(InteractionJukeBox jukeBox) { + if(this.jukeBox.getId() != jukeBox.getId()) return; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement_1 = connection.prepareStatement("DELETE FROM room_trax WHERE room_id = ?")) + { + statement_1.setInt(1, this.room.getId()); + statement_1.execute(); + } + catch (SQLException e) { + log.error("Caught SQL exception", e); + return; + } + + this.stop(); + this.jukeBox = null; + this.songs.clear(); + } + + public void cycle() { + if (this.isPlaying()) { + if (this.timePlaying() >= this.totalLength) { + this.play(0); + //restart + } + + if (this.currentSong() != null && Emulator.getIntUnixTimestamp() >= this.startedTimestamp + this.currentSong().getLength()) { + this.play((this.playingIndex + 1) % this.songs.size()); + } + } + } + + public void play(int index) { + this.play(index, null); + } + + public void play(int index, Habbo starter) { + if (this.currentlyPlaying == null) { + this.jukeBox.setExtradata("1"); + this.room.updateItem(this.jukeBox); + } + + if (!this.songs.isEmpty()) { + index = index % this.songs.size(); + + this.currentlyPlaying = this.songs.get(index); + + if (this.currentlyPlaying != null) { + this.room.setJukeBoxActive(true); + this.startedTimestamp = Emulator.getIntUnixTimestamp(); + this.playingIndex = index; + + if (starter != null) { + this.starter = starter; + this.cycleStartedTimestamp = Emulator.getIntUnixTimestamp(); + } + } + + this.room.sendComposer(new JukeBoxNowPlayingMessageComposer(Emulator.getGameEnvironment().getItemManager().getSoundTrack(this.currentlyPlaying.getSongId()), this.playingIndex, 0).compose()); + } else { + this.stop(); + } + } + + public void stop() { + if (this.starter != null && this.cycleStartedTimestamp > 0) { + AchievementManager.progressAchievement(this.starter, Emulator.getGameEnvironment().getAchievementManager().getAchievement("MusicPlayer"), (Emulator.getIntUnixTimestamp() - cycleStartedTimestamp) / 60); + } + + this.room.setJukeBoxActive(false); + this.currentlyPlaying = null; + this.startedTimestamp = 0; + this.cycleStartedTimestamp = 0; + this.starter = null; + this.playingIndex = 0; + + this.jukeBox.setExtradata("0"); + this.room.updateItem(this.jukeBox); + + this.room.sendComposer(new JukeBoxNowPlayingMessageComposer(null, -1, 0).compose()); + } + + public SoundTrack currentSong() { + if (!this.songs.isEmpty() && this.playingIndex < this.songs.size()) { + return Emulator.getGameEnvironment().getItemManager().getSoundTrack(this.songs.get(this.playingIndex).getSongId()); + } + return null; + } + + public void addSong(InteractionMusicDisc musicDisc, Habbo habbo) { + if(this.jukeBox == null) return; + + if(this.songsLimit < this.songs.size() + 1) + { + THashMap codes = new THashMap<>(); + ServerMessage msg = new BubbleAlertComposer("${playlist.editor.alert.playlist.full.title}", "${playlist.editor.alert.playlist.full}").compose(); + habbo.getClient().sendResponse(msg); + return; + } + + SoundTrack track = Emulator.getGameEnvironment().getItemManager().getSoundTrack(musicDisc.getSongId()); + + if (track != null) + { + this.totalLength += track.getLength(); + this.songs.add(musicDisc); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO trax_playlist (trax_item_id, item_id) VALUES (?, ?)")) { + statement.setInt(1, this.jukeBox.getId()); + statement.setInt(2, musicDisc.getId()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + return; + } + + this.room.sendComposer(new JukeBoxPlayListComposer(this.songs, this.totalLength).compose()); + + musicDisc.setRoomId(-1); + musicDisc.needsUpdate(true); + Emulator.getThreading().run(musicDisc); + + habbo.getInventory().getItemsComponent().removeHabboItem(musicDisc); + habbo.getClient().sendResponse(new RemoveHabboItemComposer(musicDisc.getGiftAdjustedId())); + } + + this.sendUpdatedSongList(); + } + + public void removeSong(int itemId) { + if(this.songs.isEmpty()) return; + + InteractionMusicDisc musicDisc = this.getSong(itemId); + + if (musicDisc != null) { + this.songs.remove(musicDisc); + + deleteSongFromPlaylist(this.jukeBox.getId(), itemId); + + this.totalLength -= Emulator.getGameEnvironment().getItemManager().getSoundTrack(musicDisc.getSongId()).getLength(); + if (this.currentlyPlaying == musicDisc) { + this.play(this.playingIndex); + } + + this.room.sendComposer(new JukeBoxPlayListComposer(this.songs, this.totalLength).compose()); + + musicDisc.setRoomId(0); + musicDisc.needsUpdate(true); + Emulator.getThreading().run(musicDisc); + + Habbo owner = Emulator.getGameEnvironment().getHabboManager().getHabbo(musicDisc.getUserId()); + + if (owner != null) { + owner.getInventory().getItemsComponent().addItem(musicDisc); + + GameClient client = owner.getClient(); + if (client != null) { + client.sendResponse(new AddHabboItemComposer(musicDisc)); + client.sendResponse(new InventoryRefreshComposer()); + } + } + } + + this.sendUpdatedSongList(); + } + + public static void removeAllSongs(InteractionJukeBox jukebox) + { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM trax_playlist WHERE trax_item_id = ?")) { + statement.setInt(1, jukebox.getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + HabboItem musicDisc = Emulator.getGameEnvironment().getItemManager().loadHabboItem(set.getInt("item_id")); + deleteSongFromPlaylist(jukebox.getId(), set.getInt("item_id")); + + if(musicDisc != null) { + if (musicDisc instanceof InteractionMusicDisc && musicDisc.getRoomId() == -1) { + musicDisc.setRoomId(0); + musicDisc.needsUpdate(true); + Emulator.getThreading().run(musicDisc); + + Habbo owner = Emulator.getGameEnvironment().getHabboManager().getHabbo(musicDisc.getUserId()); + + if (owner != null) { + owner.getInventory().getItemsComponent().addItem(musicDisc); + + GameClient client = owner.getClient(); + if (client != null) { + client.sendResponse(new AddHabboItemComposer(musicDisc)); + client.sendResponse(new InventoryRefreshComposer()); + } + } + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public List soundTrackList() { + List trax = new ArrayList<>(this.songs.size()); + + for (InteractionMusicDisc musicDisc : this.songs) { + SoundTrack track = Emulator.getGameEnvironment().getItemManager().getSoundTrack(musicDisc.getSongId()); + + if (track != null) { + trax.add(track); + } + } + + return trax; + } + + public List myList(Habbo habbo) { + return habbo.getInventory().getItemsComponent().getItems().valueCollection().stream() + .filter(i -> i instanceof InteractionMusicDisc && i.getRoomId() == 0) + .map(i -> (InteractionMusicDisc) i) + .collect(Collectors.toList()); + } + + public InteractionMusicDisc getSong(int itemId) { + for (InteractionMusicDisc musicDisc : this.songs) { + if (musicDisc != null && musicDisc.getId() == itemId) { + return musicDisc; + } + } + + return null; + } + + public int getSongsLimit(InteractionJukeBox jukeBox) { + if ("jukebox_big".equals(jukeBox.getBaseItem().getName())) { + return LARGE_JUKEBOX_LIMIT; + } + return NORMAL_JUKEBOX_LIMIT; + } + + public void updateCurrentPlayingSong(Habbo habbo) { + if (this.isPlaying()) { + habbo.getClient().sendResponse(new JukeBoxNowPlayingMessageComposer(Emulator.getGameEnvironment().getItemManager().getSoundTrack(this.currentlyPlaying.getSongId()), this.playingIndex, 1000 * (Emulator.getIntUnixTimestamp() - this.startedTimestamp))); + } else { + habbo.getClient().sendResponse(new JukeBoxNowPlayingMessageComposer(null, -1, 0)); + } + } + + public void sendUpdatedSongList() { + this.room.getHabbos().forEach(h -> { + GameClient client = h.getClient(); + + if (client != null) { + client.sendResponse(new JukeBoxMySongsComposer(this.myList(h))); + } + }); + } + + public int timePlaying() { + return Emulator.getIntUnixTimestamp() - this.startedTimestamp; + } + + public int totalLength() { + return this.totalLength; + } + + public List getSongs() { + return this.songs; + } + + public boolean isPlaying() { + return this.currentlyPlaying != null; + } + + public int getSongsLimit() { + return this.songsLimit; + } + + public InteractionJukeBox getJukeBox() { + return this.jukeBox; + } + + @Override + public void dispose() { + this.disposed = true; + } + + @Override + public boolean disposed() { + return this.disposed; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/DanceType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/DanceType.java new file mode 100644 index 0000000..45097b6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/DanceType.java @@ -0,0 +1,19 @@ +package com.eu.habbo.habbohotel.users; + +public enum DanceType { + NONE(0), + HAB_HOP(1), + POGO_MOGO(2), + DUCK_FUNK(3), + THE_ROLLIE(4); + + private final int type; + + DanceType(int type) { + this.type = type; + } + + public int getType() { + return this.type; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java new file mode 100644 index 0000000..dff68de --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java @@ -0,0 +1,503 @@ +package com.eu.habbo.habbohotel.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.messenger.Messenger; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.inventory.BadgesComponent; +import com.eu.habbo.messages.outgoing.generic.alerts.*; +import com.eu.habbo.messages.outgoing.inventory.*; +import com.eu.habbo.messages.outgoing.rooms.FloodCounterComposer; +import com.eu.habbo.messages.outgoing.rooms.ForwardToRoomComposer; +import com.eu.habbo.messages.outgoing.rooms.users.*; +import com.eu.habbo.messages.outgoing.users.*; +import com.eu.habbo.plugin.events.furniture.FurnitureBuildheightEvent; +import com.eu.habbo.plugin.events.users.UserCreditsEvent; +import com.eu.habbo.plugin.events.users.UserDisconnectEvent; +import com.eu.habbo.plugin.events.users.UserGetIPAddressEvent; +import com.eu.habbo.plugin.events.users.UserPointsEvent; +import gnu.trove.TIntCollection; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.sql.ResultSet; +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +public class Habbo implements Runnable { + + private final HabboInfo habboInfo; + private final HabboStats habboStats; + private final Messenger messenger; + private final HabboInventory habboInventory; + private GameClient client; + private RoomUnit roomUnit; + + private volatile boolean update; + private volatile boolean disconnected = false; + private volatile boolean disconnecting = false; + + public Habbo(ResultSet set) { + this.client = null; + this.habboInfo = new HabboInfo(set); + this.habboStats = HabboStats.load(this.habboInfo); + this.habboInventory = new HabboInventory(this); + + this.messenger = new Messenger(); + this.messenger.loadFriends(this); + this.messenger.loadFriendRequests(this); + + this.roomUnit = new RoomUnit(); + this.roomUnit.setRoomUnitType(RoomUnitType.USER); + this.update = false; + } + + public boolean isOnline() { + return this.habboInfo.isOnline(); + } + + void isOnline(boolean value) { + this.habboInfo.setOnline(value); + this.update(); + } + + void update() { + this.update = true; + this.run(); + } + + void needsUpdate(boolean value) { + this.update = value; + } + + boolean needsUpdate() { + return this.update; + } + + public Messenger getMessenger() { + return this.messenger; + } + + public HabboInfo getHabboInfo() { + return this.habboInfo; + } + + public HabboStats getHabboStats() { + return this.habboStats; + } + + public HabboInventory getInventory() { + return this.habboInventory; + } + + public RoomUnit getRoomUnit() { + return this.roomUnit; + } + + public void setRoomUnit(RoomUnit roomUnit) { + this.roomUnit = roomUnit; + } + + public GameClient getClient() { + return this.client; + } + + public void setClient(GameClient client) { + this.client = client; + } + + + public boolean connect() { + String ip = ""; + String ProxyIP = ""; + + if (!Emulator.getConfig().getBoolean("networking.tcp.proxy") && this.client.getChannel().remoteAddress() != null) { + SocketAddress address = this.client.getChannel().remoteAddress(); + ip = ((InetSocketAddress) address).getAddress().getHostAddress(); + ProxyIP = "- no proxy server used"; + } + else + { + SocketAddress address = this.client.getChannel().remoteAddress(); + ProxyIP = ((InetSocketAddress) address).getAddress().getHostAddress(); + } + + if (Emulator.getPluginManager().isRegistered(UserGetIPAddressEvent.class, true)) { + UserGetIPAddressEvent event = Emulator.getPluginManager().fireEvent(new UserGetIPAddressEvent(this, ip)); + if (event.hasChangedIP()) { + ip = event.getUpdatedIp(); + } + } + + if (!ip.isEmpty()) { + this.habboInfo.setIpLogin(ip); + } + + if (this.client.getMachineId() == null || this.client.getMachineId().length() == 0) { + return false; + } + + this.habboInfo.setMachineID(this.client.getMachineId()); + + if (Emulator.getGameEnvironment().getModToolManager().hasMACBan(this.client)) { + return false; + } + + if (Emulator.getGameEnvironment().getModToolManager().hasIPBan(this.habboInfo.getIpLogin())) { + return false; + } + + this.isOnline(true); + this.messenger.connectionChanged(this, true, false); + + Emulator.getGameEnvironment().getRoomManager().loadRoomsForHabbo(this); + log.info("{} logged in from IP {} using proxyserver {}", this.habboInfo.getUsername(), this.habboInfo.getIpLogin(), ProxyIP); + log.info("{} client MachineId = {}", this.habboInfo.getUsername(), this.client.getMachineId()); + return true; + } + + + public synchronized void disconnect() { + if (!Emulator.isShuttingDown) { + if (Emulator.getPluginManager().fireEvent(new UserDisconnectEvent(this)).isCancelled()) return; + } + + if (this.disconnected || this.disconnecting) + return; + + this.disconnecting = true; + + try { + if (this.getHabboInfo().getCurrentRoom() != null) { + Emulator.getGameEnvironment().getRoomManager().leaveRoom(this, this.getHabboInfo().getCurrentRoom()); + } + if (this.getHabboInfo().getRoomQueueId() > 0) { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getHabboInfo().getRoomQueueId()); + + if (room != null) { + room.removeFromQueue(this); + } + } + } catch (Exception e) { + log.error("Caught exception", e); + } + + try { + Emulator.getGameEnvironment().getGuideManager().userLogsOut(this); + this.isOnline(false); + this.needsUpdate(true); + this.run(); + this.getInventory().dispose(); + this.messenger.connectionChanged(this, false, false); + this.messenger.dispose(); + this.disconnected = true; + AchievementManager.saveAchievements(this); + + this.habboStats.dispose(); + } catch (Exception e) { + log.error("Caught exception", e); + return; + } finally { + Emulator.getGameEnvironment().getRoomManager().unloadRoomsForHabbo(this); + Emulator.getGameEnvironment().getHabboManager().removeHabbo(this); + } + log.info("{} disconnected.", this.habboInfo.getUsername()); + this.client = null; + } + + @Override + public void run() { + if (this.needsUpdate()) { + this.habboInfo.run(); + this.needsUpdate(false); + } + } + + + public boolean hasPermission(String key) { + return this.hasPermission(key, false); + } + + + public boolean hasPermission(String key, boolean hasRoomRights) { + return Emulator.getGameEnvironment().getPermissionsManager().hasPermission(this, key, hasRoomRights); + } + + + public void giveCredits(int credits) { + if (credits == 0) + return; + + UserCreditsEvent event = new UserCreditsEvent(this, credits); + if (Emulator.getPluginManager().fireEvent(event).isCancelled()) + return; + + this.getHabboInfo().addCredits(event.credits); + + if (this.client != null) this.client.sendResponse(new UserCreditsComposer(this.client.getHabbo())); + } + + + public void givePixels(int pixels) { + if (pixels == 0) + return; + + + UserPointsEvent event = new UserPointsEvent(this, pixels, 0); + if (Emulator.getPluginManager().fireEvent(event).isCancelled()) + return; + + this.getHabboInfo().addPixels(event.points); + if (this.client != null) this.client.sendResponse(new UserCurrencyComposer(this.client.getHabbo())); + } + + + public void givePoints(int points) { + this.givePoints(Emulator.getConfig().getInt("seasonal.primary.type"), points); + } + + + public void givePoints(int type, int points) { + if (points == 0) + return; + + UserPointsEvent event = new UserPointsEvent(this, points, type); + if (Emulator.getPluginManager().fireEvent(event).isCancelled()) + return; + + this.getHabboInfo().addCurrencyAmount(event.type, event.points); + if (this.client != null) + this.client.sendResponse(new UserPointsComposer(this.client.getHabbo().getHabboInfo().getCurrencyAmount(type), event.points, event.type)); + } + + + public void whisper(String message) { + this.whisper(message, this.habboStats.chatColor); + } + + + public void whisper(String message, RoomChatMessageBubbles bubble) { + if (this.getRoomUnit().isInRoom()) { + this.client.sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(message, this.client.getHabbo().getRoomUnit(), bubble))); + } + } + + + public void talk(String message) { + this.talk(message, this.habboStats.chatColor); + } + + + public void talk(String message, RoomChatMessageBubbles bubble) { + if (this.getRoomUnit().isInRoom()) { + this.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserTalkComposer(new RoomChatMessage(message, this.client.getHabbo().getRoomUnit(), bubble)).compose()); + } + } + + + public void shout(String message) { + this.shout(message, this.habboStats.chatColor); + } + + + public void shout(String message, RoomChatMessageBubbles bubble) { + if (this.getRoomUnit().isInRoom()) { + this.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserShoutComposer(new RoomChatMessage(message, this.client.getHabbo().getRoomUnit(), bubble)).compose()); + } + } + + + public void alert(String message) { + if (Emulator.getConfig().getBoolean("hotel.alert.oldstyle")) { + this.client.sendResponse(new MessagesForYouComposer(new String[]{message})); + } else { + this.client.sendResponse(new GenericAlertComposer(message)); + } + } + + + public void alert(String[] messages) { + this.client.sendResponse(new MessagesForYouComposer(messages)); + } + + + public void alertWithUrl(String message, String url) { + this.client.sendResponse(new StaffAlertWithLinkComposer(message, url)); + } + + + public void goToRoom(int id) { + this.client.sendResponse(new ForwardToRoomComposer(id)); + } + + + public void addFurniture(HabboItem item) { + this.habboInventory.getItemsComponent().addItem(item); + this.client.sendResponse(new AddHabboItemComposer(item)); + this.client.sendResponse(new InventoryRefreshComposer()); + } + + + public void addFurniture(THashSet items) { + this.habboInventory.getItemsComponent().addItems(items); + this.client.sendResponse(new AddHabboItemComposer(items)); + this.client.sendResponse(new InventoryRefreshComposer()); + } + + + public void removeFurniture(HabboItem item) { + this.habboInventory.getItemsComponent().removeHabboItem(item); + this.client.sendResponse(new RemoveHabboItemComposer(item.getId())); + } + + + public void addBot(Bot bot) { + this.habboInventory.getBotsComponent().addBot(bot); + this.client.sendResponse(new AddBotComposer(bot)); + } + + + public void removeBot(Bot bot) { + this.habboInventory.getBotsComponent().removeBot(bot); + this.client.sendResponse(new RemoveBotComposer(bot)); + } + + + public void deleteBot(Bot bot) { + this.removeBot(bot); + bot.getRoom().removeBot(bot); + Emulator.getGameEnvironment().getBotManager().deleteBot(bot); + } + + + public void addPet(Pet pet) { + this.habboInventory.getPetsComponent().addPet(pet); + this.client.sendResponse(new AddPetComposer(pet)); + } + + + public void removePet(Pet pet) { + this.habboInventory.getPetsComponent().removePet(pet); + this.client.sendResponse(new RemovePetComposer(pet)); + } + + + public boolean addBadge(String code) { + if (!this.habboInventory.getBadgesComponent().hasBadge(code)) { + HabboBadge badge = BadgesComponent.createBadge(code, this); + this.habboInventory.getBadgesComponent().addBadge(badge); + this.client.sendResponse(new AddUserBadgeComposer(badge)); + this.client.sendResponse(new AddHabboItemComposer(badge.getId(), AddHabboItemComposer.AddHabboItemCategory.BADGE)); + + THashMap keys = new THashMap<>(); + keys.put("display", "BUBBLE"); + keys.put("image", "${image.library.url}album1584/" + badge.getCode() + ".gif"); + keys.put("message", Emulator.getTexts().getValue("commands.generic.cmd_badge.received")); + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.RECEIVED_BADGE.key, keys)); + + return true; + } + + return false; + } + + + public void deleteBadge(HabboBadge badge) { + if (badge != null) { + this.habboInventory.getBadgesComponent().removeBadge(badge); + BadgesComponent.deleteBadge(this.getHabboInfo().getId(), badge.getCode()); + this.client.sendResponse(new InventoryBadgesComposer(this)); + } + } + + public void mute(int seconds, boolean isFlood) { + if (seconds <= 0) { + log.warn("Tried to mute user for {} seconds, which is invalid.", seconds); + return; + } + + if (!this.hasPermission("acc_no_mute")) { + int remaining = this.habboStats.addMuteTime(seconds); + this.client.sendResponse(new FloodCounterComposer(remaining)); + this.client.sendResponse(new MutedWhisperComposer(remaining)); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + if (room != null && !isFlood) { + room.sendComposer(new RoomUserIgnoredComposer(this, RoomUserIgnoredComposer.MUTED).compose()); + } + } + } + + public void unMute() { + this.habboStats.unMute(); + this.client.sendResponse(new FloodCounterComposer(3)); + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + if (room != null) { + room.sendComposer(new RoomUserIgnoredComposer(this, RoomUserIgnoredComposer.UNIGNORED).compose()); + } + } + + public int noobStatus() { + + return 1; + + } + + public void clearCaches() { + int currentTimestamp = Emulator.getIntUnixTimestamp(); + int twentyFourHoursInSeconds = 24 * 60 * 60; // 24 hours in seconds + + THashMap> newLog = new THashMap<>(); + + for (Map.Entry> ltdLog : this.habboStats.ltdPurchaseLog.entrySet()) { + List filteredTimestamps = new ArrayList<>(); + + for (Integer time : ltdLog.getValue()) { + if (currentTimestamp - time <= twentyFourHoursInSeconds) { + filteredTimestamps.add(time); + } + } + + if (!filteredTimestamps.isEmpty()) { + newLog.put(ltdLog.getKey(), filteredTimestamps); + } + } + this.habboStats.ltdPurchaseLog = newLog; + } + + + public void respect(Habbo target) { + if (target != null && target != this.client.getHabbo()) { + target.getHabboStats().respectPointsReceived++; + this.client.getHabbo().getHabboStats().respectPointsGiven++; + this.client.getHabbo().getHabboStats().respectPointsToGive--; + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserRespectComposer(target).compose()); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserActionComposer(this.client.getHabbo().getRoomUnit(), RoomUserAction.THUMB_UP).compose()); + + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("RespectGiven")); + AchievementManager.progressAchievement(target, Emulator.getGameEnvironment().getAchievementManager().getAchievement("RespectEarned")); + + this.client.getHabbo().getHabboInfo().getCurrentRoom().unIdle(this.client.getHabbo()); + this.client.getHabbo().getHabboInfo().getCurrentRoom().dance(this.client.getHabbo().getRoomUnit(), DanceType.NONE); + } + } + + public Set getForbiddenClothing() { + TIntCollection clothingIDs = this.getInventory().getWardrobeComponent().getClothing(); + + return Emulator.getGameEnvironment().getCatalogManager().clothing.values().stream() + .filter(c -> !clothingIDs.contains(c.id)) + .map(c -> c.setId) + .flatMap(c -> Arrays.stream(c).boxed()) + .collect(Collectors.toSet()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboBadge.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboBadge.java new file mode 100644 index 0000000..2db0cff --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboBadge.java @@ -0,0 +1,92 @@ +package com.eu.habbo.habbohotel.users; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; +import java.sql.*; + +@Slf4j +public class HabboBadge implements Runnable { + private int id; + private String code; + private int slot; + private Habbo habbo; + private boolean needsUpdate; + private boolean needsInsert; + + public HabboBadge(ResultSet set, Habbo habbo) throws SQLException { + this.id = set.getInt("id"); + this.code = set.getString("badge_code"); + this.slot = set.getInt("slot_id"); + this.habbo = habbo; + this.needsUpdate = false; + this.needsInsert = false; + } + + public HabboBadge(int id, String code, int slot, Habbo habbo) { + this.id = id; + this.code = code; + this.slot = slot; + this.habbo = habbo; + this.needsUpdate = false; + this.needsInsert = true; + } + + public int getId() { + return this.id; + } + + public String getCode() { + return this.code; + } + + public void setCode(String code) { + this.code = code; + } + + public int getSlot() { + return this.slot; + } + + public void setSlot(int slot) { + this.slot = slot; + } + + @Override + public void run() { + try { + if (this.needsInsert) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO users_badges (user_id, slot_id, badge_code) VALUES (?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, this.habbo.getHabboInfo().getId()); + statement.setInt(2, this.slot); + statement.setString(3, this.code); + statement.execute(); + try (ResultSet set = statement.getGeneratedKeys()) { + if (set.next()) { + this.id = set.getInt(1); + } + } + } + this.needsInsert = false; + } else if (this.needsUpdate) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users_badges SET slot_id = ?, badge_code = ? WHERE id = ? AND user_id = ?")) { + statement.setInt(1, this.slot); + statement.setString(2, this.code); + statement.setInt(3, this.id); + statement.setInt(4, this.habbo.getHabboInfo().getId()); + statement.execute(); + } + this.needsUpdate = false; + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void needsUpdate(boolean needsUpdate) { + this.needsUpdate = needsUpdate; + } + + public void needsInsert(boolean needsInsert) { + this.needsInsert = needsInsert; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboGender.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboGender.java new file mode 100644 index 0000000..c72c45c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboGender.java @@ -0,0 +1,6 @@ +package com.eu.habbo.habbohotel.users; + +public enum HabboGender { + M, + F +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboInfo.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboInfo.java new file mode 100644 index 0000000..cda9ac3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboInfo.java @@ -0,0 +1,576 @@ +package com.eu.habbo.habbohotel.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.games.GamePlayer; +import com.eu.habbo.habbohotel.messenger.MessengerCategory; +import com.eu.habbo.habbohotel.navigation.NavigatorSavedSearch; +import com.eu.habbo.habbohotel.permissions.Rank; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.pets.RideablePet; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import gnu.trove.map.hash.TIntIntHashMap; +import gnu.trove.procedure.TIntIntProcedure; +import lombok.extern.slf4j.Slf4j; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +public class HabboInfo implements Runnable { + public boolean firstVisit = false; + private String username; + private String motto; + private String look; + private HabboGender gender; + private String mail; + private String sso; + private String ipRegister; + private String ipLogin; + private int id; + private int accountCreated; + private Rank rank; + private int credits; + private int lastOnline; + private int homeRoom; + private boolean online; + private int loadingRoom; + private Room currentRoom; + private int roomQueueId; + private RideablePet riding; + private Class currentGame; + private TIntIntHashMap currencies; + private GamePlayer gamePlayer; + private int photoRoomId; + private int photoTimestamp; + private String photoURL; + private String photoJSON; + private int webPublishTimestamp; + private String machineID; + private List savedSearches = new ArrayList<>(); + private List messengerCategories = new ArrayList<>(); + private Boolean isInvisibleInRooms = false; + public HabboInfo(ResultSet set) { + try { + this.id = set.getInt("id"); + this.username = set.getString("username"); + this.motto = set.getString("motto"); + this.look = set.getString("look"); + this.gender = HabboGender.valueOf(set.getString("gender")); + this.mail = set.getString("mail"); + this.sso = set.getString("auth_ticket"); + this.ipRegister = set.getString("ip_register"); + this.ipLogin = set.getString("ip_current"); + this.rank = Emulator.getGameEnvironment().getPermissionsManager().getRank(set.getInt("rank")); + + if (this.rank == null) { + log.error("No existing rank found with id " + set.getInt("rank") + ". Make sure an entry in the permissions table exists."); + log.warn(this.username + " has an invalid rank with id " + set.getInt("rank") + ". Make sure an entry in the permissions table exists."); + this.rank = Emulator.getGameEnvironment().getPermissionsManager().getRank(1); + } + + this.accountCreated = set.getInt("account_created"); + this.credits = set.getInt("credits"); + this.homeRoom = set.getInt("home_room"); + this.lastOnline = set.getInt("last_online"); + this.machineID = set.getString("machine_id"); + this.online = false; + this.currentRoom = null; + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.loadCurrencies(); + this.loadSavedSearches(); + this.loadMessengerCategories(); + } + + private void loadCurrencies() { + this.currencies = new TIntIntHashMap(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM users_currency WHERE user_id = ?")) { + statement.setInt(1, this.id); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + this.currencies.put(set.getInt("type"), set.getInt("amount")); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + private void saveCurrencies() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO users_currency (user_id, type, amount) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE amount = ?")) { + this.currencies.forEachEntry(new TIntIntProcedure() { + @Override + public boolean execute(int a, int b) { + try { + statement.setInt(1, HabboInfo.this.getId()); + statement.setInt(2, a); + statement.setInt(3, b); + statement.setInt(4, b); + statement.addBatch(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + return true; + } + }); + statement.executeBatch(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + private void loadSavedSearches() { + this.savedSearches = new ArrayList<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM users_saved_searches WHERE user_id = ?")) { + statement.setInt(1, this.id); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + this.savedSearches.add(new NavigatorSavedSearch(set.getString("search_code"), set.getString("filter"), set.getInt("id"))); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void addSavedSearch(NavigatorSavedSearch search) { + this.savedSearches.add(search); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO users_saved_searches (search_code, filter, user_id) VALUES (?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setString(1, search.getSearchCode()); + statement.setString(2, search.getFilter()); + statement.setInt(3, this.id); + int affectedRows = statement.executeUpdate(); + + if (affectedRows == 0) { + throw new SQLException("Creating saved search failed, no rows affected."); + } + + try (ResultSet generatedKeys = statement.getGeneratedKeys()) { + if (generatedKeys.next()) { + search.setId(generatedKeys.getInt(1)); + } else { + throw new SQLException("Creating saved search failed, no ID found."); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void deleteSavedSearch(NavigatorSavedSearch search) { + this.savedSearches.remove(search); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM users_saved_searches WHERE id = ?")) { + statement.setInt(1, search.getId()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + private void loadMessengerCategories() { + this.messengerCategories = new ArrayList<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM messenger_categories WHERE user_id = ?")) { + statement.setInt(1, this.id); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + this.messengerCategories.add(new MessengerCategory(set.getString("name"), set.getInt("user_id"), set.getInt("id"))); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void addMessengerCategory(MessengerCategory category) { + this.messengerCategories.add(category); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO messenger_categories (name, user_id) VALUES (?, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setString(1, category.getName()); + statement.setInt(2, this.id); + int affectedRows = statement.executeUpdate(); + + if (affectedRows == 0) { + throw new SQLException("Creating messenger category failed, no rows affected."); + } + + try (ResultSet generatedKeys = statement.getGeneratedKeys()) { + if (generatedKeys.next()) { + category.setId(generatedKeys.getInt(1)); + } else { + throw new SQLException("Creating messenger category failed, no ID found."); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void deleteMessengerCategory(MessengerCategory category) { + this.messengerCategories.remove(category); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM messenger_categories WHERE id = ?")) { + statement.setInt(1, category.getId()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public int getCurrencyAmount(int type) { + return this.currencies.get(type); + } + + public TIntIntHashMap getCurrencies() { + return this.currencies; + } + + public void addCurrencyAmount(int type, int amount) { + this.currencies.adjustOrPutValue(type, amount, amount); + this.run(); + } + + public void setCurrencyAmount(int type, int amount) { + this.currencies.put(type, amount); + this.run(); + } + + public int getId() { + return this.id; + } + + public String getUsername() { + return this.username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getMotto() { + return this.motto; + } + + public void setMotto(String motto) { + this.motto = motto; + } + + public Rank getRank() { + return this.rank; + } + + public void setRank(Rank rank) { + this.rank = rank; + } + + public String getLook() { + return this.look; + } + + public void setLook(String look) { + this.look = look; + } + + public HabboGender getGender() { + return this.gender; + } + + public void setGender(HabboGender gender) { + this.gender = gender; + } + + public String getMail() { + return this.mail; + } + + public void setMail(String mail) { + this.mail = mail; + } + + public String getSso() { + return this.sso; + } + + public void setSso(String sso) { + this.sso = sso; + } + + public String getIpRegister() { + return this.ipRegister; + } + + public void setIpRegister(String ipRegister) { + this.ipRegister = ipRegister; + } + + public String getIpLogin() { + return this.ipLogin; + } + + public void setIpLogin(String ipLogin) { + this.ipLogin = ipLogin; + } + + public int getAccountCreated() { + return this.accountCreated; + } + + public void setAccountCreated(int accountCreated) { + this.accountCreated = accountCreated; + } + + public boolean canBuy(CatalogItem item) { + return this.credits >= item.getCredits() && this.getCurrencies().get(item.getPointsType()) >= item.getPoints(); + } + + public int getCredits() { + return this.credits; + } + + public void setCredits(int credits) { + this.credits = credits; + this.run(); + } + + public void addCredits(int credits) { + this.credits += credits; + this.run(); + } + + public int getPixels() { + return this.getCurrencyAmount(0); + } + + public void setPixels(int pixels) { + this.setCurrencyAmount(0, pixels); + this.run(); + } + + public void addPixels(int pixels) { + this.addCurrencyAmount(0, pixels); + this.run(); + } + + public int getLastOnline() { + return this.lastOnline; + } + + public void setLastOnline(int lastOnline) { + this.lastOnline = lastOnline; + } + + public int getHomeRoom() { + return this.homeRoom; + } + + public void setHomeRoom(int homeRoom) { + this.homeRoom = homeRoom; + } + + public boolean isOnline() { + return this.online; + } + + public void setOnline(boolean value) { + this.online = value; + } + + public int getLoadingRoom() { + return this.loadingRoom; + } + + public void setLoadingRoom(int loadingRoom) { + this.loadingRoom = loadingRoom; + } + + public Room getCurrentRoom() { + return this.currentRoom; + } + + public void setCurrentRoom(Room room) { + this.currentRoom = room; + } + + public int getRoomQueueId() { + return this.roomQueueId; + } + + public void setRoomQueueId(int roomQueueId) { + this.roomQueueId = roomQueueId; + } + + public RideablePet getRiding() { + return this.riding; + } + + public void setRiding(RideablePet riding) { + this.riding = riding; + } + + public void dismountPet() { + this.dismountPet(false); + } + + public void dismountPet(boolean isRemoving) { + if (this.getRiding() == null) + return; + + Habbo habbo = this.getCurrentRoom().getHabbo(this.getId()); + if (habbo == null) + return; + + RideablePet riding = this.getRiding(); + + riding.setRider(null); + riding.setTask(PetTasks.FREE); + this.setRiding(null); + + Room room = this.getCurrentRoom(); + if (room != null) + room.giveEffect(habbo, 0, -1); + + RoomUnit roomUnit = habbo.getRoomUnit(); + if (roomUnit == null) + return; + + roomUnit.setZ(riding.getRoomUnit().getZ()); + roomUnit.setPreviousLocationZ(riding.getRoomUnit().getZ()); + roomUnit.stopWalking(); + room.sendComposer(new RoomUserStatusComposer(roomUnit).compose()); + List availableTiles = isRemoving ? new ArrayList<>() : this.getCurrentRoom().getLayout().getWalkableTilesAround(roomUnit.getCurrentLocation()); + + RoomTile tile = availableTiles.isEmpty() ? roomUnit.getCurrentLocation() : availableTiles.get(0); + roomUnit.setGoalLocation(tile); + roomUnit.statusUpdate(true); + } + + public Class getCurrentGame() { + return this.currentGame; + } + + public void setCurrentGame(Class currentGame) { + this.currentGame = currentGame; + } + + public boolean isInGame() { + return this.currentGame != null; + } + + public synchronized GamePlayer getGamePlayer() { + return this.gamePlayer; + } + + public synchronized void setGamePlayer(GamePlayer gamePlayer) { + this.gamePlayer = gamePlayer; + } + + public int getPhotoRoomId() { + return this.photoRoomId; + } + + public void setPhotoRoomId(int roomId) { + this.photoRoomId = roomId; + } + + public int getPhotoTimestamp() { + return this.photoTimestamp; + } + + public void setPhotoTimestamp(int photoTimestamp) { + this.photoTimestamp = photoTimestamp; + } + + public String getPhotoURL() { + return this.photoURL; + } + + public void setPhotoURL(String photoURL) { + this.photoURL = photoURL; + } + + public String getPhotoJSON() { + return this.photoJSON; + } + + public void setPhotoJSON(String photoJSON) { + this.photoJSON = photoJSON; + } + + public int getWebPublishTimestamp() { + return this.webPublishTimestamp; + } + + public void setWebPublishTimestamp(int webPublishTimestamp) { + this.webPublishTimestamp = webPublishTimestamp; + } + + public String getMachineID() { + return this.machineID; + } + + public void setMachineID(String machineID) { + this.machineID = machineID; + } + + public List getSavedSearches() { + return this.savedSearches; + } + + public List getMessengerCategories() { return this.messengerCategories; } + + @Override + public void run() { + this.saveCurrencies(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users SET motto = ?, online = ?, look = ?, gender = ?, credits = ?, last_login = ?, last_online = ?, home_room = ?, ip_current = ?, `rank` = ?, machine_id = ?, username = ? WHERE id = ?")) { + statement.setString(1, this.motto); + statement.setString(2, this.online ? "1" : "0"); + statement.setString(3, this.look); + statement.setString(4, this.gender.name()); + statement.setInt(5, this.credits); + statement.setInt(7, this.lastOnline); + statement.setInt(6, Emulator.getIntUnixTimestamp()); + statement.setInt(8, this.homeRoom); + statement.setString(9, this.ipLogin); + statement.setInt(10, this.rank != null ? this.rank.getId() : 1); + statement.setString(11, this.machineID); + statement.setString(12, this.username); + statement.setInt(13, this.id); + statement.executeUpdate(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public int getBonusRarePoints() { + return this.getCurrencyAmount(Emulator.getConfig().getInt("hotelview.promotional.points.type")); + } + + public HabboStats getHabboStats() { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getId()); + if (habbo != null) { + return habbo.getHabboStats(); + } + + return HabboStats.load(this); + } + + public Boolean isInvisibleInRooms() { + return this.isInvisibleInRooms; + } + + public void toggleInvisibility() { + this.isInvisibleInRooms = !this.isInvisibleInRooms; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboInventory.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboInventory.java new file mode 100644 index 0000000..1b42330 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboInventory.java @@ -0,0 +1,164 @@ +package com.eu.habbo.habbohotel.users; + +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlace; +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlaceOffer; +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlaceState; +import com.eu.habbo.habbohotel.users.inventory.*; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class HabboInventory { + //Configuration. Loaded from database & updated accordingly. + public static int MAXIMUM_ITEMS = 10000; + private final THashSet items; + private final Habbo habbo; + private WardrobeComponent wardrobeComponent; + private BadgesComponent badgesComponent; + private BotsComponent botsComponent; + private EffectsComponent effectsComponent; + private ItemsComponent itemsComponent; + private PetsComponent petsComponent; + + public HabboInventory(Habbo habbo) { + this.habbo = habbo; + try { + this.badgesComponent = new BadgesComponent(this.habbo); + } catch (Exception e) { + log.error("Caught exception", e); + } + + try { + this.botsComponent = new BotsComponent(this.habbo); + } catch (Exception e) { + log.error("Caught exception", e); + } + + try { + this.effectsComponent = new EffectsComponent(this.habbo); + } catch (Exception e) { + log.error("Caught exception", e); + } + + try { + this.itemsComponent = new ItemsComponent(this, this.habbo); + } catch (Exception e) { + log.error("Caught exception", e); + } + + try { + this.petsComponent = new PetsComponent(this.habbo); + } catch (Exception e) { + log.error("Caught exception", e); + } + + try { + this.wardrobeComponent = new WardrobeComponent(this.habbo); + } catch (Exception e) { + log.error("Caught exception", e); + } + + this.items = MarketPlace.getOwnOffers(this.habbo); + } + + public WardrobeComponent getWardrobeComponent() { + return this.wardrobeComponent; + } + + public void setWardrobeComponent(WardrobeComponent wardrobeComponent) { + this.wardrobeComponent = wardrobeComponent; + } + + public BadgesComponent getBadgesComponent() { + return this.badgesComponent; + } + + public void setBadgesComponent(BadgesComponent badgesComponent) { + this.badgesComponent = badgesComponent; + } + + public BotsComponent getBotsComponent() { + return this.botsComponent; + } + + public void setBotsComponent(BotsComponent botsComponent) { + this.botsComponent = botsComponent; + } + + public EffectsComponent getEffectsComponent() { + return this.effectsComponent; + } + + public void setEffectsComponent(EffectsComponent effectsComponent) { + this.effectsComponent = effectsComponent; + } + + public ItemsComponent getItemsComponent() { + return this.itemsComponent; + } + + public void setItemsComponent(ItemsComponent itemsComponent) { + this.itemsComponent = itemsComponent; + } + + public PetsComponent getPetsComponent() { + return this.petsComponent; + } + + public void setPetsComponent(PetsComponent petsComponent) { + this.petsComponent = petsComponent; + } + + public void dispose() { + this.badgesComponent.dispose(); + this.botsComponent.dispose(); + this.effectsComponent.dispose(); + this.itemsComponent.dispose(); + this.petsComponent.dispose(); + this.wardrobeComponent.dispose(); + + this.badgesComponent = null; + this.botsComponent = null; + this.effectsComponent = null; + this.itemsComponent = null; + this.petsComponent = null; + this.wardrobeComponent = null; + } + + public void addMarketplaceOffer(MarketPlaceOffer marketPlaceOffer) { + this.items.add(marketPlaceOffer); + } + + public void removeMarketplaceOffer(MarketPlaceOffer marketPlaceOffer) { + this.items.remove(marketPlaceOffer); + } + + public THashSet getMarketplaceItems() { + return this.items; + } + + public int getSoldPriceTotal() { + int i = 0; + for (MarketPlaceOffer offer : this.items) { + if (offer.getState().equals(MarketPlaceState.SOLD)) { + i += offer.getPrice(); + } + } + return i; + } + + public MarketPlaceOffer getOffer(int id) { + synchronized (this.items) { + for (MarketPlaceOffer offer : this.items) { + if (offer.getOfferId() == id) + return offer; + } + } + + return null; + } + + public Habbo getHabbo() { + return this.habbo; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboItem.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboItem.java new file mode 100644 index 0000000..5d6f596 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboItem.java @@ -0,0 +1,555 @@ +package com.eu.habbo.habbohotel.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.FurnitureType; +import com.eu.habbo.habbohotel.items.IEventTriggers; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.*; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTimer; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.wired.WiredEffectType; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDanceComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer; +import com.eu.habbo.messages.outgoing.users.UpdateUserLookComposer; +import gnu.trove.set.hash.THashSet; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.math3.util.Pair; +import lombok.extern.slf4j.Slf4j; +import java.awt.*; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +@Slf4j +public abstract class HabboItem implements Runnable, IEventTriggers { + + private static Class[] TOGGLING_INTERACTIONS = new Class[]{ + InteractionGameTimer.class, + InteractionWired.class, + InteractionWiredHighscore.class, + InteractionMultiHeight.class + }; + + private int id; + private int userId; + private int roomId; + private Item baseItem; + private String wallPosition; + private short x; + private short y; + private double z; + private int rotation; + private String extradata; + private int limitedStack; + private int limitedSells; + private boolean needsUpdate = false; + private boolean needsDelete = false; + private boolean isFromGift = false; + + public HabboItem(ResultSet set, Item baseItem) throws SQLException { + this.id = set.getInt("id"); + this.userId = set.getInt("user_id"); + this.roomId = set.getInt("room_id"); + this.baseItem = baseItem; + this.wallPosition = set.getString("wall_pos"); + this.x = set.getShort("x"); + this.y = set.getShort("y"); + this.z = set.getDouble("z"); + this.rotation = set.getInt("rot"); + this.extradata = set.getString("extra_data").isEmpty() ? "0" : set.getString("extra_data"); + + String ltdData = set.getString("limited_data"); + if (!ltdData.isEmpty()) { + this.limitedStack = Integer.parseInt(set.getString("limited_data").split(":")[0]); + this.limitedSells = Integer.parseInt(set.getString("limited_data").split(":")[1]); + } + } + + public HabboItem(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + this.id = id; + this.userId = userId; + this.roomId = 0; + this.baseItem = item; + this.wallPosition = ""; + this.x = 0; + this.y = 0; + this.z = 0; + this.rotation = 0; + this.extradata = extradata.isEmpty() ? "0" : extradata; + this.limitedSells = limitedSells; + this.limitedStack = limitedStack; + } + + public static RoomTile getSquareInFront(RoomLayout roomLayout, HabboItem item) { + return roomLayout.getTileInFront(roomLayout.getTile(item.getX(), item.getY()), item.getRotation()); + } + + public void serializeFloorData(ServerMessage serverMessage) { + try { + serverMessage.appendInt(this.getId()); + serverMessage.appendInt(this.baseItem.getSpriteId()); + serverMessage.appendInt(this.x); + serverMessage.appendInt(this.y); + serverMessage.appendInt(this.getRotation()); + serverMessage.appendString(Double.toString(this.z)); + + serverMessage.appendString((this.getBaseItem().getInteractionType().getType() == InteractionTrophy.class || this.getBaseItem().getInteractionType().getType() == InteractionCrackable.class || this.getBaseItem().getName().toLowerCase().equals("gnome_box")) ? "1.0" : ((this.getBaseItem().allowWalk() || this.getBaseItem().allowSit() && this.roomId != 0) ? Item.getCurrentHeight(this) + "" : "")); + //serverMessage.appendString( ? "1.0" : ((this.getBaseItem().allowWalk() || this.getBaseItem().allowSit() && this.roomId != 0) ? Item.getCurrentHeight(this) : "")); + + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + public void serializeExtradata(ServerMessage serverMessage) { + if (this.isLimited()) { + serverMessage.appendInt(this.getLimitedSells()); + serverMessage.appendInt(this.getLimitedStack()); + } + } + + public void serializeWallData(ServerMessage serverMessage) { + serverMessage.appendString(this.getId() + ""); + serverMessage.appendInt(this.baseItem.getSpriteId()); + serverMessage.appendString(this.wallPosition); + + if (this instanceof InteractionPostIt) + serverMessage.appendString(this.extradata.split(" ")[0]); + else + serverMessage.appendString(this.extradata); + serverMessage.appendInt(-1); + serverMessage.appendInt(this.isUsable()); + serverMessage.appendInt(this.getUserId()); + } + + public int getId() { + return this.id; + } + + public int getGiftAdjustedId() { + if (this.isFromGift) return -this.id; + + return this.id; + } + + public int getUserId() { + return this.userId; + } + + public void setUserId(int userId) { + this.userId = userId; + } + + public int getRoomId() { + return this.roomId; + } + + public void setRoomId(int roomId) { + this.roomId = roomId; + } + + public Item getBaseItem() { + return this.baseItem; + } + + public String getWallPosition() { + return this.wallPosition; + } + + public void setWallPosition(String wallPosition) { + this.wallPosition = wallPosition; + } + + public short getX() { + return this.x; + } + + public void setX(short x) { + this.x = x; + } + + public short getY() { + return this.y; + } + + public void setY(short y) { + this.y = y; + } + + public double getZ() { + return this.z; + } + + public void setZ(double z) { + if (z > 9999 || z < -9999) return; + this.z = z; + } + + public int getRotation() { + return this.rotation; + } + + public void setRotation(int rotation) { + this.rotation = (byte) (rotation % 8); + } + + public String getExtradata() { + return this.extradata; + } + + public void setExtradata(String extradata) { + this.extradata = extradata; + } + + public boolean needsUpdate() { + return this.needsUpdate; + } + + public boolean needsDelete() { + return needsDelete; + } + + public void needsUpdate(boolean value) { + this.needsUpdate = value; + } + + public void needsDelete(boolean value) { + this.needsDelete = value; + } + + public boolean isLimited() { + return this.limitedStack > 0; + } + + public int getLimitedStack() { + return this.limitedStack; + } + + public int getLimitedSells() { + return this.limitedSells; + } + + public int getMaximumRotations() { return this.baseItem.getRotations(); } + + @Override + public void run() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + if (this.needsDelete) { + this.needsUpdate = false; + this.needsDelete = false; + + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM items WHERE id = ?")) { + statement.setInt(1, this.getId()); + statement.execute(); + } + } else if (this.needsUpdate) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE items SET user_id = ?, room_id = ?, wall_pos = ?, x = ?, y = ?, z = ?, rot = ?, extra_data = ?, limited_data = ? WHERE id = ?")) { + statement.setInt(1, this.userId); + statement.setInt(2, this.roomId); + statement.setString(3, this.wallPosition); + statement.setInt(4, this.x); + statement.setInt(5, this.y); + statement.setDouble(6, Math.max(-9999, Math.min(9999, Math.round(this.z * Math.pow(10, 6)) / Math.pow(10, 6)))); + statement.setInt(7, this.rotation); + statement.setString(8, this instanceof InteractionGuildGate ? "" : this.getDatabaseExtraData()); + statement.setString(9, this.limitedStack + ":" + this.limitedSells); + statement.setInt(10, this.id); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + log.error("SQLException trying to save HabboItem: " + this.toString()); + } + + this.needsUpdate = false; + } + + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public abstract boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects); + + public abstract boolean isWalkable(); + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + if (client != null && this.getBaseItem().getType() == FurnitureType.FLOOR) { + if (objects != null && objects.length >= 2) { + if (objects[1] instanceof WiredEffectType) { + return; + } + } + + if ((this.getBaseItem().getStateCount() > 1 && !(this instanceof InteractionDice)) || Arrays.asList(HabboItem.TOGGLING_INTERACTIONS).contains(this.getClass()) || (objects != null && objects.length == 1 && objects[0].equals("TOGGLE_OVERRIDE"))) { + WiredHandler.handle(WiredTriggerType.STATE_CHANGED, client.getHabbo().getRoomUnit(), room, new Object[]{this}); + } + } + } + + @Override + public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + /*if (objects != null && objects.length >= 1 && objects[0] instanceof InteractionWired) + return;*/ + + WiredHandler.handle(WiredTriggerType.WALKS_ON_FURNI, roomUnit, room, new Object[]{this}); + + if ((this.getBaseItem().allowSit() || this.getBaseItem().allowLay()) && !roomUnit.getDanceType().equals(DanceType.NONE)) { + roomUnit.setDanceType(DanceType.NONE); + room.sendComposer(new RoomUserDanceComposer(roomUnit).compose()); + } + + if (!this.getBaseItem().getClothingOnWalk().isEmpty() && roomUnit.getPreviousLocation() != roomUnit.getGoal() && roomUnit.getGoal() == room.getLayout().getTile(this.x, this.y)) { + Habbo habbo = room.getHabbo(roomUnit); + + if (habbo != null && habbo.getClient() != null) { + String[] clothingKeys = Arrays.stream(this.getBaseItem().getClothingOnWalk().split("\\.")).map(k -> k.split("-")[0]).toArray(String[]::new); + habbo.getHabboInfo().setLook(String.join(".", Arrays.stream(habbo.getHabboInfo().getLook().split("\\.")).filter(k -> !ArrayUtils.contains(clothingKeys, k.split("-")[0])).toArray(String[]::new)) + "." + this.getBaseItem().getClothingOnWalk()); + + habbo.getClient().sendResponse(new UpdateUserLookComposer(habbo)); + if (habbo.getHabboInfo().getCurrentRoom() != null) { + habbo.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserDataComposer(habbo).compose()); + } + } + } + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + if(objects != null && objects.length > 0) { + WiredHandler.handle(WiredTriggerType.WALKS_OFF_FURNI, roomUnit, room, new Object[]{this}); + } + } + + public abstract void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception; + + + public void onPlace(Room room) { + //TODO: IMPORTANT: MAKE THIS GENERIC. (HOLES, ICE SKATE PATCHES, BLACK HOLE, BUNNY RUN FIELD, FOOTBALL FIELD) + Achievement roomDecoAchievement = Emulator.getGameEnvironment().getAchievementManager().getAchievement("RoomDecoFurniCount"); + Habbo owner = room.getHabbo(this.getUserId()); + + int furniCollecterProgress; + if (owner == null) { + furniCollecterProgress = AchievementManager.getAchievementProgressForHabbo(this.getUserId(), roomDecoAchievement); + } else { + furniCollecterProgress = owner.getHabboStats().getAchievementProgress(roomDecoAchievement); + } + + int difference = room.getUserFurniCount(this.getUserId()) - furniCollecterProgress; + if (difference > 0) { + if (owner != null) { + AchievementManager.progressAchievement(owner, roomDecoAchievement, difference); + } else { + AchievementManager.progressAchievement(this.getUserId(), roomDecoAchievement, difference); + } + } + + Achievement roomDecoUniqueAchievement = Emulator.getGameEnvironment().getAchievementManager().getAchievement("RoomDecoFurniTypeCount"); + + int uniqueFurniCollecterProgress; + if (owner == null) { + uniqueFurniCollecterProgress = AchievementManager.getAchievementProgressForHabbo(this.getUserId(), roomDecoUniqueAchievement); + } else { + uniqueFurniCollecterProgress = owner.getHabboStats().getAchievementProgress(roomDecoUniqueAchievement); + } + + int uniqueDifference = room.getUserUniqueFurniCount(this.getUserId()) - uniqueFurniCollecterProgress; + if (uniqueDifference > 0) { + if (owner != null) { + AchievementManager.progressAchievement(owner, roomDecoUniqueAchievement, uniqueDifference); + } else { + AchievementManager.progressAchievement(this.getUserId(), roomDecoUniqueAchievement, uniqueDifference); + } + } + } + + public void onPickUp(Room room) { + if (this.getBaseItem().getEffectF() > 0 || this.getBaseItem().getEffectM() > 0) { + HabboItem topItem2 = room.getTopItemAt(this.getX(), this.getY(), this); + int nextEffectM = 0; + int nextEffectF = 0; + + if(topItem2 != null) { + nextEffectM = topItem2.getBaseItem().getEffectM(); + nextEffectF = topItem2.getBaseItem().getEffectF(); + } + + for (Habbo habbo : room.getHabbosOnItem(this)) { + if (this.getBaseItem().getEffectM() > 0 && habbo.getHabboInfo().getGender().equals(HabboGender.M) && habbo.getRoomUnit().getEffectId() == this.getBaseItem().getEffectM()) { + room.giveEffect(habbo, nextEffectM, -1); + } + + if (this.getBaseItem().getEffectF() > 0 && habbo.getHabboInfo().getGender().equals(HabboGender.F) && habbo.getRoomUnit().getEffectId() == this.getBaseItem().getEffectF()) { + room.giveEffect(habbo, nextEffectF, -1); + } + } + + for (Bot bot : room.getBotsAt(room.getLayout().getTile(this.getX(), this.getY()))) { + if (this.getBaseItem().getEffectM() > 0 && bot.getGender().equals(HabboGender.M) && bot.getRoomUnit().getEffectId() == this.getBaseItem().getEffectM()) { + room.giveEffect(bot.getRoomUnit(), nextEffectM, -1); + } + + if (this.getBaseItem().getEffectF() > 0 && bot.getGender().equals(HabboGender.F) && bot.getRoomUnit().getEffectId() == this.getBaseItem().getEffectF()) { + room.giveEffect(bot.getRoomUnit(), nextEffectF, -1); + } + } + } + } + + public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + if (this.getBaseItem().getEffectF() > 0 || this.getBaseItem().getEffectM() > 0) { + HabboItem topItem2 = room.getTopItemAt(oldLocation.x, oldLocation.y, this); + int nextEffectM = 0; + int nextEffectF = 0; + + if(topItem2 != null) { + nextEffectM = topItem2.getBaseItem().getEffectM(); + nextEffectF = topItem2.getBaseItem().getEffectF(); + } + + List oldHabbos = new ArrayList<>(); + List newHabbos = new ArrayList<>(); + List oldBots = new ArrayList<>(); + List newBots = new ArrayList<>(); + + for (RoomTile tile : room.getLayout().getTilesAt(oldLocation, this.getBaseItem().getWidth(), this.getBaseItem().getLength(), this.getRotation())) { + oldHabbos.addAll(room.getHabbosAt(tile)); + oldBots.addAll(room.getBotsAt(tile)); + } + + for (RoomTile tile : room.getLayout().getTilesAt(oldLocation, this.getBaseItem().getWidth(), this.getBaseItem().getLength(), this.getRotation())) { + newHabbos.addAll(room.getHabbosAt(tile)); + newBots.addAll(room.getBotsAt(tile)); + } + + oldHabbos.removeAll(newHabbos); + oldBots.removeAll(newBots); + + for (Habbo habbo : oldHabbos) { + if (this.getBaseItem().getEffectM() > 0 && habbo.getHabboInfo().getGender().equals(HabboGender.M) && habbo.getRoomUnit().getEffectId() == this.getBaseItem().getEffectM()) { + room.giveEffect(habbo, nextEffectM, -1); + } + + if (this.getBaseItem().getEffectF() > 0 && habbo.getHabboInfo().getGender().equals(HabboGender.F) && habbo.getRoomUnit().getEffectId() == this.getBaseItem().getEffectF()) { + room.giveEffect(habbo, nextEffectF, -1); + } + } + + for (Habbo habbo : newHabbos) { + if (this.getBaseItem().getEffectM() > 0 && habbo.getHabboInfo().getGender().equals(HabboGender.M) && habbo.getRoomUnit().getEffectId() != this.getBaseItem().getEffectM()) { + room.giveEffect(habbo, this.getBaseItem().getEffectM(), -1); + } + + if (this.getBaseItem().getEffectF() > 0 && habbo.getHabboInfo().getGender().equals(HabboGender.F) && habbo.getRoomUnit().getEffectId() != this.getBaseItem().getEffectF()) { + room.giveEffect(habbo, this.getBaseItem().getEffectF(), -1); + } + } + + for (Bot bot : oldBots) { + if (this.getBaseItem().getEffectM() > 0 && bot.getGender().equals(HabboGender.M) && bot.getRoomUnit().getEffectId() == this.getBaseItem().getEffectM()) { + room.giveEffect(bot.getRoomUnit(), nextEffectM, -1); + } + + if (this.getBaseItem().getEffectF() > 0 && bot.getGender().equals(HabboGender.F) && bot.getRoomUnit().getEffectId() == this.getBaseItem().getEffectF()) { + room.giveEffect(bot.getRoomUnit(), nextEffectF, -1); + } + } + + for (Bot bot : newBots) { + if (this.getBaseItem().getEffectM() > 0 && bot.getGender().equals(HabboGender.M) && bot.getRoomUnit().getEffectId() != this.getBaseItem().getEffectM()) { + room.giveEffect(bot.getRoomUnit(), this.getBaseItem().getEffectM(), -1); + } + + if (this.getBaseItem().getEffectF() > 0 && bot.getGender().equals(HabboGender.F) && bot.getRoomUnit().getEffectId() != this.getBaseItem().getEffectF()) { + room.giveEffect(bot.getRoomUnit(), this.getBaseItem().getEffectF(), -1); + } + } + } + } + + public String getDatabaseExtraData() { + return this.getExtradata(); + } + + @Override + public String toString() { + return "ID: " + this.id + ", BaseID: " + this.getBaseItem().getId() + ", X: " + this.x + ", Y: " + this.y + ", Z: " + this.z + ", Extradata: " + this.extradata; + } + + public boolean allowWiredResetState() { + return false; + } + + public boolean isUsable() { + return this.baseItem.getStateCount() > 1; + } + + public boolean canStackAt(Room room, List>> itemsAtLocation) { + return true; + } + + public boolean isFromGift() { + return isFromGift; + } + + public void setFromGift(boolean fromGift) { + isFromGift = fromGift; + } + + public boolean invalidatesToRoomKick() { return false; } + + public List getOccupyingTiles(RoomLayout layout) { + List tiles = new ArrayList<>(); + + Rectangle rect = RoomLayout.getRectangle(this.getX(), this.getY(), this.getBaseItem().getWidth(), this.getBaseItem().getLength(), this.getRotation()); + + for (int i = rect.x; i < rect.x + rect.getWidth(); i++) { + for (int j = rect.y; j < rect.y + rect.getHeight(); j++) { + tiles.add(layout.getTile((short) i, (short) j)); + } + } + + return tiles; + } + + public RoomTile getOverrideGoalTile(RoomUnit unit, Room room, RoomTile tile) { + return tile; + } + + public RoomTileState getOverrideTileState(RoomTile tile, Room room) { + return null; + } + + public boolean canOverrideTile(RoomUnit unit, Room room, RoomTile tile) { + return false; + } + + public Rectangle getRectangle() { + return RoomLayout.getRectangle( + this.getX(), + this.getY(), + this.getBaseItem().getWidth(), + this.getBaseItem().getLength(), + this.getRotation()); + } + + public Rectangle getRectangle(int marginX, int marginY) { + return RoomLayout.getRectangle( + this.getX() - marginX, + this.getY() - marginY, + this.getBaseItem().getWidth() + (marginX * 2), + this.getBaseItem().getLength() + (marginY * 2), + this.getRotation()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboManager.java new file mode 100644 index 0000000..4bff088 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboManager.java @@ -0,0 +1,313 @@ +package com.eu.habbo.habbohotel.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolBan; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.permissions.Rank; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.catalog.*; +import com.eu.habbo.messages.outgoing.catalog.marketplace.MarketplaceConfigComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.GenericAlertComposer; +import com.eu.habbo.messages.outgoing.modtool.ModToolComposer; +import com.eu.habbo.messages.outgoing.users.UserPerksComposer; +import com.eu.habbo.messages.outgoing.users.UserPermissionsComposer; +import com.eu.habbo.plugin.events.users.UserRankChangedEvent; +import com.eu.habbo.plugin.events.users.UserRegisteredEvent; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Slf4j +public class HabboManager { + //Configuration. Loaded from database & updated accordingly. + public static String WELCOME_MESSAGE = ""; + + private final ConcurrentHashMap onlineHabbos; + + public HabboManager() { + long millis = System.currentTimeMillis(); + + this.onlineHabbos = new ConcurrentHashMap<>(); + + log.info("Habbo Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)"); + } + + public static HabboInfo getOfflineHabboInfo(int id) { + HabboInfo info = null; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM users WHERE id = ? LIMIT 1")) { + statement.setInt(1, id); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + info = new HabboInfo(set); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return info; + } + + public static HabboInfo getOfflineHabboInfo(String username) { + HabboInfo info = null; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM users WHERE username = ? LIMIT 1")) { + statement.setString(1, username); + + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + info = new HabboInfo(set); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return info; + } + + public void addHabbo(Habbo habbo) { + this.onlineHabbos.put(habbo.getHabboInfo().getId(), habbo); + } + + public void removeHabbo(Habbo habbo) { + this.onlineHabbos.remove(habbo.getHabboInfo().getId()); + } + + public Habbo getHabbo(int id) { + return this.onlineHabbos.get(id); + } + + public Habbo getHabbo(String username) { + synchronized (this.onlineHabbos) { + for (Map.Entry map : this.onlineHabbos.entrySet()) { + if (map.getValue().getHabboInfo().getUsername().equalsIgnoreCase(username)) + return map.getValue(); + } + } + + return null; + } + + public Habbo loadHabbo(String sso) { + Habbo habbo; + int userId = 0; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("SELECT id FROM users WHERE auth_ticket = ? LIMIT 1")) { + statement.setString(1, sso); + try (ResultSet s = statement.executeQuery()) { + if (s.next()) { + userId = s.getInt("id"); + } + } + statement.close(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + habbo = this.cloneCheck(userId); + if (habbo != null) { + habbo.alert(Emulator.getTexts().getValue("loggedin.elsewhere")); + Emulator.getGameServer().getGameClientManager().disposeClient(habbo.getClient()); + habbo = null; + } + + ModToolBan ban = Emulator.getGameEnvironment().getModToolManager().checkForBan(userId); + if (ban != null) { + return null; + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("SELECT * FROM users WHERE auth_ticket = ? LIMIT 1")) { + statement.setString(1, sso); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + habbo = new Habbo(set); + + if (habbo.getHabboInfo().firstVisit) { + Emulator.getPluginManager().fireEvent(new UserRegisteredEvent(habbo)); + } + + if (!Emulator.debugging) { + + try (PreparedStatement stmt = connection.prepareStatement("UPDATE users SET auth_ticket = ? WHERE id = ? LIMIT 1")) { + stmt.setString(1, ""); + stmt.setInt(2, habbo.getHabboInfo().getId()); + stmt.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + } + + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } catch (Exception ex) { + log.error("Caught exception", ex); + } + + return habbo; + } + + public HabboInfo getHabboInfo(int id) { + if (this.getHabbo(id) == null) { + return getOfflineHabboInfo(id); + } + return this.getHabbo(id).getHabboInfo(); + } + + public int getOnlineCount() { + return this.onlineHabbos.size(); + } + + public Habbo cloneCheck(int id) { + return Emulator.getGameServer().getGameClientManager().getHabbo(id); + } + + public void sendPacketToHabbosWithPermission(ServerMessage message, String perm) { + synchronized (this.onlineHabbos) { + for (Habbo habbo : this.onlineHabbos.values()) { + if (habbo.hasPermission(perm)) { + habbo.getClient().sendResponse(message); + } + } + } + } + + public ConcurrentHashMap getOnlineHabbos() { + return this.onlineHabbos; + } + + public synchronized void dispose() { + + +// + + + log.info("Habbo Manager -> Disposed!"); + } + + public ArrayList getCloneAccounts(Habbo habbo, int limit) { + ArrayList habboInfo = new ArrayList<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM users WHERE ip_register = ? OR ip_current = ? AND id != ? ORDER BY id DESC LIMIT ?")) { + statement.setString(1, habbo.getHabboInfo().getIpRegister()); + statement.setString(2, habbo.getHabboInfo().getIpLogin()); + statement.setInt(3, habbo.getHabboInfo().getId()); + statement.setInt(4, limit); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + habboInfo.add(new HabboInfo(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return habboInfo; + } + + public List> getNameChanges(int userId, int limit) { + List> nameChanges = new ArrayList<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT timestamp, new_name FROM namechange_log WHERE user_id = ? ORDER by timestamp DESC LIMIT ?")) { + statement.setInt(1, userId); + statement.setInt(2, limit); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + nameChanges.add(new AbstractMap.SimpleEntry<>(set.getInt("timestamp"), set.getString("new_name"))); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return nameChanges; + } + + + public void setRank(int userId, int rankId) throws Exception { + Habbo habbo = this.getHabbo(userId); + + if (!Emulator.getGameEnvironment().getPermissionsManager().rankExists(rankId)) { + throw new Exception("Rank ID (" + rankId + ") does not exist"); + } + Rank newRank = Emulator.getGameEnvironment().getPermissionsManager().getRank(rankId); + if (habbo != null && habbo.getHabboStats() != null) { + Rank oldRank = habbo.getHabboInfo().getRank(); + if (!oldRank.getBadge().isEmpty()) { + habbo.deleteBadge(habbo.getInventory().getBadgesComponent().getBadge(oldRank.getBadge())); + } + if(oldRank.getRoomEffect() > 0) { + habbo.getInventory().getEffectsComponent().effects.remove(oldRank.getRoomEffect()); + } + + habbo.getHabboInfo().setRank(newRank); + + if (!newRank.getBadge().isEmpty()) { + habbo.addBadge(newRank.getBadge()); + } + + if(newRank.getRoomEffect() > 0) { + habbo.getInventory().getEffectsComponent().createRankEffect(habbo.getHabboInfo().getRank().getRoomEffect()); + } + + habbo.getClient().sendResponse(new UserPermissionsComposer(habbo)); + habbo.getClient().sendResponse(new UserPerksComposer(habbo)); + + if (habbo.hasPermission(Permission.ACC_SUPPORTTOOL)) { + habbo.getClient().sendResponse(new ModToolComposer(habbo)); + } + habbo.getHabboInfo().run(); + + habbo.getClient().sendResponse(new CatalogUpdatedComposer()); + habbo.getClient().sendResponse(new CatalogModeComposer(0)); + habbo.getClient().sendResponse(new DiscountComposer()); + habbo.getClient().sendResponse(new MarketplaceConfigComposer()); + habbo.getClient().sendResponse(new GiftConfigurationComposer()); + habbo.getClient().sendResponse(new RecyclerLogicComposer()); + habbo.alert(Emulator.getTexts().getValue("commands.generic.cmd_give_rank.new_rank").replace("id", newRank.getName())); + } else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users SET `rank` = ? WHERE id = ? LIMIT 1")) { + statement.setInt(1, rankId); + statement.setInt(2, userId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + Emulator.getPluginManager().fireEvent(new UserRankChangedEvent(habbo)); + } + + public void giveCredits(int userId, int credits) { + Habbo habbo = this.getHabbo(userId); + if (habbo != null) { + habbo.giveCredits(credits); + } else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users SET credits = credits + ? WHERE id = ? LIMIT 1")) { + statement.setInt(1, credits); + statement.setInt(2, userId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public void staffAlert(String message) { + message = Emulator.getTexts().getValue("commands.generic.cmd_staffalert.title") + "\r\n" + message; + ServerMessage msg = new GenericAlertComposer(message).compose(); + Emulator.getGameEnvironment().getHabboManager().sendPacketToHabbosWithPermission(msg, "cmd_staffalert"); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboNavigatorPersonalDisplayMode.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboNavigatorPersonalDisplayMode.java new file mode 100644 index 0000000..df103c7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboNavigatorPersonalDisplayMode.java @@ -0,0 +1,22 @@ +package com.eu.habbo.habbohotel.users; + +import com.eu.habbo.habbohotel.navigation.DisplayMode; +import com.eu.habbo.habbohotel.navigation.ListMode; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class HabboNavigatorPersonalDisplayMode { + public ListMode listMode; + public DisplayMode displayMode; + + public HabboNavigatorPersonalDisplayMode(ListMode listMode, DisplayMode collapsed) { + this.listMode = listMode; + this.displayMode = collapsed; + } + + public HabboNavigatorPersonalDisplayMode(ResultSet set) throws SQLException { + this.listMode = set.getString("list_type").equals("thumbnails") ? ListMode.THUMBNAILS : ListMode.LIST; + this.displayMode = DisplayMode.valueOf(set.getString("display").toUpperCase()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboNavigatorWindowSettings.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboNavigatorWindowSettings.java new file mode 100644 index 0000000..26b8958 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboNavigatorWindowSettings.java @@ -0,0 +1,121 @@ +package com.eu.habbo.habbohotel.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.navigation.DisplayMode; +import com.eu.habbo.habbohotel.navigation.ListMode; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Map; + +@Slf4j +public class HabboNavigatorWindowSettings { + public final THashMap displayModes = new THashMap<>(2); + private final int userId; + public int x = 100; + public int y = 100; + public int width = 425; + public int height = 535; + public boolean openSearches = false; + public int unknown = 0; + + public HabboNavigatorWindowSettings(int userId) { + this.userId = userId; + } + + public HabboNavigatorWindowSettings(ResultSet set) throws SQLException { + this.userId = set.getInt("user_id"); + this.x = set.getInt("x"); + this.y = set.getInt("y"); + this.width = set.getInt("width"); + this.height = set.getInt("height"); + this.openSearches = set.getBoolean("open_searches"); + this.unknown = 0; + } + + public void addDisplayMode(String category, HabboNavigatorPersonalDisplayMode displayMode) { + this.displayModes.put(category, displayMode); + } + + public boolean hasDisplayMode(String category) { + return this.displayModes.containsKey(category); + } + + public void insertDisplayMode(String category, ListMode listMode, DisplayMode displayMode) { + if (!this.displayModes.containsKey(category)) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("INSERT INTO users_navigator_settings (user_id, caption, list_type, display) VALUES (?, ?, ?, ?)")) { + statement.setInt(1, this.userId); + statement.setString(2, category); + statement.setString(3, listMode.name().toLowerCase()); + statement.setString(4, displayMode.name().toLowerCase()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.displayModes.put(category, new HabboNavigatorPersonalDisplayMode(listMode, displayMode)); + } + } + + public void setDisplayMode(String category, DisplayMode displayMode) { + HabboNavigatorPersonalDisplayMode personalDisplayMode = this.displayModes.get(category); + + if (personalDisplayMode != null) { + personalDisplayMode.displayMode = displayMode; + } else { + this.insertDisplayMode(category, ListMode.LIST, displayMode); + } + } + + public void setListMode(String category, ListMode listMode) { + HabboNavigatorPersonalDisplayMode personalDisplayMode = this.displayModes.get(category); + + if (personalDisplayMode != null) { + personalDisplayMode.listMode = listMode; + } else { + this.insertDisplayMode(category, listMode, DisplayMode.VISIBLE); + } + } + + public DisplayMode getDisplayModeForCategory(String category) { + return this.getDisplayModeForCategory(category, DisplayMode.VISIBLE); + } + + public DisplayMode getDisplayModeForCategory(String category, DisplayMode standard) { + if (this.displayModes.containsKey(category)) { + return this.displayModes.get(category).displayMode; + } + + return standard; + } + + public ListMode getListModeForCategory(String category) { + return this.getListModeForCategory(category, ListMode.LIST); + } + + public ListMode getListModeForCategory(String category, ListMode standard) { + if (this.displayModes.containsKey(category)) { + return this.displayModes.get(category).listMode; + } + + return standard; + } + + public void save(Connection connection) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE users_navigator_settings SET list_type = ?, display = ? WHERE user_id = ? AND caption = ? LIMIT 1")) { + for (Map.Entry set : this.displayModes.entrySet()) { + statement.setString(1, set.getValue().listMode.name().toLowerCase()); + statement.setString(2, set.getValue().displayMode.name().toLowerCase()); + statement.setInt(3, this.userId); + statement.setString(4, set.getKey()); + statement.execute(); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java new file mode 100644 index 0000000..8a1f9bb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java @@ -0,0 +1,802 @@ +package com.eu.habbo.habbohotel.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarRewardClaimed; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.achievements.TalentTrackType; +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.rooms.RoomTrade; +import com.eu.habbo.habbohotel.users.cache.HabboOfferPurchase; +import com.eu.habbo.habbohotel.users.subscriptions.Subscription; +import com.eu.habbo.plugin.events.users.subscriptions.UserSubscriptionCreatedEvent; +import com.eu.habbo.plugin.events.users.subscriptions.UserSubscriptionExtendedEvent; +import gnu.trove.list.array.TIntArrayList; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.set.hash.THashSet; +import gnu.trove.stack.array.TIntArrayStack; +import lombok.extern.slf4j.Slf4j; +import java.lang.reflect.Constructor; +import java.sql.*; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; + +@Slf4j +public class HabboStats implements Runnable { + public final TIntArrayList secretRecipes; + public final HabboNavigatorWindowSettings navigatorWindowSettings; + public final THashMap cache; + public final ArrayList calendarRewardsClaimed; + public final TIntObjectMap offerCache = new TIntObjectHashMap<>(); + private final AtomicInteger lastOnlineTime = new AtomicInteger(Emulator.getIntUnixTimestamp()); + private final THashMap achievementProgress; + private final THashMap achievementCache; + private final THashMap recentPurchases; + private final TIntArrayList favoriteRooms; + private final TIntArrayList ignoredUsers; + private TIntArrayList roomsVists; + public int achievementScore; + public int respectPointsReceived; + public int respectPointsGiven; + public int respectPointsToGive; + public int petRespectPointsToGive; + public boolean blockFollowing; + public boolean blockFriendRequests; + public boolean blockRoomInvites; + public boolean blockStaffAlerts; + public boolean preferOldChat; + public boolean blockCameraFollow; + public RoomChatMessageBubbles chatColor; + public int volumeSystem; + public int volumeFurni; + public int volumeTrax; + public int guild; + public List guilds; + public String[] tags; + public TIntArrayStack votedRooms; + public int loginStreak; + public int rentedItemId; + public int rentedTimeEnd; + public int hofPoints; + public boolean ignorePets; + public boolean ignoreBots; + public int citizenshipLevel; + public int helpersLevel; + public boolean perkTrade; + public long roomEnterTimestamp; + public AtomicInteger chatCounter = new AtomicInteger(0); + public long lastChat; + public long lastUsersSearched; + public boolean nux; + public boolean nuxReward; + public int nuxStep = 1; + public int mutedCount = 0; + public boolean mutedBubbleTracker = false; + public String changeNameChecked = ""; + public boolean allowNameChange; + public boolean isPurchasingFurniture = false; + public int forumPostsCount; + public THashMap> ltdPurchaseLog = new THashMap<>(0); + public long lastTradeTimestamp = Emulator.getIntUnixTimestamp(); + public long lastGiftTimestamp = Emulator.getIntUnixTimestamp(); + public long lastPurchaseTimestamp = Emulator.getIntUnixTimestamp(); + public int uiFlags; + public boolean hasGottenDefaultSavedSearches; + private HabboInfo habboInfo; + private boolean allowTrade; + private int clubExpireTimestamp; + private int muteEndTime; + public int maxFriends; + public int maxRooms; + public int lastHCPayday; + public int hcGiftsClaimed; + public int hcMessageLastModified = Emulator.getIntUnixTimestamp(); + public THashSet subscriptions; + + private HabboStats(ResultSet set, HabboInfo habboInfo) throws SQLException { + this.cache = new THashMap<>(10000); + this.achievementProgress = new THashMap<>(0); + this.achievementCache = new THashMap<>(0); + this.recentPurchases = new THashMap<>(0); + this.favoriteRooms = new TIntArrayList(0); + this.ignoredUsers = new TIntArrayList(0); + this.roomsVists = new TIntArrayList(0); + this.secretRecipes = new TIntArrayList(0); + this.calendarRewardsClaimed = new ArrayList<>(); + + this.habboInfo = habboInfo; + + this.achievementScore = set.getInt("achievement_score"); + this.respectPointsReceived = set.getInt("respects_received"); + this.respectPointsGiven = set.getInt("respects_given"); + this.petRespectPointsToGive = set.getInt("daily_pet_respect_points"); + this.respectPointsToGive = set.getInt("daily_respect_points"); + this.blockFollowing = set.getString("block_following").equals("1"); + this.blockFriendRequests = set.getString("block_friendrequests").equals("1"); + this.blockRoomInvites = set.getString("block_roominvites").equals("1"); + this.preferOldChat = set.getString("old_chat").equals("1"); + this.blockCameraFollow = set.getString("block_camera_follow").equals("1"); + this.guild = set.getInt("guild_id"); + this.guilds = new ArrayList<>(); + this.tags = set.getString("tags").split(";"); + this.allowTrade = set.getString("can_trade").equals("1"); + this.votedRooms = new TIntArrayStack(); + this.clubExpireTimestamp = set.getInt("club_expire_timestamp"); + this.loginStreak = set.getInt("login_streak"); + this.rentedItemId = set.getInt("rent_space_id"); + this.rentedTimeEnd = set.getInt("rent_space_endtime"); + this.volumeSystem = set.getInt("volume_system"); + this.volumeFurni = set.getInt("volume_furni"); + this.volumeTrax = set.getInt("volume_trax"); + this.chatColor = RoomChatMessageBubbles.getBubble(set.getInt("chat_color")); + this.hofPoints = set.getInt("hof_points"); + this.blockStaffAlerts = set.getString("block_alerts").equals("1"); + this.citizenshipLevel = set.getInt("talent_track_citizenship_level"); + this.helpersLevel = set.getInt("talent_track_helpers_level"); + this.ignoreBots = set.getString("ignore_bots").equalsIgnoreCase("1"); + this.ignorePets = set.getString("ignore_pets").equalsIgnoreCase("1"); + this.nux = set.getString("nux").equals("1"); + this.muteEndTime = set.getInt("mute_end_timestamp"); + this.allowNameChange = set.getString("allow_name_change").equalsIgnoreCase("1"); + this.perkTrade = set.getString("perk_trade").equalsIgnoreCase("1"); + this.forumPostsCount = set.getInt("forums_post_count"); + this.uiFlags = set.getInt("ui_flags"); + this.hasGottenDefaultSavedSearches = set.getInt("has_gotten_default_saved_searches") == 1; + this.maxFriends = set.getInt("max_friends"); + this.maxRooms = set.getInt("max_rooms"); + this.lastHCPayday = set.getInt("last_hc_payday"); + this.hcGiftsClaimed = set.getInt("hc_gifts_claimed"); + + this.nuxReward = this.nux; + + this.subscriptions = Emulator.getGameEnvironment().getSubscriptionManager().getSubscriptionsForUser(this.habboInfo.getId()); + + try (PreparedStatement statement = set.getStatement().getConnection().prepareStatement("SELECT * FROM user_window_settings WHERE user_id = ? LIMIT 1")) { + statement.setInt(1, this.habboInfo.getId()); + try (ResultSet nSet = statement.executeQuery()) { + if (nSet.next()) { + this.navigatorWindowSettings = new HabboNavigatorWindowSettings(nSet); + } else { + try (PreparedStatement stmt = statement.getConnection().prepareStatement("INSERT INTO user_window_settings (user_id) VALUES (?)")) { + stmt.setInt(1, this.habboInfo.getId()); + stmt.executeUpdate(); + } + + this.navigatorWindowSettings = new HabboNavigatorWindowSettings(habboInfo.getId()); + } + } + } + + try (PreparedStatement statement = set.getStatement().getConnection().prepareStatement("SELECT * FROM users_navigator_settings WHERE user_id = ?")) { + statement.setInt(1, this.habboInfo.getId()); + try (ResultSet nSet = statement.executeQuery()) { + while (nSet.next()) { + this.navigatorWindowSettings.addDisplayMode(nSet.getString("caption"), new HabboNavigatorPersonalDisplayMode(nSet)); + } + } + } + + try (PreparedStatement favoriteRoomsStatement = set.getStatement().getConnection().prepareStatement("SELECT * FROM users_favorite_rooms WHERE user_id = ?")) { + favoriteRoomsStatement.setInt(1, this.habboInfo.getId()); + try (ResultSet favoriteSet = favoriteRoomsStatement.executeQuery()) { + while (favoriteSet.next()) { + this.favoriteRooms.add(favoriteSet.getInt("room_id")); + } + } + + } + + try (PreparedStatement recipesStatement = set.getStatement().getConnection().prepareStatement("SELECT * FROM users_recipes WHERE user_id = ?")) { + recipesStatement.setInt(1, this.habboInfo.getId()); + try (ResultSet recipeSet = recipesStatement.executeQuery()) { + while (recipeSet.next()) { + this.secretRecipes.add(recipeSet.getInt("recipe")); + } + } + } + + try (PreparedStatement calendarRewardsStatement = set.getStatement().getConnection().prepareStatement("SELECT * FROM calendar_rewards_claimed WHERE user_id = ?")) { + calendarRewardsStatement.setInt(1, this.habboInfo.getId()); + try (ResultSet rewardSet = calendarRewardsStatement.executeQuery()) { + while (rewardSet.next()) { + this.calendarRewardsClaimed.add(new CalendarRewardClaimed(rewardSet)); + } + } + } + + try (PreparedStatement ltdPurchaseLogStatement = set.getStatement().getConnection().prepareStatement("SELECT catalog_item_id, timestamp FROM catalog_items_limited WHERE user_id = ? AND timestamp > ?")) { + ltdPurchaseLogStatement.setInt(1, this.habboInfo.getId()); + ltdPurchaseLogStatement.setInt(2, Emulator.getIntUnixTimestamp() - 86400); + try (ResultSet ltdSet = ltdPurchaseLogStatement.executeQuery()) { + while (ltdSet.next()) { + this.addLtdLog(ltdSet.getInt("catalog_item_id"), ltdSet.getInt("timestamp")); + } + } + } + + try (PreparedStatement ignoredPlayersStatement = set.getStatement().getConnection().prepareStatement("SELECT target_id FROM users_ignored WHERE user_id = ?")) { + ignoredPlayersStatement.setInt(1, this.habboInfo.getId()); + try (ResultSet ignoredSet = ignoredPlayersStatement.executeQuery()) { + while (ignoredSet.next()) { + this.ignoredUsers.add(ignoredSet.getInt(1)); + } + } + } + + try (PreparedStatement loadOfferPurchaseStatement = set.getStatement().getConnection().prepareStatement("SELECT * FROM users_target_offer_purchases WHERE user_id = ?")) { + loadOfferPurchaseStatement.setInt(1, this.habboInfo.getId()); + try (ResultSet offerSet = loadOfferPurchaseStatement.executeQuery()) { + while (offerSet.next()) { + this.offerCache.put(offerSet.getInt("offer_id"), new HabboOfferPurchase(offerSet)); + } + } + } + + try (PreparedStatement loadRoomsVisit = set.getStatement().getConnection().prepareStatement("SELECT DISTINCT room_id FROM room_enter_log WHERE user_id = ?")) { + loadRoomsVisit.setInt(1, this.habboInfo.getId()); + try (ResultSet roomSet = loadRoomsVisit.executeQuery()) { + while (roomSet.next()) { + this.roomsVists.add(roomSet.getInt("room_id")); + } + } + } + } + + private static HabboStats createNewStats(HabboInfo habboInfo) { + habboInfo.firstVisit = true; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO users_settings (user_id) VALUES (?)")) { + statement.setInt(1, habboInfo.getId()); + statement.executeUpdate(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return load(habboInfo); + } + + public static HabboStats load(HabboInfo habboInfo) { + HabboStats stats = null; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM users_settings WHERE user_id = ? LIMIT 1")) { + statement.setInt(1, habboInfo.getId()); + try (ResultSet set = statement.executeQuery()) { + set.next(); + if (set.getRow() != 0) { + stats = new HabboStats(set, habboInfo); + } else { + stats = createNewStats(habboInfo); + } + } + } + + if (stats != null) { + try (PreparedStatement statement = connection.prepareStatement("SELECT guild_id FROM guilds_members WHERE user_id = ? AND level_id < 3 LIMIT 100")) { + statement.setInt(1, habboInfo.getId()); + try (ResultSet set = statement.executeQuery()) { + + int i = 0; + while (set.next()) { + stats.guilds.add(set.getInt("guild_id")); + i++; + } + } + } + + Collections.sort(stats.guilds); + + try (PreparedStatement statement = connection.prepareStatement("SELECT room_id FROM room_votes WHERE user_id = ?")) { + statement.setInt(1, habboInfo.getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + stats.votedRooms.push(set.getInt("room_id")); + } + } + } + + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM users_achievements WHERE user_id = ?")) { + statement.setInt(1, habboInfo.getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + Achievement achievement = Emulator.getGameEnvironment().getAchievementManager().getAchievement(set.getString("achievement_name")); + + if (achievement != null) { + stats.achievementProgress.put(achievement, set.getInt("progress")); + } + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return stats; + } + + @Override + public void run() { + // Find difference between last sync and update with a new timestamp. + int onlineTimeLast = this.lastOnlineTime.getAndUpdate(operand -> Emulator.getIntUnixTimestamp()); + int onlineTime = Emulator.getIntUnixTimestamp() - onlineTimeLast; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE users_settings SET achievement_score = ?, respects_received = ?, respects_given = ?, daily_respect_points = ?, block_following = ?, block_friendrequests = ?, online_time = online_time + ?, guild_id = ?, daily_pet_respect_points = ?, club_expire_timestamp = ?, login_streak = ?, rent_space_id = ?, rent_space_endtime = ?, volume_system = ?, volume_furni = ?, volume_trax = ?, block_roominvites = ?, old_chat = ?, block_camera_follow = ?, chat_color = ?, hof_points = ?, block_alerts = ?, talent_track_citizenship_level = ?, talent_track_helpers_level = ?, ignore_bots = ?, ignore_pets = ?, nux = ?, mute_end_timestamp = ?, allow_name_change = ?, perk_trade = ?, can_trade = ?, `forums_post_count` = ?, ui_flags = ?, has_gotten_default_saved_searches = ?, max_friends = ?, max_rooms = ?, last_hc_payday = ?, hc_gifts_claimed = ? WHERE user_id = ? LIMIT 1")) { + statement.setInt(1, this.achievementScore); + statement.setInt(2, this.respectPointsReceived); + statement.setInt(3, this.respectPointsGiven); + statement.setInt(4, this.respectPointsToGive); + statement.setString(5, this.blockFollowing ? "1" : "0"); + statement.setString(6, this.blockFriendRequests ? "1" : "0"); + statement.setInt(7, onlineTime); + statement.setInt(8, this.guild); + statement.setInt(9, this.petRespectPointsToGive); + statement.setInt(10, this.clubExpireTimestamp); + statement.setInt(11, this.loginStreak); + statement.setInt(12, this.rentedItemId); + statement.setInt(13, this.rentedTimeEnd); + statement.setInt(14, this.volumeSystem); + statement.setInt(15, this.volumeFurni); + statement.setInt(16, this.volumeTrax); + statement.setString(17, this.blockRoomInvites ? "1" : "0"); + statement.setString(18, this.preferOldChat ? "1" : "0"); + statement.setString(19, this.blockCameraFollow ? "1" : "0"); + statement.setInt(20, this.chatColor.getType()); + statement.setInt(21, this.hofPoints); + statement.setString(22, this.blockStaffAlerts ? "1" : "0"); + statement.setInt(23, this.citizenshipLevel); + statement.setInt(24, this.helpersLevel); + statement.setString(25, this.ignoreBots ? "1" : "0"); + statement.setString(26, this.ignorePets ? "1" : "0"); + statement.setString(27, this.nux ? "1" : "0"); + statement.setInt(28, this.muteEndTime); + statement.setString(29, this.allowNameChange ? "1" : "0"); + statement.setString(30, this.perkTrade ? "1" : "0"); + statement.setString(31, this.allowTrade ? "1" : "0"); + statement.setInt(32, this.forumPostsCount); + statement.setInt(33, this.uiFlags); + statement.setInt(34, this.hasGottenDefaultSavedSearches ? 1 : 0); + statement.setInt(35, this.maxFriends); + statement.setInt(36, this.maxRooms); + statement.setInt(37, this.lastHCPayday); + statement.setInt(38, this.hcGiftsClaimed); + statement.setInt(39, this.habboInfo.getId()); + + statement.executeUpdate(); + } + + try (PreparedStatement statement = connection.prepareStatement("UPDATE user_window_settings SET x = ?, y = ?, width = ?, height = ?, open_searches = ? WHERE user_id = ? LIMIT 1")) { + statement.setInt(1, this.navigatorWindowSettings.x); + statement.setInt(2, this.navigatorWindowSettings.y); + statement.setInt(3, this.navigatorWindowSettings.width); + statement.setInt(4, this.navigatorWindowSettings.height); + statement.setString(5, this.navigatorWindowSettings.openSearches ? "1" : "0"); + statement.setInt(6, this.habboInfo.getId()); + statement.executeUpdate(); + } + + if (!this.offerCache.isEmpty()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE users_target_offer_purchases SET state = ?, amount = ?, last_purchase = ? WHERE user_id = ? AND offer_id = ?")) { + for (HabboOfferPurchase purchase : this.offerCache.valueCollection()) { + if (!purchase.needsUpdate()) continue; + + statement.setInt(1, purchase.getState()); + statement.setInt(2, purchase.getAmount()); + statement.setInt(3, purchase.getLastPurchaseTimestamp()); + statement.setInt(4, this.habboInfo.getId()); + statement.setInt(5, purchase.getOfferId()); + statement.execute(); + } + } + } + + this.navigatorWindowSettings.save(connection); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void dispose() { + this.run(); + this.habboInfo = null; + this.recentPurchases.clear(); + } + + public void addGuild(int guildId) { + if (!this.guilds.contains(guildId)) { + this.guilds.add(guildId); + } + } + + public void removeGuild(int guildId) { + this.guilds.remove((Integer) guildId); + } + + public boolean hasGuild(int guildId) { + for (int i : this.guilds) { + if (i == guildId) + return true; + } + + return false; + } + + public int getAchievementScore() { + return this.achievementScore; + } + + public void addAchievementScore(int achievementScore) { + this.achievementScore += achievementScore; + } + + public int getAchievementProgress(Achievement achievement) { + if (this.achievementProgress.containsKey(achievement)) + return this.achievementProgress.get(achievement); + + return -1; + } + + public void setProgress(Achievement achievement, int progress) { + this.achievementProgress.put(achievement, progress); + } + + public int getRentedTimeEnd() { + return this.rentedTimeEnd; + } + + public void setRentedTimeEnd(int rentedTimeEnd) { + this.rentedTimeEnd = rentedTimeEnd; + } + + public int getRentedItemId() { + return this.rentedItemId; + } + + public void setRentedItemId(int rentedItemId) { + this.rentedItemId = rentedItemId; + } + + public boolean isRentingSpace() { + return this.rentedTimeEnd >= Emulator.getIntUnixTimestamp(); + } + + public Subscription getSubscription(String subscriptionType) { + for(Subscription subscription : subscriptions) { + if(subscription.getSubscriptionType().equalsIgnoreCase(subscriptionType) && subscription.isActive() && subscription.getRemaining() > 0) { + return subscription; + } + } + return null; + } + + public boolean hasSubscription(String subscriptionType) { + Subscription subscription = getSubscription(subscriptionType); + return subscription != null; + } + + public int getSubscriptionExpireTimestamp(String subscriptionType) { + Subscription subscription = getSubscription(subscriptionType); + + if(subscription == null) + return 0; + + return subscription.getTimestampEnd(); + } + + public Subscription createSubscription(String subscriptionType, int duration) { + Subscription subscription = getSubscription(subscriptionType); + + if(subscription != null) { + if (!Emulator.getPluginManager().fireEvent(new UserSubscriptionExtendedEvent(this.habboInfo.getId(), subscription, duration)).isCancelled()) { + subscription.addDuration(duration); + subscription.onExtended(duration); + } + return subscription; + } + + if (!Emulator.getPluginManager().fireEvent(new UserSubscriptionCreatedEvent(this.habboInfo.getId(), subscriptionType, duration)).isCancelled()) { + int startTimestamp = Emulator.getIntUnixTimestamp(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO `users_subscriptions` (`user_id`, `subscription_type`, `timestamp_start`, `duration`, `active`) VALUES (?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, this.habboInfo.getId()); + statement.setString(2, subscriptionType); + statement.setInt(3, startTimestamp); + statement.setInt(4, duration); + statement.setInt(5, 1); + statement.execute(); + try (ResultSet set = statement.getGeneratedKeys()) { + if (set.next()) { + Class subClazz = Emulator.getGameEnvironment().getSubscriptionManager().getSubscriptionClass(subscriptionType); + try { + Constructor c = subClazz.getConstructor(Integer.class, Integer.class, String.class, Integer.class, Integer.class, Boolean.class); + c.setAccessible(true); + Subscription sub = c.newInstance(set.getInt(1), this.habboInfo.getId(), subscriptionType, startTimestamp, duration, true); + this.subscriptions.add(sub); + sub.onCreated(); + return sub; + } + catch (Exception e) { + log.error("Caught exception", e); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + return null; + } + + public int getClubExpireTimestamp() { + return getSubscriptionExpireTimestamp(Subscription.HABBO_CLUB); + } + + public void setClubExpireTimestamp(int clubExpireTimestamp) { + Subscription subscription = getSubscription(Subscription.HABBO_CLUB); + int duration = clubExpireTimestamp - Emulator.getIntUnixTimestamp(); + + if(subscription != null) { + duration = clubExpireTimestamp - subscription.getTimestampStart(); + } + + if(duration > 0) { + createSubscription(Subscription.HABBO_CLUB, duration); + } + } + + public boolean hasActiveClub() { + return hasSubscription(Subscription.HABBO_CLUB); + } + + public int getPastTimeAsClub() { + int pastTimeAsHC = 0; + for(Subscription subs : this.subscriptions) { + if(subs.getSubscriptionType().equalsIgnoreCase(Subscription.HABBO_CLUB)) { + pastTimeAsHC += subs.getDuration() - (Math.max(subs.getRemaining(), 0)); + } + } + return pastTimeAsHC; + } + + public int getTimeTillNextClubGift() { + int pastTimeAsClub = getPastTimeAsClub(); + int totalGifts = (int)Math.ceil(pastTimeAsClub / 2678400.0); + return (totalGifts * 2678400) - pastTimeAsClub; + } + + public int getRemainingClubGifts() { + int totalGifts = (int)Math.ceil(getPastTimeAsClub() / 2678400.0); + return totalGifts - this.hcGiftsClaimed; + } + + public THashMap getAchievementProgress() { + return this.achievementProgress; + } + + public THashMap getAchievementCache() { + return this.achievementCache; + } + + public void addPurchase(CatalogItem item) { + if (!this.recentPurchases.containsKey(item.getId())) { + this.recentPurchases.put(item.getId(), item); + } + } + + public THashMap getRecentPurchases() { + return this.recentPurchases; + } + + public void disposeRecentPurchases() { + this.recentPurchases.clear(); + } + + public boolean addFavoriteRoom(int roomId) { + if (this.favoriteRooms.contains(roomId)) + return false; + + if (Emulator.getConfig().getInt("hotel.rooms.max.favorite") <= this.favoriteRooms.size()) + return false; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO users_favorite_rooms (user_id, room_id) VALUES (?, ?)")) { + statement.setInt(1, this.habboInfo.getId()); + statement.setInt(2, roomId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.favoriteRooms.add(roomId); + return true; + } + + public void removeFavoriteRoom(int roomId) { + if (this.favoriteRooms.remove(roomId)) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM users_favorite_rooms WHERE user_id = ? AND room_id = ? LIMIT 1")) { + statement.setInt(1, this.habboInfo.getId()); + statement.setInt(2, roomId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public boolean hasFavoriteRoom(int roomId) { + return this.favoriteRooms.contains(roomId); + } + + public boolean visitedRoom(int roomId) { return this.roomsVists.contains(roomId); } + + public void addVisitRoom(int roomId) { this.roomsVists.add(roomId); } + + public TIntArrayList getFavoriteRooms() { + return this.favoriteRooms; + } + + public boolean hasRecipe(int id) { + return this.secretRecipes.contains(id); + } + + public boolean addRecipe(int id) { + if (this.secretRecipes.contains(id)) + return false; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO users_recipes (user_id, recipe) VALUES (?, ?)")) { + statement.setInt(1, this.habboInfo.getId()); + statement.setInt(2, id); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.secretRecipes.add(id); + return true; + } + + public int talentTrackLevel(TalentTrackType type) { + if (type == TalentTrackType.CITIZENSHIP) + return this.citizenshipLevel; + else if (type == TalentTrackType.HELPER) + return this.helpersLevel; + + return -1; + } + + public void setTalentLevel(TalentTrackType type, int level) { + if (type == TalentTrackType.CITIZENSHIP) + this.citizenshipLevel = level; + else if (type == TalentTrackType.HELPER) + this.helpersLevel = level; + } + + public int getMuteEndTime() { + return this.muteEndTime; + } + + public int addMuteTime(int seconds) { + if (this.remainingMuteTime() == 0) { + this.muteEndTime = Emulator.getIntUnixTimestamp(); + } + + this.mutedBubbleTracker = true; + this.muteEndTime += seconds; + + return this.remainingMuteTime(); + } + + public int remainingMuteTime() { + return Math.max(0, this.muteEndTime - Emulator.getIntUnixTimestamp()); + } + + public boolean allowTalk() { + return this.remainingMuteTime() == 0; + } + + public void unMute() { + this.muteEndTime = 0; + this.mutedBubbleTracker = false; + } + + public void addLtdLog(int catalogItemId, int timestamp) { + if (!this.ltdPurchaseLog.containsKey(catalogItemId)) { + this.ltdPurchaseLog.put(catalogItemId, new ArrayList<>(1)); + } + + this.ltdPurchaseLog.get(catalogItemId).add(timestamp); + } + + public int totalLtds() { + int total = 0; + for (Map.Entry> entry : this.ltdPurchaseLog.entrySet()) { + total += entry.getValue().size(); + } + + return total; + } + + public int totalLtds(int catalogItemId) { + if (this.ltdPurchaseLog.containsKey(catalogItemId)) { + return this.ltdPurchaseLog.get(catalogItemId).size(); + } + + return 0; + } + + /** + * Ignore an user. + * + * @param gameClient The client to which this HabboStats instance belongs. + * @param userId The user to ignore. + * @return true if successfully ignored, false otherwise. + */ + public boolean ignoreUser(GameClient gameClient, int userId) { + final Habbo target = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + + if (!Emulator.getConfig().getBoolean("hotel.allow.ignore.staffs")) { + final int ownRank = gameClient.getHabbo().getHabboInfo().getRank().getId(); + final int targetRank = target.getHabboInfo().getRank().getId(); + + if (targetRank >= ownRank) { + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("generic.error.ignore_higher_rank"), RoomChatMessageBubbles.ALERT); + return false; + } + } + + if (!this.userIgnored(userId)) { + this.ignoredUsers.add(userId); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("INSERT INTO users_ignored (user_id, target_id) VALUES (?, ?)")) { + statement.setInt(1, this.habboInfo.getId()); + statement.setInt(2, userId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + return true; + } + + public void unignoreUser(int userId) { + if (this.userIgnored(userId)) { + this.ignoredUsers.remove(userId); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("DELETE FROM users_ignored WHERE user_id = ? AND target_id = ?")) { + statement.setInt(1, this.habboInfo.getId()); + statement.setInt(2, userId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public boolean userIgnored(int userId) { + return this.ignoredUsers.contains(userId); + } + + public boolean allowTrade() { + if (AchievementManager.TALENTTRACK_ENABLED && RoomTrade.TRADING_REQUIRES_PERK) + return this.perkTrade && this.allowTrade; + else return this.allowTrade; + } + + public void setAllowTrade(boolean allowTrade) { + this.allowTrade = allowTrade; + } + + public HabboOfferPurchase getHabboOfferPurchase(int offerId) { + return this.offerCache.get(offerId); + } + + public void addHabboOfferPurchase(HabboOfferPurchase offerPurchase) { + this.offerCache.put(offerPurchase.getOfferId(), offerPurchase); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/SignType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/SignType.java new file mode 100644 index 0000000..4fc3d09 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/SignType.java @@ -0,0 +1,33 @@ +package com.eu.habbo.habbohotel.users; + +public enum SignType { + ZERO(0), + ONE(1), + TWO(2), + THREE(3), + FOUR(4), + FIVE(5), + SIX(6), + SEVEN(7), + EIGHT(8), + NINE(9), + TEN(10), + LOVE(11), + HATE(12), + EXCLAMATION(13), + SMILE(14), + FOOTBALL(15), + CARD_YELLOW(16), + CARD_RED(17), + NONE(100); + + private final int id; + + SignType(int id) { + this.id = id; + } + + public int getId() { + return this.id; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/cache/HabboOfferPurchase.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/cache/HabboOfferPurchase.java new file mode 100644 index 0000000..9ea6991 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/cache/HabboOfferPurchase.java @@ -0,0 +1,93 @@ +package com.eu.habbo.habbohotel.users.cache; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class HabboOfferPurchase { + private final int userId; + private final int offerId; + private int state; + private int amount; + private int lastPurchaseTimestamp; + private boolean needsUpdate = false; + + public HabboOfferPurchase(ResultSet set) throws SQLException { + this.userId = set.getInt("user_id"); + this.offerId = set.getInt("offer_id"); + this.state = set.getInt("state"); + this.amount = set.getInt("amount"); + this.lastPurchaseTimestamp = set.getInt("last_purchase"); + } + + private HabboOfferPurchase(int userId, int offerId) { + this.userId = userId; + this.offerId = offerId; + } + + public static HabboOfferPurchase getOrCreate(Habbo habbo, int offerId) { + HabboOfferPurchase purchase = habbo.getHabboStats().getHabboOfferPurchase(offerId); + + if (purchase == null) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO users_target_offer_purchases (user_id, offer_id) VALUES (?, ?)")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + statement.setInt(2, offerId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + return null; + } + + purchase = new HabboOfferPurchase(habbo.getHabboInfo().getId(), offerId); + habbo.getHabboStats().addHabboOfferPurchase(purchase); + } + + return purchase; + } + + public int getOfferId() { + return this.offerId; + } + + public int getState() { + return this.state; + } + + public void setState(int state) { + this.state = state; + this.needsUpdate = true; + } + + public int getAmount() { + return this.amount; + } + + public void incrementAmount(int amount) { + this.amount += amount; + this.needsUpdate = true; + } + + public int getLastPurchaseTimestamp() { + return this.lastPurchaseTimestamp; + } + + public void setLastPurchaseTimestamp(int timestamp) { + this.lastPurchaseTimestamp = timestamp; + this.needsUpdate = true; + } + + public void update(int amount, int timestamp) { + this.amount += amount; + this.lastPurchaseTimestamp = timestamp; + this.needsUpdate = true; + } + + public boolean needsUpdate() { + return this.needsUpdate; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/ClothingValidationManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/ClothingValidationManager.java new file mode 100644 index 0000000..9565465 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/ClothingValidationManager.java @@ -0,0 +1,212 @@ +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 lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.regex.Pattern; + +@Slf4j +public class ClothingValidationManager { + + public static String FIGUREDATA_URL = ""; + public static boolean VALIDATE_ON_HC_EXPIRE = false; + public static boolean VALIDATE_ON_LOGIN = false; + public static boolean VALIDATE_ON_CHANGE_LOOKS = false; + public static boolean VALIDATE_ON_MIMIC = false; + public static boolean VALIDATE_ON_MANNEQUIN = false; + public static boolean VALIDATE_ON_FBALLGATE = false; + + private static final Figuredata FIGUREDATA = new Figuredata(); + + /** + * Parses the new figuredata.xml file + * @param newUrl URI of figuredata.xml file. Can be a file path or URL + */ + public static void reloadFiguredata(String newUrl) { + try { + FIGUREDATA.parseXML(newUrl); + } catch (Exception e) { + VALIDATE_ON_HC_EXPIRE = false; + VALIDATE_ON_LOGIN = false; + VALIDATE_ON_CHANGE_LOOKS = false; + VALIDATE_ON_MIMIC = false; + VALIDATE_ON_MANNEQUIN = false; + VALIDATE_ON_FBALLGATE = false; + log.error("Caught exception", e); + } + } + + /** + * Validates a figure string on a given user + * @param habbo User to validate + * @return Cleaned figure string + */ + public static String validateLook(Habbo habbo) { + return validateLook(habbo.getHabboInfo().getLook(), habbo.getHabboInfo().getGender().name(), habbo.getHabboStats().hasActiveClub(), habbo.getInventory().getWardrobeComponent().getClothingSets()); + } + + /** + * Validates a given figure string and gender on a given user + * @param habbo User to validate + * @param look Figure string + * @param gender Gender (M/F) + * @return Cleaned figure string + */ + public static String validateLook(Habbo habbo, String look, String gender) { + return validateLook(look, gender, habbo.getHabboStats().hasActiveClub(), habbo.getInventory().getWardrobeComponent().getClothingSets()); + } + + /** + * Validates a given figure string against a given gender + * @param look Figure string + * @param gender Gender (M/F) + * @return Cleaned figure string + */ + public static String validateLook(String look, String gender) { + return validateLook(look, gender, false, new TIntHashSet()); + } + + /** + * Validates a given figure string against a given gender with club clothing option + * @param look Figure string + * @param gender Gender (M/F) + * @param isHC Boolean indicating if club clothing is permitted + * @return Cleaned figure string + */ + public static String validateLook(String look, String gender, boolean isHC) { + return validateLook(look, gender, isHC, new TIntHashSet()); + } + + /** + * Validates a figure string with all available options + * @param look Figure string + * @param gender Gender (M/F) + * @param isHC Boolean indicating if club clothing is permitted + * @param ownedClothing Array of owned clothing set IDs. If sellable and setId not in this array clothing will be removed + * @return Cleaned figure string + */ + public static String validateLook(String look, String gender, boolean isHC, TIntCollection ownedClothing) { + if(FIGUREDATA.palettes.size() == 0 || FIGUREDATA.settypes.size() == 0) + return look; + + String[] newLookParts = look.split(Pattern.quote(".")); + ArrayList lookParts = new ArrayList<>(); + + THashMap parts = new THashMap<>(); + + // add mandatory settypes + for(String lookpart : newLookParts) { + 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()); + log.error("Error in clothing validation", e); + } + }); + + return String.join(".", lookParts); + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/Figuredata.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/Figuredata.java new file mode 100644 index 0000000..0f4aec7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/Figuredata.java @@ -0,0 +1,122 @@ +package com.eu.habbo.habbohotel.users.clothingvalidation; + +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.IOException; +import java.io.StringWriter; +import java.util.Map; +import java.util.TreeMap; + +public class Figuredata { + public Map palettes; + public Map settypes; + + public Figuredata() { + palettes = new TreeMap<>(); + settypes = new TreeMap<>(); + } + + /** + * Parses the figuredata.xml file + * @param uri URI to the figuredata.xml file + * @throws ParserConfigurationException + * @throws IOException + * @throws SAXException + */ + public void parseXML(String uri) throws Exception, ParserConfigurationException, IOException, SAXException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setValidating(false); + factory.setIgnoringElementContentWhitespace(true); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.parse(uri); + + Element rootElement = document.getDocumentElement(); + + if(!rootElement.getTagName().equalsIgnoreCase("figuredata") || document.getElementsByTagName("colors") == null || document.getElementsByTagName("sets") == null) { + StringWriter writer = new StringWriter(); + TransformerFactory.newInstance().newTransformer().transform(new DOMSource(document), new StreamResult(writer)); + String documentString = writer.getBuffer().toString(); + throw new Exception("The passed file is not in figuredata format. Received " + documentString.substring(0, Math.min(documentString.length(), 200))); + } + + NodeList palettesList = document.getElementsByTagName("colors").item(0).getChildNodes(); + NodeList settypesList = document.getElementsByTagName("sets").item(0).getChildNodes(); + + palettes.clear(); + settypes.clear(); + + for(int i = 0; i < palettesList.getLength(); i++) { + Node nNode = palettesList.item(i); + if(nNode.getNodeType() == Node.ELEMENT_NODE) { + Element element = (Element) nNode; + int paletteId = Integer.parseInt(element.getAttribute("id")); + FiguredataPalette palette = new FiguredataPalette(paletteId); + + NodeList colorsList = nNode.getChildNodes(); + for (int ii = 0; ii < colorsList.getLength(); ii++) { + if(colorsList.item(ii).getNodeType() == Node.ELEMENT_NODE) { + Element colorElement = (Element) colorsList.item(ii); + FiguredataPaletteColor color = new FiguredataPaletteColor( + Integer.parseInt(colorElement.getAttribute("id")), + Integer.parseInt(colorElement.getAttribute("index")), + !colorElement.getAttribute("club").equals("0"), + colorElement.getAttribute("selectable").equals("1"), + colorElement.getTextContent() + ); + palette.addColor(color); + } + } + + palettes.put(palette.id, palette); + } + } + + for(int i = 0; i < settypesList.getLength(); i++) { + Node nNode = settypesList.item(i); + + if(nNode.getNodeType() == Node.ELEMENT_NODE) { + Element element = (Element) nNode; + + String type = element.getAttribute("type"); + int paletteId = Integer.parseInt(element.getAttribute("paletteid")); + boolean mandM0 = element.getAttribute("mand_m_0").equals("1"); + boolean mandF0 = element.getAttribute("mand_f_0").equals("1"); + boolean mandM1 = element.getAttribute("mand_m_1").equals("1"); + boolean mandF1 = element.getAttribute("mand_f_1").equals("1"); + + FiguredataSettype settype = new FiguredataSettype(type, paletteId, mandM0, mandF0, mandM1, mandF1); + + NodeList setsList = nNode.getChildNodes(); + for (int ii = 0; ii < setsList.getLength(); ii++) { + if(setsList.item(ii).getNodeType() == Node.ELEMENT_NODE) { + Element setElement = (Element) setsList.item(ii); + FiguredataSettypeSet set = new FiguredataSettypeSet( + Integer.parseInt(setElement.getAttribute("id")), + setElement.getAttribute("gender"), + !setElement.getAttribute("club").equals("0"), + setElement.getAttribute("colorable").equals("1"), + setElement.getAttribute("selectable").equals("1"), + setElement.getAttribute("preselectable").equals("1"), + setElement.getAttribute("sellable").equals("1") + ); + settype.addSet(set); + } + } + + settypes.put(settype.type, settype); + } + } + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataPalette.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataPalette.java new file mode 100644 index 0000000..4a1c48d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataPalette.java @@ -0,0 +1,31 @@ +package com.eu.habbo.habbohotel.users.clothingvalidation; + +import java.util.TreeMap; + +public class FiguredataPalette { + public int id; + public TreeMap colors; + + public FiguredataPalette(int id) { + this.id = id; + this.colors = new TreeMap<>(); + } + + public void addColor(FiguredataPaletteColor color) { + this.colors.put(color.id, color); + } + + public FiguredataPaletteColor getColor(int colorId) { + return this.colors.get(colorId); + } + + public FiguredataPaletteColor getFirstNonHCColor() { + for(FiguredataPaletteColor color : this.colors.values()) { + if(!color.club && color.selectable) + return color; + } + + return this.colors.size() > 0 ? this.colors.entrySet().iterator().next().getValue() : null; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataPaletteColor.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataPaletteColor.java new file mode 100644 index 0000000..7ba0b9a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataPaletteColor.java @@ -0,0 +1,17 @@ +package com.eu.habbo.habbohotel.users.clothingvalidation; + +public class FiguredataPaletteColor { + public int id; + public int index; + public boolean club; + public boolean selectable; + public String colorHex; + + public FiguredataPaletteColor(int id, int index, boolean club, boolean selectable, String colorHex) { + this.id = id; + this.index = index; + this.club = club; + this.selectable = selectable; + this.colorHex = colorHex; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataSettype.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataSettype.java new file mode 100644 index 0000000..e369881 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataSettype.java @@ -0,0 +1,60 @@ +package com.eu.habbo.habbohotel.users.clothingvalidation; + +import java.util.Map; +import java.util.TreeMap; + +public class FiguredataSettype { + public String type; + public int paletteId; + public boolean mandatoryMale0; + public boolean mandatoryFemale0; + public boolean mandatoryMale1; + public boolean mandatoryFemale1; + public TreeMap sets; + + public FiguredataSettype(String type, int paletteId, boolean mandatoryMale0, boolean mandatoryFemale0, boolean mandatoryMale1, boolean mandatoryFemale1) { + this.type = type; + this.paletteId = paletteId; + this.mandatoryMale0 = mandatoryMale0; + this.mandatoryFemale0 = mandatoryFemale0; + this.mandatoryMale1 = mandatoryMale1; + this.mandatoryFemale1 = mandatoryFemale1; + this.sets = new TreeMap<>(); + } + + public void addSet(FiguredataSettypeSet set) { + this.sets.put(set.id, set); + } + + public FiguredataSettypeSet getSet(int id) { + return this.sets.get(id); + } + + /** + * @param gender Gender (M/F) + * @return First non-sellable and selectable set for given gender + */ + public FiguredataSettypeSet getFirstSetForGender(String gender) { + for(FiguredataSettypeSet set : this.sets.descendingMap().values()) { + if((set.gender.equalsIgnoreCase(gender) || set.gender.equalsIgnoreCase("u")) && !set.sellable && set.selectable) { + return set; + } + } + + return this.sets.size() > 0 ? this.sets.descendingMap().entrySet().iterator().next().getValue() : null; + } + + /** + * @param gender Gender (M/F) + * @return First non-club, non-sellable and selectable set for given gender + */ + public FiguredataSettypeSet getFirstNonHCSetForGender(String gender) { + for(FiguredataSettypeSet set : this.sets.descendingMap().values()) { + if((set.gender.equalsIgnoreCase(gender) || set.gender.equalsIgnoreCase("u")) && !set.club && !set.sellable && set.selectable) { + return set; + } + } + + return getFirstSetForGender(gender); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataSettypeSet.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataSettypeSet.java new file mode 100644 index 0000000..a5a15f3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/clothingvalidation/FiguredataSettypeSet.java @@ -0,0 +1,21 @@ +package com.eu.habbo.habbohotel.users.clothingvalidation; + +public class FiguredataSettypeSet { + public int id; + public String gender; + public boolean club; + public boolean colorable; + public boolean selectable; + public boolean preselectable; + public boolean sellable; + + public FiguredataSettypeSet(int id, String gender, boolean club, boolean colorable, boolean selectable, boolean preselectable, boolean sellable) { + this.id = id; + this.gender = gender; + this.club = club; + this.colorable = colorable; + this.selectable = selectable; + this.preselectable = preselectable; + this.sellable = sellable; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java new file mode 100644 index 0000000..c109e3c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java @@ -0,0 +1,174 @@ +package com.eu.habbo.habbohotel.users.inventory; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.permissions.Rank; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboBadge; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Set; + +@Slf4j +public class BadgesComponent { + + private final THashSet badges = new THashSet<>(); + + public BadgesComponent(Habbo habbo) { + this.badges.addAll(loadBadges(habbo)); + } + + private static THashSet loadBadges(Habbo habbo) { + THashSet badgesList = new THashSet<>(); + Set staffBadges = Emulator.getGameEnvironment().getPermissionsManager().getStaffBadges(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM users_badges WHERE user_id = ?")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + HabboBadge badge = new HabboBadge(set, habbo); + + if (staffBadges.contains(badge.getCode())) { + boolean delete = true; + + for (Rank rank : Emulator.getGameEnvironment().getPermissionsManager().getRanksByBadgeCode(badge.getCode())) { + if (rank.getId() == habbo.getHabboInfo().getRank().getId()) { + delete = false; + break; + } + } + + if (delete) { + deleteBadge(habbo.getHabboInfo().getId(), badge.getCode()); + continue; + } + } + + badgesList.add(badge); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return badgesList; + } + + public static void resetSlots(Habbo habbo) { + for (HabboBadge badge : habbo.getInventory().getBadgesComponent().getBadges()) { + if (badge.getSlot() == 0) + continue; + + badge.setSlot(0); + badge.needsUpdate(true); + Emulator.getThreading().run(badge); + } + } + + public static ArrayList getBadgesOfflineHabbo(int userId) { + ArrayList badgesList = new ArrayList<>(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM users_badges WHERE slot_id > 0 AND user_id = ? ORDER BY slot_id ASC")) { + statement.setInt(1, userId); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + badgesList.add(new HabboBadge(set, null)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + return badgesList; + } + + public static HabboBadge createBadge(String code, Habbo habbo) { + HabboBadge badge = new HabboBadge(0, code, 0, habbo); + badge.run(); + habbo.getInventory().getBadgesComponent().addBadge(badge); + return badge; + } + + public static void deleteBadge(int userId, String badge) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE users_badges FROM users_badges WHERE user_id = ? AND badge_code LIKE ?")) { + statement.setInt(1, userId); + statement.setString(2, badge); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public ArrayList getWearingBadges() { + synchronized (this.badges) { + ArrayList badgesList = new ArrayList<>(); + for (HabboBadge badge : this.badges) { + if (badge.getSlot() == 0) + continue; + + badgesList.add(badge); + } + + badgesList.sort(new Comparator() { + @Override + public int compare(HabboBadge o1, HabboBadge o2) { + return o1.getSlot() - o2.getSlot(); + } + }); + return badgesList; + } + } + + public THashSet getBadges() { + return this.badges; + } + + public boolean hasBadge(String badge) { + return this.getBadge(badge) != null; + } + + public HabboBadge getBadge(String badgeCode) { + synchronized (this.badges) { + for (HabboBadge badge : this.badges) { + if (badge.getCode().equalsIgnoreCase(badgeCode)) + return badge; + } + return null; + } + } + + public void addBadge(HabboBadge badge) { + synchronized (this.badges) { + this.badges.add(badge); + } + } + + public HabboBadge removeBadge(String badge) { + synchronized (this.badges) { + for (HabboBadge b : this.badges) { + if (b.getCode().equalsIgnoreCase(badge)) { + this.badges.remove(b); + return b; + } + } + } + + return null; + } + + public void removeBadge(HabboBadge badge) { + synchronized (this.badges) { + this.badges.remove(badge); + } + } + + public void dispose() { + synchronized (this.badges) { + this.badges.clear(); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/BotsComponent.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/BotsComponent.java new file mode 100644 index 0000000..d2cd0bd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/BotsComponent.java @@ -0,0 +1,71 @@ +package com.eu.habbo.habbohotel.users.inventory; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.users.Habbo; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Map; + +@Slf4j +public class BotsComponent { + private final THashMap bots = new THashMap<>(); + + public BotsComponent(Habbo habbo) { + this.loadBots(habbo); + } + + private void loadBots(Habbo habbo) { + synchronized (this.bots) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.username AS owner_name, bots.* FROM bots INNER JOIN users ON users.id = bots.user_id WHERE user_id = ? AND room_id = 0 ORDER BY id ASC")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + Bot bot = Emulator.getGameEnvironment().getBotManager().loadBot(set); + if (bot != null) { + this.bots.put(set.getInt("id"), bot); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public Bot getBot(int botId) { + return this.bots.get(botId); + } + + public void addBot(Bot bot) { + synchronized (this.bots) { + this.bots.put(bot.getId(), bot); + } + } + + public void removeBot(Bot bot) { + synchronized (this.bots) { + this.bots.remove(bot.getId()); + } + } + + public THashMap getBots() { + return this.bots; + } + + public void dispose() { + synchronized (this.bots) { + for (Map.Entry map : this.bots.entrySet()) { + if (map.getValue().needsUpdate()) { + Emulator.getThreading().run(map.getValue()); + } + } + this.bots.clear(); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/EffectsComponent.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/EffectsComponent.java new file mode 100644 index 0000000..00fe828 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/EffectsComponent.java @@ -0,0 +1,222 @@ +package com.eu.habbo.habbohotel.users.inventory; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.inventory.EffectsListAddComposer; +import com.eu.habbo.messages.outgoing.inventory.EffectsListEffectEnableComposer; +import com.eu.habbo.messages.outgoing.inventory.EffectsListRemoveComposer; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class EffectsComponent { + public final THashMap effects = new THashMap<>(); + public final Habbo habbo; + public int activatedEffect = 0; + + public EffectsComponent(Habbo habbo) { + this.habbo = habbo; + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM users_effects WHERE user_id = ?")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + this.effects.put(set.getInt("effect"), new HabboEffect(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + if(habbo.getHabboInfo().getRank().getRoomEffect() > 0) + this.createRankEffect(habbo.getHabboInfo().getRank().getRoomEffect()); + } + + public HabboEffect createEffect(int effectId) { + return createEffect(effectId, 86400); + } + + public HabboEffect createEffect(int effectId, int duration) { + HabboEffect effect; + synchronized (this.effects) { + if (this.effects.containsKey(effectId)) { + effect = this.effects.get(effectId); + + if (effect.total <= 99) { + effect.total++; + } + } else { + effect = new HabboEffect(effectId, this.habbo.getHabboInfo().getId()); + effect.duration = duration; + effect.insert(); + } + + this.addEffect(effect); + } + + return effect; + } + + public HabboEffect createRankEffect(int effectId) { + HabboEffect rankEffect = new HabboEffect(effectId, habbo.getHabboInfo().getId()); + rankEffect.duration = 0; + rankEffect.isRankEnable = true; + rankEffect.activationTimestamp = Emulator.getIntUnixTimestamp(); + rankEffect.enabled = true; + this.effects.put(effectId, rankEffect); + this.activatedEffect = effectId; // enabled by default + return rankEffect; + } + + public void addEffect(HabboEffect effect) { + this.effects.put(effect.effect, effect); + + this.habbo.getClient().sendResponse(new EffectsListAddComposer(effect)); + } + + public void dispose() { + synchronized (this.effects) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users_effects SET duration = ?, activation_timestamp = ?, total = ? WHERE user_id = ? AND effect = ?")) { + this.effects.forEachValue(effect -> { + if(!effect.isRankEnable) { + try { + statement.setInt(1, effect.duration); + statement.setInt(2, effect.activationTimestamp); + statement.setInt(3, effect.total); + statement.setInt(4, effect.userId); + statement.setInt(5, effect.effect); + statement.addBatch(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + return true; + }); + + statement.executeBatch(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.effects.clear(); + } + } + + public boolean ownsEffect(int effectId) { + return this.effects.containsKey(effectId); + } + + public void activateEffect(int effectId) { + HabboEffect effect = this.effects.get(effectId); + + if (effect != null) { + if (effect.isRemaining()) { + effect.activationTimestamp = Emulator.getIntUnixTimestamp(); + } else { + this.habbo.getClient().sendResponse(new EffectsListRemoveComposer(effect)); + } + } + } + + public void enableEffect(int effectId) { + HabboEffect effect = this.effects.get(effectId); + + if (effect != null) { + if (!effect.isActivated()) { + this.activateEffect(effect.effect); + } + + this.activatedEffect = effectId; + + if (this.habbo.getHabboInfo().getCurrentRoom() != null) { + this.habbo.getHabboInfo().getCurrentRoom().giveEffect(this.habbo, effectId, effect.remainingTime()); + } + + this.habbo.getClient().sendResponse(new EffectsListEffectEnableComposer(effect)); + } + } + + public boolean hasActivatedEffect(int effectId) { + HabboEffect effect = this.effects.get(effectId); + + if (effect != null) { + return effect.isActivated(); + } + + return false; + } + + public static class HabboEffect { + public int effect; + public int userId; + public int duration = 86400; + public int activationTimestamp = -1; + public int total = 1; + public boolean enabled = false; + public boolean isRankEnable = false; + + public HabboEffect(ResultSet set) throws SQLException { + this.effect = set.getInt("effect"); + this.userId = set.getInt("user_id"); + this.duration = set.getInt("duration"); + this.activationTimestamp = set.getInt("activation_timestamp"); + this.total = set.getInt("total"); + } + + public HabboEffect(int effect, int userId) { + this.effect = effect; + this.userId = userId; + } + + public boolean isActivated() { + return this.activationTimestamp >= 0; + } + + public boolean isRemaining() { + if(this.duration <= 0) + return true; + + if (this.total > 0) { + if (this.activationTimestamp >= 0) { + if (Emulator.getIntUnixTimestamp() - this.activationTimestamp >= this.duration) { + this.activationTimestamp = -1; + this.total--; + } + } + } + + return this.total > 0; + } + + public int remainingTime() { + if(this.duration <= 0) //permanant + return Integer.MAX_VALUE; + + return Emulator.getIntUnixTimestamp() - this.activationTimestamp + this.duration; + } + + public void insert() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO users_effects (user_id, effect, total, duration) VALUES (?, ?, ?, ?)")) { + statement.setInt(1, this.userId); + statement.setInt(2, this.effect); + statement.setInt(3, this.total); + statement.setInt(4, this.duration); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void delete() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM users_effects WHERE user_id = ? AND effect = ?")) { + statement.setInt(1, this.userId); + statement.setInt(2, this.effect); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/ItemsComponent.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/ItemsComponent.java new file mode 100644 index 0000000..8d2e14e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/ItemsComponent.java @@ -0,0 +1,171 @@ +package com.eu.habbo.habbohotel.users.inventory; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInventory; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.plugin.events.inventory.InventoryItemAddedEvent; +import com.eu.habbo.plugin.events.inventory.InventoryItemRemovedEvent; +import com.eu.habbo.plugin.events.inventory.InventoryItemsAddedEvent; +import gnu.trove.TCollections; +import gnu.trove.iterator.TIntObjectIterator; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.NoSuchElementException; + +@Slf4j +public class ItemsComponent { + private final TIntObjectMap items = TCollections.synchronizedMap(new TIntObjectHashMap<>()); + private final HabboInventory inventory; + public ItemsComponent(HabboInventory inventory, Habbo habbo) { + this.inventory = inventory; + this.items.putAll(loadItems(habbo)); + } + + public static THashMap loadItems(Habbo habbo) { + THashMap itemsList = new THashMap<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM items WHERE room_id = ? AND user_id = ?")) { + statement.setInt(1, 0); + statement.setInt(2, habbo.getHabboInfo().getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + try { + HabboItem item = Emulator.getGameEnvironment().getItemManager().loadHabboItem(set); + + if (item != null) { + itemsList.put(set.getInt("id"), item); + } else { + log.error("Failed to load HabboItem: " + set.getInt("id")); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return itemsList; + } + + public void addItem(HabboItem item) { + if (item == null) { + return; + } + + InventoryItemAddedEvent event = new InventoryItemAddedEvent(this.inventory, item); + if (Emulator.getPluginManager().fireEvent(event).isCancelled()) { + return; + } + + synchronized (this.items) { + this.items.put(event.item.getId(), event.item); + } + } + + public void addItems(THashSet items) { + InventoryItemsAddedEvent event = new InventoryItemsAddedEvent(this.inventory, items); + if (Emulator.getPluginManager().fireEvent(event).isCancelled()) { + return; + } + + synchronized (this.items) { + for (HabboItem item : event.items) { + if (item == null) { + continue; + } + + this.items.put(item.getId(), item); + } + } + } + + public HabboItem getHabboItem(int itemId) { + return this.items.get(Math.abs(itemId)); + } + + public HabboItem getAndRemoveHabboItem(final Item item) { + final HabboItem[] habboItem = {null}; + synchronized (this.items) { + this.items.forEachValue(new TObjectProcedure() { + @Override + public boolean execute(HabboItem object) { + if (object.getBaseItem() == item) { + habboItem[0] = object; + return false; + } + + return true; + } + }); + } + this.removeHabboItem(habboItem[0]); + return habboItem[0]; + } + + public void removeHabboItem(int itemId) { + this.items.remove(itemId); + } + + public void removeHabboItem(HabboItem item) { + InventoryItemRemovedEvent event = new InventoryItemRemovedEvent(this.inventory, item); + if (Emulator.getPluginManager().fireEvent(event).isCancelled()) { + return; + } + + synchronized (this.items) { + this.items.remove(event.item.getId()); + } + } + + public TIntObjectMap getItems() { + return this.items; + } + + public THashSet getItemsAsValueCollection() { + THashSet items = new THashSet<>(); + items.addAll(this.items.valueCollection()); + + return items; + } + + public int itemCount() { + return this.items.size(); + } + + public void dispose() { + synchronized (this.items) { + TIntObjectIterator items = this.items.iterator(); + + if (items == null) { + log.error("Items is NULL!"); + return; + } + + if (!this.items.isEmpty()) { + for (int i = this.items.size(); i-- > 0; ) { + try { + items.advance(); + } catch (NoSuchElementException e) { + break; + } + if (items.value().needsUpdate()) + Emulator.getThreading().run(items.value()); + } + } + + this.items.clear(); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/PetsComponent.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/PetsComponent.java new file mode 100644 index 0000000..222b896 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/PetsComponent.java @@ -0,0 +1,90 @@ +package com.eu.habbo.habbohotel.users.inventory; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetManager; +import com.eu.habbo.habbohotel.users.Habbo; +import gnu.trove.TCollections; +import gnu.trove.iterator.TIntObjectIterator; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.NoSuchElementException; +import java.util.Set; + +@Slf4j +public class PetsComponent { + private final TIntObjectMap pets = TCollections.synchronizedMap(new TIntObjectHashMap<>()); + + public PetsComponent(Habbo habbo) { + this.loadPets(habbo); + } + + private void loadPets(Habbo habbo) { + synchronized (this.pets) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM users_pets WHERE user_id = ? AND room_id = 0")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + this.pets.put(set.getInt("id"), PetManager.loadPet(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + public Pet getPet(int id) { + return this.pets.get(id); + } + + public void addPet(Pet pet) { + synchronized (this.pets) { + this.pets.put(pet.getId(), pet); + } + } + + public void addPets(Set pets) { + synchronized (this.pets) { + for (Pet p : pets) { + this.pets.put(p.getId(), p); + } + } + } + + public void removePet(Pet pet) { + synchronized (this.pets) { + this.pets.remove(pet.getId()); + } + } + + public TIntObjectMap getPets() { + return this.pets; + } + + public int getPetsCount() { + return this.pets.size(); + } + + public void dispose() { + synchronized (this.pets) { + TIntObjectIterator petIterator = this.pets.iterator(); + + for (int i = this.pets.size(); i-- > 0; ) { + try { + petIterator.advance(); + } catch (NoSuchElementException e) { + break; + } + if (petIterator.value().needsUpdate) + Emulator.getThreading().run(petIterator.value()); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/WardrobeComponent.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/WardrobeComponent.java new file mode 100644 index 0000000..6f041d3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/inventory/WardrobeComponent.java @@ -0,0 +1,172 @@ +package com.eu.habbo.habbohotel.users.inventory; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; +import gnu.trove.TIntCollection; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.TIntSet; +import gnu.trove.set.hash.TIntHashSet; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.regex.Pattern; + +@Slf4j +public class WardrobeComponent { + + private final THashMap looks; + private final TIntSet clothing; + private final TIntSet clothingSets; + + public WardrobeComponent(Habbo habbo) { + this.looks = new THashMap<>(); + this.clothing = new TIntHashSet(); + this.clothingSets = new TIntHashSet(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM users_wardrobe WHERE user_id = ?")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + this.looks.put(set.getInt("slot_id"), new WardrobeItem(set, habbo)); + } + } + } + + try (PreparedStatement statement = connection.prepareStatement("SELECT users_clothing.*, catalog_clothing.setid FROM users_clothing LEFT JOIN catalog_clothing ON catalog_clothing.id = users_clothing.clothing_id WHERE users_clothing.user_id = ?")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + int value = set.getInt("clothing_id"); + this.clothing.add(value); + + for(String x : set.getString("setid").split(Pattern.quote(","))) { + try { + this.clothingSets.add(Integer.parseInt(x)); + } + catch (Exception e) { } + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public WardrobeItem createLook(Habbo habbo, int slotId, String look) { + return new WardrobeItem(habbo.getHabboInfo().getGender(), look, slotId, habbo); + } + + public THashMap getLooks() { + return this.looks; + } + + public TIntCollection getClothing() { + return this.clothing; + } + + public TIntCollection getClothingSets() { + return this.clothingSets; + } + + public void dispose() { + this.looks.values().stream().filter(item -> item.needsInsert || item.needsUpdate).forEach(item -> { + Emulator.getThreading().run(item); + }); + + this.looks.clear(); + } + +public class WardrobeItem implements Runnable { + private int slotId; + private HabboGender gender; + private Habbo habbo; + private String look; + private boolean needsInsert = false; + private boolean needsUpdate = false; + + private WardrobeItem(ResultSet set, Habbo habbo) throws SQLException { + this.gender = HabboGender.valueOf(set.getString("gender")); + this.look = set.getString("look"); + this.slotId = set.getInt("slot_id"); + this.habbo = habbo; + } + + private WardrobeItem(HabboGender gender, String look, int slotId, Habbo habbo) { + this.gender = gender; + this.look = look; + this.slotId = slotId; + this.habbo = habbo; + } + + public HabboGender getGender() { + return this.gender; + } + + public void setGender(HabboGender gender) { + this.gender = gender; + } + + public Habbo getHabbo() { + return this.habbo; + } + + public void setHabbo(Habbo habbo) { + this.habbo = habbo; + } + + public String getLook() { + return this.look; + } + + public void setLook(String look) { + this.look = look; + } + + public void setNeedsInsert(boolean needsInsert) { + this.needsInsert = needsInsert; + } + + public void setNeedsUpdate(boolean needsUpdate) { + this.needsUpdate = needsUpdate; + } + + public int getSlotId() { + return this.slotId; + } + + @Override + public void run() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + if (this.needsInsert) { + this.needsInsert = false; + this.needsUpdate = false; + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO users_wardrobe (slot_id, look, user_id, gender) VALUES (?, ?, ?, ?)")) { + statement.setInt(1, this.slotId); + statement.setString(2, this.look); + statement.setInt(3, this.habbo.getHabboInfo().getId()); + statement.setString(4, this.gender.name()); + statement.execute(); + } + } + + if (this.needsUpdate) { + this.needsUpdate = false; + try (PreparedStatement statement = connection.prepareStatement("UPDATE users_wardrobe SET look = ? WHERE slot_id = ? AND user_id = ?")) { + statement.setString(1, this.look); + statement.setInt(2, this.slotId); + statement.setInt(3, this.habbo.getHabboInfo().getId()); + statement.execute(); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/HcPayDayLogEntry.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/HcPayDayLogEntry.java new file mode 100644 index 0000000..e96d64b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/HcPayDayLogEntry.java @@ -0,0 +1,64 @@ +package com.eu.habbo.habbohotel.users.subscriptions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.core.DatabaseLoggable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +/** + * @author Beny + */ +public class HcPayDayLogEntry implements Runnable, DatabaseLoggable { + + private static final Logger LOGGER = LoggerFactory.getLogger(HcPayDayLogEntry.class); + private static final String QUERY = "INSERT INTO `logs_hc_payday` (`timestamp`, `user_id`, `hc_streak`, `total_coins_spent`, `reward_coins_spent`, `reward_streak`, `total_payout`, `currency`, `claimed`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + + public final int timestamp; + public final int userId; + public final int hcStreak; + public final int totalCoinsSpent; + public final int rewardCoinsSpent; + public final int rewardStreak; + public final int totalPayout; + public final String currency; + public final boolean claimed; + + public HcPayDayLogEntry(int timestamp, int userId, int hcStreak, int totalCoinsSpent, int rewardCoinsSpent, int rewardStreak, int totalPayout, String currency, boolean claimed) { + this.timestamp = timestamp; + this.userId = userId; + this.hcStreak = hcStreak; + this.totalCoinsSpent = totalCoinsSpent; + this.rewardCoinsSpent = rewardCoinsSpent; + this.rewardStreak = rewardStreak; + this.totalPayout = totalPayout; + this.currency = currency; + this.claimed = claimed; + } + + @Override + public String getQuery() { + return QUERY; + } + + @Override + public void log(PreparedStatement statement) throws SQLException { + statement.setInt(1, this.timestamp); + statement.setInt(2, this.userId); + statement.setInt(3, this.hcStreak); + statement.setInt(4, this.totalCoinsSpent); + statement.setInt(5, this.rewardCoinsSpent); + statement.setInt(6, this.rewardStreak); + statement.setInt(7, this.totalPayout); + statement.setString(8, this.currency); + statement.setInt(9, this.claimed ? 1 : 0); + statement.addBatch(); + } + + @Override + public void run() { + Emulator.getDatabaseLogger().store(this); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/Subscription.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/Subscription.java new file mode 100644 index 0000000..12fab80 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/Subscription.java @@ -0,0 +1,146 @@ +package com.eu.habbo.habbohotel.users.subscriptions; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class Subscription { + public static final String HABBO_CLUB = "HABBO_CLUB"; + + private final int id; + private final int userId; + private final String subscriptionType; + private final int timestampStart; + private int duration; + private boolean active; + + /** + * Subscription constructor + * @param id ID of the subscription + * @param userId ID of user who has the subscription + * @param subscriptionType Subscription type name (e.g. HABBO_CLUB) + * @param timestampStart Unix timestamp start of subscription + * @param duration Length of subscription in seconds + * @param active Boolean indicating if subscription is active + */ + public Subscription(Integer id, Integer userId, String subscriptionType, Integer timestampStart, Integer duration, Boolean active) { + this.id = id; + this.userId = userId; + this.subscriptionType = subscriptionType; + this.timestampStart = timestampStart; + this.duration = duration; + this.active = active; + } + + /** + * @return ID of the subscription + */ + public int getSubscriptionId() { + return id; + } + + /** + * @return ID of user who has the subscription + */ + public int getUserId() { + return userId; + } + + /** + * @return Subscription type name (e.g. HABBO_CLUB) + */ + public String getSubscriptionType() { + return subscriptionType; + } + + /** + * @return Length of subscription in seconds + */ + public int getDuration() { + return duration; + } + + /** + * Updates the Subscription record with new duration + * @param amount Length of time to add in seconds + */ + public void addDuration(int amount) { + this.duration += amount; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users_subscriptions` SET `duration` = ? WHERE `id` = ? LIMIT 1")) { + statement.setInt(1, this.duration); + statement.setInt(2, this.id); + statement.executeUpdate(); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + /** + * Sets the subscription as active or inactive. If active and remaining time <= 0 the SubscriptionScheduler will inactivate the subscription and call onExpired() + * @param active Boolean indicating if the subscription is active + */ + public void setActive(boolean active) { + this.active = active; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE `users_subscriptions` SET `active` = ? WHERE `id` = ? LIMIT 1")) { + statement.setInt(1, this.active ? 1 : 0); + statement.setInt(2, this.id); + statement.executeUpdate(); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + /** + * @return Remaining duration of subscription in seconds + */ + public int getRemaining() { + return (this.timestampStart + this.duration) - Emulator.getIntUnixTimestamp(); + } + + /** + * @return Unix timestamp start of subscription + */ + public int getTimestampStart() { + return this.timestampStart; + } + + /** + * @return Unix timestamp end of subscription + */ + public int getTimestampEnd() { + return (this.timestampStart + this.duration); + } + + /** + * @return Boolean indicating if the subscription is active + */ + public boolean isActive() { + return active; + } + + /** + * Called when the subscription is first created + */ + public void onCreated() { } + + /** + * Called when the subscription is extended or bought again when already exists + * @param duration Extended duration time in seconds + */ + public void onExtended(int duration) { } + + /** + * Called by SubscriptionScheduler when isActive() && getRemaining() < 0 + */ + public void onExpired() { } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionHabboClub.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionHabboClub.java new file mode 100644 index 0000000..d8770b6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionHabboClub.java @@ -0,0 +1,429 @@ +package com.eu.habbo.habbohotel.users.subscriptions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.database.Database; +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.messenger.Messenger; +import com.eu.habbo.habbohotel.rooms.RoomManager; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboStats; +import com.eu.habbo.habbohotel.users.clothingvalidation.ClothingValidationManager; +import com.eu.habbo.messages.outgoing.catalog.ClubCenterDataComposer; +import com.eu.habbo.messages.outgoing.generic.PickMonthlyClubGiftNotificationComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer; +import com.eu.habbo.messages.outgoing.users.*; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; +import java.util.TreeMap; + +@Slf4j +public class SubscriptionHabboClub extends Subscription { + + public static boolean HC_PAYDAY_ENABLED = false; + public static int HC_PAYDAY_NEXT_DATE = Integer.MAX_VALUE; // yyyy-MM-dd HH:mm:ss + public static String HC_PAYDAY_INTERVAL = ""; + public static String HC_PAYDAY_QUERY = ""; + public static TreeMap HC_PAYDAY_STREAK = new TreeMap<>(); + public static String HC_PAYDAY_CURRENCY = ""; + public static Double HC_PAYDAY_KICKBACK_PERCENTAGE = 0.1; + public static String ACHIEVEMENT_NAME = ""; + public static boolean DISCOUNT_ENABLED = false; + public static int DISCOUNT_DAYS_BEFORE_END = 7; + + /** + * When true "coins spent" will be calculated from the timestamp the user joins HC instead of from the last HC pay day execution timestamp + */ + public static boolean HC_PAYDAY_COINSSPENT_RESET_ON_EXPIRE = false; + + /** + * Boolean indicating if HC pay day currency executing. Prevents double execution + */ + public static boolean isExecuting = false; + + public SubscriptionHabboClub(Integer id, Integer userId, String subscriptionType, Integer timestampStart, Integer duration, Boolean active) { + super(id, userId, subscriptionType, timestampStart, duration, active); + } + + /** + * Called when the subscription is first created. + * Actions: + * - Set user's max_friends to MAXIMUM_FRIENDS_HC + * - Set user's max_rooms to MAXIMUM_ROOMS_HC + * - Reset the user's HC pay day timer (used in calculating the coins spent) + * - Send associated HC packets to client + */ + @Override + public void onCreated() { + super.onCreated(); + + HabboInfo habboInfo = Emulator.getGameEnvironment().getHabboManager().getHabboInfo(this.getUserId()); + HabboStats stats = habboInfo.getHabboStats(); + + stats.maxFriends = Messenger.MAXIMUM_FRIENDS_HC; + stats.maxRooms = RoomManager.MAXIMUM_ROOMS_HC; + stats.lastHCPayday = HC_PAYDAY_COINSSPENT_RESET_ON_EXPIRE ? Emulator.getIntUnixTimestamp() : HC_PAYDAY_NEXT_DATE - Emulator.timeStringToSeconds(HC_PAYDAY_INTERVAL); + Emulator.getThreading().run(stats); + + progressAchievement(habboInfo); + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getUserId()); + if (habbo != null && habbo.getClient() != null) { + + if (habbo.getHabboStats().getRemainingClubGifts() > 0) { + habbo.getClient().sendResponse(new PickMonthlyClubGiftNotificationComposer(habbo.getHabboStats().getRemainingClubGifts())); + } + + if ((Emulator.getIntUnixTimestamp() - habbo.getHabboStats().hcMessageLastModified) < 60) { + Emulator.getThreading().run(() -> { + habbo.getClient().sendResponse(new UserClubComposer(habbo)); + habbo.getClient().sendResponse(new UserPermissionsComposer(habbo)); + }, (Emulator.getIntUnixTimestamp() - habbo.getHabboStats().hcMessageLastModified)); + } else { + habbo.getClient().sendResponse(new UserClubComposer(habbo, SubscriptionHabboClub.HABBO_CLUB, UserClubComposer.RESPONSE_TYPE_NORMAL)); + habbo.getClient().sendResponse(new UserPermissionsComposer(habbo)); + } + } + } + + /** + * Called when the subscription is extended by manual action (by admin command or RCON) + * Actions: + * - Extend duration of the subscription + * - Send associated HC packets to client + */ + @Override + public void addDuration(int amount) { + super.addDuration(amount); + + if (amount < 0) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getUserId()); + if (habbo != null && habbo.getClient() != null) { + habbo.getClient().sendResponse(new UserClubComposer(habbo, SubscriptionHabboClub.HABBO_CLUB, UserClubComposer.RESPONSE_TYPE_NORMAL)); + habbo.getClient().sendResponse(new UserPermissionsComposer(habbo)); + } + } + } + + /** + * Called when the subscription is extended or bought again when already exists + * Actions: + * - Extend duration of the subscription + * - Send associated HC packets to client + */ + @Override + public void onExtended(int duration) { + super.onExtended(duration); + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getUserId()); + + if (habbo != null && habbo.getClient() != null) { + habbo.getClient().sendResponse(new UserClubComposer(habbo, SubscriptionHabboClub.HABBO_CLUB, UserClubComposer.RESPONSE_TYPE_NORMAL)); + habbo.getClient().sendResponse(new UserPermissionsComposer(habbo)); + } + } + + /** + * Called by SubscriptionScheduler when isActive() && getRemaining() < 0 + * Actions: + * - Set user's max_friends to MAXIMUM_FRIENDS + * - Set user's max_rooms to MAXIMUM_ROOMS + * - Remove HC clothing + * - Send associated HC packets to client + */ + @Override + public void onExpired() { + super.onExpired(); + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getUserId()); + HabboInfo habboInfo = Emulator.getGameEnvironment().getHabboManager().getHabboInfo(this.getUserId()); + HabboStats stats = habboInfo.getHabboStats(); + + stats.maxFriends = Messenger.MAXIMUM_FRIENDS; + stats.maxRooms = RoomManager.MAXIMUM_ROOMS_USER; + Emulator.getThreading().run(stats); + + if (habbo != null && ClothingValidationManager.VALIDATE_ON_HC_EXPIRE) { + habboInfo.setLook(ClothingValidationManager.validateLook(habbo, habboInfo.getLook(), habboInfo.getGender().name())); + Emulator.getThreading().run(habbo.getHabboInfo()); + + if (habbo.getClient() != null) { + habbo.getClient().sendResponse(new UpdateUserLookComposer(habbo)); + } + + if (habbo.getHabboInfo().getCurrentRoom() != null) { + habbo.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserDataComposer(habbo).compose()); + } + } + + if (habbo != null && habbo.getClient() != null) { + habbo.getClient().sendResponse(new UserClubComposer(habbo, SubscriptionHabboClub.HABBO_CLUB, UserClubComposer.RESPONSE_TYPE_NORMAL)); + habbo.getClient().sendResponse(new UserPermissionsComposer(habbo)); + } + } + + /** + * Calculate's a users upcoming HC Pay day rewards + * + * @param habbo User to calculate for + * @return ClubCenterDataComposer + */ + public static ClubCenterDataComposer calculatePayday(HabboInfo habbo) { + Subscription activeSub = null; + Subscription firstEverSub = null; + int currentHcStreak = 0; + int totalCreditsSpent = 0; + int creditRewardForStreakBonus = 0; + int creditRewardForMonthlySpent = 0; + int timeUntilPayday = 0; + + for (Subscription sub : habbo.getHabboStats().subscriptions) { + if (sub.getSubscriptionType().equalsIgnoreCase(Subscription.HABBO_CLUB)) { + + if (firstEverSub == null || sub.getTimestampStart() < firstEverSub.getTimestampStart()) { + firstEverSub = sub; + } + + if (sub.isActive()) { + activeSub = sub; + } + } + } + + if (HC_PAYDAY_ENABLED && activeSub != null) { + currentHcStreak = (int) Math.floor((Emulator.getIntUnixTimestamp() - activeSub.getTimestampStart()) / (60 * 60 * 24.0)); + if (currentHcStreak < 1) { + currentHcStreak = 0; + } + + for (Map.Entry set : HC_PAYDAY_STREAK.entrySet()) { + if (currentHcStreak >= set.getKey() && set.getValue() > creditRewardForStreakBonus) { + creditRewardForStreakBonus = set.getValue(); + } + } + + THashMap queryParams = new THashMap(); + queryParams.put("@user_id", habbo.getId()); + queryParams.put("@timestamp_start", habbo.getHabboStats().lastHCPayday); + queryParams.put("@timestamp_end", HC_PAYDAY_NEXT_DATE); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = Database.preparedStatementWithParams(connection, HC_PAYDAY_QUERY, queryParams)) { + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + totalCreditsSpent = set.getInt("amount_spent"); + } + } + + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + creditRewardForMonthlySpent = (int) Math.floor(totalCreditsSpent * HC_PAYDAY_KICKBACK_PERCENTAGE); + + timeUntilPayday = (HC_PAYDAY_NEXT_DATE - Emulator.getIntUnixTimestamp()) / 60; + } + + return new ClubCenterDataComposer( + currentHcStreak, + (firstEverSub != null ? new SimpleDateFormat("dd-MM-yyyy").format(new Date(firstEverSub.getTimestampStart() * 1000L)) : ""), + HC_PAYDAY_KICKBACK_PERCENTAGE, + 0, + 0, + totalCreditsSpent, + creditRewardForStreakBonus, + creditRewardForMonthlySpent, + timeUntilPayday + ); + } + + /** + * Executes the HC Pay day, calculating reward for all active HABBO_CLUB subscribers and issuing rewards. + */ + public static void executePayDay() { + isExecuting = true; + int timestampNow = Emulator.getIntUnixTimestamp(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("SELECT user_id FROM `users_subscriptions` WHERE subscription_type = '" + Subscription.HABBO_CLUB + "' AND `active` = 1 AND `timestamp_start` < ? AND (`timestamp_start` + `duration`) > ? GROUP BY user_id")) { + statement.setInt(1, timestampNow); + statement.setInt(2, timestampNow); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + try { + int userId = set.getInt("user_id"); + HabboInfo habboInfo = Emulator.getGameEnvironment().getHabboManager().getHabboInfo(userId); + HabboStats stats = habboInfo.getHabboStats(); + ClubCenterDataComposer calculated = calculatePayday(habboInfo); + int totalReward = (calculated.creditRewardForMonthlySpent + calculated.creditRewardForStreakBonus); + if (totalReward > 0) { + boolean claimed = claimPayDay(Emulator.getGameEnvironment().getHabboManager().getHabbo(userId), totalReward, HC_PAYDAY_CURRENCY); + HcPayDayLogEntry le = new HcPayDayLogEntry(timestampNow, userId, calculated.currentHcStreak, calculated.totalCreditsSpent, calculated.creditRewardForMonthlySpent, calculated.creditRewardForStreakBonus, totalReward, HC_PAYDAY_CURRENCY, claimed); + Emulator.getThreading().run(le); + } + stats.lastHCPayday = timestampNow; + Emulator.getThreading().run(stats); + } catch (Exception e) { + log.error("Exception processing HC payday for user #" + set.getInt("user_id"), e); + } + } + } + + Date date = new java.util.Date(HC_PAYDAY_NEXT_DATE * 1000L); + date = Emulator.modifyDate(date, HC_PAYDAY_INTERVAL); + HC_PAYDAY_NEXT_DATE = (int) (date.getTime() / 1000L); + + try (PreparedStatement stm2 = connection.prepareStatement("UPDATE `emulator_settings` SET `value` = ? WHERE `key` = ?")) { + SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + stm2.setString(1, sdf.format(date)); + stm2.setString(2, "subscriptions.hc.payday.next_date"); + stm2.execute(); + } + + try (PreparedStatement stm2 = connection.prepareStatement("UPDATE users_settings SET last_hc_payday = ? WHERE user_id IN (SELECT user_id FROM `users_subscriptions` WHERE subscription_type = '" + Subscription.HABBO_CLUB + "' AND `active` = 1 AND `timestamp_start` < ? AND (`timestamp_start` + `duration`) > ? GROUP BY user_id)")) { + stm2.setInt(1, timestampNow); + stm2.setInt(2, timestampNow); + stm2.setInt(3, timestampNow); + stm2.execute(); + } + + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + isExecuting = false; + } + + /** + * Called when a user logs in. Checks for any unclaimed HC Pay day rewards and issues rewards. + * + * @param habbo User to process + */ + public static void processUnclaimed(Habbo habbo) { + + progressAchievement(habbo.getHabboInfo()); + + if (habbo.getHabboStats().getRemainingClubGifts() > 0) { + habbo.getClient().sendResponse(new PickMonthlyClubGiftNotificationComposer(habbo.getHabboStats().getRemainingClubGifts())); + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("SELECT * FROM `logs_hc_payday` WHERE user_id = ? AND claimed = 0")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + try { + int logId = set.getInt("id"); + int userId = set.getInt("user_id"); + int totalPayout = set.getInt("total_payout"); + String currency = set.getString("currency"); + + if (claimPayDay(habbo, totalPayout, currency)) { + try (PreparedStatement stm2 = connection.prepareStatement("UPDATE logs_hc_payday SET claimed = 1 WHERE id = ?")) { + stm2.setInt(1, logId); + stm2.execute(); + } + } + } catch (Exception e) { + log.error("Exception processing HC payday for user #" + set.getInt("user_id"), e); + } + } + } + + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + /** + * + * Seperated these because Beny shouldn't have tied them to Payday. + */ + public static void processClubBadge(Habbo habbo) { + progressAchievement(habbo.getHabboInfo()); + } + + /** + * Issues rewards to user. + * @param habbo User to reward to + * @param amount Amount of currency to reward + * @param currency Currency string (Can be one of: credits, diamonds, duckets, pixels or a currency ID e.g. 5) + * @return Boolean indicating success of the operation + */ + public static boolean claimPayDay(Habbo habbo, int amount, String currency) { + if(habbo == null) + return false; + + int pointCurrency; + switch(currency.toLowerCase()) { + case "credits": + case "coins": + case "credit": + case "coin": + habbo.getClient().getHabbo().giveCredits(amount); + break; + + case "diamonds": + case "diamond": + pointCurrency = 5; + habbo.getClient().getHabbo().givePoints(pointCurrency, amount); + break; + + case "duckets": + case "ducket": + case "pixels": + case "pixel": + pointCurrency = 0; + habbo.getClient().getHabbo().givePoints(pointCurrency, amount); + break; + + default: + pointCurrency = -1; + try { + pointCurrency = Integer.parseInt(currency); + } + catch (NumberFormatException ex) { + log.error("Couldn't convert the type point currency {} on HC PayDay. The number must be a integer and positive.", pointCurrency); + } + + if (pointCurrency >= 0) { + habbo.getClient().getHabbo().givePoints(pointCurrency, amount); + } + break; + } + + habbo.alert(Emulator.getTexts().getValue("subscriptions.hc.payday.message", "Woohoo HC Payday has arrived! You have received %amount% credits to your purse. Enjoy!").replace("%amount%", "" + amount)); + + return true; + } + + private static void progressAchievement(HabboInfo habboInfo) { + HabboStats stats = habboInfo.getHabboStats(); + Achievement achievement = Emulator.getGameEnvironment().getAchievementManager().getAchievement(ACHIEVEMENT_NAME); + if(achievement != null) { + int currentProgress = stats.getAchievementProgress(achievement); + if(currentProgress == -1) { + currentProgress = 0; + } + + int progressToSet = (int)Math.ceil(stats.getPastTimeAsClub() / 2678400.0); + int toIncrease = Math.max(progressToSet - currentProgress, 0); + + if(toIncrease > 0) { + AchievementManager.progressAchievement(habboInfo.getId(), achievement, toIncrease); + } + } + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionManager.java new file mode 100644 index 0000000..071128e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionManager.java @@ -0,0 +1,84 @@ +package com.eu.habbo.habbohotel.users.subscriptions; + +import com.eu.habbo.Emulator; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class SubscriptionManager { + + public THashMap> types; + + public SubscriptionManager() { + this.types = new THashMap<>(); + } + + public void init() { + this.types.put(Subscription.HABBO_CLUB, SubscriptionHabboClub.class); + } + + public void addSubscriptionType(String type, Class clazz) { + if(this.types.containsKey(type) || this.types.containsValue(clazz)) { + throw new RuntimeException("Subscription Type must be unique. An class with type: " + clazz.getName() + " was already added OR the key: " + type + " is already in use."); + } + + this.types.put(type, clazz); + } + + public void removeSubscriptionType(String type) { + this.types.remove(type); + } + + public Class getSubscriptionClass(String type) { + if(!this.types.containsKey(type)) { + log.debug("Can't find subscription class: {}", type); + return Subscription.class; + } + + return this.types.get(type); + } + + public void dispose() { + this.types.clear(); + } + + public THashSet getSubscriptionsForUser(int userId) { + THashSet subscriptions = new THashSet<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("SELECT * FROM users_subscriptions WHERE user_id = ?")) { + statement.setInt(1, userId); + + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + Class subClazz = Emulator.getGameEnvironment().getSubscriptionManager().getSubscriptionClass(set.getString("subscription_type")); + Constructor c = subClazz.getConstructor(Integer.class, Integer.class, String.class, Integer.class, Integer.class, Boolean.class); + c.setAccessible(true); + Subscription subscription = c.newInstance(set.getInt("id"), set.getInt("user_id"), set.getString("subscription_type"), set.getInt("timestamp_start"), set.getInt("duration"), set.getInt("active") == 1); + subscriptions.add(subscription); + } + } catch (IllegalAccessException e) { + log.error("IllegalAccessException", e); + } catch (InstantiationException e) { + log.error("InstantiationException", e); + } catch (InvocationTargetException e) { + log.error("InvocationTargetException", e); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + catch (NoSuchMethodException e) { + log.error("Caught NoSuchMethodException", e); + } + + return subscriptions; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionScheduler.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionScheduler.java new file mode 100644 index 0000000..0d474e6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionScheduler.java @@ -0,0 +1,69 @@ +package com.eu.habbo.habbohotel.users.subscriptions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.core.Scheduler; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.events.users.subscriptions.UserSubscriptionExpiredEvent; +import lombok.extern.slf4j.Slf4j; + +import java.util.Map; + +@Slf4j +public class SubscriptionScheduler extends Scheduler { + + public SubscriptionScheduler() { + super(Emulator.getConfig().getInt("subscriptions.scheduler.interval", 10)); + this.reloadConfig(); + } + + /** + * Called when config is changed. Should end the scheduler if disabled. + */ + public void reloadConfig() { + if (Emulator.getConfig().getBoolean("subscriptions.scheduler.enabled", true)) { + if (this.disposed) { + this.disposed = false; + this.run(); + } + } else { + this.disposed = true; + } + } + + @Override + public void run() { + super.run(); + + Habbo habbo; + for (Map.Entry map : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + habbo = map.getValue(); + + try { + if (habbo != null) { + for(Subscription subscription : habbo.getHabboStats().subscriptions) { + if(subscription.isActive() && subscription.getRemaining() < 0) { + if (!Emulator.getPluginManager().fireEvent(new UserSubscriptionExpiredEvent(habbo.getHabboInfo().getId(), subscription)).isCancelled()) { + subscription.onExpired(); + subscription.setActive(false); + } + } + } + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + if(SubscriptionHabboClub.HC_PAYDAY_ENABLED && !SubscriptionHabboClub.isExecuting && SubscriptionHabboClub.HC_PAYDAY_NEXT_DATE < Emulator.getIntUnixTimestamp()) { + SubscriptionHabboClub.executePayDay(); + } + } + + public boolean isDisposed() { + return this.disposed; + } + + public void setDisposed(boolean disposed) { + this.disposed = disposed; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredChangeDirectionSetting.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredChangeDirectionSetting.java new file mode 100644 index 0000000..748bff4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredChangeDirectionSetting.java @@ -0,0 +1,15 @@ +package com.eu.habbo.habbohotel.wired; + +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; + +public class WiredChangeDirectionSetting { + public final int item_id; + public int rotation; + public RoomUserRotation direction; + + public WiredChangeDirectionSetting(int itemId, int rotation, RoomUserRotation direction) { + this.item_id = itemId; + this.rotation = rotation; + this.direction = direction; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredConditionOperator.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredConditionOperator.java new file mode 100644 index 0000000..71b829d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredConditionOperator.java @@ -0,0 +1,6 @@ +package com.eu.habbo.habbohotel.wired; + +public enum WiredConditionOperator { + AND, + OR +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredConditionType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredConditionType.java new file mode 100644 index 0000000..86ffa57 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredConditionType.java @@ -0,0 +1,34 @@ +package com.eu.habbo.habbohotel.wired; + +public enum WiredConditionType { + MATCH_SSHOT(0), + FURNI_HAVE_HABBO(1), + TRIGGER_ON_FURNI(2), + TIME_MORE_THAN(3), + TIME_LESS_THAN(4), + USER_COUNT(5), + ACTOR_IN_TEAM(6), + FURNI_HAS_FURNI(7), + STUFF_IS(8), + ACTOR_IN_GROUP(10), + ACTOR_WEARS_BADGE(11), + ACTOR_WEARS_EFFECT(12), + NOT_MATCH_SSHOT(13), + NOT_FURNI_HAVE_HABBO(14), + NOT_ACTOR_ON_FURNI(15), + NOT_USER_COUNT(16), + NOT_ACTOR_IN_TEAM(17), + NOT_FURNI_HAVE_FURNI(18), + NOT_STUFF_IS(19), + NOT_ACTOR_IN_GROUP(21), + NOT_ACTOR_WEARS_BADGE(22), + NOT_ACTOR_WEARS_EFFECT(23), + DATE_RANGE(24), + ACTOR_HAS_HANDITEM(25); + + public final int code; + + WiredConditionType(int code) { + this.code = code; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredEffectType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredEffectType.java new file mode 100644 index 0000000..951e4d0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredEffectType.java @@ -0,0 +1,36 @@ +package com.eu.habbo.habbohotel.wired; + +public enum WiredEffectType { + TOGGLE_STATE(0), + RESET_TIMERS(1), + MATCH_SSHOT(3), + MOVE_ROTATE(4), + GIVE_SCORE(6), + SHOW_MESSAGE(7), + TELEPORT(8), + JOIN_TEAM(9), + LEAVE_TEAM(10), + CHASE(11), + FLEE(12), + MOVE_DIRECTION(13), + GIVE_SCORE_TEAM(14), + TOGGLE_RANDOM(15), + MOVE_FURNI_TO(16), + GIVE_REWARD(17), + CALL_STACKS(18), + KICK_USER(19), + MUTE_TRIGGER(20), + BOT_TELEPORT(21), + BOT_MOVE(22), + BOT_TALK(23), + BOT_GIVE_HANDITEM(24), + BOT_FOLLOW_AVATAR(25), + BOT_CLOTHES(26), + BOT_TALK_TO_AVATAR(27); + + public final int code; + + WiredEffectType(int code) { + this.code = code; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredGiveRewardItem.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredGiveRewardItem.java new file mode 100644 index 0000000..dd6ac23 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredGiveRewardItem.java @@ -0,0 +1,33 @@ +package com.eu.habbo.habbohotel.wired; + +public class WiredGiveRewardItem { + public final int id; + public final boolean badge; + public final String data; + public final int probability; + + public WiredGiveRewardItem(int id, boolean badge, String data, int probability) { + this.id = id; + this.badge = badge; + this.data = data; + this.probability = probability; + } + + public WiredGiveRewardItem(String dataString) { + String[] data = dataString.split(","); + + this.id = Integer.valueOf(data[0]); + this.badge = data[1].equalsIgnoreCase("0"); + this.data = data[2]; + this.probability = Integer.valueOf(data[3]); + } + + @Override + public String toString() { + return this.id + "," + (this.badge ? 0 : 1) + "," + this.data + "," + this.probability; + } + + public String wiredString() { + return (this.badge ? 0 : 1) + "," + this.data + "," + this.probability; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredHandler.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredHandler.java new file mode 100644 index 0000000..a3a2a17 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredHandler.java @@ -0,0 +1,474 @@ +package com.eu.habbo.habbohotel.wired; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredExtra; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.items.interactions.wired.WiredTriggerReset; +import com.eu.habbo.habbohotel.items.interactions.wired.effects.WiredEffectGiveReward; +import com.eu.habbo.habbohotel.items.interactions.wired.effects.WiredEffectTriggerStacks; +import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraRandom; +import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraUnseen; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.catalog.PurchaseOKComposer; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.users.AddUserBadgeComposer; +import com.eu.habbo.messages.outgoing.wired.WiredRewardAlertComposer; +import com.eu.habbo.plugin.events.furniture.wired.WiredConditionFailedEvent; +import com.eu.habbo.plugin.events.furniture.wired.WiredStackExecutedEvent; +import com.eu.habbo.plugin.events.furniture.wired.WiredStackTriggeredEvent; +import com.eu.habbo.plugin.events.users.UserWiredRewardReceived; +import com.google.gson.GsonBuilder; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Slf4j +public class WiredHandler { + //Configuration. Loaded from database & updated accordingly. + public static int MAXIMUM_FURNI_SELECTION = 5; + public static int TELEPORT_DELAY = 500; + + private static GsonBuilder gsonBuilder = null; + + public static boolean handle(WiredTriggerType triggerType, RoomUnit roomUnit, Room room, Object[] stuff) { + if (triggerType == WiredTriggerType.CUSTOM) return false; + + boolean talked = false; + + if (!Emulator.isReady) + return false; + + if (room == null) + return false; + + if (!room.isLoaded()) + return false; + + if (room.getRoomSpecialTypes() == null) + return false; + + THashSet triggers = room.getRoomSpecialTypes().getTriggers(triggerType); + + if (triggers == null || triggers.isEmpty()) + return false; + + long millis = System.currentTimeMillis(); + THashSet effectsToExecute = new THashSet(); + + List triggeredTiles = new ArrayList<>(); + for (InteractionWiredTrigger trigger : triggers) { + RoomTile tile = room.getLayout().getTile(trigger.getX(), trigger.getY()); + + if (triggeredTiles.contains(tile)) + continue; + + THashSet tEffectsToExecute = new THashSet(); + + if (handle(trigger, roomUnit, room, stuff, tEffectsToExecute)) { + effectsToExecute.addAll(tEffectsToExecute); + + if (triggerType.equals(WiredTriggerType.SAY_SOMETHING)) + talked = true; + + triggeredTiles.add(tile); + } + } + + for (InteractionWiredEffect effect : effectsToExecute) { + triggerEffect(effect, roomUnit, room, stuff, millis); + } + + return talked; + } + + public static boolean handleCustomTrigger(Class triggerType, RoomUnit roomUnit, Room room, Object[] stuff) { + if (!Emulator.isReady) + return false; + + if (room == null) + return false; + + if (!room.isLoaded()) + return false; + + if (room.getRoomSpecialTypes() == null) + return false; + + THashSet triggers = room.getRoomSpecialTypes().getTriggers(WiredTriggerType.CUSTOM); + + if (triggers == null || triggers.isEmpty()) + return false; + + long millis = System.currentTimeMillis(); + THashSet effectsToExecute = new THashSet(); + + List triggeredTiles = new ArrayList<>(); + for (InteractionWiredTrigger trigger : triggers) { + if (trigger.getClass() != triggerType) continue; + + RoomTile tile = room.getLayout().getTile(trigger.getX(), trigger.getY()); + + if (triggeredTiles.contains(tile)) + continue; + + THashSet tEffectsToExecute = new THashSet(); + + if (handle(trigger, roomUnit, room, stuff, tEffectsToExecute)) { + effectsToExecute.addAll(tEffectsToExecute); + triggeredTiles.add(tile); + } + } + + for (InteractionWiredEffect effect : effectsToExecute) { + triggerEffect(effect, roomUnit, room, stuff, millis); + } + + return effectsToExecute.size() > 0; + } + + public static boolean handle(InteractionWiredTrigger trigger, final RoomUnit roomUnit, final Room room, final Object[] stuff) { + long millis = System.currentTimeMillis(); + THashSet effectsToExecute = new THashSet(); + + if(handle(trigger, roomUnit, room, stuff, effectsToExecute)) { + for (InteractionWiredEffect effect : effectsToExecute) { + triggerEffect(effect, roomUnit, room, stuff, millis); + } + return true; + } + return false; + } + + public static boolean handle(InteractionWiredTrigger trigger, final RoomUnit roomUnit, final Room room, final Object[] stuff, final THashSet effectsToExecute) { + long millis = System.currentTimeMillis(); + int roomUnitId = roomUnit != null ? roomUnit.getId() : -1; + if (Emulator.isReady && ((Emulator.getConfig().getBoolean("wired.custom.enabled", false) && (trigger.canExecute(millis) || roomUnitId > -1) && trigger.userCanExecute(roomUnitId, millis)) || (!Emulator.getConfig().getBoolean("wired.custom.enabled", false) && trigger.canExecute(millis))) && trigger.execute(roomUnit, room, stuff)) { + trigger.activateBox(room, roomUnit, millis); + + THashSet conditions = room.getRoomSpecialTypes().getConditions(trigger.getX(), trigger.getY()); + THashSet effects = room.getRoomSpecialTypes().getEffects(trigger.getX(), trigger.getY()); + if (Emulator.getPluginManager().fireEvent(new WiredStackTriggeredEvent(room, roomUnit, trigger, effects, conditions)).isCancelled()) + return false; + + if (!conditions.isEmpty()) { + ArrayList matchedConditions = new ArrayList<>(conditions.size()); + for (InteractionWiredCondition searchMatched : conditions) { + if (!matchedConditions.contains(searchMatched.getType()) && searchMatched.operator() == WiredConditionOperator.OR && searchMatched.execute(roomUnit, room, stuff)) { + matchedConditions.add(searchMatched.getType()); + } + } + + for (InteractionWiredCondition condition : conditions) { + if (!((condition.operator() == WiredConditionOperator.OR && matchedConditions.contains(condition.getType())) || + (condition.operator() == WiredConditionOperator.AND && condition.execute(roomUnit, room, stuff))) && + !Emulator.getPluginManager().fireEvent(new WiredConditionFailedEvent(room, roomUnit, trigger, condition)).isCancelled()) { + + return false; + } + } + } + + trigger.setCooldown(millis); + + boolean hasExtraRandom = room.getRoomSpecialTypes().hasExtraType(trigger.getX(), trigger.getY(), WiredExtraRandom.class); + boolean hasExtraUnseen = room.getRoomSpecialTypes().hasExtraType(trigger.getX(), trigger.getY(), WiredExtraUnseen.class); + THashSet extras = room.getRoomSpecialTypes().getExtras(trigger.getX(), trigger.getY()); + + for (InteractionWiredExtra extra : extras) { + extra.activateBox(room, roomUnit, millis); + } + + List effectList = new ArrayList<>(effects); + + if (hasExtraRandom || hasExtraUnseen) { + Collections.shuffle(effectList); + } + + + if (hasExtraUnseen) { + for (InteractionWiredExtra extra : room.getRoomSpecialTypes().getExtras(trigger.getX(), trigger.getY())) { + if (extra instanceof WiredExtraUnseen) { + extra.setExtradata(extra.getExtradata().equals("1") ? "0" : "1"); + InteractionWiredEffect effect = ((WiredExtraUnseen) extra).getUnseenEffect(effectList); + effectsToExecute.add(effect); // triggerEffect(effect, roomUnit, room, stuff, millis); + break; + } + } + } else { + for (final InteractionWiredEffect effect : effectList) { + boolean executed = effectsToExecute.add(effect); //triggerEffect(effect, roomUnit, room, stuff, millis); + if (hasExtraRandom && executed) { + break; + } + } + } + + return !Emulator.getPluginManager().fireEvent(new WiredStackExecutedEvent(room, roomUnit, trigger, effects, conditions)).isCancelled(); + } + + return false; + } + + private static boolean triggerEffect(InteractionWiredEffect effect, RoomUnit roomUnit, Room room, Object[] stuff, long millis) { + boolean executed = false; + if (effect != null && (effect.canExecute(millis) || (roomUnit != null && effect.requiresTriggeringUser() && Emulator.getConfig().getBoolean("wired.custom.enabled", false) && effect.userCanExecute(roomUnit.getId(), millis)))) { + executed = true; + if (!effect.requiresTriggeringUser() || (roomUnit != null && effect.requiresTriggeringUser())) { + Emulator.getThreading().run(() -> { + if (room.isLoaded()) { + try { + if (!effect.execute(roomUnit, room, stuff)) return; + effect.setCooldown(millis); + } catch (Exception e) { + log.error("Caught exception", e); + } + + effect.activateBox(room, roomUnit, millis); + } + }, effect.getDelay() * 500); + } + } + + return executed; + } + + public static GsonBuilder getGsonBuilder() { + if(gsonBuilder == null) { + gsonBuilder = new GsonBuilder(); + } + return gsonBuilder; + } + + public static boolean executeEffectsAtTiles(THashSet tiles, final RoomUnit roomUnit, final Room room, final Object[] stuff) { + for (RoomTile tile : tiles) { + if (room != null) { + THashSet items = room.getItemsAt(tile); + + long millis = room.getCycleTimestamp(); + for (final HabboItem item : items) { + if (item instanceof InteractionWiredEffect && !(item instanceof WiredEffectTriggerStacks)) { + triggerEffect((InteractionWiredEffect) item, roomUnit, room, stuff, millis); + ((InteractionWiredEffect) item).setCooldown(millis); + } + } + } + } + + return true; + } + + public static void dropRewards(int wiredId) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM wired_rewards_given WHERE wired_item = ?")) { + statement.setInt(1, wiredId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + private static void giveReward(Habbo habbo, WiredEffectGiveReward wiredBox, WiredGiveRewardItem reward) { + if (wiredBox.limit > 0) + wiredBox.given++; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO wired_rewards_given (wired_item, user_id, reward_id, timestamp) VALUES ( ?, ?, ?, ?)")) { + statement.setInt(1, wiredBox.getId()); + statement.setInt(2, habbo.getHabboInfo().getId()); + statement.setInt(3, reward.id); + statement.setInt(4, Emulator.getIntUnixTimestamp()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + if (reward.badge) { + UserWiredRewardReceived rewardReceived = new UserWiredRewardReceived(habbo, wiredBox, "badge", reward.data); + if (Emulator.getPluginManager().fireEvent(rewardReceived).isCancelled()) + return; + + if (rewardReceived.value.isEmpty()) + return; + + if (habbo.getInventory().getBadgesComponent().hasBadge(rewardReceived.value)) + return; + + HabboBadge badge = new HabboBadge(0, rewardReceived.value, 0, habbo); + Emulator.getThreading().run(badge); + habbo.getInventory().getBadgesComponent().addBadge(badge); + habbo.getClient().sendResponse(new AddUserBadgeComposer(badge)); + habbo.getClient().sendResponse(new WiredRewardAlertComposer(WiredRewardAlertComposer.REWARD_RECEIVED_BADGE)); + } else { + String[] data = reward.data.split("#"); + + if (data.length == 2) { + UserWiredRewardReceived rewardReceived = new UserWiredRewardReceived(habbo, wiredBox, data[0], data[1]); + if (Emulator.getPluginManager().fireEvent(rewardReceived).isCancelled()) + return; + + if (rewardReceived.value.isEmpty()) + return; + + if (rewardReceived.type.equalsIgnoreCase("credits")) { + int credits = Integer.valueOf(rewardReceived.value); + habbo.giveCredits(credits); + } else if (rewardReceived.type.equalsIgnoreCase("pixels")) { + int pixels = Integer.valueOf(rewardReceived.value); + habbo.givePixels(pixels); + } else if (rewardReceived.type.startsWith("points")) { + int points = Integer.valueOf(rewardReceived.value); + int type = 5; + + try { + type = Integer.valueOf(rewardReceived.type.replace("points", "")); + } catch (Exception e) { + } + + habbo.givePoints(type, points); + } else if (rewardReceived.type.equalsIgnoreCase("furni")) { + Item baseItem = Emulator.getGameEnvironment().getItemManager().getItem(Integer.valueOf(rewardReceived.value)); + if (baseItem != null) { + HabboItem item = Emulator.getGameEnvironment().getItemManager().createItem(habbo.getHabboInfo().getId(), baseItem, 0, 0, ""); + + if (item != null) { + habbo.getClient().sendResponse(new AddHabboItemComposer(item)); + habbo.getClient().getHabbo().getInventory().getItemsComponent().addItem(item); + habbo.getClient().sendResponse(new PurchaseOKComposer(null)); + habbo.getClient().sendResponse(new InventoryRefreshComposer()); + habbo.getClient().sendResponse(new WiredRewardAlertComposer(WiredRewardAlertComposer.REWARD_RECEIVED_ITEM)); + } + } + } else if (rewardReceived.type.equalsIgnoreCase("respect")) { + habbo.getHabboStats().respectPointsReceived += Integer.valueOf(rewardReceived.value); + } else if (rewardReceived.type.equalsIgnoreCase("cata")) { + CatalogItem item = Emulator.getGameEnvironment().getCatalogManager().getCatalogItem(Integer.valueOf(rewardReceived.value)); + + if (item != null) { + Emulator.getGameEnvironment().getCatalogManager().purchaseItem(null, item, habbo, 1, "", true); + } + habbo.getClient().sendResponse(new WiredRewardAlertComposer(WiredRewardAlertComposer.REWARD_RECEIVED_ITEM)); + } + } + } + } + + public static boolean getReward(Habbo habbo, WiredEffectGiveReward wiredBox) { + if (wiredBox.limit > 0) { + if (wiredBox.limit - wiredBox.given == 0) { + habbo.getClient().sendResponse(new WiredRewardAlertComposer(WiredRewardAlertComposer.LIMITED_NO_MORE_AVAILABLE)); + return false; + } + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT COUNT(*) as row_count, wired_rewards_given.* FROM wired_rewards_given WHERE user_id = ? AND wired_item = ? ORDER BY timestamp DESC LIMIT ?", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) { + statement.setInt(1, habbo.getHabboInfo().getId()); + statement.setInt(2, wiredBox.getId()); + statement.setInt(3, wiredBox.rewardItems.size()); + + try (ResultSet set = statement.executeQuery()) { + if (set.first()) { + if (set.getInt("row_count") >= 1) { + if (wiredBox.rewardTime == WiredEffectGiveReward.LIMIT_ONCE) { + habbo.getClient().sendResponse(new WiredRewardAlertComposer(WiredRewardAlertComposer.REWARD_ALREADY_RECEIVED)); + return false; + } + } + + set.beforeFirst(); + if (set.next()) { + if (wiredBox.rewardTime == WiredEffectGiveReward.LIMIT_N_MINUTES) { + if (Emulator.getIntUnixTimestamp() - set.getInt("timestamp") <= 60) { + habbo.getClient().sendResponse(new WiredRewardAlertComposer(WiredRewardAlertComposer.REWARD_ALREADY_RECEIVED_THIS_MINUTE)); + return false; + } + } + + if (wiredBox.uniqueRewards) { + if (set.getInt("row_count") == wiredBox.rewardItems.size()) { + habbo.getClient().sendResponse(new WiredRewardAlertComposer(WiredRewardAlertComposer.REWARD_ALL_COLLECTED)); + return false; + } + } + + if (wiredBox.rewardTime == WiredEffectGiveReward.LIMIT_N_HOURS) { + if (!(Emulator.getIntUnixTimestamp() - set.getInt("timestamp") >= (3600 * wiredBox.limitationInterval))) { + habbo.getClient().sendResponse(new WiredRewardAlertComposer(WiredRewardAlertComposer.REWARD_ALREADY_RECEIVED_THIS_HOUR)); + return false; + } + } + + if (wiredBox.rewardTime == WiredEffectGiveReward.LIMIT_N_DAY) { + if (!(Emulator.getIntUnixTimestamp() - set.getInt("timestamp") >= (86400 * wiredBox.limitationInterval))) { + habbo.getClient().sendResponse(new WiredRewardAlertComposer(WiredRewardAlertComposer.REWARD_ALREADY_RECEIVED_THIS_TODAY)); + return false; + } + } + } + + if (wiredBox.uniqueRewards) { + for (WiredGiveRewardItem item : wiredBox.rewardItems) { + set.beforeFirst(); + boolean found = false; + + while (set.next()) { + if (set.getInt("reward_id") == item.id) + found = true; + } + + if (!found) { + giveReward(habbo, wiredBox, item); + return true; + } + } + } else { + int randomNumber = Emulator.getRandom().nextInt(101); + + int count = 0; + for (WiredGiveRewardItem item : wiredBox.rewardItems) { + if (randomNumber >= count && randomNumber <= (count + item.probability)) { + giveReward(habbo, wiredBox, item); + return true; + } + + count += item.probability; + } + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return false; + } + + public static void resetTimers(Room room) { + if (!room.isLoaded() || room.getRoomSpecialTypes() == null) + return; + + room.getRoomSpecialTypes().getTriggers().forEach(t -> { + if (t == null) return; + + if (t.getType() == WiredTriggerType.AT_GIVEN_TIME || t.getType() == WiredTriggerType.PERIODICALLY || t.getType() == WiredTriggerType.PERIODICALLY_LONG) { + ((WiredTriggerReset) t).resetTimer(); + } + }); + + room.setLastTimerReset(Emulator.getIntUnixTimestamp()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredMatchFurniSetting.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredMatchFurniSetting.java new file mode 100644 index 0000000..7771450 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredMatchFurniSetting.java @@ -0,0 +1,27 @@ +package com.eu.habbo.habbohotel.wired; + +public class WiredMatchFurniSetting { + public final int item_id; + public final String state; + public final int rotation; + public final int x; + public final int y; + + public WiredMatchFurniSetting(int itemId, String state, int rotation, int x, int y) { + this.item_id = itemId; + this.state = state.replace("\t\t\t", " "); + this.rotation = rotation; + this.x = x; + this.y = y; + } + + @Override + public String toString() { + return this.toString(true); + } + + public String toString(boolean includeState) { + return this.item_id + "-" + (this.state.isEmpty() || !includeState ? " " : this.state) + "-" + this.rotation + "-" + this.x + "-" + this.y; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredTriggerType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredTriggerType.java new file mode 100644 index 0000000..e1286fa --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/WiredTriggerType.java @@ -0,0 +1,30 @@ +package com.eu.habbo.habbohotel.wired; + +public enum WiredTriggerType { + SAY_SOMETHING(0), + WALKS_ON_FURNI(1), + WALKS_OFF_FURNI(2), + AT_GIVEN_TIME(3), + STATE_CHANGED(4), + PERIODICALLY(6), + ENTER_ROOM(7), + GAME_STARTS(8), + GAME_ENDS(9), + SCORE_ACHIEVED(10), + COLLISION(11), + PERIODICALLY_LONG(12), + BOT_REACHED_STF(13), + BOT_REACHED_AVTR(14), + SAY_COMMAND(0), + IDLES(11), + UNIDLES(11), + CUSTOM(13), + STARTS_DANCING(11), + STOPS_DANCING(11); + + public final int code; + + WiredTriggerType(int code) { + this.code = code; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreClearType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreClearType.java new file mode 100644 index 0000000..602daa0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreClearType.java @@ -0,0 +1,14 @@ +package com.eu.habbo.habbohotel.wired.highscores; + +public enum WiredHighscoreClearType { + ALLTIME(0), + DAILY(1), + WEEKLY(2), + MONTHLY(3); + + public final int type; + + WiredHighscoreClearType(int type) { + this.type = type; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreDataEntry.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreDataEntry.java new file mode 100644 index 0000000..4cf262c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreDataEntry.java @@ -0,0 +1,55 @@ +package com.eu.habbo.habbohotel.wired.highscores; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class WiredHighscoreDataEntry { + private final int itemId; + private final List userIds; + private int score; + private final boolean isWin; + private final int timestamp; + + public WiredHighscoreDataEntry(int itemId, List userIds, int score, boolean isWin, int timestamp) { + this.itemId = itemId; + this.userIds = userIds; + this.score = score; + this.isWin = isWin; + this.timestamp = timestamp; + } + + public WiredHighscoreDataEntry(ResultSet set) throws SQLException { + this.itemId = set.getInt("item_id"); + this.userIds = Arrays.stream(set.getString("user_ids").split(",")).map(Integer::valueOf).collect(Collectors.toList()); + this.score = set.getInt("score"); + this.isWin = set.getInt("is_win") == 1; + this.timestamp = set.getInt("timestamp"); + } + + public int getItemId() { + return itemId; + } + + public List getUserIds() { + return userIds; + } + + public int getScore() { + return score; + } + + public void setScore(int score) { + this.score = score; + } + + public boolean isWin() { + return isWin; + } + + public int getTimestamp() { + return timestamp; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreManager.java new file mode 100644 index 0000000..8e19ff6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreManager.java @@ -0,0 +1,229 @@ +package com.eu.habbo.habbohotel.wired.highscores; + +import com.eu.habbo.Emulator; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.time.*; +import java.time.temporal.TemporalAdjusters; +import java.time.temporal.WeekFields; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Slf4j +public class WiredHighscoreManager { + + private final static String locale = (System.getProperty("user.language") != null ? System.getProperty("user.language") : "en"); + private final static String country = (System.getProperty("user.country") != null ? System.getProperty("user.country") : "US"); + + private final static DayOfWeek firstDayOfWeek = WeekFields.of(new Locale(locale, country)).getFirstDayOfWeek(); + private final static DayOfWeek lastDayOfWeek = DayOfWeek.of(((firstDayOfWeek.getValue() + 5) % DayOfWeek.values().length) + 1); + private final static ZoneId zoneId = ZoneId.systemDefault(); + + public void load() { + log.info("Highscore Manager -> Loaded"); + } + + public void addHighscoreData(WiredHighscoreDataEntry entry) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO `items_highscore_data` (`item_id`, `user_ids`, `score`, `is_win`, `timestamp`) VALUES (?, ?, ?, ?, ?)")) { + statement.setInt(1, entry.getItemId()); + statement.setString(2, String.join(",", entry.getUserIds().stream().map(Object::toString).collect(Collectors.toList()))); + statement.setInt(3, entry.getScore()); + statement.setInt(4, entry.isWin() ? 1 : 0); + statement.setInt(5, entry.getTimestamp()); + + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void addOrUpdateHighscoreData(WiredHighscoreDataEntry entry) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + final String userIds = String.join(",", entry.getUserIds().stream().map(Object::toString).collect(Collectors.toList())); + + // Select existing + try (PreparedStatement selectScore = connection.prepareStatement("SELECT `id` FROM `items_highscore_data` WHERE `item_id` = ? AND `user_ids` = ? LIMIT 1")) { + selectScore.setInt(1, entry.getItemId()); + selectScore.setString(2, userIds); + + try (final ResultSet scoreResult = selectScore.executeQuery()) { + if (scoreResult.next()) { + // Update + try (PreparedStatement statement = connection.prepareStatement("UPDATE `items_highscore_data` SET `score` = `score` + ? WHERE `id` = ?")) { + statement.setInt(1, entry.getScore()); + statement.setInt(2, scoreResult.getInt("id")); + statement.execute(); + } + } else { + // Insert + addHighscoreData(entry); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + public void setHighscoreData(WiredHighscoreDataEntry entry) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + final String userIds = String.join(",", entry.getUserIds().stream().map(Object::toString).collect(Collectors.toList())); + + // Select existing + try (PreparedStatement selectScore = connection.prepareStatement("SELECT `id` FROM `items_highscore_data` WHERE `item_id` = ? AND `user_ids` = ? LIMIT 1")) { + selectScore.setInt(1, entry.getItemId()); + selectScore.setString(2, userIds); + + try (final ResultSet scoreResult = selectScore.executeQuery()) { + if (scoreResult.next()) { + // Set + try (PreparedStatement statement = connection.prepareStatement("UPDATE `items_highscore_data` SET `score` = ? WHERE `id` = ?")) { + statement.setInt(1, entry.getScore()); + statement.setInt(2, scoreResult.getInt("id")); + statement.execute(); + } + } else { + // Insert + addHighscoreData(entry); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + private List loadHighscoreData(final int itemId) { + final List result = new ArrayList<>(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("SELECT * FROM items_highscore_data WHERE `item_id` = ?")) { + statement.setInt(1, itemId); + + try (final ResultSet set = statement.executeQuery()) { + while (set.next()) { + result.add(new WiredHighscoreDataEntry(set)); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return result; + } + + public WiredHighscoreDataEntry getHighscoreRow(final int itemId, final List userIds) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + final String userIdsStr = String.join(",", userIds.stream().map(Object::toString).collect(Collectors.toList())); + + // Select existing + try (PreparedStatement selectScore = connection.prepareStatement("SELECT * FROM `items_highscore_data` WHERE `item_id` = ? AND `user_ids` = ? LIMIT 1")) { + selectScore.setInt(1, itemId); + selectScore.setString(2, userIdsStr); + + try (final ResultSet scoreResult = selectScore.executeQuery()) { + if (scoreResult.next()) { + return new WiredHighscoreDataEntry(scoreResult); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + return null; + } + + public List getHighscoreRowsForItem(int itemId, WiredHighscoreClearType clearType, WiredHighscoreScoreType scoreType) { + final List highscoreData = this.loadHighscoreData(itemId); + + if (highscoreData.size() == 0) { + return null; + } + + Stream highscores = new ArrayList<>(highscoreData).stream() + .filter(entry -> this.timeMatchesEntry(entry, clearType) && (scoreType != WiredHighscoreScoreType.MOSTWIN || entry.isWin())) + .map(entry -> new WiredHighscoreRow( + entry.getUserIds().stream() + .map(id -> Emulator.getGameEnvironment().getHabboManager().getHabboInfo(id).getUsername()) + .collect(Collectors.toList()), + entry.getScore() + )); + + if (scoreType == WiredHighscoreScoreType.CLASSIC) { + return highscores + .filter(Objects::nonNull) // Filter out any null rows (in case of null usernames) + .sorted(WiredHighscoreRow::compareTo) + .collect(Collectors.toList()); + } + + if (scoreType == WiredHighscoreScoreType.PERTEAM) { + return highscores + .collect(Collectors.groupingBy(h -> h.getUsers().hashCode())) + .entrySet() + .stream() + .map(e -> e.getValue().stream() + .sorted(WiredHighscoreRow::compareTo) + .collect(Collectors.toList()) + .get(0) + ) + .sorted(WiredHighscoreRow::compareTo) + .collect(Collectors.toList()); + } + + if (scoreType == WiredHighscoreScoreType.MOSTWIN) { + return highscores + .collect(Collectors.groupingBy(h -> h.getUsers().hashCode())) + .entrySet() + .stream() + .map(e -> new WiredHighscoreRow(e.getValue().get(0).getUsers(), e.getValue().size())) + .sorted(WiredHighscoreRow::compareTo) + .collect(Collectors.toList()); + } + + return null; + } + + private boolean timeMatchesEntry(WiredHighscoreDataEntry entry, WiredHighscoreClearType timeType) { + switch (timeType) { + case DAILY: + return entry.getTimestamp() > this.getTodayStartTimestamp() && entry.getTimestamp() < this.getTodayEndTimestamp(); + case WEEKLY: + return entry.getTimestamp() > this.getWeekStartTimestamp() && entry.getTimestamp() < this.getWeekEndTimestamp(); + case MONTHLY: + return entry.getTimestamp() > this.getMonthStartTimestamp() && entry.getTimestamp() < this.getMonthEndTimestamp(); + case ALLTIME: + return true; + } + + return false; + } + + private long getTodayStartTimestamp() { + return LocalDateTime.now().with(LocalTime.MIDNIGHT).atZone(zoneId).toEpochSecond(); + } + + private long getTodayEndTimestamp() { + return LocalDateTime.now().with(LocalTime.MIDNIGHT).plusDays(1).plusSeconds(-1).atZone(zoneId).toEpochSecond(); + } + + private long getWeekStartTimestamp() { + return LocalDateTime.now().with(LocalTime.MIDNIGHT).with(TemporalAdjusters.previousOrSame(firstDayOfWeek)).atZone(zoneId).toEpochSecond(); + } + + private long getWeekEndTimestamp() { + return LocalDateTime.now().with(LocalTime.MIDNIGHT).plusDays(1).plusSeconds(-1).with(TemporalAdjusters.nextOrSame(lastDayOfWeek)).atZone(zoneId).toEpochSecond(); + } + + private long getMonthStartTimestamp() { + return LocalDateTime.now().with(LocalTime.MIDNIGHT).with(TemporalAdjusters.firstDayOfMonth()).atZone(zoneId).toEpochSecond(); + } + + private long getMonthEndTimestamp() { + return LocalDateTime.now().with(LocalTime.MIDNIGHT).plusDays(1).plusSeconds(-1).with(TemporalAdjusters.lastDayOfMonth()).atZone(zoneId).toEpochSecond(); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreRow.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreRow.java new file mode 100644 index 0000000..1282a1b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreRow.java @@ -0,0 +1,32 @@ +package com.eu.habbo.habbohotel.wired.highscores; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class WiredHighscoreRow implements Comparable { + public static final Comparator COMPARATOR = Comparator.comparing(WiredHighscoreRow::getValue).reversed(); + + private final List users; + private final int value; + + public WiredHighscoreRow(List users, int value) { + Collections.sort(users); + + this.users = users; + this.value = value; + } + + public List getUsers() { + return users; + } + + public int getValue() { + return value; + } + + @Override + public int compareTo(WiredHighscoreRow otherRow) { + return COMPARATOR.compare(this, otherRow); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreScoreType.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreScoreType.java new file mode 100644 index 0000000..d70e07e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreScoreType.java @@ -0,0 +1,13 @@ +package com.eu.habbo.habbohotel.wired.highscores; + +public enum WiredHighscoreScoreType { + PERTEAM(0), + MOSTWIN(1), + CLASSIC(2); + + public final int type; + + WiredHighscoreScoreType(int type) { + this.type = type; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/ClientMessage.java b/Emulator/src/main/java/com/eu/habbo/messages/ClientMessage.java new file mode 100644 index 0000000..55fdae4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/ClientMessage.java @@ -0,0 +1,85 @@ +package com.eu.habbo.messages; + +import com.eu.habbo.util.PacketUtils; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +public class ClientMessage { + private final int header; + private final ByteBuf buffer; + + public ClientMessage(int messageId, ByteBuf buffer) { + this.header = messageId; + this.buffer = ((buffer == null) || (buffer.readableBytes() == 0) ? Unpooled.EMPTY_BUFFER : buffer); + } + + public ByteBuf getBuffer() { + return this.buffer; + } + + public int getMessageId() { + return this.header; + } + + + /** + * + * @return + * @throws CloneNotSupportedException + */ + @Override + public ClientMessage clone() throws CloneNotSupportedException { + return new ClientMessage(this.header, this.buffer.duplicate()); + } + + public int readShort() { + try { + return this.buffer.readShort(); + } catch (Exception e) { + } + + return 0; + } + + public Integer readInt() { + try { + return this.buffer.readInt(); + } catch (Exception e) { + } + + return 0; + } + + public boolean readBoolean() { + try { + return this.buffer.readByte() == 1; + } catch (Exception e) { + } + + return false; + } + + public String readString() { + try { + int length = this.readShort(); + byte[] data = new byte[length]; + this.buffer.readBytes(data); + return new String(data); + } catch (Exception e) { + return ""; + } + } + + public String getMessageBody() { + return PacketUtils.formatPacket(this.buffer); + } + + public int bytesAvailable() { + return this.buffer.readableBytes(); + } + + public boolean release() { + return this.buffer.release(); + } + +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/ICallable.java b/Emulator/src/main/java/com/eu/habbo/messages/ICallable.java new file mode 100644 index 0000000..5587fbd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/ICallable.java @@ -0,0 +1,7 @@ +package com.eu.habbo.messages; + +import com.eu.habbo.messages.incoming.MessageHandler; + +public interface ICallable { + void call(MessageHandler handler); +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/ISerialize.java b/Emulator/src/main/java/com/eu/habbo/messages/ISerialize.java new file mode 100644 index 0000000..0099693 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/ISerialize.java @@ -0,0 +1,5 @@ +package com.eu.habbo.messages; + +public interface ISerialize { + void serialize(ServerMessage message); +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/NoAuthMessage.java b/Emulator/src/main/java/com/eu/habbo/messages/NoAuthMessage.java new file mode 100644 index 0000000..4748706 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/NoAuthMessage.java @@ -0,0 +1,7 @@ +package com.eu.habbo.messages; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface NoAuthMessage {} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/PacketManager.java b/Emulator/src/main/java/com/eu/habbo/messages/PacketManager.java new file mode 100644 index 0000000..123fe9a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/PacketManager.java @@ -0,0 +1,647 @@ +package com.eu.habbo.messages; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.messages.incoming.Incoming; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.incoming.achievements.RequestAchievementConfigurationEvent; +import com.eu.habbo.messages.incoming.achievements.RequestAchievementsEvent; +import com.eu.habbo.messages.incoming.ambassadors.AmbassadorAlertCommandEvent; +import com.eu.habbo.messages.incoming.ambassadors.AmbassadorVisitCommandEvent; +import com.eu.habbo.messages.incoming.camera.*; +import com.eu.habbo.messages.incoming.catalog.*; +import com.eu.habbo.messages.incoming.catalog.marketplace.*; +import com.eu.habbo.messages.incoming.catalog.recycler.OpenRecycleBoxEvent; +import com.eu.habbo.messages.incoming.catalog.recycler.RecycleEvent; +import com.eu.habbo.messages.incoming.catalog.recycler.ReloadRecyclerEvent; +import com.eu.habbo.messages.incoming.catalog.recycler.RequestRecyclerLogicEvent; +import com.eu.habbo.messages.incoming.crafting.*; +import com.eu.habbo.messages.incoming.events.calendar.AdventCalendarForceOpenEvent; +import com.eu.habbo.messages.incoming.events.calendar.AdventCalendarOpenDayEvent; +import com.eu.habbo.messages.incoming.floorplaneditor.FloorPlanEditorRequestBlockedTilesEvent; +import com.eu.habbo.messages.incoming.floorplaneditor.FloorPlanEditorRequestDoorSettingsEvent; +import com.eu.habbo.messages.incoming.floorplaneditor.FloorPlanEditorSaveEvent; +import com.eu.habbo.messages.incoming.friends.*; +import com.eu.habbo.messages.incoming.gamecenter.*; +import com.eu.habbo.messages.incoming.guardians.GuardianAcceptRequestEvent; +import com.eu.habbo.messages.incoming.guardians.GuardianNoUpdatesWantedEvent; +import com.eu.habbo.messages.incoming.guardians.GuardianVoteEvent; +import com.eu.habbo.messages.incoming.guides.*; +import com.eu.habbo.messages.incoming.guilds.*; +import com.eu.habbo.messages.incoming.guilds.forums.*; +import com.eu.habbo.messages.incoming.handshake.*; +import com.eu.habbo.messages.incoming.helper.MySanctionStatusEvent; +import com.eu.habbo.messages.incoming.helper.RequestTalentTrackEvent; +import com.eu.habbo.messages.incoming.hotelview.*; +import com.eu.habbo.messages.incoming.inventory.RequestInventoryBadgesEvent; +import com.eu.habbo.messages.incoming.inventory.RequestInventoryBotsEvent; +import com.eu.habbo.messages.incoming.inventory.RequestInventoryItemsEvent; +import com.eu.habbo.messages.incoming.inventory.RequestInventoryPetsEvent; +import com.eu.habbo.messages.incoming.inventory.RequestInventoryItemsDelete; +import com.eu.habbo.messages.incoming.modtool.*; +import com.eu.habbo.messages.incoming.navigator.*; +import com.eu.habbo.messages.incoming.polls.AnswerPollEvent; +import com.eu.habbo.messages.incoming.polls.CancelPollEvent; +import com.eu.habbo.messages.incoming.polls.GetPollDataEvent; +import com.eu.habbo.messages.incoming.rooms.*; +import com.eu.habbo.messages.incoming.rooms.bots.BotPickupEvent; +import com.eu.habbo.messages.incoming.rooms.bots.BotPlaceEvent; +import com.eu.habbo.messages.incoming.rooms.bots.BotSaveSettingsEvent; +import com.eu.habbo.messages.incoming.rooms.bots.BotSettingsEvent; +import com.eu.habbo.messages.incoming.rooms.items.*; +import com.eu.habbo.messages.incoming.rooms.items.jukebox.*; +import com.eu.habbo.messages.incoming.rooms.items.lovelock.LoveLockStartConfirmEvent; +import com.eu.habbo.messages.incoming.rooms.items.rentablespace.RentSpaceCancelEvent; +import com.eu.habbo.messages.incoming.rooms.items.rentablespace.RentSpaceEvent; +import com.eu.habbo.messages.incoming.rooms.items.youtube.YoutubeRequestPlaylistChange; +import com.eu.habbo.messages.incoming.rooms.items.youtube.YoutubeRequestPlaylists; +import com.eu.habbo.messages.incoming.rooms.items.youtube.YoutubeRequestStateChange; +import com.eu.habbo.messages.incoming.rooms.pets.*; +import com.eu.habbo.messages.incoming.rooms.promotions.BuyRoomPromotionEvent; +import com.eu.habbo.messages.incoming.rooms.promotions.RequestPromotionRoomsEvent; +import com.eu.habbo.messages.incoming.rooms.promotions.UpdateRoomPromotionEvent; +import com.eu.habbo.messages.incoming.rooms.users.*; +import com.eu.habbo.messages.incoming.trading.*; +import com.eu.habbo.messages.incoming.unknown.RequestResolutionEvent; +import com.eu.habbo.messages.incoming.unknown.UnknownEvent1; +import com.eu.habbo.messages.incoming.users.*; +import com.eu.habbo.messages.incoming.wired.WiredApplySetConditionsEvent; +import com.eu.habbo.messages.incoming.wired.WiredConditionSaveDataEvent; +import com.eu.habbo.messages.incoming.wired.WiredEffectSaveDataEvent; +import com.eu.habbo.messages.incoming.wired.WiredTriggerSaveDataEvent; +import com.eu.habbo.plugin.EventHandler; +import com.eu.habbo.plugin.events.emulator.EmulatorConfigUpdatedEvent; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +public class PacketManager { + private static final List logList = new ArrayList<>(); + public static boolean DEBUG_SHOW_PACKETS = false; + public static boolean MULTI_THREADED_PACKET_HANDLING = false; + private final THashMap> incoming; + private final THashMap> callables; + private final PacketNames names; + + public PacketManager() throws Exception { + this.incoming = new THashMap<>(); + this.callables = new THashMap<>(); + this.names = new PacketNames(); + this.names.initialize(); + + this.registerHandshake(); + this.registerCatalog(); + this.registerEvent(); + this.registerFriends(); + this.registerNavigator(); + this.registerUsers(); + this.registerHotelview(); + this.registerInventory(); + this.registerRooms(); + this.registerPolls(); + this.registerUnknown(); + this.registerModTool(); + this.registerTrading(); + this.registerGuilds(); + this.registerPets(); + this.registerWired(); + this.registerAchievements(); + this.registerFloorPlanEditor(); + this.registerAmbassadors(); + this.registerGuides(); + this.registerCrafting(); + this.registerCamera(); + this.registerGameCenter(); + } + + public PacketNames getNames() { + return names; + } + + @EventHandler + public static void onConfigurationUpdated(EmulatorConfigUpdatedEvent event) { + logList.clear(); + + for (String s : Emulator.getConfig().getValue("debug.show.headers").split(";")) { + try { + logList.add(Integer.valueOf(s)); + } catch (NumberFormatException e) { + + } + } + } + + public void registerHandler(Integer header, Class handler) throws Exception { + if (header < 0) + return; + + if (this.incoming.containsKey(header)) { + throw new Exception("Header already registered. Failed to register " + handler.getName() + " with header " + header); + } + + this.incoming.putIfAbsent(header, handler); + } + + public void registerCallable(Integer header, ICallable callable) { + this.callables.putIfAbsent(header, new ArrayList<>()); + this.callables.get(header).add(callable); + } + + public void unregisterCallables(Integer header, ICallable callable) { + if (this.callables.containsKey(header)) { + this.callables.get(header).remove(callable); + } + } + + public void unregisterCallables(Integer header) { + if (this.callables.containsKey(header)) { + this.callables.clear(); + } + } + + public void handlePacket(GameClient client, ClientMessage packet) { + if (client == null || Emulator.isShuttingDown) + return; + + try { + if (this.isRegistered(packet.getMessageId())) { + Class handlerClass = this.incoming.get(packet.getMessageId()); + + if (handlerClass == null) throw new Exception("Unknown message " + packet.getMessageId()); + + if (client.getHabbo() == null && !handlerClass.isAnnotationPresent(NoAuthMessage.class)) { + if (DEBUG_SHOW_PACKETS) { + log.warn("Client packet {} requires an authenticated session.", packet.getMessageId()); + } + + return; + } + + final MessageHandler handler = handlerClass.newInstance(); + + if (handler.getRatelimit() > 0) { + if (client.messageTimestamps.containsKey(handlerClass) && System.currentTimeMillis() - client.messageTimestamps.get(handlerClass) < handler.getRatelimit()) { + if (PacketManager.DEBUG_SHOW_PACKETS) { + log.warn("Client packet {} was ratelimited.", packet.getMessageId()); + } + + return; + } else { + client.messageTimestamps.put(handlerClass, System.currentTimeMillis()); + } + } + + if (logList.contains(packet.getMessageId()) && client.getHabbo() != null) { + log.info("User {} sent packet {} with body {}", client.getHabbo().getHabboInfo().getUsername(), packet.getMessageId(), packet.getMessageBody()); + } + + handler.client = client; + handler.packet = packet; + + if (this.callables.containsKey(packet.getMessageId())) { + for (ICallable callable : this.callables.get(packet.getMessageId())) { + callable.call(handler); + } + } + + if (!handler.isCancelled) { + handler.handle(); + } + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + boolean isRegistered(int header) { + return this.incoming.containsKey(header); + } + + private void registerAmbassadors() throws Exception { + this.registerHandler(Incoming.AmbassadorAlertCommandEvent, AmbassadorAlertCommandEvent.class); + this.registerHandler(Incoming.AmbassadorVisitCommandEvent, AmbassadorVisitCommandEvent.class); + } + + private void registerCatalog() throws Exception { + this.registerHandler(Incoming.RequestRecylerLogicEvent, RequestRecyclerLogicEvent.class); + this.registerHandler(Incoming.RequestDiscountEvent, RequestDiscountEvent.class); + this.registerHandler(Incoming.RequestGiftConfigurationEvent, RequestGiftConfigurationEvent.class); + this.registerHandler(Incoming.GetMarketplaceConfigEvent, RequestMarketplaceConfigEvent.class); + this.registerHandler(Incoming.RequestCatalogModeEvent, RequestCatalogModeEvent.class); + this.registerHandler(Incoming.RequestCatalogIndexEvent, RequestCatalogIndexEvent.class); + this.registerHandler(Incoming.RequestCatalogPageEvent, RequestCatalogPageEvent.class); + this.registerHandler(Incoming.CatalogBuyItemAsGiftEvent, CatalogBuyItemAsGiftEvent.class); + this.registerHandler(Incoming.CatalogBuyItemEvent, CatalogBuyItemEvent.class); + this.registerHandler(Incoming.RedeemVoucherEvent, RedeemVoucherEvent.class); + this.registerHandler(Incoming.ReloadRecyclerEvent, ReloadRecyclerEvent.class); + this.registerHandler(Incoming.RecycleEvent, RecycleEvent.class); + this.registerHandler(Incoming.OpenRecycleBoxEvent, OpenRecycleBoxEvent.class); + this.registerHandler(Incoming.RequestOwnItemsEvent, RequestOwnItemsEvent.class); + this.registerHandler(Incoming.TakeBackItemEvent, TakeBackItemEvent.class); + this.registerHandler(Incoming.RequestOffersEvent, RequestOffersEvent.class); + this.registerHandler(Incoming.RequestItemInfoEvent, RequestItemInfoEvent.class); + this.registerHandler(Incoming.BuyItemEvent, BuyItemEvent.class); + this.registerHandler(Incoming.RequestSellItemEvent, RequestSellItemEvent.class); + this.registerHandler(Incoming.SellItemEvent, SellItemEvent.class); + this.registerHandler(Incoming.RequestCreditsEvent, RequestCreditsEvent.class); + this.registerHandler(Incoming.RequestPetBreedsEvent, RequestPetBreedsEvent.class); + this.registerHandler(Incoming.CheckPetNameEvent, CheckPetNameEvent.class); + this.registerHandler(Incoming.GetClubDataEvent, RequestClubDataEvent.class); + this.registerHandler(Incoming.RequestClubGiftsEvent, RequestClubGiftsEvent.class); + this.registerHandler(Incoming.CatalogSearchedItemEvent, CatalogSearchedItemEvent.class); + this.registerHandler(Incoming.PurchaseTargetOfferEvent, PurchaseTargetOfferEvent.class); + this.registerHandler(Incoming.TargetOfferStateEvent, TargetOfferStateEvent.class); + this.registerHandler(Incoming.CatalogSelectClubGiftEvent, CatalogSelectClubGiftEvent.class); + this.registerHandler(Incoming.RequestClubCenterEvent, RequestClubCenterEvent.class); + this.registerHandler(Incoming.CatalogRequestClubDiscountEvent, CatalogRequestClubDiscountEvent.class); + this.registerHandler(Incoming.CatalogBuyClubDiscountEvent, CatalogBuyClubDiscountEvent.class); + } + + private void registerEvent() throws Exception { + this.registerHandler(Incoming.AdventCalendarOpenDayEvent, AdventCalendarOpenDayEvent.class); + this.registerHandler(Incoming.AdventCalendarForceOpenEvent, AdventCalendarForceOpenEvent.class); + } + + private void registerHandshake() throws Exception { + this.registerHandler(Incoming.ReleaseVersionEvent, ReleaseVersionEvent.class); + this.registerHandler(Incoming.InitDiffieHandshake, InitDiffieHandshakeEvent.class); + this.registerHandler(Incoming.CompleteDiffieHandshake, CompleteDiffieHandshakeEvent.class); + this.registerHandler(Incoming.SecureLoginEvent, SecureLoginEvent.class); + this.registerHandler(Incoming.MachineIDEvent, MachineIDEvent.class); + this.registerHandler(Incoming.UsernameEvent, UsernameEvent.class); + this.registerHandler(Incoming.PingEvent, PingEvent.class); + } + + private void registerFriends() throws Exception { + this.registerHandler(Incoming.RequestFriendsEvent, RequestFriendsEvent.class); + this.registerHandler(Incoming.ChangeRelationEvent, ChangeRelationEvent.class); + this.registerHandler(Incoming.RemoveFriendEvent, RemoveFriendEvent.class); + this.registerHandler(Incoming.SearchUserEvent, SearchUserEvent.class); + this.registerHandler(Incoming.FriendRequestEvent, FriendRequestEvent.class); + this.registerHandler(Incoming.AcceptFriendRequest, AcceptFriendRequestEvent.class); + this.registerHandler(Incoming.DeclineFriendRequest, DeclineFriendRequestEvent.class); + this.registerHandler(Incoming.FriendPrivateMessageEvent, FriendPrivateMessageEvent.class); + this.registerHandler(Incoming.FriendListUpdateEvent, FriendListUpdateEvent.class); + this.registerHandler(Incoming.RequestFriendRequestEvent, RequestFriendRequestsEvent.class); + this.registerHandler(Incoming.StalkFriendEvent, StalkFriendEvent.class); + this.registerHandler(Incoming.RequestInitFriendsEvent, RequestInitFriendsEvent.class); + this.registerHandler(Incoming.FindNewFriendsEvent, FindNewFriendsEvent.class); + this.registerHandler(Incoming.InviteFriendsEvent, InviteFriendsEvent.class); + } + + private void registerUsers() throws Exception { + this.registerHandler(Incoming.RequestUserDataEvent, RequestUserDataEvent.class); + this.registerHandler(Incoming.RequestUserCreditsEvent, RequestUserCreditsEvent.class); + this.registerHandler(Incoming.RequestUserClubEvent, RequestUserClubEvent.class); + this.registerHandler(Incoming.RequestMeMenuSettingsEvent, RequestMeMenuSettingsEvent.class); + this.registerHandler(Incoming.RequestUserCitizinShipEvent, RequestUserCitizinShipEvent.class); + this.registerHandler(Incoming.RequestUserProfileEvent, RequestUserProfileEvent.class); + this.registerHandler(Incoming.RequestProfileFriendsEvent, RequestProfileFriendsEvent.class); + this.registerHandler(Incoming.RequestUserWardrobeEvent, RequestUserWardrobeEvent.class); + this.registerHandler(Incoming.SaveWardrobeEvent, SaveWardrobeEvent.class); + this.registerHandler(Incoming.SaveMottoEvent, SaveMottoEvent.class); + this.registerHandler(Incoming.UserSaveLookEvent, UserSaveLookEvent.class); + this.registerHandler(Incoming.UserWearBadgeEvent, UserWearBadgeEvent.class); + this.registerHandler(Incoming.RequestWearingBadgesEvent, RequestWearingBadgesEvent.class); + this.registerHandler(Incoming.SaveUserVolumesEvent, SaveUserVolumesEvent.class); + this.registerHandler(Incoming.SaveBlockCameraFollowEvent, SaveBlockCameraFollowEvent.class); + this.registerHandler(Incoming.SaveIgnoreRoomInvitesEvent, SaveIgnoreRoomInvitesEvent.class); + this.registerHandler(Incoming.SavePreferOldChatEvent, SavePreferOldChatEvent.class); + this.registerHandler(Incoming.ActivateEffectEvent, ActivateEffectEvent.class); + this.registerHandler(Incoming.PerformanceLogMessageEvent, PerformanceLogMessageEvent.class); + this.registerHandler(Incoming.EnableEffectEvent, EnableEffectEvent.class); + this.registerHandler(Incoming.UserActivityEvent, UserActivityEvent.class); + this.registerHandler(Incoming.UserNuxEvent, UserNuxEvent.class); + this.registerHandler(Incoming.PickNewUserGiftEvent, PickNewUserGiftEvent.class); + this.registerHandler(Incoming.ChangeNameCheckUsernameEvent, ChangeNameCheckUsernameEvent.class); + this.registerHandler(Incoming.ConfirmChangeNameEvent, ConfirmChangeNameEvent.class); + this.registerHandler(Incoming.ChangeChatBubbleEvent, ChangeChatBubbleEvent.class); + this.registerHandler(Incoming.UpdateUIFlagsEvent, UpdateUIFlagsEvent.class); + } + + private void registerNavigator() throws Exception { + this.registerHandler(Incoming.RequestRoomCategoriesEvent, RequestRoomCategoriesEvent.class); + this.registerHandler(Incoming.RequestPopularRoomsEvent, RequestPopularRoomsEvent.class); + this.registerHandler(Incoming.RequestHighestScoreRoomsEvent, RequestHighestScoreRoomsEvent.class); + this.registerHandler(Incoming.RequestMyRoomsEvent, RequestMyRoomsEvent.class); + this.registerHandler(Incoming.RequestCanCreateRoomEvent, RequestCanCreateRoomEvent.class); + this.registerHandler(Incoming.RequestPromotedRoomsEvent, RequestPromotedRoomsEvent.class); + this.registerHandler(Incoming.RequestCreateRoomEvent, RequestCreateRoomEvent.class); + this.registerHandler(Incoming.RequestTagsEvent, RequestTagsEvent.class); + this.registerHandler(Incoming.SearchRoomsByTagEvent, SearchRoomsByTagEvent.class); + this.registerHandler(Incoming.SearchRoomsEvent, SearchRoomsEvent.class); + this.registerHandler(Incoming.SearchRoomsFriendsNowEvent, SearchRoomsFriendsNowEvent.class); + this.registerHandler(Incoming.SearchRoomsFriendsOwnEvent, SearchRoomsFriendsOwnEvent.class); + this.registerHandler(Incoming.SearchRoomsWithRightsEvent, SearchRoomsWithRightsEvent.class); + this.registerHandler(Incoming.SearchRoomsInGroupEvent, SearchRoomsInGroupEvent.class); + this.registerHandler(Incoming.SearchRoomsMyFavoriteEvent, SearchRoomsMyFavouriteEvent.class); + this.registerHandler(Incoming.SearchRoomsVisitedEvent, SearchRoomsVisitedEvent.class); + this.registerHandler(Incoming.RequestNewNavigatorDataEvent, RequestNewNavigatorDataEvent.class); + this.registerHandler(Incoming.RequestNewNavigatorRoomsEvent, RequestNewNavigatorRoomsEvent.class); + this.registerHandler(Incoming.NewNavigatorActionEvent, NewNavigatorActionEvent.class); + this.registerHandler(Incoming.RequestNavigatorSettingsEvent, RequestNavigatorSettingsEvent.class); + this.registerHandler(Incoming.SaveWindowSettingsEvent, SaveWindowSettingsEvent.class); + this.registerHandler(Incoming.RequestDeleteRoomEvent, RequestDeleteRoomEvent.class); + this.registerHandler(Incoming.NavigatorCategoryListModeEvent, NavigatorCategoryListModeEvent.class); + this.registerHandler(Incoming.NavigatorCollapseCategoryEvent, NavigatorCollapseCategoryEvent.class); + this.registerHandler(Incoming.NavigatorUncollapseCategoryEvent, NavigatorUncollapseCategoryEvent.class); + this.registerHandler(Incoming.AddSavedSearchEvent, AddSavedSearchEvent.class); + this.registerHandler(Incoming.DeleteSavedSearchEvent, DeleteSavedSearchEvent.class); + } + + private void registerHotelview() throws Exception { + this.registerHandler(Incoming.HotelViewEvent, HotelViewEvent.class); + this.registerHandler(Incoming.HotelViewRequestBonusRareEvent, HotelViewRequestBonusRareEvent.class); + this.registerHandler(Incoming.RequestNewsListEvent, RequestNewsListEvent.class); + this.registerHandler(Incoming.HotelViewDataEvent, HotelViewDataEvent.class); + this.registerHandler(Incoming.HotelViewRequestBadgeRewardEvent, HotelViewRequestBadgeRewardEvent.class); + this.registerHandler(Incoming.HotelViewClaimBadgeRewardEvent, HotelViewClaimBadgeRewardEvent.class); + this.registerHandler(Incoming.HotelViewRequestLTDAvailabilityEvent, HotelViewRequestLTDAvailabilityEvent.class); + this.registerHandler(Incoming.HotelViewRequestSecondsUntilEvent, HotelViewRequestSecondsUntilEvent.class); + } + + private void registerInventory() throws Exception { + this.registerHandler(Incoming.RequestInventoryBadgesEvent, RequestInventoryBadgesEvent.class); + this.registerHandler(Incoming.RequestInventoryBotsEvent, RequestInventoryBotsEvent.class); + this.registerHandler(Incoming.RequestInventoryItemsEvent, RequestInventoryItemsEvent.class); + this.registerHandler(Incoming.HotelViewInventoryEvent, RequestInventoryItemsEvent.class); + this.registerHandler(Incoming.RequestInventoryPetsEvent, RequestInventoryPetsEvent.class); + this.registerHandler(Incoming.RequestInventoryItemsDelete, RequestInventoryItemsDelete.class); + } + + void registerRooms() throws Exception { + this.registerHandler(Incoming.RequestRoomLoadEvent, RequestRoomLoadEvent.class); + this.registerHandler(Incoming.RequestHeightmapEvent, RequestRoomHeightmapEvent.class); + this.registerHandler(Incoming.RequestRoomHeightmapEvent, RequestRoomHeightmapEvent.class); + this.registerHandler(Incoming.RoomVoteEvent, RoomVoteEvent.class); + this.registerHandler(Incoming.RequestRoomDataEvent, RequestRoomDataEvent.class); + this.registerHandler(Incoming.RoomSettingsSaveEvent, RoomSettingsSaveEvent.class); + this.registerHandler(Incoming.RoomPlaceItemEvent, RoomPlaceItemEvent.class); + this.registerHandler(Incoming.RotateMoveItemEvent, RotateMoveItemEvent.class); + this.registerHandler(Incoming.MoveWallItemEvent, MoveWallItemEvent.class); + this.registerHandler(Incoming.RoomPickupItemEvent, RoomPickupItemEvent.class); + this.registerHandler(Incoming.RoomPlacePaintEvent, RoomPlacePaintEvent.class); + this.registerHandler(Incoming.RoomUserStartTypingEvent, RoomUserStartTypingEvent.class); + this.registerHandler(Incoming.RoomUserStopTypingEvent, RoomUserStopTypingEvent.class); + this.registerHandler(Incoming.ToggleFloorItemEvent, ToggleFloorItemEvent.class); + this.registerHandler(Incoming.ToggleWallItemEvent, ToggleWallItemEvent.class); + this.registerHandler(Incoming.RoomBackgroundEvent, RoomBackgroundEvent.class); + this.registerHandler(Incoming.MannequinSaveNameEvent, MannequinSaveNameEvent.class); + this.registerHandler(Incoming.MannequinSaveLookEvent, MannequinSaveLookEvent.class); + this.registerHandler(Incoming.FootballGateSaveLookEvent, FootballGateSaveLookEvent.class); + this.registerHandler(Incoming.AdvertisingSaveEvent, AdvertisingSaveEvent.class); + this.registerHandler(Incoming.RequestRoomSettingsEvent, RequestRoomSettingsEvent.class); + this.registerHandler(Incoming.MoodLightSettingsEvent, MoodLightSettingsEvent.class); + this.registerHandler(Incoming.MoodLightTurnOnEvent, MoodLightTurnOnEvent.class); + this.registerHandler(Incoming.RoomUserDropHandItemEvent, RoomUserDropHandItemEvent.class); + this.registerHandler(Incoming.RoomUserLookAtPoint, RoomUserLookAtPoint.class); + this.registerHandler(Incoming.RoomUserTalkEvent, RoomUserTalkEvent.class); + this.registerHandler(Incoming.RoomUserShoutEvent, RoomUserShoutEvent.class); + this.registerHandler(Incoming.RoomUserWhisperEvent, RoomUserWhisperEvent.class); + this.registerHandler(Incoming.RoomUserActionEvent, RoomUserActionEvent.class); + this.registerHandler(Incoming.RoomUserSitEvent, RoomUserSitEvent.class); + this.registerHandler(Incoming.RoomUserDanceEvent, RoomUserDanceEvent.class); + this.registerHandler(Incoming.RoomUserSignEvent, RoomUserSignEvent.class); + this.registerHandler(Incoming.RoomUserWalkEvent, RoomUserWalkEvent.class); + this.registerHandler(Incoming.RoomUserGiveRespectEvent, RoomUserGiveRespectEvent.class); + this.registerHandler(Incoming.RoomUserGiveRightsEvent, RoomUserGiveRightsEvent.class); + this.registerHandler(Incoming.RoomRemoveRightsEvent, RoomRemoveRightsEvent.class); + this.registerHandler(Incoming.RequestRoomRightsEvent, RequestRoomRightsEvent.class); + this.registerHandler(Incoming.RoomRemoveAllRightsEvent, RoomRemoveAllRightsEvent.class); + this.registerHandler(Incoming.RoomUserRemoveRightsEvent, RoomUserRemoveRightsEvent.class); + this.registerHandler(Incoming.BotPlaceEvent, BotPlaceEvent.class); + this.registerHandler(Incoming.BotPickupEvent, BotPickupEvent.class); + this.registerHandler(Incoming.BotSaveSettingsEvent, BotSaveSettingsEvent.class); + this.registerHandler(Incoming.BotSettingsEvent, BotSettingsEvent.class); + this.registerHandler(Incoming.TriggerDiceEvent, TriggerDiceEvent.class); + this.registerHandler(Incoming.CloseDiceEvent, CloseDiceEvent.class); + this.registerHandler(Incoming.TriggerColorWheelEvent, TriggerColorWheelEvent.class); + this.registerHandler(Incoming.RedeemItemEvent, RedeemItemEvent.class); + this.registerHandler(Incoming.PetPlaceEvent, PetPlaceEvent.class); + this.registerHandler(Incoming.RoomUserKickEvent, RoomUserKickEvent.class); + this.registerHandler(Incoming.SetStackHelperHeightEvent, SetStackHelperHeightEvent.class); + this.registerHandler(Incoming.TriggerOneWayGateEvent, TriggerOneWayGateEvent.class); + this.registerHandler(Incoming.HandleDoorbellEvent, HandleDoorbellEvent.class); + this.registerHandler(Incoming.RedeemClothingEvent, RedeemClothingEvent.class); + this.registerHandler(Incoming.PostItPlaceEvent, PostItPlaceEvent.class); + this.registerHandler(Incoming.PostItRequestDataEvent, PostItRequestDataEvent.class); + this.registerHandler(Incoming.PostItSaveDataEvent, PostItSaveDataEvent.class); + this.registerHandler(Incoming.PostItDeleteEvent, PostItDeleteEvent.class); + this.registerHandler(Incoming.MoodLightSaveSettingsEvent, MoodLightSaveSettingsEvent.class); + this.registerHandler(Incoming.RentSpaceEvent, RentSpaceEvent.class); + this.registerHandler(Incoming.RentSpaceCancelEvent, RentSpaceCancelEvent.class); + this.registerHandler(Incoming.SetHomeRoomEvent, SetHomeRoomEvent.class); + this.registerHandler(Incoming.RoomUserGiveHandItemEvent, RoomUserGiveHandItemEvent.class); + this.registerHandler(Incoming.RoomMuteEvent, RoomMuteEvent.class); + this.registerHandler(Incoming.RequestRoomWordFilterEvent, RequestRoomWordFilterEvent.class); + this.registerHandler(Incoming.RoomWordFilterModifyEvent, RoomWordFilterModifyEvent.class); + this.registerHandler(Incoming.RoomStaffPickEvent, RoomStaffPickEvent.class); + this.registerHandler(Incoming.RoomRequestBannedUsersEvent, RoomRequestBannedUsersEvent.class); + this.registerHandler(Incoming.JukeBoxRequestTrackCodeEvent, JukeBoxRequestTrackCodeEvent.class); + this.registerHandler(Incoming.JukeBoxRequestTrackDataEvent, JukeBoxRequestTrackDataEvent.class); + this.registerHandler(Incoming.JukeBoxAddSoundTrackEvent, JukeBoxAddSoundTrackEvent.class); + this.registerHandler(Incoming.JukeBoxRemoveSoundTrackEvent, JukeBoxRemoveSoundTrackEvent.class); + this.registerHandler(Incoming.JukeBoxRequestPlayListEvent, JukeBoxRequestPlayListEvent.class); + this.registerHandler(Incoming.JukeBoxEventOne, JukeBoxEventOne.class); + this.registerHandler(Incoming.JukeBoxEventTwo, JukeBoxEventTwo.class); + this.registerHandler(Incoming.SavePostItStickyPoleEvent, SavePostItStickyPoleEvent.class); + this.registerHandler(Incoming.RequestPromotionRoomsEvent, RequestPromotionRoomsEvent.class); + this.registerHandler(Incoming.BuyRoomPromotionEvent, BuyRoomPromotionEvent.class); + this.registerHandler(Incoming.EditRoomPromotionMessageEvent, UpdateRoomPromotionEvent.class); + this.registerHandler(Incoming.IgnoreRoomUserEvent, IgnoreRoomUserEvent.class); + this.registerHandler(Incoming.UnIgnoreRoomUserEvent, UnIgnoreRoomUserEvent.class); + this.registerHandler(Incoming.RoomUserMuteEvent, RoomUserMuteEvent.class); + this.registerHandler(Incoming.RoomUserBanEvent, RoomUserBanEvent.class); + this.registerHandler(Incoming.UnbanRoomUserEvent, UnbanRoomUserEvent.class); + this.registerHandler(Incoming.RequestRoomUserTagsEvent, RequestRoomUserTagsEvent.class); + this.registerHandler(Incoming.YoutubeRequestPlaylists, YoutubeRequestPlaylists.class); + this.registerHandler(Incoming.YoutubeRequestStateChange, YoutubeRequestStateChange.class); + this.registerHandler(Incoming.YoutubeRequestPlaylistChange, YoutubeRequestPlaylistChange.class); + this.registerHandler(Incoming.RoomFavoriteEvent, RoomFavoriteEvent.class); + this.registerHandler(Incoming.LoveLockStartConfirmEvent, LoveLockStartConfirmEvent.class); + this.registerHandler(Incoming.RoomUnFavoriteEvent, RoomUnFavoriteEvent.class); + this.registerHandler(Incoming.UseRandomStateItemEvent, UseRandomStateItemEvent.class); + } + + void registerPolls() throws Exception { + this.registerHandler(Incoming.CancelPollEvent, CancelPollEvent.class); + this.registerHandler(Incoming.GetPollDataEvent, GetPollDataEvent.class); + this.registerHandler(Incoming.AnswerPollEvent, AnswerPollEvent.class); + } + + void registerModTool() throws Exception { + this.registerHandler(Incoming.ModToolRequestRoomInfoEvent, ModToolRequestRoomInfoEvent.class); + this.registerHandler(Incoming.ModToolRequestRoomChatlogEvent, ModToolRequestRoomChatlogEvent.class); + this.registerHandler(Incoming.ModToolRequestUserInfoEvent, ModToolRequestUserInfoEvent.class); + this.registerHandler(Incoming.ModToolPickTicketEvent, ModToolPickTicketEvent.class); + this.registerHandler(Incoming.ModToolCloseTicketEvent, ModToolCloseTicketEvent.class); + this.registerHandler(Incoming.ModToolReleaseTicketEvent, ModToolReleaseTicketEvent.class); + this.registerHandler(Incoming.ModToolAlertEvent, ModToolAlertEvent.class); + this.registerHandler(Incoming.ModToolWarnEvent, ModToolWarnEvent.class); + this.registerHandler(Incoming.ModToolKickEvent, ModToolKickEvent.class); + this.registerHandler(Incoming.ModToolRoomAlertEvent, ModToolRoomAlertEvent.class); + this.registerHandler(Incoming.ModToolChangeRoomSettingsEvent, ModToolChangeRoomSettingsEvent.class); + this.registerHandler(Incoming.ModToolRequestRoomVisitsEvent, ModToolRequestRoomVisitsEvent.class); + this.registerHandler(Incoming.ModToolRequestIssueChatlogEvent, ModToolRequestIssueChatlogEvent.class); + this.registerHandler(Incoming.ModToolRequestRoomUserChatlogEvent, ModToolRequestRoomUserChatlogEvent.class); + this.registerHandler(Incoming.ModToolRequestUserChatlogEvent, ModToolRequestUserChatlogEvent.class); + this.registerHandler(Incoming.ModToolSanctionAlertEvent, ModToolSanctionAlertEvent.class); + this.registerHandler(Incoming.ModToolSanctionMuteEvent, ModToolSanctionMuteEvent.class); + this.registerHandler(Incoming.ModToolSanctionBanEvent, ModToolSanctionBanEvent.class); + this.registerHandler(Incoming.ModToolSanctionTradeLockEvent, ModToolSanctionTradeLockEvent.class); + this.registerHandler(Incoming.ModToolIssueChangeTopicEvent, ModToolIssueChangeTopicEvent.class); + this.registerHandler(Incoming.ModToolIssueDefaultSanctionEvent, ModToolIssueDefaultSanctionEvent.class); + + this.registerHandler(Incoming.RequestReportRoomEvent, RequestReportRoomEvent.class); + this.registerHandler(Incoming.RequestReportUserBullyingEvent, RequestReportUserBullyingEvent.class); + this.registerHandler(Incoming.ReportBullyEvent, ReportBullyEvent.class); + this.registerHandler(Incoming.ReportEvent, ReportEvent.class); + this.registerHandler(Incoming.ReportFriendPrivateChatEvent, ReportFriendPrivateChatEvent.class); + this.registerHandler(Incoming.ReportThreadEvent, ReportThreadEvent.class); + this.registerHandler(Incoming.ReportCommentEvent, ReportCommentEvent.class); + this.registerHandler(Incoming.ReportPhotoEvent, ReportPhotoEvent.class); + } + + void registerTrading() throws Exception { + this.registerHandler(Incoming.TradeStartEvent, TradeStartEvent.class); + this.registerHandler(Incoming.TradeOfferItemEvent, TradeOfferItemEvent.class); + this.registerHandler(Incoming.TradeOfferMultipleItemsEvent, TradeOfferMultipleItemsEvent.class); + this.registerHandler(Incoming.TradeCancelOfferItemEvent, TradeCancelOfferItemEvent.class); + this.registerHandler(Incoming.TradeAcceptEvent, TradeAcceptEvent.class); + this.registerHandler(Incoming.TradeUnAcceptEvent, TradeUnAcceptEvent.class); + this.registerHandler(Incoming.TradeConfirmEvent, TradeConfirmEvent.class); + this.registerHandler(Incoming.TradeCloseEvent, TradeCloseEvent.class); + this.registerHandler(Incoming.TradeCancelEvent, TradeCancelEvent.class); + } + + void registerGuilds() throws Exception { + this.registerHandler(Incoming.RequestGuildBuyRoomsEvent, RequestGuildBuyRoomsEvent.class); + this.registerHandler(Incoming.RequestGuildPartsEvent, RequestGuildPartsEvent.class); + this.registerHandler(Incoming.RequestGuildBuyEvent, RequestGuildBuyEvent.class); + this.registerHandler(Incoming.RequestGuildInfoEvent, RequestGuildInfoEvent.class); + this.registerHandler(Incoming.RequestGuildManageEvent, RequestGuildManageEvent.class); + this.registerHandler(Incoming.RequestGuildMembersEvent, RequestGuildMembersEvent.class); + this.registerHandler(Incoming.RequestGuildJoinEvent, RequestGuildJoinEvent.class); + this.registerHandler(Incoming.GuildChangeNameDescEvent, GuildChangeNameDescEvent.class); + this.registerHandler(Incoming.GuildChangeBadgeEvent, GuildChangeBadgeEvent.class); + this.registerHandler(Incoming.GuildChangeColorsEvent, GuildChangeColorsEvent.class); + this.registerHandler(Incoming.GuildRemoveAdminEvent, GuildRemoveAdminEvent.class); + this.registerHandler(Incoming.GuildRemoveMemberEvent, GuildRemoveMemberEvent.class); + this.registerHandler(Incoming.GuildChangeSettingsEvent, GuildChangeSettingsEvent.class); + this.registerHandler(Incoming.GuildAcceptMembershipEvent, GuildAcceptMembershipEvent.class); + this.registerHandler(Incoming.GuildDeclineMembershipEvent, GuildDeclineMembershipEvent.class); + this.registerHandler(Incoming.GuildSetAdminEvent, GuildSetAdminEvent.class); + this.registerHandler(Incoming.GuildSetFavoriteEvent, GuildSetFavoriteEvent.class); + this.registerHandler(Incoming.RequestOwnGuildsEvent, RequestOwnGuildsEvent.class); + this.registerHandler(Incoming.RequestGuildFurniWidgetEvent, RequestGuildFurniWidgetEvent.class); + this.registerHandler(Incoming.GuildConfirmRemoveMemberEvent, GuildConfirmRemoveMemberEvent.class); + this.registerHandler(Incoming.GuildRemoveFavoriteEvent, GuildRemoveFavoriteEvent.class); + this.registerHandler(Incoming.GuildDeleteEvent, GuildDeleteEvent.class); + this.registerHandler(Incoming.GuildForumListEvent, GuildForumListEvent.class); + this.registerHandler(Incoming.GuildForumThreadsEvent, GuildForumThreadsEvent.class); + this.registerHandler(Incoming.GuildForumDataEvent, GuildForumDataEvent.class); + this.registerHandler(Incoming.GuildForumPostThreadEvent, GuildForumPostThreadEvent.class); + this.registerHandler(Incoming.GuildForumUpdateSettingsEvent, GuildForumUpdateSettingsEvent.class); + this.registerHandler(Incoming.GuildForumThreadsMessagesEvent, GuildForumThreadsMessagesEvent.class); + this.registerHandler(Incoming.GuildForumModerateMessageEvent, GuildForumModerateMessageEvent.class); + this.registerHandler(Incoming.GuildForumModerateThreadEvent, GuildForumModerateThreadEvent.class); + this.registerHandler(Incoming.GuildForumThreadUpdateEvent, GuildForumThreadUpdateEvent.class); + this.registerHandler(Incoming.GetHabboGuildBadgesMessageEvent, GetHabboGuildBadgesMessageEvent.class); + +// this.registerHandler(Incoming.GuildForumDataEvent, GuildForumModerateMessageEvent.class); +// this.registerHandler(Incoming.GuildForumDataEvent, GuildForumModerateThreadEvent.class); +// this.registerHandler(Incoming.GuildForumDataEvent, GuildForumPostThreadEvent.class); +// this.registerHandler(Incoming.GuildForumDataEvent, GuildForumThreadsEvent.class); +// this.registerHandler(Incoming.GuildForumDataEvent, GuildForumThreadsMessagesEvent.class); +// this.registerHandler(Incoming.GuildForumDataEvent, GuildForumUpdateSettingsEvent.class); + } + + void registerPets() throws Exception { + this.registerHandler(Incoming.RequestPetInformationEvent, RequestPetInformationEvent.class); + this.registerHandler(Incoming.PetPickupEvent, PetPickupEvent.class); + this.registerHandler(Incoming.ScratchPetEvent, ScratchPetEvent.class); + this.registerHandler(Incoming.RequestPetTrainingPanelEvent, RequestPetTrainingPanelEvent.class); + this.registerHandler(Incoming.PetUseItemEvent, PetUseItemEvent.class); + this.registerHandler(Incoming.HorseRideSettingsEvent, PetRideSettingsEvent.class); + this.registerHandler(Incoming.HorseRideEvent, PetRideEvent.class); + this.registerHandler(Incoming.HorseRemoveSaddleEvent, HorseRemoveSaddleEvent.class); + this.registerHandler(Incoming.ToggleMonsterplantBreedableEvent, ToggleMonsterplantBreedableEvent.class); + this.registerHandler(Incoming.CompostMonsterplantEvent, CompostMonsterplantEvent.class); + this.registerHandler(Incoming.BreedMonsterplantsEvent, BreedMonsterplantsEvent.class); + this.registerHandler(Incoming.MovePetEvent, MovePetEvent.class); + this.registerHandler(Incoming.PetPackageNameEvent, PetPackageNameEvent.class); + this.registerHandler(Incoming.StopBreedingEvent, StopBreedingEvent.class); + this.registerHandler(Incoming.ConfirmPetBreedingEvent, ConfirmPetBreedingEvent.class); + } + + void registerWired() throws Exception { + this.registerHandler(Incoming.WiredTriggerSaveDataEvent, WiredTriggerSaveDataEvent.class); + this.registerHandler(Incoming.WiredEffectSaveDataEvent, WiredEffectSaveDataEvent.class); + this.registerHandler(Incoming.WiredConditionSaveDataEvent, WiredConditionSaveDataEvent.class); + this.registerHandler(Incoming.WiredApplySetConditionsEvent, WiredApplySetConditionsEvent.class); + } + + void registerUnknown() throws Exception { + this.registerHandler(Incoming.RequestResolutionEvent, RequestResolutionEvent.class); + this.registerHandler(Incoming.RequestTalenTrackEvent, RequestTalentTrackEvent.class); + this.registerHandler(Incoming.UnknownEvent1, UnknownEvent1.class); + this.registerHandler(Incoming.MySanctionStatusEvent, MySanctionStatusEvent.class); + } + + void registerFloorPlanEditor() throws Exception { + this.registerHandler(Incoming.FloorPlanEditorSaveEvent, FloorPlanEditorSaveEvent.class); + this.registerHandler(Incoming.FloorPlanEditorRequestBlockedTilesEvent, FloorPlanEditorRequestBlockedTilesEvent.class); + this.registerHandler(Incoming.FloorPlanEditorRequestDoorSettingsEvent, FloorPlanEditorRequestDoorSettingsEvent.class); + } + + void registerAchievements() throws Exception { + this.registerHandler(Incoming.RequestAchievementsEvent, RequestAchievementsEvent.class); + this.registerHandler(Incoming.RequestAchievementConfigurationEvent, RequestAchievementConfigurationEvent.class); + } + + void registerGuides() throws Exception { + this.registerHandler(Incoming.RequestGuideToolEvent, RequestGuideToolEvent.class); + this.registerHandler(Incoming.RequestGuideAssistanceEvent, RequestGuideAssistanceEvent.class); + this.registerHandler(Incoming.GuideUserTypingEvent, GuideUserTypingEvent.class); + this.registerHandler(Incoming.GuideReportHelperEvent, GuideReportHelperEvent.class); + this.registerHandler(Incoming.GuideRecommendHelperEvent, GuideRecommendHelperEvent.class); + this.registerHandler(Incoming.GuideUserMessageEvent, GuideUserMessageEvent.class); + this.registerHandler(Incoming.GuideCancelHelpRequestEvent, GuideCancelHelpRequestEvent.class); + this.registerHandler(Incoming.GuideHandleHelpRequestEvent, GuideHandleHelpRequestEvent.class); + this.registerHandler(Incoming.GuideInviteUserEvent, GuideInviteUserEvent.class); + this.registerHandler(Incoming.GuideVisitUserEvent, GuideVisitUserEvent.class); + this.registerHandler(Incoming.GuideCloseHelpRequestEvent, GuideCloseHelpRequestEvent.class); + + this.registerHandler(Incoming.GuardianNoUpdatesWantedEvent, GuardianNoUpdatesWantedEvent.class); + this.registerHandler(Incoming.GuardianAcceptRequestEvent, GuardianAcceptRequestEvent.class); + this.registerHandler(Incoming.GuardianVoteEvent, GuardianVoteEvent.class); + } + + void registerCrafting() throws Exception { + this.registerHandler(Incoming.RequestCraftingRecipesEvent, RequestCraftingRecipesEvent.class); + this.registerHandler(Incoming.CraftingAddRecipeEvent, CraftingAddRecipeEvent.class); + this.registerHandler(Incoming.CraftingCraftItemEvent, CraftingCraftItemEvent.class); + this.registerHandler(Incoming.CraftingCraftSecretEvent, CraftingCraftSecretEvent.class); + this.registerHandler(Incoming.RequestCraftingRecipesAvailableEvent, RequestCraftingRecipesAvailableEvent.class); + } + + void registerCamera() throws Exception { + this.registerHandler(Incoming.CameraRoomPictureEvent, CameraRoomPictureEvent.class); + this.registerHandler(Incoming.RequestCameraConfigurationEvent, RequestCameraConfigurationEvent.class); + this.registerHandler(Incoming.CameraPurchaseEvent, CameraPurchaseEvent.class); + this.registerHandler(Incoming.CameraRoomThumbnailEvent, CameraRoomThumbnailEvent.class); + this.registerHandler(Incoming.CameraPublishToWebEvent, CameraPublishToWebEvent.class); + } + + void registerGameCenter() throws Exception { + this.registerHandler(Incoming.GameCenterRequestGamesEvent, GameCenterRequestGamesEvent.class); + this.registerHandler(Incoming.GameCenterRequestAccountStatusEvent, GameCenterRequestAccountStatusEvent.class); + this.registerHandler(Incoming.GameCenterJoinGameEvent, GameCenterJoinGameEvent.class); + this.registerHandler(Incoming.GameCenterLoadGameEvent, GameCenterLoadGameEvent.class); + this.registerHandler(Incoming.GameCenterLeaveGameEvent, GameCenterLeaveGameEvent.class); + this.registerHandler(Incoming.GameCenterEvent, GameCenterEvent.class); + this.registerHandler(Incoming.GameCenterRequestGameStatusEvent, GameCenterRequestGameStatusEvent.class); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/PacketNames.java b/Emulator/src/main/java/com/eu/habbo/messages/PacketNames.java new file mode 100644 index 0000000..d493c15 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/PacketNames.java @@ -0,0 +1,54 @@ +package com.eu.habbo.messages; + +import com.eu.habbo.messages.incoming.Incoming; +import com.eu.habbo.messages.outgoing.Outgoing; +import lombok.extern.slf4j.Slf4j; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.HashMap; + +@Slf4j +public class PacketNames { + private final HashMap incoming; + private final HashMap outgoing; + + public PacketNames() { + this.incoming = new HashMap<>(); + this.outgoing = new HashMap<>(); + } + + public void initialize() { + PacketNames.getNames(Incoming.class, this.incoming); + PacketNames.getNames(Outgoing.class, this.outgoing); + } + + public String getIncomingName(int key) { + return this.incoming.getOrDefault(key, "Unknown"); + } + + public String getOutgoingName(int key) { + return this.outgoing.getOrDefault(key, "Unknown"); + } + + private static void getNames(Class clazz, HashMap target) { + for (Field field : clazz.getFields()) { + int modifiers = field.getModifiers(); + if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers) && field.getType() == int.class) { + try { + int packetId = field.getInt(null); + if (packetId > 0) { + if (target.containsKey(packetId)) { + log.warn("Duplicate packet id found {} for {}.", packetId, clazz.getSimpleName()); + continue; + } + + target.put(packetId, field.getName()); + } + } catch (IllegalAccessException e) { + log.error("Failed to read field integer.", e); + } + } + } + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/ServerMessage.java b/Emulator/src/main/java/com/eu/habbo/messages/ServerMessage.java new file mode 100644 index 0000000..91f5245 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/ServerMessage.java @@ -0,0 +1,188 @@ +package com.eu.habbo.messages; + +import com.eu.habbo.util.PacketUtils; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufOutputStream; +import io.netty.buffer.Unpooled; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.concurrent.atomic.AtomicInteger; + +public class ServerMessage { + + private static final Logger LOGGER = LoggerFactory.getLogger(ServerMessage.class); + private boolean initialized; + + private int header; + private AtomicInteger refs; + private ByteBufOutputStream stream; + private ByteBuf channelBuffer; + + public ServerMessage() { + + } + + public ServerMessage(int header) { + this.init(header); + } + + public ServerMessage init(int id) { + if (this.initialized) { + throw new ServerMessageException("ServerMessage was already initialized."); + } + + this.initialized = true; + this.header = id; + this.refs = new AtomicInteger(0); + this.channelBuffer = Unpooled.buffer(); + this.stream = new ByteBufOutputStream(this.channelBuffer); + + try { + this.stream.writeInt(0); + this.stream.writeShort(id); + } catch (IOException e) { + throw new ServerMessageException(e); + } + + return this; + } + + public void appendRawBytes(byte[] bytes) { + try { + this.stream.write(bytes); + } catch (IOException e) { + throw new ServerMessageException(e); + } + } + + public void appendString(String obj) { + if (obj == null) { + this.appendString(""); + return; + } + + try { + byte[] data = obj.getBytes(); + this.stream.writeShort(data.length); + this.stream.write(data); + } catch (IOException e) { + throw new ServerMessageException(e); + } + } + + public void appendChar(int obj) { + try { + this.stream.writeChar(obj); + } catch (IOException e) { + throw new ServerMessageException(e); + } + } + + public void appendChars(Object obj) { + try { + this.stream.writeChars(obj.toString()); + } catch (IOException e) { + throw new ServerMessageException(e); + } + } + + public void appendInt(Integer obj) { + try { + this.stream.writeInt(obj); + } catch (IOException e) { + throw new ServerMessageException(e); + } + } + + public void appendInt(Short obj) { + this.appendShort(0); + this.appendShort(obj); + } + + public void appendInt(Byte obj) { + try { + this.stream.writeInt((int) obj); + } catch (IOException e) { + throw new ServerMessageException(e); + } + } + + public void appendInt(Boolean obj) { + try { + this.stream.writeInt(obj ? 1 : 0); + } catch (IOException e) { + throw new ServerMessageException(e); + } + } + + public void appendShort(int obj) { + try { + this.stream.writeShort((short) obj); + } catch (IOException e) { + throw new ServerMessageException(e); + } + } + + public void appendByte(Integer b) { + try { + this.stream.writeByte(b); + } catch (IOException e) { + throw new ServerMessageException(e); + } + } + + public void appendBoolean(Boolean obj) { + try { + this.stream.writeBoolean(obj); + } catch (IOException e) { + throw new ServerMessageException(e); + } + } + + public void appendDouble(double d) { + try { + this.stream.writeDouble(d); + } catch (IOException e) { + throw new ServerMessageException(e); + } + } + + public void appendDouble(Double obj) { + try { + this.stream.writeDouble(obj); + } catch (IOException e) { + throw new ServerMessageException(e); + } + } + + public ServerMessage appendResponse(ServerMessage obj) { + try { + this.stream.write(obj.get().array()); + } catch (IOException e) { + throw new ServerMessageException(e); + } + + return this; + } + + public void append(ISerialize obj) { + obj.serialize(this); + } + + public String getBodyString() { + return PacketUtils.formatPacket(this.channelBuffer); + } + + public int getHeader() { + return this.header; + } + + public ByteBuf get() { + this.channelBuffer.setInt(0, this.channelBuffer.writerIndex() - 4); + + return this.channelBuffer.copy(); + } + +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/ServerMessageException.java b/Emulator/src/main/java/com/eu/habbo/messages/ServerMessageException.java new file mode 100644 index 0000000..17e5ecb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/ServerMessageException.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages; + +public class ServerMessageException extends RuntimeException { + + public ServerMessageException() { + } + + public ServerMessageException(String message) { + super(message); + } + + public ServerMessageException(String message, Throwable cause) { + super(message, cause); + } + + public ServerMessageException(Throwable cause) { + super(cause); + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/Incoming.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/Incoming.java new file mode 100644 index 0000000..2bc223f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/Incoming.java @@ -0,0 +1,408 @@ +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; + public static final int EnableEffectEvent = 1752; + public static final int UserActivityEvent = 3457; + public static final int NavigatorCategoryListModeEvent = 1202; + public static final int NavigatorCollapseCategoryEvent = 1834; + public static final int NavigatorUncollapseCategoryEvent = 637; + public static final int PickNewUserGiftEvent = 1822; + public static final int FootballGateSaveLookEvent = 924; + public static final int MannequinSaveLookEvent = 2209; + public static final int RequestCatalogPageEvent = 412; + public static final int RequestWearingBadgesEvent = 2091; + public static final int BotPickupEvent = 3323; + public static final int HorseRideEvent = 1036; + public static final int RequestCreateRoomEvent = 2752; + public static final int SaveMottoEvent = 2228; + public static final int ModToolAlertEvent = 1840; + public static final int TradeAcceptEvent = 3863; + public static final int RequestCatalogModeEvent = 1195; + public static final int RequestUserCreditsEvent = 273; + public static final int FriendListUpdateEvent = 1419; + public static final int FriendPrivateMessageEvent = 3567; + public static final int CloseDiceEvent = 1533; + public static final int RoomUserRemoveRightsEvent = 2064; + public static final int RoomRemoveRightsEvent = 3182; + public static final int GuildDeclineMembershipEvent = 1894; + public static final int AnswerPollEvent = 3505; + public static final int UserWearBadgeEvent = 644; + public static final int RoomVoteEvent = 3582; + public static final int RoomUserSignEvent = 1975; + public static final int RequestUserDataEvent = 357; + public static final int RoomUserShoutEvent = 2085; + public static final int ScratchPetEvent = 3202; + public static final int RoomUserWalkEvent = 3320; + public static final int RequestTagsEvent = 826; + public static final int GetMarketplaceConfigEvent = 2597; + public static final int RequestHeightmapEvent = 3898; + public static final int TradeCloseEvent = 2551; + public static final int CatalogBuyItemEvent = 3492; + public static final int CatalogSelectClubGiftEvent = 2276; + public static final int CatalogRequestClubDiscountEvent = 2462; + public static final int CatalogBuyClubDiscountEvent = 3407; + public static final int RequestGuildMembersEvent = 312; + public static final int RequestPetInformationEvent = 2934; + public static final int RoomUserWhisperEvent = 1543; + public static final int ModToolRequestUserInfoEvent = 3295; + public static final int RotateMoveItemEvent = 248; + public static final int CancelPollEvent = 1773; + public static final int RequestRoomLoadEvent = 2312; + public static final int RequestGuildPartsEvent = 813; + public static final int RoomPlacePaintEvent = 711; + public static final int RequestPopularRoomsEvent = 2758; + public static final int ModToolRequestRoomInfoEvent = 707; + public static final int FriendRequestEvent = 3157; + public static final int RecycleEvent = 2771; + public static final int RequestRoomCategoriesEvent = 3027; //1371; + public static final int ToggleWallItemEvent = 210; + public static final int RoomUserTalkEvent = 1314; + public static final int HotelViewDataEvent = 2912; + public static final int RoomUserDanceEvent = 2080; + public static final int RequestUserProfileEvent = 3265; + public static final int SearchRoomsFriendsNowEvent = 1786; + public static final int SetStackHelperHeightEvent = 3839; + public static final int RedeemVoucherEvent = 339; + public static final int PetUseItemEvent = 1328; + public static final int HorseRemoveSaddleEvent = 186; + public static final int BuyItemEvent = 1603; + public static final int AdvertisingSaveEvent = 3608; + public static final int RequestPetTrainingPanelEvent = 2161; + public static final int RoomBackgroundEvent = 2880; + public static final int RequestNewsListEvent = 1827; + public static final int RequestPromotedRoomsEvent = 2908; + public static final int GuildSetAdminEvent = 2894; + public static final int GetClubDataEvent = 3285; + public static final int RequestClubCenterEvent = 869; + public static final int RequestMeMenuSettingsEvent = 2388; + public static final int MannequinSaveNameEvent = 2850; + public static final int SellItemEvent = 3447; + public static final int GuildAcceptMembershipEvent = 3386; + public static final int RequestRecylerLogicEvent = 398; + public static final int RequestGuildJoinEvent = 998; + public static final int RequestCatalogIndexEvent = 2529; + public static final int RequestInventoryPetsEvent = 3095; + public static final int ModToolRequestRoomVisitsEvent = 3526; + public static final int ModToolWarnEvent = -1;//3763 + public static final int RequestItemInfoEvent = 3288; + public static final int ModToolRequestRoomChatlogEvent = 2587; + public static final int UserSaveLookEvent = 2730; + public static final int ToggleFloorItemEvent = 99; + public static final int TradeUnAcceptEvent = 1444; + public static final int WiredTriggerSaveDataEvent = 1520; + public static final int RoomRemoveAllRightsEvent = 2683; + public static final int TakeBackItemEvent = 434; + public static final int OpenRecycleBoxEvent = 3558; + public static final int GuildChangeNameDescEvent = 3137; + public static final int RequestSellItemEvent = 848; + public static final int ModToolChangeRoomSettingsEvent = 3260; + public static final int ModToolRequestUserChatlogEvent = 1391;//203 + public static final int GuildChangeSettingsEvent = 3435; + public static final int RoomUserDropHandItemEvent = 2814; + public static final int RequestProfileFriendsEvent = 2138; + public static final int TradeCancelOfferItemEvent = 3845; + public static final int TriggerDiceEvent = 1990; + public static final int GetPollDataEvent = 109; + public static final int MachineIDEvent = 2490; + public static final int RequestDiscountEvent = 223; + public static final int RequestFriendRequestEvent = 2448; + public static final int RoomSettingsSaveEvent = 1969; + public static final int AcceptFriendRequest = 137; + public static final int DeclineFriendRequest = 2890; //835; //TODO + public static final int ReleaseVersionEvent = 4000;//4000 + public static final int InitDiffieHandshake = 3110; + public static final int CompleteDiffieHandshake = 773; + public static final int SearchRoomsMyFavoriteEvent = 2578; + public static final int TradeStartEvent = 1481; + public static final int RequestTargetOfferEvent = 2487; + public static final int ChangeRelationEvent = 3768; + public static final int RoomUserSitEvent = 2235; + public static final int RequestCanCreateRoomEvent = 2128; + public static final int ModToolKickEvent = 2582; + public static final int MoveWallItemEvent = 168; + public static final int SearchRoomsEvent = 3943; + public static final int RequestHighestScoreRoomsEvent = 2939; + public static final int CatalogBuyItemAsGiftEvent = 1411; + public static final int RoomUserGiveRespectEvent = 2694; + public static final int RemoveFriendEvent = 1689; + public static final int SearchRoomsFriendsOwnEvent = 2266; + public static final int GuildSetFavoriteEvent = 3549; + public static final int PetPlaceEvent = 2647; + public static final int BotSettingsEvent = 1986; + public static final int StalkFriendEvent = 3997; + public static final int RoomPickupItemEvent = 3456; + public static final int RedeemItemEvent = 3115; + public static final int RequestFriendsEvent = 1523; + public static final int RequestAchievementsEvent = 219; + public static final int GuildChangeColorsEvent = 1764; + public static final int RequestInventoryBadgesEvent = 2769; + + public static final int RequestInventoryItemsDelete = 10018; + public static final int HotelViewInventoryEvent = 3500; + public static final int RequestPetBreedsEvent = 1756; + public static final int GuildChangeBadgeEvent = 1991; + public static final int ModToolBanEvent = -1; + public static final int SaveWardrobeEvent = 800; + public static final int HotelViewEvent = 105; + public static final int ModToolPickTicketEvent = 15; + public static final int ModToolReleaseTicketEvent = 1572; + public static final int ModToolCloseTicketEvent = 2067; + public static final int TriggerColorWheelEvent = 2144; + public static final int SearchRoomsByTagEvent = -1;//1956 + public static final int RequestPublicRoomsEvent = 1229; + public static final int RequestResolutionEvent = 359; + public static final int RequestInventoryItemsEvent = 3150; + public static final int ModToolRoomAlertEvent = 3842; + public static final int WiredEffectSaveDataEvent = 2281; + public static final int WiredApplySetConditionsEvent = 3373; + public static final int CheckPetNameEvent = 2109; + public static final int SecureLoginEvent = 2419; + public static final int BotSaveSettingsEvent = 2624; + public static final int RequestGuildBuyEvent = 230; + public static final int SearchUserEvent = 1210; + public static final int GuildConfirmRemoveMemberEvent = 3593; + public static final int GuildRemoveMemberEvent = 593; + public static final int WiredConditionSaveDataEvent = 3203; + public static final int RoomUserLookAtPoint = 3301; + public static final int MoodLightTurnOnEvent = 2296; + public static final int MoodLightSettingsEvent = 2813; + public static final int RequestMyRoomsEvent = 2277; + public static final int RequestCreditsEvent = 2650; + public static final int SearchRoomsInGroupEvent = 39; + public static final int HorseRideSettingsEvent = 1472; + public static final int HandleDoorbellEvent = 1644; + public static final int RoomUserKickEvent = 1320; + public static final int RoomPlaceItemEvent = 1258; + public static final int RequestInventoryBotsEvent = 3848; + public static final int RequestUserWardrobeEvent = 2742; + public static final int RequestRoomRightsEvent = 3385; + public static final int RequestGuildBuyRoomsEvent = 798; + public static final int BotPlaceEvent = 1592; + public static final int SearchRoomsWithRightsEvent = 272; + public static final int HotelViewRequestBonusRareEvent = 957; + public static final int GuildRemoveAdminEvent = 722; + public static final int RequestRoomSettingsEvent = 3129; + public static final int RequestOffersEvent = 2407; + public static final int RequestUserCitizinShipEvent = 2127; + public static final int RoomUserStopTypingEvent = 1474; + public static final int RoomUserStartTypingEvent = 1597; + public static final int RequestGuildManageEvent = 1004; + public static final int RequestUserClubEvent = 3166; + public static final int PetPickupEvent = 1581; + public static final int RequestOwnGuildsEvent = 367; + public static final int SearchRoomsVisitedEvent = 2264; + public static final int TradeOfferItemEvent = 3107; + public static final int TradeOfferMultipleItemsEvent = 1263; + public static final int TradeConfirmEvent = 2760; + public static final int RoomUserGiveRightsEvent = 808; + public static final int RequestGuildInfoEvent = 2991; + public static final int ReloadRecyclerEvent = 1342; + public static final int RoomUserActionEvent = 2456; + public static final int RequestGiftConfigurationEvent = 418; + public static final int RequestRoomDataEvent = 2230; + public static final int RequestRoomHeightmapEvent = 2300; + public static final int RequestGuildFurniWidgetEvent = 2651; + public static final int RequestOwnItemsEvent = 2105; + public static final int RequestReportRoomEvent = 3267; + public static final int ReportEvent = 1691; + public static final int TriggerOneWayGateEvent = 2765; + public static final int FloorPlanEditorSaveEvent = 875; + public static final int FloorPlanEditorRequestDoorSettingsEvent = 3559; + public static final int FloorPlanEditorRequestBlockedTilesEvent = 1687; + public static final int UnknownEvent1 = 1371; + public static final int RequestTalenTrackEvent = 196; + public static final int RequestNewNavigatorDataEvent = 2110; + public static final int RequestNewNavigatorRoomsEvent = 249; + public static final int RedeemClothingEvent = 3374; + public static final int NewNavigatorActionEvent = 1703; + public static final int PostItPlaceEvent = 2248; + public static final int PostItRequestDataEvent = 3964; + public static final int PostItSaveDataEvent = 3666; + public static final int PostItDeleteEvent = 3336; + public static final int UseRandomStateItemEvent = 3617; + + public static final int MySanctionStatusEvent = 2746; + + public static final int MoodLightSaveSettingsEvent = 1648; + public static final int ModToolRequestIssueChatlogEvent = 211; + public static final int ModToolRequestRoomUserChatlogEvent = -1; + public static final int UsernameEvent = 3878; + public static final int RequestClubGiftsEvent = 487; + public static final int RentSpaceEvent = 2946; + public static final int RentSpaceCancelEvent = 1667; + public static final int RequestInitFriendsEvent = 2781; + public static final int RequestCameraConfigurationEvent = 796; + public static final int PingEvent = 295; + public static final int FindNewFriendsEvent = 516; + public static final int InviteFriendsEvent = 1276; + public static final int GuildRemoveFavoriteEvent = 1820; + public static final int GuildDeleteEvent = 1134; + public static final int SetHomeRoomEvent = 1740; + public static final int RoomUserGiveHandItemEvent = 2941; + public static final int AmbassadorVisitCommandEvent = 2970; + public static final int AmbassadorAlertCommandEvent = 2996; + public static final int SaveUserVolumesEvent = 1367; + public static final int SavePreferOldChatEvent = 1262; + public static final int SaveIgnoreRoomInvitesEvent = 1086; + public static final int SaveBlockCameraFollowEvent = 1461; + public static final int RoomMuteEvent = 3637; + public static final int RequestRoomWordFilterEvent = 1911; + public static final int RoomWordFilterModifyEvent = 3001; + public static final int RequestRoomUserTagsEvent = 17; + public static final int CatalogSearchedItemEvent = 2594; + public static final int JukeBoxRequestTrackCodeEvent = 3189; + public static final int JukeBoxRequestTrackDataEvent = 3082; + public static final int RoomStaffPickEvent = 1918; + public static final int RoomRequestBannedUsersEvent = 2267; + public static final int JukeBoxRequestPlayListEvent = 1325; + public static final int JukeBoxEventOne = 2304; + public static final int JukeBoxEventTwo = 1435; + public static final int RoomUserMuteEvent = 3485; + //public static final int JukeBoxEventThree = 3846; + public static final int RequestDeleteRoomEvent = 532; + public static final int RequestPromotionRoomsEvent = 1075; + public static final int BuyRoomPromotionEvent = 777; + public static final int EditRoomPromotionMessageEvent = 3991; + public static final int RequestGuideToolEvent = 1922; + public static final int RequestGuideAssistanceEvent = 3338; + public static final int GuideUserTypingEvent = 519; + public static final int GuideReportHelperEvent = 3969; + public static final int GuideRecommendHelperEvent = 477; + public static final int GuideUserMessageEvent = 3899; + public static final int GuideCancelHelpRequestEvent = 291; + public static final int GuideHandleHelpRequestEvent = 1424; + public static final int GuideVisitUserEvent = 1052; + public static final int GuideInviteUserEvent = 234; + public static final int GuideCloseHelpRequestEvent = 887; + public static final int GuardianNoUpdatesWantedEvent = 2501; + public static final int GuardianVoteEvent = 3961; + public static final int GuardianAcceptRequestEvent = 3365; + public static final int RequestAchievementConfigurationEvent = -1; + public static final int RequestReportUserBullyingEvent = 3786; + public static final int ReportBullyEvent = 3060; + public static final int CameraRoomPictureEvent = 3226; + public static final int CameraRoomThumbnailEvent = 1982; + public static final int SavePostItStickyPoleEvent = 3283; + public static final int HotelViewClaimBadgeEvent = 3077; + public static final int HotelViewRequestCommunityGoalEvent = 1145; + public static final int HotelViewRequestConcurrentUsersEvent = 1343; + public static final int HotelViewConcurrentUsersButtonEvent = 3872; + public static final int IgnoreRoomUserEvent = 1117; + public static final int UnIgnoreRoomUserEvent = 2061; + public static final int UnbanRoomUserEvent = 992; + public static final int RoomUserBanEvent = 1477; + public static final int RequestNavigatorSettingsEvent = 1782; + public static final int AddSavedSearchEvent = 2226; + public static final int DeleteSavedSearchEvent = 1954; + public static final int SaveWindowSettingsEvent = 3159; + public static final int GetHabboGuildBadgesMessageEvent = 21; + public static final int UpdateUIFlagsEvent = 2313; + public static final int ReportThreadEvent = 534; + public static final int ReportCommentEvent = 1412; + public static final int ReportPhotoEvent = 2492; + + public static final int RequestCraftingRecipesEvent = 1173; + public static final int RequestCraftingRecipesAvailableEvent = 3086; + public static final int CraftingAddRecipeEvent = 633; + public static final int CraftingCraftItemEvent = 3591; + public static final int CraftingCraftSecretEvent = 1251; + + public static final int AdventCalendarOpenDayEvent = 2257; + public static final int AdventCalendarForceOpenEvent = 3889; + public static final int CameraPurchaseEvent = 2408; + public static final int RoomFavoriteEvent = 3817; + public static final int RoomUnFavoriteEvent = 309; + + public static final int YoutubeRequestPlaylists = 336; + public static final int YoutubeRequestStateChange = 3005; + public static final int YoutubeRequestPlaylistChange = 2069; + + public static final int HotelViewRequestBadgeRewardEvent = 2318; + public static final int HotelViewClaimBadgeRewardEvent = -1; + + public static final int JukeBoxAddSoundTrackEvent = 753; + public static final int JukeBoxRemoveSoundTrackEvent = 3050; + public static final int ToggleMonsterplantBreedableEvent = 3379; + public static final int CompostMonsterplantEvent = 3835; + public static final int BreedMonsterplantsEvent = 1638; + public static final int MovePetEvent = 3449; + public static final int PetPackageNameEvent = 3698; + + public static final int GameCenterRequestGamesEvent = 741; + public static final int GameCenterRequestAccountStatusEvent = 3171; + public static final int GameCenterRequestGameStatusEvent = 11; + public static final int CameraPublishToWebEvent = 2068; + + public static final int GameCenterJoinGameEvent = 1458; + public static final int GameCenterLoadGameEvent = 1054; + public static final int GameCenterEvent = 2914; + public static final int GameCenterLeaveGameEvent = 3207; + + public static final int ModToolSanctionAlertEvent = 229; + public static final int ModToolSanctionMuteEvent = 1945; + public static final int ModToolSanctionBanEvent = 2766; + public static final int ModToolSanctionTradeLockEvent = 3742; + public static final int UserNuxEvent = 1299; + + public static final int ReportFriendPrivateChatEvent = 2950; + public static final int ModToolIssueChangeTopicEvent = 1392; + public static final int ModToolIssueDefaultSanctionEvent = 2717; + + public static final int TradeCancelEvent = 2341; + public static final int ChangeChatBubbleEvent = 1030; + public static final int LoveLockStartConfirmEvent = 3775; + + public static final int HotelViewRequestLTDAvailabilityEvent = 410; + public static final int HotelViewRequestSecondsUntilEvent = 271; + + public static final int PurchaseTargetOfferEvent = 1826; + public static final int TargetOfferStateEvent = 2041; + public static final int StopBreedingEvent = 2713; + public static final int ConfirmPetBreedingEvent = 3382; + + + public static final int GuildForumListEvent = 873; + public static final int GuildForumThreadsEvent = 436; + public static final int GuildForumDataEvent = 3149; + public static final int GuildForumPostThreadEvent = 3529; + public static final int GuildForumUpdateSettingsEvent = 2214; + public static final int GuildForumThreadsMessagesEvent = 232; + public static final int GuildForumModerateMessageEvent = 286; + public static final int GuildForumModerateThreadEvent = 1397; + public static final int GuildForumThreadUpdateEvent = 3045; + public static final int GuildForumMarkAsReadEvent = 1855; + + public static final int UNKNOWN_SNOWSTORM_6000 = 6000; + public static final int UNKNOWN_SNOWSTORM_6001 = 6001; + public static final int UNKNOWN_SNOWSTORM_6002 = 6002; + public static final int UNKNOWN_SNOWSTORM_6003 = 6003; + public static final int UNKNOWN_SNOWSTORM_6004 = 6004; + public static final int UNKNOWN_SNOWSTORM_6005 = 6005; + public static final int UNKNOWN_SNOWSTORM_6006 = 6006; + public static final int UNKNOWN_SNOWSTORM_6007 = 6007; + public static final int UNKNOWN_SNOWSTORM_6008 = 6008; + public static final int UNKNOWN_SNOWSTORM_6009 = 6009; + public static final int UNKNOWN_SNOWSTORM_6010 = 6010; + public static final int UNKNOWN_SNOWSTORM_6011 = 6011; + public static final int SnowStormJoinQueueEvent = 6012; + public static final int UNKNOWN_SNOWSTORM_6013 = 6013; + public static final int UNKNOWN_SNOWSTORM_6014 = 6014; + public static final int UNKNOWN_SNOWSTORM_6015 = 6015; + public static final int UNKNOWN_SNOWSTORM_6016 = 6016; + public static final int UNKNOWN_SNOWSTORM_6017 = 6017; + public static final int UNKNOWN_SNOWSTORM_6018 = 6018; + public static final int UNKNOWN_SNOWSTORM_6019 = 6019; + public static final int UNKNOWN_SNOWSTORM_6020 = 6020; + public static final int UNKNOWN_SNOWSTORM_6021 = 6021; + public static final int UNKNOWN_SNOWSTORM_6022 = 6022; + public static final int UNKNOWN_SNOWSTORM_6023 = 6023; + public static final int UNKNOWN_SNOWSTORM_6024 = 6024; + public static final int UNKNOWN_SNOWSTORM_6025 = 6025; + public static final int SnowStormUserPickSnowballEvent = 6026; + + public static final int PerformanceLogMessageEvent = 2743; +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/MessageHandler.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/MessageHandler.java new file mode 100644 index 0000000..38920af --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/MessageHandler.java @@ -0,0 +1,16 @@ +package com.eu.habbo.messages.incoming; + +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.messages.ClientMessage; + +public abstract class MessageHandler { + public GameClient client; + public ClientMessage packet; + public boolean isCancelled = false; + + public abstract void handle() throws Exception; + + public int getRatelimit() { + return 0; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/achievements/RequestAchievementConfigurationEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/achievements/RequestAchievementConfigurationEvent.java new file mode 100644 index 0000000..ff1d31c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/achievements/RequestAchievementConfigurationEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.achievements; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.inventory.InventoryAchievementsComposer; + +public class RequestAchievementConfigurationEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new InventoryAchievementsComposer()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/achievements/RequestAchievementsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/achievements/RequestAchievementsEvent.java new file mode 100644 index 0000000..c4ec8b3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/achievements/RequestAchievementsEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.achievements; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.achievements.AchievementListComposer; + +public class RequestAchievementsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new AchievementListComposer(this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/ambassadors/AmbassadorAlertCommandEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/ambassadors/AmbassadorAlertCommandEvent.java new file mode 100644 index 0000000..dc37847 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/ambassadors/AmbassadorAlertCommandEvent.java @@ -0,0 +1,34 @@ +package com.eu.habbo.messages.incoming.ambassadors; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.plugin.events.support.SupportUserAlertedEvent; +import com.eu.habbo.plugin.events.support.SupportUserAlertedReason; + +public class AmbassadorAlertCommandEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (!this.client.getHabbo().hasPermission(Permission.ACC_AMBASSADOR)) { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.modtools.alert").replace("%username%", client.getHabbo().getHabboInfo().getUsername()).replace("%message%", "${notification.ambassador.alert.warning.message}")); + return; + } + + int userId = this.packet.readInt(); + + Habbo habbo = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabbo(userId); + + if (habbo == null) + return; + + SupportUserAlertedEvent alertedEvent = new SupportUserAlertedEvent(client.getHabbo(), habbo, "${notification.ambassador.alert.warning.message}", SupportUserAlertedReason.AMBASSADOR); + + if (Emulator.getPluginManager().fireEvent(alertedEvent).isCancelled()) + return; + + habbo.getClient().sendResponse(new BubbleAlertComposer("ambassador.alert.warning")); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/ambassadors/AmbassadorVisitCommandEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/ambassadors/AmbassadorVisitCommandEvent.java new file mode 100644 index 0000000..867ff0d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/ambassadors/AmbassadorVisitCommandEvent.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.incoming.ambassadors; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.ForwardToRoomComposer; + +public class AmbassadorVisitCommandEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_AMBASSADOR)) { + String username = this.packet.readString(); + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(username); + + if (habbo != null) { + if (habbo.getHabboInfo().getCurrentRoom() != null) { + this.client.sendResponse(new ForwardToRoomComposer(habbo.getHabboInfo().getCurrentRoom().getId())); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/CameraPublishToWebEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/CameraPublishToWebEvent.java new file mode 100644 index 0000000..7f1c085 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/CameraPublishToWebEvent.java @@ -0,0 +1,62 @@ +package com.eu.habbo.messages.incoming.camera; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.camera.CameraPublishWaitMessageComposer; +import com.eu.habbo.messages.outgoing.catalog.NotEnoughPointsTypeComposer; +import com.eu.habbo.plugin.events.users.UserPublishPictureEvent; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class CameraPublishToWebEvent extends MessageHandler { + + public static int CAMERA_PUBLISH_POINTS = 5; + public static int CAMERA_PUBLISH_POINTS_TYPE = 0; + + @Override + public void handle() throws Exception { + Habbo habbo = this.client.getHabbo(); + + if (habbo == null) return; + if (habbo.getHabboInfo().getPhotoTimestamp() == 0) return; + if (habbo.getHabboInfo().getPhotoJSON().isEmpty()) return; + if (!habbo.getHabboInfo().getPhotoJSON().contains(habbo.getHabboInfo().getPhotoTimestamp() + "")) return; + + if (habbo.getHabboInfo().getCurrencyAmount(CameraPublishToWebEvent.CAMERA_PUBLISH_POINTS_TYPE) < CameraPublishToWebEvent.CAMERA_PUBLISH_POINTS) { + this.client.sendResponse(new NotEnoughPointsTypeComposer(false, true, CameraPublishToWebEvent.CAMERA_PUBLISH_POINTS)); + return; + } + + int timestamp = Emulator.getIntUnixTimestamp(); + + boolean isOk = false; + int cooldownLeft = Math.max(0, Emulator.getConfig().getInt("camera.publish.delay") - (timestamp - this.client.getHabbo().getHabboInfo().getWebPublishTimestamp())); + + if (cooldownLeft == 0) { + UserPublishPictureEvent publishPictureEvent = new UserPublishPictureEvent(this.client.getHabbo(), this.client.getHabbo().getHabboInfo().getPhotoURL(), timestamp, this.client.getHabbo().getHabboInfo().getPhotoRoomId()); + + if (!Emulator.getPluginManager().fireEvent(publishPictureEvent).isCancelled()) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO camera_web (user_id, room_id, timestamp, url) VALUES (?, ?, ?, ?)")) { + statement.setInt(1, this.client.getHabbo().getHabboInfo().getId()); + statement.setInt(2, publishPictureEvent.roomId); + statement.setInt(3, publishPictureEvent.timestamp); + statement.setString(4, publishPictureEvent.URL); + statement.execute(); + + this.client.getHabbo().getHabboInfo().setWebPublishTimestamp(timestamp); + this.client.getHabbo().givePoints(CameraPublishToWebEvent.CAMERA_PUBLISH_POINTS_TYPE, -CameraPublishToWebEvent.CAMERA_PUBLISH_POINTS); + + isOk = true; + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + this.client.sendResponse(new CameraPublishWaitMessageComposer(isOk, cooldownLeft, isOk ? this.client.getHabbo().getHabboInfo().getPhotoURL() : "")); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/CameraPurchaseEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/CameraPurchaseEvent.java new file mode 100644 index 0000000..173f3ca --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/CameraPurchaseEvent.java @@ -0,0 +1,57 @@ +package com.eu.habbo.messages.incoming.camera; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.camera.CameraPurchaseSuccesfullComposer; +import com.eu.habbo.messages.outgoing.catalog.NotEnoughPointsTypeComposer; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.plugin.events.users.UserPurchasePictureEvent; + +public class CameraPurchaseEvent extends MessageHandler { + public static int CAMERA_PURCHASE_CREDITS = 5; + public static int CAMERA_PURCHASE_POINTS = 5; + public static int CAMERA_PURCHASE_POINTS_TYPE = 0; + + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getCredits() < CameraPurchaseEvent.CAMERA_PURCHASE_CREDITS) { + this.client.sendResponse(new NotEnoughPointsTypeComposer(true, false, 0)); + return; + } + + if (this.client.getHabbo().getHabboInfo().getCurrencyAmount(CameraPurchaseEvent.CAMERA_PURCHASE_POINTS_TYPE) < CameraPurchaseEvent.CAMERA_PURCHASE_POINTS) { + this.client.sendResponse(new NotEnoughPointsTypeComposer(false, true, CameraPurchaseEvent.CAMERA_PURCHASE_POINTS_TYPE)); + return; + } + + if (this.client.getHabbo().getHabboInfo().getPhotoTimestamp() == 0) return; + if (this.client.getHabbo().getHabboInfo().getPhotoJSON().isEmpty()) return; + if (!this.client.getHabbo().getHabboInfo().getPhotoJSON().contains(this.client.getHabbo().getHabboInfo().getPhotoTimestamp() + "")) + return; + + if (Emulator.getPluginManager().fireEvent(new UserPurchasePictureEvent(this.client.getHabbo(), this.client.getHabbo().getHabboInfo().getPhotoURL(), this.client.getHabbo().getHabboInfo().getCurrentRoom().getId(), this.client.getHabbo().getHabboInfo().getPhotoTimestamp())).isCancelled()) { + return; + } + + HabboItem photoItem = Emulator.getGameEnvironment().getItemManager().createItem(this.client.getHabbo().getHabboInfo().getId(), Emulator.getGameEnvironment().getItemManager().getItem(Emulator.getConfig().getInt("camera.item_id")), 0, 0, this.client.getHabbo().getHabboInfo().getPhotoJSON()); + + if (photoItem != null) { + photoItem.setExtradata(photoItem.getExtradata().replace("%id%", photoItem.getId() + "")); + photoItem.needsUpdate(true); + + this.client.getHabbo().getInventory().getItemsComponent().addItem(photoItem); + + this.client.sendResponse(new CameraPurchaseSuccesfullComposer()); + this.client.sendResponse(new AddHabboItemComposer(photoItem)); + this.client.sendResponse(new InventoryRefreshComposer()); + + this.client.getHabbo().giveCredits(-CameraPurchaseEvent.CAMERA_PURCHASE_CREDITS); + this.client.getHabbo().givePoints(CameraPurchaseEvent.CAMERA_PURCHASE_POINTS_TYPE, -CameraPurchaseEvent.CAMERA_PURCHASE_POINTS); + + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("CameraPhotoCount")); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/CameraRoomPictureEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/CameraRoomPictureEvent.java new file mode 100644 index 0000000..1550603 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/CameraRoomPictureEvent.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.incoming.camera; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.networking.camera.CameraClient; +import com.eu.habbo.networking.camera.messages.outgoing.CameraRenderImageComposer; +import com.eu.habbo.util.crypto.ZIP; + +public class CameraRoomPictureEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (!this.client.getHabbo().hasPermission("acc_camera")) { + this.client.getHabbo().alert(Emulator.getTexts().getValue("camera.permission")); + return; + } + + if (CameraClient.isLoggedIn) { + this.packet.getBuffer().readFloat(); + + byte[] data = this.packet.getBuffer().readBytes(this.packet.getBuffer().readableBytes()).array(); + + String content = new String(ZIP.inflate(data)); + CameraRenderImageComposer composer = new CameraRenderImageComposer(this.client.getHabbo().getHabboInfo().getId(), this.client.getHabbo().getHabboInfo().getCurrentRoom().getBackgroundTonerColor().getRGB(), 320, 320, content); + this.client.getHabbo().getHabboInfo().setPhotoJSON(Emulator.getConfig().getValue("camera.extradata").replace("%timestamp%", composer.timestamp + "")); + this.client.getHabbo().getHabboInfo().setPhotoTimestamp(composer.timestamp); + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) { + this.client.getHabbo().getHabboInfo().setPhotoRoomId(this.client.getHabbo().getHabboInfo().getCurrentRoom().getId()); + } + + Emulator.getCameraClient().sendMessage(composer); + } else { + this.client.getHabbo().alert(Emulator.getTexts().getValue("camera.disabled")); + } + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/CameraRoomThumbnailEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/CameraRoomThumbnailEvent.java new file mode 100644 index 0000000..c9c1bc1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/CameraRoomThumbnailEvent.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.incoming.camera; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.camera.CameraRoomThumbnailSavedComposer; +import com.eu.habbo.networking.camera.CameraClient; +import com.eu.habbo.networking.camera.messages.outgoing.CameraRenderImageComposer; +import com.eu.habbo.util.crypto.ZIP; + +public class CameraRoomThumbnailEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (!this.client.getHabbo().hasPermission("acc_camera")) { + this.client.getHabbo().alert(Emulator.getTexts().getValue("camera.permission")); + return; + } + + if (!this.client.getHabbo().getHabboInfo().getCurrentRoom().isOwner(this.client.getHabbo())) + return; + + if (CameraClient.isLoggedIn) { + this.packet.getBuffer().readFloat(); + byte[] data = this.packet.getBuffer().readBytes(this.packet.getBuffer().readableBytes()).array(); + String content = new String(ZIP.inflate(data)); + + CameraRenderImageComposer composer = new CameraRenderImageComposer(this.client.getHabbo().getHabboInfo().getId(), this.client.getHabbo().getHabboInfo().getCurrentRoom().getBackgroundTonerColor().getRGB(), 110, 110, content); + + this.client.getHabbo().getHabboInfo().setPhotoJSON(Emulator.getConfig().getValue("camera.extradata").replace("%timestamp%", composer.timestamp + "")); + this.client.getHabbo().getHabboInfo().setPhotoTimestamp(composer.timestamp); + + Emulator.getCameraClient().sendMessage(composer); + } else { + this.client.sendResponse(new CameraRoomThumbnailSavedComposer()); + this.client.getHabbo().alert(Emulator.getTexts().getValue("camera.disabled")); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/RequestCameraConfigurationEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/RequestCameraConfigurationEvent.java new file mode 100644 index 0000000..cc90af9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/camera/RequestCameraConfigurationEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.camera; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.camera.CameraPriceComposer; + +public class RequestCameraConfigurationEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new CameraPriceComposer(Emulator.getConfig().getInt("camera.price.credits"), Emulator.getConfig().getInt("camera.price.points"), Emulator.getConfig().getInt("camera.price.points.publish"))); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyClubDiscountEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyClubDiscountEvent.java new file mode 100644 index 0000000..8a66d92 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyClubDiscountEvent.java @@ -0,0 +1,82 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.ClubOffer; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.subscriptions.Subscription; +import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionHabboClub; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.AlertPurchaseFailedComposer; +import com.eu.habbo.messages.outgoing.catalog.PurchaseOKComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.unknown.ExtendClubMessageComposer; +import com.eu.habbo.messages.outgoing.users.UserClubComposer; +import com.eu.habbo.messages.outgoing.users.UserCreditsComposer; +import com.eu.habbo.messages.outgoing.users.UserCurrencyComposer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CatalogBuyClubDiscountEvent extends MessageHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(CatalogBuyClubDiscountEvent.class); + + @Override + public void handle() throws Exception { + + Subscription subscription = this.client.getHabbo().getHabboStats().getSubscription(SubscriptionHabboClub.HABBO_CLUB); + + int days = 0; + int minutes = 0; + int timeRemaining = 0; + + if(subscription != null) { + timeRemaining = subscription.getRemaining(); + days = (int) Math.floor(timeRemaining / 86400.0); + minutes = (int) Math.ceil(timeRemaining / 60.0); + + if(days < 1 && minutes > 0) { + days = 1; + } + } + + if(timeRemaining > 0 && SubscriptionHabboClub.DISCOUNT_ENABLED && days <= SubscriptionHabboClub.DISCOUNT_DAYS_BEFORE_END) { + ClubOffer deal = Emulator.getGameEnvironment().getCatalogManager().clubOffers.values().stream().filter(ClubOffer::isDeal).findAny().orElse(null); + + if(deal != null) { + ClubOffer regular = Emulator.getGameEnvironment().getCatalogManager().getClubOffers().stream().filter(x -> x.getDays() == deal.getDays()).findAny().orElse(null); + if(regular != null) { + + int totalDays = deal.getDays(); + int totalCredits = deal.getCredits(); + int totalDuckets = deal.getPoints(); + + if (totalDays > 0) { + if (this.client.getHabbo().getHabboInfo().getCurrencyAmount(deal.getPointsType()) < totalDuckets) + return; + + if (this.client.getHabbo().getHabboInfo().getCredits() < totalCredits) + return; + + if (!this.client.getHabbo().hasPermission(Permission.ACC_INFINITE_CREDITS)) + this.client.getHabbo().giveCredits(-totalCredits); + + if (!this.client.getHabbo().hasPermission(Permission.ACC_INFINITE_POINTS)) + this.client.getHabbo().givePoints(deal.getPointsType(), -totalDuckets); + + + if(this.client.getHabbo().getHabboStats().createSubscription(Subscription.HABBO_CLUB, (totalDays * 86400)) == null) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + throw new Exception("Unable to create or extend subscription"); + } + + this.client.sendResponse(new PurchaseOKComposer(null)); + this.client.sendResponse(new InventoryRefreshComposer()); + + this.client.getHabbo().getHabboStats().run(); + } + } + } + } + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyItemAsGiftEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyItemAsGiftEvent.java new file mode 100644 index 0000000..2ea3fe3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyItemAsGiftEvent.java @@ -0,0 +1,378 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.habbohotel.catalog.CatalogLimitedConfiguration; +import com.eu.habbo.habbohotel.catalog.CatalogManager; +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.habbohotel.items.FurnitureType; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.*; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.*; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.generic.alerts.GenericAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.HotelWillCloseInMinutesComposer; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.users.UserPointsComposer; +import com.eu.habbo.threading.runnables.ShutdownEmulator; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Calendar; + +@Slf4j +public class CatalogBuyItemAsGiftEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + if (Emulator.getIntUnixTimestamp() - this.client.getHabbo().getHabboStats().lastGiftTimestamp >= CatalogManager.PURCHASE_COOLDOWN) { + this.client.getHabbo().getHabboStats().lastGiftTimestamp = Emulator.getIntUnixTimestamp(); + if (ShutdownEmulator.timestamp > 0) { + this.client.sendResponse(new HotelWillCloseInMinutesComposer((ShutdownEmulator.timestamp - Emulator.getIntUnixTimestamp()) / 60)); + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + return; + } + + if (this.client.getHabbo().getHabboStats().isPurchasingFurniture) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + return; + } else { + this.client.getHabbo().getHabboStats().isPurchasingFurniture = true; + } + + try { + + int pageId = this.packet.readInt(); + int itemId = this.packet.readInt(); + String extraData = this.packet.readString(); + String username = this.packet.readString(); + String message = this.packet.readString(); + int spriteId = this.packet.readInt(); + int color = this.packet.readInt(); + int ribbonId = this.packet.readInt(); + boolean showName = this.packet.readBoolean(); + + int count = 1; + int userId = 0; + + if (!Emulator.getGameEnvironment().getCatalogManager().giftWrappers.containsKey(spriteId) && !Emulator.getGameEnvironment().getCatalogManager().giftFurnis.containsKey(spriteId)) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + return; + } + + if (!GiftConfigurationComposer.BOX_TYPES.contains(color) || !GiftConfigurationComposer.RIBBON_TYPES.contains(ribbonId)) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + return; + } + + if (message.length() > Emulator.getConfig().getInt("hotel.gifts.length.max", 300)) { + message = message.substring(0, Emulator.getConfig().getInt("hotel.gifts.length.max", 300)); + } + + Integer iItemId = Emulator.getGameEnvironment().getCatalogManager().giftWrappers.get(spriteId); + + if (iItemId == null) + iItemId = Emulator.getGameEnvironment().getCatalogManager().giftFurnis.get(spriteId); + + if (iItemId == null) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + return; + } + + Item giftItem = Emulator.getGameEnvironment().getItemManager().getItem(iItemId); + + if (giftItem == null) { + giftItem = Emulator.getGameEnvironment().getItemManager().getItem((Integer) Emulator.getGameEnvironment().getCatalogManager().giftFurnis.values().toArray()[Emulator.getRandom().nextInt(Emulator.getGameEnvironment().getCatalogManager().giftFurnis.size())]); + + if (giftItem == null) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + return; + } + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(username); + + if (habbo == null) { + try (PreparedStatement statement = connection.prepareStatement("SELECT id FROM users WHERE username = ?")) { + statement.setString(1, username); + + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + userId = set.getInt(1); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } else { + userId = habbo.getHabboInfo().getId(); + } + + if (userId == 0) { + this.client.sendResponse(new GiftReceiverNotFoundComposer()); + return; + } + + CatalogPage page = Emulator.getGameEnvironment().getCatalogManager().catalogPages.get(pageId); + + if (page == null) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + return; + } + + if (page.getRank() > this.client.getHabbo().getHabboInfo().getRank().getId() || !page.isEnabled() || !page.isVisible()) { + this.client.sendResponse(new AlertPurchaseUnavailableComposer(AlertPurchaseUnavailableComposer.ILLEGAL)); + return; + } + + CatalogItem item = page.getCatalogItem(itemId); + + if (item == null) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + return; + } + + if (item.isClubOnly() && !this.client.getHabbo().getHabboStats().hasActiveClub()) { + this.client.sendResponse(new AlertPurchaseUnavailableComposer(AlertPurchaseUnavailableComposer.REQUIRES_CLUB)); + return; + } + + for (Item baseItem : item.getBaseItems()) { + if (!baseItem.allowGift()) { + this.client.sendResponse(new AlertPurchaseUnavailableComposer(AlertPurchaseUnavailableComposer.ILLEGAL)); + return; + } + } + + if (item.isLimited()) { + if (item.getLimitedStack() == item.getLimitedSells()) { + this.client.sendResponse(new AlertLimitedSoldOutComposer()); + return; + } + item.sellRare(); + } + + int totalCredits = item.getCredits(); + int totalPoints = item.getPoints(); + + if(totalCredits > this.client.getHabbo().getHabboInfo().getCredits() || totalPoints > this.client.getHabbo().getHabboInfo().getCurrencyAmount(item.getPointsType())) { + this.client.sendResponse(new AlertPurchaseUnavailableComposer(AlertPurchaseUnavailableComposer.ILLEGAL)); + return; + } + + CatalogLimitedConfiguration limitedConfiguration; + int limitedStack = 0; + int limitedNumber = 0; + if (item.isLimited()) { + count = 1; + if (Emulator.getGameEnvironment().getCatalogManager().getLimitedConfig(item).available() == 0 && habbo != null) { + habbo.getClient().sendResponse(new AlertLimitedSoldOutComposer()); + return; + } + + limitedConfiguration = Emulator.getGameEnvironment().getCatalogManager().getLimitedConfig(item); + + if (limitedConfiguration == null) { + limitedConfiguration = Emulator.getGameEnvironment().getCatalogManager().createOrUpdateLimitedConfig(item); + } + + limitedNumber = limitedConfiguration.getNumber(); + limitedStack = limitedConfiguration.getTotalSet(); + } + + THashSet itemsList = new THashSet<>(); + + boolean badgeFound = false; + for (Item baseItem : item.getBaseItems()) { + if (baseItem.getType() == FurnitureType.BADGE) { + if (habbo != null) { + if (habbo.getInventory().getBadgesComponent().hasBadge(baseItem.getName())) { + badgeFound = true; + } + } else { + int c = 0; + try (PreparedStatement statement = connection.prepareStatement("SELECT COUNT(*) as c FROM users_badges WHERE user_id = ? AND badge_code LIKE ?")) { + statement.setInt(1, userId); + statement.setString(2, baseItem.getName()); + try (ResultSet rSet = statement.executeQuery()) { + if (rSet.next()) { + c = rSet.getInt("c"); + } + } + } + + if (c != 0) { + badgeFound = true; + } + } + } + } + + if (badgeFound) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.ALREADY_HAVE_BADGE)); + return; + } + + if (item.getAmount() > 1 || item.getBaseItems().size() > 1) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + return; + } + + for (Item baseItem : item.getBaseItems()) { + if (item.getItemAmount(baseItem.getId()) > 1) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + return; + } + + for (int k = 0; k < item.getItemAmount(baseItem.getId()); k++) { + if (!baseItem.getName().contains("avatar_effect")) { + if (baseItem.getType() == FurnitureType.BADGE) { + if (!badgeFound) { + if (habbo != null) { + HabboBadge badge = new HabboBadge(0, baseItem.getName(), 0, habbo); + Emulator.getThreading().run(badge); + habbo.getInventory().getBadgesComponent().addBadge(badge); + } else { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO users_badges (user_id, badge_code) VALUES (?, ?)")) { + statement.setInt(1, userId); + statement.setString(2, baseItem.getName()); + statement.execute(); + } + } + + badgeFound = true; + } + } else if (item.getName().startsWith("rentable_bot_")) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + return; + } else if (Item.isPet(baseItem)) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + return; + } else { + if (baseItem.getInteractionType().getType() == InteractionTrophy.class || baseItem.getInteractionType().getType() == InteractionBadgeDisplay.class) { + if (baseItem.getInteractionType().getType() == InteractionBadgeDisplay.class && habbo != null && !habbo.getClient().getHabbo().getInventory().getBadgesComponent().hasBadge(extraData)) { + ScripterManager.scripterDetected(habbo.getClient(), Emulator.getTexts().getValue("scripter.warning.catalog.badge_display").replace("%username%", habbo.getClient().getHabbo().getHabboInfo().getUsername()).replace("%badge%", extraData)); + extraData = "UMAD"; + } + + extraData = this.client.getHabbo().getHabboInfo().getUsername() + (char) 9 + Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + "-" + (Calendar.getInstance().get(Calendar.MONTH) + 1) + "-" + Calendar.getInstance().get(Calendar.YEAR) + (char) 9 + extraData; + } + + if (baseItem.getInteractionType().getType() == InteractionTeleport.class || baseItem.getInteractionType().getType() == InteractionTeleportTile.class) { + HabboItem teleportOne = Emulator.getGameEnvironment().getItemManager().createItem(0, baseItem, limitedStack, limitedNumber, extraData); + HabboItem teleportTwo = Emulator.getGameEnvironment().getItemManager().createItem(0, baseItem, limitedStack, limitedNumber, extraData); + Emulator.getGameEnvironment().getItemManager().insertTeleportPair(teleportOne.getId(), teleportTwo.getId()); + itemsList.add(teleportOne); + itemsList.add(teleportTwo); + } else if (baseItem.getInteractionType().getType() == InteractionHopper.class) { + HabboItem hopper = Emulator.getGameEnvironment().getItemManager().createItem(0, baseItem, limitedNumber, limitedNumber, extraData); + + Emulator.getGameEnvironment().getItemManager().insertHopper(hopper); + + itemsList.add(hopper); + } else if (baseItem.getInteractionType().getType() == InteractionGuildFurni.class || baseItem.getInteractionType().getType() == InteractionGuildGate.class) { + InteractionGuildFurni habboItem = (InteractionGuildFurni) Emulator.getGameEnvironment().getItemManager().createItem(0, baseItem, limitedStack, limitedNumber, extraData); + habboItem.setExtradata(""); + habboItem.needsUpdate(true); + int guildId; + try { + guildId = Integer.parseInt(extraData); + } catch (Exception e) { + log.error("Caught exception", e); + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + Emulator.getThreading().run(habboItem); + Emulator.getGameEnvironment().getGuildManager().setGuild(habboItem, guildId); + itemsList.add(habboItem); + } else { + HabboItem habboItem = Emulator.getGameEnvironment().getItemManager().createItem(0, baseItem, limitedStack, limitedNumber, extraData); + itemsList.add(habboItem); + } + } + } else { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + this.client.sendResponse(new GenericAlertComposer(Emulator.getTexts().getValue("error.catalog.buy.not_yet"))); + return; + } + } + } + + StringBuilder giftData = new StringBuilder(itemsList.size() + "\t"); + + for (HabboItem i : itemsList) { + giftData.append(i.getId()).append("\t"); + } + + giftData.append(color).append("\t").append(ribbonId).append("\t").append(showName ? "1" : "0").append("\t").append(message.replace("\t", "")).append("\t").append(this.client.getHabbo().getHabboInfo().getUsername()).append("\t").append(this.client.getHabbo().getHabboInfo().getLook()); + + HabboItem gift = Emulator.getGameEnvironment().getItemManager().createGift(username, giftItem, giftData.toString(), 0, 0); + + if (gift == null) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + + if (this.client.getHabbo().getHabboInfo().getId() != userId) { + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("GiftGiver")); + } + + if (habbo != null) { + habbo.getClient().sendResponse(new AddHabboItemComposer(gift)); + habbo.getClient().getHabbo().getInventory().getItemsComponent().addItem(gift); + habbo.getClient().sendResponse(new InventoryRefreshComposer()); + THashMap keys = new THashMap<>(); + keys.put("display", "BUBBLE"); + keys.put("image", "${image.library.url}notifications/gift.gif"); + keys.put("message", Emulator.getTexts().getValue("generic.gift.received.anonymous")); + if (showName) { + keys.put("message", Emulator.getTexts().getValue("generic.gift.received").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername())); + } + habbo.getClient().sendResponse(new BubbleAlertComposer(BubbleAlertKeys.RECEIVED_BADGE.key, keys)); + } + + if (this.client.getHabbo().getHabboInfo().getId() != userId) { + AchievementManager.progressAchievement(userId, Emulator.getGameEnvironment().getAchievementManager().getAchievement("GiftReceiver")); + } + + if (!this.client.getHabbo().hasPermission(Permission.ACC_INFINITE_CREDITS)) { + if (totalCredits > 0) { + this.client.getHabbo().giveCredits(-totalCredits); + } + } + if (totalPoints > 0) { + if (item.getPointsType() == 0 && !this.client.getHabbo().hasPermission(Permission.ACC_INFINITE_PIXELS)) { + this.client.getHabbo().givePixels(-totalPoints); + } else if (!this.client.getHabbo().hasPermission(Permission.ACC_INFINITE_POINTS)) { + this.client.getHabbo().givePoints(item.getPointsType(), -totalPoints); + } + } + + this.client.sendResponse(new PurchaseOKComposer(item)); + } catch (Exception e) { + log.error("Exception caught", e); + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + } + } finally { + this.client.getHabbo().getHabboStats().isPurchasingFurniture = false; + } + } else { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyItemEvent.java new file mode 100644 index 0000000..1d6c06d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyItemEvent.java @@ -0,0 +1,234 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.BotManager; +import com.eu.habbo.habbohotel.catalog.*; +import com.eu.habbo.habbohotel.catalog.layouts.*; +import com.eu.habbo.habbohotel.items.FurnitureType; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.pets.PetManager; +import com.eu.habbo.habbohotel.rooms.RoomManager; +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.habbohotel.users.HabboInventory; +import com.eu.habbo.habbohotel.users.subscriptions.Subscription; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.AlertPurchaseFailedComposer; +import com.eu.habbo.messages.outgoing.catalog.AlertPurchaseUnavailableComposer; +import com.eu.habbo.messages.outgoing.catalog.PurchaseOKComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.generic.alerts.HotelWillCloseInMinutesComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.navigator.CanCreateRoomComposer; +import com.eu.habbo.messages.outgoing.users.*; +import com.eu.habbo.threading.runnables.ShutdownEmulator; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectProcedure; +import org.apache.commons.lang3.StringUtils; + +import static com.eu.habbo.messages.incoming.catalog.CheckPetNameEvent.PET_NAME_LENGTH_MAXIMUM; +import static com.eu.habbo.messages.incoming.catalog.CheckPetNameEvent.PET_NAME_LENGTH_MINIMUM; + +public class CatalogBuyItemEvent extends MessageHandler { + + + @Override + public void handle() throws Exception { + if (Emulator.getIntUnixTimestamp() - this.client.getHabbo().getHabboStats().lastPurchaseTimestamp >= CatalogManager.PURCHASE_COOLDOWN) { + this.client.getHabbo().getHabboStats().lastPurchaseTimestamp = Emulator.getIntUnixTimestamp(); + if (ShutdownEmulator.timestamp > 0) { + this.client.sendResponse(new HotelWillCloseInMinutesComposer((ShutdownEmulator.timestamp - Emulator.getIntUnixTimestamp()) / 60)); + return; + } + + int pageId = this.packet.readInt(); + int itemId = this.packet.readInt(); + String extraData = this.packet.readString(); + int count = this.packet.readInt(); + + try { + if (this.client.getHabbo().getInventory().getItemsComponent().itemCount() > HabboInventory.MAXIMUM_ITEMS) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + this.client.getHabbo().alert(Emulator.getTexts().getValue("inventory.full")); + return; + } + } catch (Exception e) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + } + + CatalogPage page = null; + + if (pageId == -12345678 || pageId == -1) { + CatalogItem searchedItem = Emulator.getGameEnvironment().getCatalogManager().getCatalogItem(itemId); + + if (searchedItem.getOfferId() > 0) { + page = Emulator.getGameEnvironment().getCatalogManager().getCatalogPage(searchedItem.getPageId()); + + if(page != null) { + if (page.getCatalogItem(itemId).getOfferId() <= 0) { + page = null; + } else if (page.getRank() > this.client.getHabbo().getHabboInfo().getRank().getId()) { + page = null; + } else if (page.getLayout() != null && page.getLayout().equalsIgnoreCase(CatalogPageLayouts.club_gift.name())) { + page = null; + } + } + } + } else { + page = Emulator.getGameEnvironment().getCatalogManager().catalogPages.get(pageId); + + if(page != null && page.getLayout() != null && page.getLayout().equalsIgnoreCase(CatalogPageLayouts.club_gift.name())) { + page = null; + } + + if (page instanceof RoomBundleLayout) { + final CatalogItem[] item = new CatalogItem[1]; + page.getCatalogItems().forEachValue(new TObjectProcedure() { + @Override + public boolean execute(CatalogItem object) { + item[0] = object; + return false; + } + }); + + CatalogItem roomBundleItem = item[0]; + if (roomBundleItem == null || roomBundleItem.getCredits() > this.client.getHabbo().getHabboInfo().getCredits() || roomBundleItem.getPoints() > this.client.getHabbo().getHabboInfo().getCurrencyAmount(roomBundleItem.getPointsType())) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + int roomCount = Emulator.getGameEnvironment().getRoomManager().getRoomsForHabbo(this.client.getHabbo()).size(); + int maxRooms = this.client.getHabbo().getHabboStats().hasActiveClub() ? RoomManager.MAXIMUM_ROOMS_HC : RoomManager.MAXIMUM_ROOMS_USER; + + if (roomCount >= maxRooms) { // checks if a user has the maximum rooms + this.client.sendResponse(new CanCreateRoomComposer(roomCount, maxRooms)); // if so throws the max room error. + this.client.sendResponse(new PurchaseOKComposer(null)); // Send this so the alert disappears, not sure if this is how it should be handled :S + return; + } + ((RoomBundleLayout) page).buyRoom(this.client.getHabbo()); + if (!this.client.getHabbo().hasPermission(Permission.ACC_INFINITE_CREDITS)) { //if the player has this perm disabled + this.client.getHabbo().giveCredits(-roomBundleItem.getCredits()); // takes their credits away + } + if (!this.client.getHabbo().hasPermission(Permission.ACC_INFINITE_POINTS)) { //if the player has this perm disabled + this.client.getHabbo().givePoints(roomBundleItem.getPointsType(), -roomBundleItem.getPoints()); // takes their points away + } + this.client.sendResponse(new PurchaseOKComposer()); // Sends the composer to close the window. + + final boolean[] badgeFound = {false}; + item[0].getBaseItems().stream().filter(i -> i.getType() == FurnitureType.BADGE).forEach(i -> { + if (!this.client.getHabbo().getInventory().getBadgesComponent().hasBadge(i.getName())) { + HabboBadge badge = new HabboBadge(0, i.getName(), 0, this.client.getHabbo()); + Emulator.getThreading().run(badge); + this.client.getHabbo().getInventory().getBadgesComponent().addBadge(badge); + this.client.sendResponse(new AddUserBadgeComposer(badge)); + THashMap keys = new THashMap<>(); + keys.put("display", "BUBBLE"); + keys.put("image", "${image.library.url}album1584/" + badge.getCode() + ".gif"); + keys.put("message", Emulator.getTexts().getValue("commands.generic.cmd_badge.received")); + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.RECEIVED_BADGE.key, keys)); //:test 1992 s:npc.gift.received i:2 s:npc_name s:Admin s:image s:${image.library.url}album1584/ADM.gif); + } else { + badgeFound[0] = true; + } + }); + + if (badgeFound[0]) { + this.client.getHabbo().getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.ALREADY_HAVE_BADGE)); + } + + return; + } + } + + if (page == null) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + return; + } + + if (page.getRank() > this.client.getHabbo().getHabboInfo().getRank().getId()) { + this.client.sendResponse(new AlertPurchaseUnavailableComposer(AlertPurchaseUnavailableComposer.ILLEGAL)); + return; + } + + if (page instanceof ClubBuyLayout || page instanceof VipBuyLayout) { + ClubOffer item = Emulator.getGameEnvironment().getCatalogManager().clubOffers.get(itemId); + + if (item == null) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + return; + } + + int totalDays = 0; + int totalCredits = 0; + int totalDuckets = 0; + + for (int i = 0; i < count; i++) { + totalDays += item.getDays(); + totalCredits += item.getCredits(); + totalDuckets += item.getPoints(); + } + + if (totalDays > 0) { + if (this.client.getHabbo().getHabboInfo().getCurrencyAmount(item.getPointsType()) < totalDuckets) + return; + + if (this.client.getHabbo().getHabboInfo().getCredits() < totalCredits) + return; + + if (!this.client.getHabbo().hasPermission(Permission.ACC_INFINITE_CREDITS)) + this.client.getHabbo().giveCredits(-totalCredits); + + if (!this.client.getHabbo().hasPermission(Permission.ACC_INFINITE_POINTS)) + this.client.getHabbo().givePoints(item.getPointsType(), -totalDuckets); + + + if(this.client.getHabbo().getHabboStats().createSubscription(Subscription.HABBO_CLUB, (totalDays * 86400)) == null) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + throw new Exception("Unable to create or extend subscription"); + } + + /*if (this.client.getHabbo().getHabboStats().getClubExpireTimestamp() <= Emulator.getIntUnixTimestamp()) + this.client.getHabbo().getHabboStats().setClubExpireTimestamp(Emulator.getIntUnixTimestamp()); + + this.client.getHabbo().getHabboStats().setClubExpireTimestamp(this.client.getHabbo().getHabboStats().getClubExpireTimestamp() + (totalDays * 86400)); + + this.client.sendResponse(new UserPermissionsComposer(this.client.getHabbo())); + this.client.sendResponse(new UserClubComposer(this.client.getHabbo()));*/ + + this.client.sendResponse(new PurchaseOKComposer(null)); + this.client.sendResponse(new InventoryRefreshComposer()); + + this.client.getHabbo().getHabboStats().run(); + } + return; + } + + CatalogItem item; + + if (page instanceof RecentPurchasesLayout) + item = this.client.getHabbo().getHabboStats().getRecentPurchases().get(itemId); + + else + item = page.getCatalogItem(itemId); + // temp patch, can a dev with better knowledge than me look into this asap pls. + if (page instanceof BotsLayout) { + if (!this.client.getHabbo().hasPermission(Permission.ACC_UNLIMITED_BOTS) && this.client.getHabbo().getInventory().getBotsComponent().getBots().size() >= BotManager.MAXIMUM_BOT_INVENTORY_SIZE) { + this.client.getHabbo().alert(Emulator.getTexts().getValue("error.bots.max.inventory").replace("%amount%", BotManager.MAXIMUM_BOT_INVENTORY_SIZE + "")); + return; + } + } + if (page instanceof PetsLayout) { // checks it's the petlayout + if (!this.client.getHabbo().hasPermission(Permission.ACC_UNLIMITED_PETS) && this.client.getHabbo().getInventory().getPetsComponent().getPets().size() >= PetManager.MAXIMUM_PET_INVENTORY_SIZE) { + this.client.getHabbo().alert(Emulator.getTexts().getValue("error.pets.max.inventory").replace("%amount%", PetManager.MAXIMUM_PET_INVENTORY_SIZE + "")); + return; + } + String[] check = extraData.split("\n"); // splits the extradata + if ((check.length != 3) || (check[0].length() < PET_NAME_LENGTH_MINIMUM) || (check[0].length() > PET_NAME_LENGTH_MAXIMUM) || (!StringUtils.isAlphanumeric(check[0])))// checks if there's 3 parts (always is with pets, if not it fucks them off) + return; // if it does it fucks off. + } + + Emulator.getGameEnvironment().getCatalogManager().purchaseItem(page, item, this.client.getHabbo(), count, extraData, false); + + } else { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose()); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogRequestClubDiscountEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogRequestClubDiscountEvent.java new file mode 100644 index 0000000..1d5bc5c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogRequestClubDiscountEvent.java @@ -0,0 +1,54 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.habbohotel.catalog.CatalogPageLayouts; +import com.eu.habbo.habbohotel.catalog.ClubOffer; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.users.subscriptions.Subscription; +import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionHabboClub; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.AlertPurchaseFailedComposer; +import com.eu.habbo.messages.outgoing.unknown.ExtendClubMessageComposer; +import com.eu.habbo.messages.outgoing.users.ClubGiftReceivedComposer; +import gnu.trove.set.hash.THashSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CatalogRequestClubDiscountEvent extends MessageHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(CatalogRequestClubDiscountEvent.class); + + @Override + public void handle() throws Exception { + + Subscription subscription = this.client.getHabbo().getHabboStats().getSubscription(SubscriptionHabboClub.HABBO_CLUB); + + int days = 0; + int minutes = 0; + int timeRemaining = 0; + + if(subscription != null) { + timeRemaining = subscription.getRemaining(); + days = (int) Math.floor(timeRemaining / 86400.0); + minutes = (int) Math.ceil(timeRemaining / 60.0); + + if(days < 1 && minutes > 0) { + days = 1; + } + } + + if(timeRemaining > 0 && SubscriptionHabboClub.DISCOUNT_ENABLED && days <= SubscriptionHabboClub.DISCOUNT_DAYS_BEFORE_END) { + ClubOffer deal = Emulator.getGameEnvironment().getCatalogManager().clubOffers.values().stream().filter(ClubOffer::isDeal).findAny().orElse(null); + + if(deal != null) { + ClubOffer regular = Emulator.getGameEnvironment().getCatalogManager().getClubOffers().stream().filter(x -> x.getDays() == deal.getDays()).findAny().orElse(null); + if(regular != null) { + this.client.sendResponse(new ExtendClubMessageComposer(this.client.getHabbo(), deal, regular.getCredits(), regular.getPoints(), regular.getPointsType(), Math.max(0, days))); + } + } + } + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogSearchedItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogSearchedItemEvent.java new file mode 100644 index 0000000..0851e03 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogSearchedItemEvent.java @@ -0,0 +1,36 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.CatalogSearchResultComposer; +import gnu.trove.iterator.TIntObjectIterator; + +public class CatalogSearchedItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int offerId = this.packet.readInt(); + + int pageId = Emulator.getGameEnvironment().getCatalogManager().offerDefs.get(offerId); + + if (pageId != 0) { + CatalogPage page = Emulator.getGameEnvironment().getCatalogManager().getCatalogPage(Emulator.getGameEnvironment().getCatalogManager().getCatalogItem(pageId).getPageId()); + + if (page != null) { + TIntObjectIterator iterator = page.getCatalogItems().iterator(); + + while (iterator.hasNext()) { + iterator.advance(); + + CatalogItem item = iterator.value(); + + if (item.getOfferId() == offerId) { + this.client.sendResponse(new CatalogSearchResultComposer(item)); + return; + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogSelectClubGiftEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogSelectClubGiftEvent.java new file mode 100644 index 0000000..16b4816 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogSelectClubGiftEvent.java @@ -0,0 +1,75 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.habbohotel.catalog.CatalogPageLayouts; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.*; +import com.eu.habbo.messages.outgoing.users.ClubGiftReceivedComposer; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CatalogSelectClubGiftEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + + String itemName = this.packet.readString(); + + if(itemName.isEmpty()) { + log.error("itemName is empty"); + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + + if(this.client.getHabbo().getHabboStats().getRemainingClubGifts() < 1) { + log.error("User has no remaining club gifts"); + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + + CatalogPage page = Emulator.getGameEnvironment().getCatalogManager().getCatalogPageByLayout(CatalogPageLayouts.club_gift.name().toLowerCase()); + + if(page == null) { + log.error("Catalog page not found"); + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + + CatalogItem catalogItem = page.getCatalogItems().valueCollection().stream().filter(x -> x.getName().equalsIgnoreCase(itemName)).findAny().orElse(null); + + if(catalogItem == null) { + log.error("Catalog item not found"); + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + + int daysRequired = 0; + try { + daysRequired = Integer.parseInt(catalogItem.getExtradata()); + } + catch (NumberFormatException ignored) { } + + if(daysRequired > (int) Math.floor(this.client.getHabbo().getHabboStats().getPastTimeAsClub() / 86400.0)) { + log.error("Not been member for long enough"); + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + + THashSet itemsGiven = new THashSet<>(); + for(Item item : catalogItem.getBaseItems()) { + if(Emulator.getGameEnvironment().getItemManager().createGift(this.client.getHabbo().getHabboInfo().getId(), item, "", 0, 0) != null) { + itemsGiven.add(item); + } + } + + this.client.getHabbo().getHabboStats().hcGiftsClaimed++; + Emulator.getThreading().run(this.client.getHabbo().getHabboStats()); + + this.client.sendResponse(new ClubGiftReceivedComposer(itemName, itemsGiven)); + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CheckPetNameEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CheckPetNameEvent.java new file mode 100644 index 0000000..6b1726b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/CheckPetNameEvent.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.PetNameErrorComposer; +import org.apache.commons.lang3.StringUtils; + +public class CheckPetNameEvent extends MessageHandler { + public static int PET_NAME_LENGTH_MINIMUM = Emulator.getConfig().getInt("hotel.pets.name.length.min"); + public static int PET_NAME_LENGTH_MAXIMUM = Emulator.getConfig().getInt("hotel.pets.name.length.max"); + + @Override + public void handle() throws Exception { + String petName = this.packet.readString(); + + if (petName.length() < PET_NAME_LENGTH_MINIMUM) { + this.client.sendResponse(new PetNameErrorComposer(PetNameErrorComposer.NAME_TO_SHORT, PET_NAME_LENGTH_MINIMUM + "")); + } else if (petName.length() > PET_NAME_LENGTH_MAXIMUM) { + this.client.sendResponse(new PetNameErrorComposer(PetNameErrorComposer.NAME_TO_LONG, PET_NAME_LENGTH_MAXIMUM + "")); + } else if (!StringUtils.isAlphanumeric(petName)) { + this.client.sendResponse(new PetNameErrorComposer(PetNameErrorComposer.FORBIDDEN_CHAR, petName)); + } else { + this.client.sendResponse(new PetNameErrorComposer(PetNameErrorComposer.NAME_OK, petName)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/JukeBoxRequestTrackCodeEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/JukeBoxRequestTrackCodeEvent.java new file mode 100644 index 0000000..d53c534 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/JukeBoxRequestTrackCodeEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.SoundTrack; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.items.jukebox.JukeBoxTrackCodeComposer; + +public class JukeBoxRequestTrackCodeEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String songName = this.packet.readString(); + + final SoundTrack track = Emulator.getGameEnvironment().getItemManager().getSoundTrack(songName); + + if (track != null) { + this.client.sendResponse(new JukeBoxTrackCodeComposer(track)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/JukeBoxRequestTrackDataEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/JukeBoxRequestTrackDataEvent.java new file mode 100644 index 0000000..de8c2c6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/JukeBoxRequestTrackDataEvent.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.SoundTrack; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.items.jukebox.JukeBoxTrackDataComposer; + +import java.util.ArrayList; +import java.util.List; + +public class JukeBoxRequestTrackDataEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int count = this.packet.readInt(); + + List tracks = new ArrayList<>(count); + + for (int i = 0; i < count; i++) { + SoundTrack track = Emulator.getGameEnvironment().getItemManager().getSoundTrack(this.packet.readInt()); + + if (track != null) + tracks.add(track); + } + + this.client.sendResponse(new JukeBoxTrackDataComposer(tracks)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/PurchaseTargetOfferEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/PurchaseTargetOfferEvent.java new file mode 100644 index 0000000..3ef97b2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/PurchaseTargetOfferEvent.java @@ -0,0 +1,42 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.habbohotel.catalog.CatalogManager; +import com.eu.habbo.habbohotel.catalog.TargetOffer; +import com.eu.habbo.habbohotel.users.cache.HabboOfferPurchase; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class PurchaseTargetOfferEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + int offerId = this.packet.readInt(); + int amount = this.packet.readInt(); + + if (amount <= 0) return; + + + if (Emulator.getIntUnixTimestamp() - this.client.getHabbo().getHabboStats().lastPurchaseTimestamp >= CatalogManager.PURCHASE_COOLDOWN) { + this.client.getHabbo().getHabboStats().lastPurchaseTimestamp = Emulator.getIntUnixTimestamp(); + + TargetOffer offer = Emulator.getGameEnvironment().getCatalogManager().getTargetOffer(offerId); + + HabboOfferPurchase purchase = HabboOfferPurchase.getOrCreate(this.client.getHabbo(), offerId); + + if (purchase != null) { + amount = Math.min(offer.getPurchaseLimit() - purchase.getAmount(), amount); + int now = Emulator.getIntUnixTimestamp(); + if (offer.getExpirationTime() > now) { + purchase.update(amount, now); + CatalogItem item = Emulator.getGameEnvironment().getCatalogManager().getCatalogItem(offer.getCatalogItem()); + if (item.isLimited()) { + amount = 1; + } + Emulator.getGameEnvironment().getCatalogManager().purchaseItem(null, item, this.client.getHabbo(), amount, "", false); + + } + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RedeemVoucherEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RedeemVoucherEvent.java new file mode 100644 index 0000000..5923398 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RedeemVoucherEvent.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.RedeemVoucherErrorComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.HotelWillCloseInMinutesComposer; +import com.eu.habbo.threading.runnables.ShutdownEmulator; + +public class RedeemVoucherEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (ShutdownEmulator.timestamp > 0) { + this.client.sendResponse(new HotelWillCloseInMinutesComposer((ShutdownEmulator.timestamp - Emulator.getIntUnixTimestamp()) / 60)); + return; + } + + String voucherCode = this.packet.readString(); + + if (voucherCode.contains(" ")) { + this.client.sendResponse(new RedeemVoucherErrorComposer(RedeemVoucherErrorComposer.TECHNICAL_ERROR)); + return; + } + + Emulator.getGameEnvironment().getCatalogManager().redeemVoucher(this.client, voucherCode); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestCatalogIndexEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestCatalogIndexEvent.java new file mode 100644 index 0000000..5aa476f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestCatalogIndexEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.messages.incoming.MessageHandler; + +public class RequestCatalogIndexEvent extends MessageHandler { + @Override + public void handle() throws Exception { + //this.client.sendResponse(new CatalogPagesListComposer(this.client.getHabbo(), "NORMAL")); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestCatalogModeEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestCatalogModeEvent.java new file mode 100644 index 0000000..9e54083 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestCatalogModeEvent.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.CatalogModeComposer; +import com.eu.habbo.messages.outgoing.catalog.CatalogPagesListComposer; + +public class RequestCatalogModeEvent extends MessageHandler { + @Override + public void handle() throws Exception { + + String MODE = this.packet.readString(); + if (MODE.equalsIgnoreCase("normal")) { + this.client.sendResponse(new CatalogModeComposer(0)); + this.client.sendResponse(new CatalogPagesListComposer(this.client.getHabbo(), MODE)); + } else { + this.client.sendResponse(new CatalogModeComposer(1)); + this.client.sendResponse(new CatalogPagesListComposer(this.client.getHabbo(), MODE)); + } + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestCatalogPageEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestCatalogPageEvent.java new file mode 100644 index 0000000..0198c01 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestCatalogPageEvent.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.CatalogPageComposer; + +public class RequestCatalogPageEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + int catalogPageId = this.packet.readInt(); + int offerId = this.packet.readInt(); + String mode = this.packet.readString(); + + CatalogPage page = Emulator.getGameEnvironment().getCatalogManager().catalogPages.get(catalogPageId); + + if (catalogPageId > 0 && page != null) { + if (page.getRank() <= this.client.getHabbo().getHabboInfo().getRank().getId() && page.isEnabled()) { + this.client.sendResponse(new CatalogPageComposer(page, this.client.getHabbo(), offerId, mode)); + } else { + if (!page.isVisible()) { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.catalog.page").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()).replace("%pagename%", page.getCaption())); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestClubDataEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestClubDataEvent.java new file mode 100644 index 0000000..6085e1e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestClubDataEvent.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionHabboClub; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.ClubCenterDataComposer; +import com.eu.habbo.messages.outgoing.catalog.ClubDataComposer; + +public class RequestClubDataEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new ClubDataComposer(this.client.getHabbo(), this.packet.readInt())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestClubGiftsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestClubGiftsEvent.java new file mode 100644 index 0000000..777e65f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestClubGiftsEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.ClubGiftsComposer; + +public class RequestClubGiftsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new ClubGiftsComposer( + (int) Math.floor(this.client.getHabbo().getHabboStats().getTimeTillNextClubGift() / 86400.0), + this.client.getHabbo().getHabboStats().getRemainingClubGifts(), + (int) Math.floor(this.client.getHabbo().getHabboStats().getPastTimeAsClub() / 86400.0) + )); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestDiscountEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestDiscountEvent.java new file mode 100644 index 0000000..fa240d8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestDiscountEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.DiscountComposer; + +public class RequestDiscountEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new DiscountComposer()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestGiftConfigurationEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestGiftConfigurationEvent.java new file mode 100644 index 0000000..7976ee3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestGiftConfigurationEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.GiftConfigurationComposer; + +public class RequestGiftConfigurationEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new GiftConfigurationComposer()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestMarketplaceConfigEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestMarketplaceConfigEvent.java new file mode 100644 index 0000000..8442fd6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestMarketplaceConfigEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.marketplace.MarketplaceConfigComposer; + +public class RequestMarketplaceConfigEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new MarketplaceConfigComposer()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestPetBreedsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestPetBreedsEvent.java new file mode 100644 index 0000000..5d005da --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestPetBreedsEvent.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.PetBreedsComposer; + +public class RequestPetBreedsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String petName = this.packet.readString(); + this.client.sendResponse(new PetBreedsComposer(petName, Emulator.getGameEnvironment().getPetManager().getBreeds(petName))); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/TargetOfferStateEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/TargetOfferStateEvent.java new file mode 100644 index 0000000..9d62582 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/TargetOfferStateEvent.java @@ -0,0 +1,17 @@ +package com.eu.habbo.messages.incoming.catalog; + +import com.eu.habbo.habbohotel.users.cache.HabboOfferPurchase; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class TargetOfferStateEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int id = this.packet.readInt(); + int state = this.packet.readInt(); + + HabboOfferPurchase purchase = this.client.getHabbo().getHabboStats().getHabboOfferPurchase(id); + if (purchase != null) { + purchase.setState(state); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/BuyItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/BuyItemEvent.java new file mode 100644 index 0000000..b9af0be --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/BuyItemEvent.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.incoming.catalog.marketplace; + +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlace; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class BuyItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int offerId = this.packet.readInt(); + + MarketPlace.buyItem(offerId, this.client); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestCreditsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestCreditsEvent.java new file mode 100644 index 0000000..b03fda1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestCreditsEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.catalog.marketplace; + +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlace; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class RequestCreditsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + MarketPlace.getCredits(this.client); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestItemInfoEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestItemInfoEvent.java new file mode 100644 index 0000000..45c043f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestItemInfoEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.incoming.catalog.marketplace; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.marketplace.MarketplaceItemInfoComposer; + +public class RequestItemInfoEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.packet.readInt(); + int id = this.packet.readInt(); + + this.client.sendResponse(new MarketplaceItemInfoComposer(id)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestOffersEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestOffersEvent.java new file mode 100644 index 0000000..c091c1b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestOffersEvent.java @@ -0,0 +1,45 @@ +package com.eu.habbo.messages.incoming.catalog.marketplace; + +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlace; +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlaceOffer; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.marketplace.MarketplaceOffersComposer; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class RequestOffersEvent extends MessageHandler { + public final static Map cachedResults = new ConcurrentHashMap<>(0); + + @Override + public void handle() throws Exception { + int min = this.packet.readInt(); + int max = this.packet.readInt(); + String query = this.packet.readString(); + int type = this.packet.readInt(); + + boolean tryCache = false; + if (min == -1 && max == -1 && query.isEmpty()) { + tryCache = true; + } + + if (tryCache) { + ServerMessage message = cachedResults.get(type); + if (message != null) { + this.client.sendResponse(message); + return; + } + } + + List offers = MarketPlace.getOffers(min, max, query, type); + + ServerMessage message = new MarketplaceOffersComposer(offers).compose(); + if (tryCache) { + cachedResults.put(type, message); + } + + this.client.sendResponse(message); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestOwnItemsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestOwnItemsEvent.java new file mode 100644 index 0000000..ddfb95a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestOwnItemsEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.catalog.marketplace; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.marketplace.MarketplaceOwnItemsComposer; + +public class RequestOwnItemsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new MarketplaceOwnItemsComposer(this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestSellItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestSellItemEvent.java new file mode 100644 index 0000000..452c74c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/RequestSellItemEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.messages.incoming.catalog.marketplace; + +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlace; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.marketplace.MarketplaceSellItemComposer; + +public class RequestSellItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (MarketPlace.MARKETPLACE_ENABLED) + this.client.sendResponse(new MarketplaceSellItemComposer(1, 0, 0)); + else + this.client.sendResponse(new MarketplaceSellItemComposer(3, 0, 0)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/SellItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/SellItemEvent.java new file mode 100644 index 0000000..b3ec58d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/SellItemEvent.java @@ -0,0 +1,53 @@ +package com.eu.habbo.messages.incoming.catalog.marketplace; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlace; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.AlertPurchaseFailedComposer; +import com.eu.habbo.messages.outgoing.catalog.marketplace.MarketplaceItemPostedComposer; +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +public class SellItemEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + if (!MarketPlace.MARKETPLACE_ENABLED) { + this.client.sendResponse(new MarketplaceItemPostedComposer(MarketplaceItemPostedComposer.MARKETPLACE_DISABLED)); + return; + } + + int credits = this.packet.readInt(); + + int unknown = this.packet.readInt(); + int itemId = this.packet.readInt(); + + HabboItem item = this.client.getHabbo().getInventory().getItemsComponent().getHabboItem(itemId); + if (item != null) { + if (!item.getBaseItem().allowMarketplace()) { + String message = Emulator.getTexts().getValue("scripter.warning.marketplace.forbidden").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()).replace("%itemname%", item.getBaseItem().getName()).replace("%credits%", credits + ""); + ScripterManager.scripterDetected(this.client, message); + log.info(message); + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + + if (credits < 0) { + String message = Emulator.getTexts().getValue("scripter.warning.marketplace.negative").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()).replace("%itemname%", item.getBaseItem().getName()).replace("%credits%", credits + ""); + ScripterManager.scripterDetected(this.client, message); + log.info(message); + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + + if (MarketPlace.sellItem(this.client, item, credits)) { + this.client.sendResponse(new MarketplaceItemPostedComposer(MarketplaceItemPostedComposer.POST_SUCCESS)); + } else { + this.client.sendResponse(new MarketplaceItemPostedComposer(MarketplaceItemPostedComposer.FAILED_TECHNICAL_ERROR)); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/TakeBackItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/TakeBackItemEvent.java new file mode 100644 index 0000000..7586afc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/marketplace/TakeBackItemEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.catalog.marketplace; + +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlace; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class TakeBackItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int offerId = this.packet.readInt(); + MarketPlace.takeBackItem(this.client.getHabbo(), offerId); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/OpenRecycleBoxEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/OpenRecycleBoxEvent.java new file mode 100644 index 0000000..f950858 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/OpenRecycleBoxEvent.java @@ -0,0 +1,71 @@ +package com.eu.habbo.messages.incoming.catalog.recycler; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionGift; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.rooms.UpdateStackHeightComposer; +import com.eu.habbo.messages.outgoing.rooms.items.PresentItemOpenedComposer; +import com.eu.habbo.messages.outgoing.rooms.items.RemoveFloorItemComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserWhisperComposer; +import com.eu.habbo.threading.runnables.OpenGift; + +public class OpenRecycleBoxEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + if (room.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER)) { + HabboItem item = room.getHabboItem(this.packet.readInt()); + + if (item == null) + return; + + if (item instanceof InteractionGift) { + if (item.getBaseItem().getName().contains("present_wrap")) { + ((InteractionGift) item).explode = true; + room.updateItem(item); + } + + Emulator.getThreading().run(new OpenGift(item, this.client.getHabbo(), room), item.getBaseItem().getName().contains("present_wrap") ? 1000 : 0); + } else { + if (item.getExtradata().length() == 0) { + this.client.sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(Emulator.getTexts().getValue("error.recycler.box.empty"), this.client.getHabbo(), this.client.getHabbo(), RoomChatMessageBubbles.BOT))); + } else { + HabboItem reward = Emulator.getGameEnvironment().getItemManager().handleOpenRecycleBox(this.client.getHabbo(), item); + + if (reward != null) { + this.client.getHabbo().getInventory().getItemsComponent().addItem(reward); + this.client.sendResponse(new AddHabboItemComposer(reward)); + this.client.sendResponse(new InventoryRefreshComposer()); + + this.client.sendResponse(new PresentItemOpenedComposer(reward, item.getExtradata(), true)); + } + } + room.sendComposer(new RemoveFloorItemComposer(item).compose()); + room.removeHabboItem(item); + + } + + if (item.getRoomId() == 0) { + room.updateTile(room.getLayout().getTile(item.getX(), item.getY())); + RoomLayout roomLayout = room.getLayout(); + short z = (short)room.getStackHeight(item.getX(), item.getY(), true); + if(roomLayout != null) { + RoomTile roomTile = roomLayout.getTile(item.getX(), item.getY()); + if(roomTile != null) { + z = roomTile.z; + } + } + room.sendComposer(new UpdateStackHeightComposer(item.getX(), item.getY(), z, room.getStackHeight(item.getX(), item.getY(), true)).compose()); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/RecycleEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/RecycleEvent.java new file mode 100644 index 0000000..05b6fc3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/RecycleEvent.java @@ -0,0 +1,70 @@ +package com.eu.habbo.messages.incoming.catalog.recycler; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.items.ItemManager; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.AlertPurchaseFailedComposer; +import com.eu.habbo.messages.outgoing.catalog.RecyclerCompleteComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.HotelWillCloseInMinutesComposer; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.inventory.RemoveHabboItemComposer; +import com.eu.habbo.threading.runnables.QueryDeleteHabboItem; +import com.eu.habbo.threading.runnables.ShutdownEmulator; +import gnu.trove.set.hash.THashSet; + +public class RecycleEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (ShutdownEmulator.timestamp > 0) { + this.client.sendResponse(new HotelWillCloseInMinutesComposer((ShutdownEmulator.timestamp - Emulator.getIntUnixTimestamp()) / 60)); + return; + } + + if (Emulator.getGameEnvironment().getCatalogManager().ecotronItem != null && ItemManager.RECYCLER_ENABLED) { + THashSet items = new THashSet<>(); + + int count = this.packet.readInt(); + if (count < Emulator.getConfig().getInt("recycler.value", 8)) return; + + for (int i = 0; i < count; i++) { + HabboItem item = this.client.getHabbo().getInventory().getItemsComponent().getHabboItem(this.packet.readInt()); + + if (item == null) + return; + + if (item.getBaseItem().allowRecyle()) { + items.add(item); + } + } + + if (items.size() == count) { + for (HabboItem item : items) { + this.client.getHabbo().getInventory().getItemsComponent().removeHabboItem(item); + this.client.sendResponse(new RemoveHabboItemComposer(item.getGiftAdjustedId())); + Emulator.getThreading().run(new QueryDeleteHabboItem(item.getId())); + } + } else { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + + HabboItem reward = Emulator.getGameEnvironment().getItemManager().handleRecycle(this.client.getHabbo(), Emulator.getGameEnvironment().getCatalogManager().getRandomRecyclerPrize().getId() + ""); + if (reward == null) { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + + this.client.sendResponse(new AddHabboItemComposer(reward)); + this.client.getHabbo().getInventory().getItemsComponent().addItem(reward); + this.client.sendResponse(new RecyclerCompleteComposer(RecyclerCompleteComposer.RECYCLING_COMPLETE)); + this.client.sendResponse(new InventoryRefreshComposer()); + + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("FurnimaticQuest")); + } else { + this.client.sendResponse(new RecyclerCompleteComposer(RecyclerCompleteComposer.RECYCLING_CLOSED)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/ReloadRecyclerEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/ReloadRecyclerEvent.java new file mode 100644 index 0000000..34fddc6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/ReloadRecyclerEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.catalog.recycler; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.ReloadRecyclerComposer; + +public class ReloadRecyclerEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new ReloadRecyclerComposer()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/RequestRecyclerLogicEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/RequestRecyclerLogicEvent.java new file mode 100644 index 0000000..0da41c0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/RequestRecyclerLogicEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.catalog.recycler; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.RecyclerLogicComposer; + +public class RequestRecyclerLogicEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new RecyclerLogicComposer()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingAddRecipeEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingAddRecipeEvent.java new file mode 100644 index 0000000..277eb19 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingAddRecipeEvent.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.incoming.crafting; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.crafting.CraftingRecipe; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.AlertLimitedSoldOutComposer; +import com.eu.habbo.messages.outgoing.crafting.CraftingRecipeComposer; + +public class CraftingAddRecipeEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String recipeName = this.packet.readString(); + CraftingRecipe recipe = Emulator.getGameEnvironment().getCraftingManager().getRecipe(recipeName); + + if (recipe != null) { + if (!recipe.canBeCrafted()) { + this.client.sendResponse(new AlertLimitedSoldOutComposer()); + return; + } + + this.client.sendResponse(new CraftingRecipeComposer(recipe)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingCraftItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingCraftItemEvent.java new file mode 100644 index 0000000..3887c6a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingCraftItemEvent.java @@ -0,0 +1,78 @@ +package com.eu.habbo.messages.incoming.crafting; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.crafting.CraftingAltar; +import com.eu.habbo.habbohotel.crafting.CraftingRecipe; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.AlertLimitedSoldOutComposer; +import com.eu.habbo.messages.outgoing.crafting.CraftingResultComposer; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.inventory.RemoveHabboItemComposer; +import com.eu.habbo.threading.runnables.QueryDeleteHabboItems; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.procedure.TObjectProcedure; + +import java.util.Map; + +public class CraftingCraftItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int craftingTable = this.packet.readInt(); + HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(craftingTable); + CraftingAltar altar = Emulator.getGameEnvironment().getCraftingManager().getAltar(item.getBaseItem()); + CraftingRecipe recipe = altar.getRecipe(this.packet.readString()); + + if (recipe != null) { + if (!recipe.canBeCrafted()) { + this.client.sendResponse(new AlertLimitedSoldOutComposer()); + return; + } + + TIntObjectHashMap toRemove = new TIntObjectHashMap<>(); + for (Map.Entry set : recipe.getIngredients().entrySet()) { + for (int i = 0; i < set.getValue(); i++) { + HabboItem habboItem = this.client.getHabbo().getInventory().getItemsComponent().getAndRemoveHabboItem(set.getKey()); + + if (habboItem == null) { + return; + } + + toRemove.put(habboItem.getId(), habboItem); + } + } + + HabboItem rewardItem = Emulator.getGameEnvironment().getItemManager().createItem(this.client.getHabbo().getHabboInfo().getId(), recipe.getReward(), 0, 0, ""); + + if (rewardItem != null) { + if (recipe.isLimited()) { + recipe.decrease(); + } + + if (!recipe.getAchievement().isEmpty()) { + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement(recipe.getAchievement())); + + } + + this.client.sendResponse(new CraftingResultComposer(recipe)); + this.client.getHabbo().getInventory().getItemsComponent().addItem(rewardItem); + this.client.sendResponse(new AddHabboItemComposer(rewardItem)); + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("Atcg")); + toRemove.forEachValue(object -> { + CraftingCraftItemEvent.this.client.sendResponse(new RemoveHabboItemComposer(object.getGiftAdjustedId())); + return true; + }); + this.client.sendResponse(new InventoryRefreshComposer()); + + Emulator.getThreading().run(new QueryDeleteHabboItems(toRemove)); + return; + } + + } + + this.client.sendResponse(new CraftingResultComposer(null)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingCraftSecretEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingCraftSecretEvent.java new file mode 100644 index 0000000..f93f208 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingCraftSecretEvent.java @@ -0,0 +1,95 @@ +package com.eu.habbo.messages.incoming.crafting; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.crafting.CraftingAltar; +import com.eu.habbo.habbohotel.crafting.CraftingRecipe; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.AlertLimitedSoldOutComposer; +import com.eu.habbo.messages.outgoing.crafting.CraftingResultComposer; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.inventory.RemoveHabboItemComposer; +import com.eu.habbo.threading.runnables.QueryDeleteHabboItem; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + +import java.util.Map; +import java.util.Set; + +public class CraftingCraftSecretEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int altarId = this.packet.readInt(); + int count = this.packet.readInt(); + + HabboItem craftingAltar = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(altarId); + + if (craftingAltar != null) { + CraftingAltar altar = Emulator.getGameEnvironment().getCraftingManager().getAltar(craftingAltar.getBaseItem()); + + if (altar != null) { + Set habboItems = new THashSet<>(); + Map items = new THashMap<>(); + + for (int i = 0; i < count; i++) { + HabboItem habboItem = this.client.getHabbo().getInventory().getItemsComponent().getHabboItem(this.packet.readInt()); + + if (habboItem == null) { + this.client.sendResponse(new CraftingResultComposer(null)); + return; + } + + habboItems.add(habboItem); + + if (!items.containsKey(habboItem.getBaseItem())) { + items.put(habboItem.getBaseItem(), 0); + } + + items.put(habboItem.getBaseItem(), items.get(habboItem.getBaseItem()) + 1); + } + + CraftingRecipe recipe = altar.getRecipe(items); + + if (recipe != null) { + if (!recipe.canBeCrafted()) { + this.client.sendResponse(new AlertLimitedSoldOutComposer()); + return; + } + + HabboItem rewardItem = Emulator.getGameEnvironment().getItemManager().createItem(this.client.getHabbo().getHabboInfo().getId(), recipe.getReward(), 0, 0, ""); + + if (rewardItem != null) { + if (recipe.isLimited()) { + recipe.decrease(); + } + + if (!recipe.getAchievement().isEmpty()) { + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement(recipe.getAchievement())); + } + + this.client.sendResponse(new CraftingResultComposer(recipe)); + if (!this.client.getHabbo().getHabboStats().hasRecipe(recipe.getId())) { + this.client.getHabbo().getHabboStats().addRecipe(recipe.getId()); + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("AtcgSecret")); + } + this.client.getHabbo().getInventory().getItemsComponent().addItem(rewardItem); + this.client.sendResponse(new AddHabboItemComposer(rewardItem)); + for (HabboItem item : habboItems) { + this.client.getHabbo().getInventory().getItemsComponent().removeHabboItem(item); + this.client.sendResponse(new RemoveHabboItemComposer(item.getGiftAdjustedId())); + Emulator.getThreading().run(new QueryDeleteHabboItem(item.getId())); + } + this.client.sendResponse(new InventoryRefreshComposer()); + + return; + } + } + } + } + + this.client.sendResponse(new CraftingResultComposer(null)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/RequestCraftingRecipesAvailableEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/RequestCraftingRecipesAvailableEvent.java new file mode 100644 index 0000000..cb709d1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/RequestCraftingRecipesAvailableEvent.java @@ -0,0 +1,64 @@ +package com.eu.habbo.messages.incoming.crafting; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.crafting.CraftingAltar; +import com.eu.habbo.habbohotel.crafting.CraftingRecipe; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.crafting.CraftingRecipesAvailableComposer; +import gnu.trove.map.hash.THashMap; + +import java.util.Map; + +public class RequestCraftingRecipesAvailableEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int altarId = this.packet.readInt(); + + HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(altarId); + + CraftingAltar altar = Emulator.getGameEnvironment().getCraftingManager().getAltar(item.getBaseItem()); + + if (altar != null) { + Map items = new THashMap<>(); + + int count = this.packet.readInt(); + for (int i = 0; i < count; i++) { + HabboItem habboItem = this.client.getHabbo().getInventory().getItemsComponent().getHabboItem(this.packet.readInt()); + + if (habboItem != null) { + if (!items.containsKey(habboItem.getBaseItem())) { + items.put(habboItem.getBaseItem(), 0); + } + + items.put(habboItem.getBaseItem(), items.get(habboItem.getBaseItem()) + 1); + } + } + + CraftingRecipe equalsRecipe = altar.getRecipe(items); + if (equalsRecipe != null && this.client.getHabbo().getHabboStats().hasRecipe(equalsRecipe.getId())) { + //this.client.sendResponse(new CraftingRecipesAvailableComposer(-1, true)); + //this.client.sendResponse(new CraftingRecipeComposer(equalsRecipe)); + //this.client.sendResponse(new CraftingResultComposer(equalsRecipe, true)); + return; + } + Map recipes = altar.matchRecipes(items); + + boolean found = false; + int c = recipes.size(); + for (Map.Entry set : recipes.entrySet()) { + if (this.client.getHabbo().getHabboStats().hasRecipe(set.getKey().getId())) { + c--; + continue; + } + + if (set.getValue()) { + found = true; + break; + } + } + this.client.sendResponse(new CraftingRecipesAvailableComposer(c, found)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/RequestCraftingRecipesEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/RequestCraftingRecipesEvent.java new file mode 100644 index 0000000..2b4b30a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/crafting/RequestCraftingRecipesEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.incoming.crafting; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.crafting.CraftingAltar; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.crafting.CraftableProductsComposer; + +public class RequestCraftingRecipesEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId); + + if (item != null) { + CraftingAltar altar = Emulator.getGameEnvironment().getCraftingManager().getAltar(item.getBaseItem()); + + if (altar != null) { + this.client.sendResponse(new CraftableProductsComposer(altar.getRecipesForHabbo(this.client.getHabbo()), altar.getIngredients())); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarForceOpenEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarForceOpenEvent.java new file mode 100644 index 0000000..bca8c1d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarForceOpenEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.incoming.events.calendar; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class AdventCalendarForceOpenEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String campaignName = this.packet.readString(); + int day = this.packet.readInt(); + + Emulator.getGameEnvironment().getCalendarManager().claimCalendarReward(this.client.getHabbo(), campaignName, day, true); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarOpenDayEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarOpenDayEvent.java new file mode 100644 index 0000000..5897027 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarOpenDayEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.incoming.events.calendar; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class AdventCalendarOpenDayEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String campaignName = this.packet.readString(); + int day = this.packet.readInt(); + + Emulator.getGameEnvironment().getCalendarManager().claimCalendarReward(this.client.getHabbo(), campaignName, day, false); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorRequestBlockedTilesEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorRequestBlockedTilesEvent.java new file mode 100644 index 0000000..9599edf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorRequestBlockedTilesEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.incoming.floorplaneditor; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.floorplaneditor.FloorPlanEditorBlockedTilesComposer; + +public class FloorPlanEditorRequestBlockedTilesEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() == null) + return; + + this.client.sendResponse(new FloorPlanEditorBlockedTilesComposer(this.client.getHabbo().getHabboInfo().getCurrentRoom())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorRequestDoorSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorRequestDoorSettingsEvent.java new file mode 100644 index 0000000..a2de884 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorRequestDoorSettingsEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.messages.incoming.floorplaneditor; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.floorplaneditor.FloorPlanEditorDoorSettingsComposer; +import com.eu.habbo.messages.outgoing.rooms.RoomFloorThicknessUpdatedComposer; + +public class FloorPlanEditorRequestDoorSettingsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() == null) + return; + + this.client.sendResponse(new FloorPlanEditorDoorSettingsComposer(this.client.getHabbo().getHabboInfo().getCurrentRoom())); + this.client.sendResponse(new RoomFloorThicknessUpdatedComposer(this.client.getHabbo().getHabboInfo().getCurrentRoom())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorSaveEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorSaveEvent.java new file mode 100644 index 0000000..0056cdb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorSaveEvent.java @@ -0,0 +1,183 @@ +package com.eu.habbo.messages.incoming.floorplaneditor; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.generic.alerts.GenericAlertComposer; +import com.eu.habbo.messages.outgoing.rooms.ForwardToRoomComposer; +import gnu.trove.set.hash.THashSet; + +import java.util.*; + +public class FloorPlanEditorSaveEvent extends MessageHandler { + public static int MAXIMUM_FLOORPLAN_WIDTH_LENGTH = 100; + public static int MAXIMUM_FLOORPLAN_SIZE = 100 * 100; + + @Override + public void handle() throws Exception { + if (!this.client.getHabbo().hasPermission(Permission.ACC_FLOORPLAN_EDITOR)) { + this.client.sendResponse(new GenericAlertComposer(Emulator.getTexts().getValue("floorplan.permission"))); + return; + } + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + if (room.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER)) { + StringJoiner errors = new StringJoiner("
"); + String map = this.packet.readString(); + map = map.replace("X", "x"); + + String[] mapRows = map.split("\r"); + + int firstRowSize = mapRows[0].length(); + + if (Emulator.getConfig().getBoolean("hotel.room.floorplan.check.enabled")) { + if (!map.matches("[a-zA-Z0-9\r]+")) errors.add("${notification.floorplan_editor.error.title}"); + + Arrays.stream(mapRows) + .filter(line -> line.length() != firstRowSize) + .findAny() + .ifPresent(s -> errors.add("(General): Line " + (Arrays.asList(mapRows).indexOf(s) + 1) + " is of different length than line 1")); + + if (map.isEmpty() || map.replace("x", "").replace("\r", "").isEmpty()) { + errors.add("${notification.floorplan_editor.error.message.effective_height_is_0}"); + } + + if (map.length() > MAXIMUM_FLOORPLAN_SIZE) { + errors.add("${notification.floorplan_editor.error.message.too_large_area}"); + } + + if (mapRows.length > MAXIMUM_FLOORPLAN_WIDTH_LENGTH) errors.add("${notification.floorplan_editor.error.message.too_large_height}"); + else if (Arrays.stream(mapRows).anyMatch(l -> l.length() > MAXIMUM_FLOORPLAN_WIDTH_LENGTH || l.length() == 0)) errors.add("${notification.floorplan_editor.error.message.too_large_width}"); + + if (errors.length() > 0) { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FLOORPLAN_EDITOR_ERROR.key, errors.toString())); + return; + } + } + + int doorX = this.packet.readInt(); + int doorY = this.packet.readInt(); + + if (doorX < 0 || doorX > firstRowSize || doorY < 0 || doorY >= mapRows.length) { + errors.add("${notification.floorplan_editor.error.message.entry_tile_outside_map}"); + } + + if (doorY < mapRows.length && doorX < mapRows[doorY].length() && mapRows[doorY].charAt(doorX) == 'x') { + errors.add("${notification.floorplan_editor.error.message.entry_not_on_tile}"); + } + + int doorRotation = this.packet.readInt(); + if (doorRotation < 0 || doorRotation > 7) { + errors.add("${notification.floorplan_editor.error.message.invalid_entry_tile_direction}"); + } + + int wallSize = this.packet.readInt(); + if (wallSize < -2 || wallSize > 1) { + errors.add("${notification.floorplan_editor.error.message.invalid_wall_thickness}"); + } + int floorSize = this.packet.readInt(); + if (floorSize < -2 || floorSize > 1) { + errors.add("${notification.floorplan_editor.error.message.invalid_floor_thickness}"); + } + + int wallHeight = -1; + if (this.packet.bytesAvailable() >= 4) + wallHeight = this.packet.readInt(); + + if (wallHeight < -1 || wallHeight > 15) { + errors.add("${notification.floorplan_editor.error.message.invalid_walls_fixed_height}"); + } + + THashSet locked_tileList = room.getLockedTiles(); + THashSet new_tileList = new THashSet<>(); + blockingRoomItemScan: + for (int y = 0; y < mapRows.length; y++) { + for (int x = 0; x < firstRowSize; x++) { + + RoomTile tile = room.getLayout().getTile((short) x, (short) y); + new_tileList.add(tile); + String square = String.valueOf(mapRows[y].charAt(x)); + short height; + + if (square.equalsIgnoreCase("x") && room.getTopItemAt(x, y) != null) { + errors.add("${notification.floorplan_editor.error.message.change_blocked_by_room_item}"); + break blockingRoomItemScan; + } else { + if (square.isEmpty()) { + height = 0; + } else if (Emulator.isNumeric(square)) { + height = Short.parseShort(square); + } else { + height = (short) (10 + "ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(square.toUpperCase())); + } + } + + if (tile != null && tile.state != RoomTileState.INVALID && height != tile.z && room.getTopItemAt(x, y) != null) { + errors.add("${notification.floorplan_editor.error.message.change_blocked_by_room_item}"); + break blockingRoomItemScan; + } + } + } + + locked_tileList.removeAll(new_tileList); + if (!locked_tileList.isEmpty()) { + errors.add("${notification.floorplan_editor.error.message.change_blocked_by_room_item}"); + } + + + + if (errors.length() > 0) { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FLOORPLAN_EDITOR_ERROR.key, errors.toString())); + return; + } + + RoomLayout layout = room.getLayout(); + + if (layout instanceof CustomRoomLayout) { + layout.setDoorX((short) doorX); + layout.setDoorY((short) doorY); + layout.setDoorDirection(doorRotation); + layout.setHeightmap(map); + layout.parse(); + + if (layout.getDoorTile() == null) { + this.client.getHabbo().alert("Error"); + ((CustomRoomLayout) layout).needsUpdate(false); + Emulator.getGameEnvironment().getRoomManager().unloadRoom(room); + return; + } + ((CustomRoomLayout) layout).needsUpdate(true); + Emulator.getThreading().run((CustomRoomLayout) layout); + } else { + layout = Emulator.getGameEnvironment().getRoomManager().insertCustomLayout(room, map, doorX, doorY, doorRotation); + } + + if (layout != null) { + room.setHasCustomLayout(true); + room.setNeedsUpdate(true); + room.setLayout(layout); + room.setWallSize(wallSize); + room.setFloorSize(floorSize); + room.setWallHeight(wallHeight); + room.save(); + Collection habbos = new ArrayList<>(room.getUserCount()); + habbos.addAll(room.getHabbos()); + Emulator.getGameEnvironment().getRoomManager().unloadRoom(room); + room = Emulator.getGameEnvironment().getRoomManager().loadRoom(room.getId()); + ServerMessage message = new ForwardToRoomComposer(room.getId()).compose(); + for (Habbo habbo : habbos) { + habbo.getClient().sendResponse(message); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/AcceptFriendRequestEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/AcceptFriendRequestEvent.java new file mode 100644 index 0000000..9132698 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/AcceptFriendRequestEvent.java @@ -0,0 +1,83 @@ +package com.eu.habbo.messages.incoming.friends; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.messenger.Messenger; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.friends.FriendRequestErrorComposer; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import static com.eu.habbo.habbohotel.users.HabboManager.getOfflineHabboInfo; + +@Slf4j +public class AcceptFriendRequestEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + int count = this.packet.readInt(); + int userId; + + for (int i = 0; i < count; i++) { + userId = this.packet.readInt(); + + if (userId == 0) + return; + + if (this.client.getHabbo().getMessenger().getFriends().containsKey(userId)) { + this.client.getHabbo().getMessenger().deleteFriendRequests(userId, this.client.getHabbo().getHabboInfo().getId()); + continue; + } + + Habbo target = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + + if(target == null) { + HabboInfo habboInfo = getOfflineHabboInfo(userId); + + if(habboInfo == null) { + this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.TARGET_NOT_FOUND)); + this.client.getHabbo().getMessenger().deleteFriendRequests(userId, this.client.getHabbo().getHabboInfo().getId()); + continue; + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.*, users_settings.block_friendrequests FROM users INNER JOIN users_settings ON users.id = users_settings.user_id WHERE username = ? LIMIT 1")) { + statement.setString(1, habboInfo.getUsername()); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + target = new Habbo(set); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + return; + } + } + + if(target == null) { + this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.TARGET_NOT_FOUND)); + this.client.getHabbo().getMessenger().deleteFriendRequests(userId, this.client.getHabbo().getHabboInfo().getId()); + continue; + } + + if(this.client.getHabbo().getMessenger().getFriends().size() >= this.client.getHabbo().getHabboStats().maxFriends && !this.client.getHabbo().hasPermission("acc_infinite_friends")) { + this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.FRIEND_LIST_OWN_FULL)); + break; + } + + if(target.getMessenger().getFriends().size() >= target.getHabboStats().maxFriends && !target.hasPermission("acc_infinite_friends")) { + this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.FRIEND_LIST_TARGET_FULL)); + continue; + } + + this.client.getHabbo().getMessenger().acceptFriendRequest(userId, this.client.getHabbo().getHabboInfo().getId()); + + Messenger.checkFriendSizeProgress(this.client.getHabbo()); + Messenger.checkFriendSizeProgress(target); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/ChangeRelationEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/ChangeRelationEvent.java new file mode 100644 index 0000000..d279019 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/ChangeRelationEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.incoming.friends; + +import com.eu.habbo.habbohotel.messenger.MessengerBuddy; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.friends.UpdateFriendComposer; +import com.eu.habbo.plugin.events.users.friends.UserRelationShipEvent; + +public class ChangeRelationEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int userId = this.packet.readInt(); + int relationId = this.packet.readInt(); + + MessengerBuddy buddy = this.client.getHabbo().getMessenger().getFriends().get(userId); + if (buddy != null && relationId >= 0 && relationId <= 3) { + UserRelationShipEvent event = new UserRelationShipEvent(this.client.getHabbo(), buddy, relationId); + if (!event.isCancelled()) { + buddy.setRelation(event.relationShip); + this.client.sendResponse(new UpdateFriendComposer(this.client.getHabbo(), buddy, 0)); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/DeclineFriendRequestEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/DeclineFriendRequestEvent.java new file mode 100644 index 0000000..8010cf5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/DeclineFriendRequestEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.incoming.friends; + +import com.eu.habbo.messages.incoming.MessageHandler; + +public class DeclineFriendRequestEvent extends MessageHandler { + @Override + public void handle() throws Exception { + boolean all = this.packet.readBoolean(); + + if (all) { + this.client.getHabbo().getMessenger().deleteAllFriendRequests(this.client.getHabbo().getHabboInfo().getId()); + } else { + int count = this.packet.readInt(); + + for (int i = 0; i < count; i++) { + this.client.getHabbo().getMessenger().deleteFriendRequests(this.packet.readInt(), this.client.getHabbo().getHabboInfo().getId()); + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/FindNewFriendsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/FindNewFriendsEvent.java new file mode 100644 index 0000000..ec42bde --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/FindNewFriendsEvent.java @@ -0,0 +1,34 @@ +package com.eu.habbo.messages.incoming.friends; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomCategory; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.friends.FriendFindingRoomComposer; +import com.eu.habbo.messages.outgoing.rooms.ForwardToRoomComposer; + +import java.util.Collections; +import java.util.List; + +public class FindNewFriendsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + List roomCategories = Emulator.getGameEnvironment().getRoomManager().roomCategoriesForHabbo(this.client.getHabbo()); + Collections.shuffle(roomCategories); + + for (RoomCategory category : roomCategories) { + List rooms = Emulator.getGameEnvironment().getRoomManager().getActiveRooms(category.getId()); + + if (!rooms.isEmpty()) { + Room room = rooms.get(0); + + if (room.getUserCountWithoutInvisibleHabbos() > 0) { + this.client.sendResponse(new ForwardToRoomComposer(room.getId())); + return; + } + } + } + + this.client.sendResponse(new FriendFindingRoomComposer(FriendFindingRoomComposer.NO_ROOM_FOUND)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/FriendListUpdateEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/FriendListUpdateEvent.java new file mode 100644 index 0000000..9cf31ef --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/FriendListUpdateEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.friends; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.friends.MessengerInitComposer; + +public class FriendListUpdateEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new MessengerInitComposer(this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/FriendPrivateMessageEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/FriendPrivateMessageEvent.java new file mode 100644 index 0000000..6145e72 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/FriendPrivateMessageEvent.java @@ -0,0 +1,36 @@ +package com.eu.habbo.messages.incoming.friends; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.messenger.MessengerBuddy; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.users.friends.UserFriendChatEvent; + +public class FriendPrivateMessageEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int userId = this.packet.readInt(); + String message = this.packet.readString(); + + if (!this.client.getHabbo().getHabboStats().allowTalk()) { + return; + } + + long millis = System.currentTimeMillis(); + if (millis - this.client.getHabbo().getHabboStats().lastChat < 750) { + return; + } + this.client.getHabbo().getHabboStats().lastChat = millis; + + MessengerBuddy buddy = this.client.getHabbo().getMessenger().getFriend(userId); + if (buddy == null) + return; + + if (message.length() > 255) message = message.substring(0, 255); + + UserFriendChatEvent event = new UserFriendChatEvent(this.client.getHabbo(), buddy, message); + if (Emulator.getPluginManager().fireEvent(event).isCancelled()) + return; + + buddy.onMessageReceived(this.client.getHabbo(), message); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/FriendRequestEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/FriendRequestEvent.java new file mode 100644 index 0000000..7663d9f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/FriendRequestEvent.java @@ -0,0 +1,90 @@ +package com.eu.habbo.messages.incoming.friends; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.messenger.FriendRequest; +import com.eu.habbo.habbohotel.messenger.Messenger; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.friends.FriendRequestComposer; +import com.eu.habbo.messages.outgoing.friends.FriendRequestErrorComposer; +import com.eu.habbo.plugin.events.users.friends.UserRequestFriendshipEvent; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + + +@Slf4j +public class FriendRequestEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + String username = this.packet.readString(); + + if (this.client == null || username == null || username.isEmpty()) + return; + + // TargetHabbo can be null if the Habbo is not online or when the Habbo doesn't exist + Habbo targetHabbo = Emulator.getGameServer().getGameClientManager().getHabbo(username); + + // If the Habbo is null, we try to get the Habbo from the database. + // If the Habbo is still null, the Habbo doesn't exist. + if (targetHabbo == null) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users.*, users_settings.block_friendrequests FROM users INNER JOIN users_settings ON users.id = users_settings.user_id WHERE username = ? LIMIT 1")) { + statement.setString(1, username); + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + targetHabbo = new Habbo(set); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + return; + } + } + + if (targetHabbo == null) { + this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.TARGET_NOT_FOUND)); + return; + } + + int targetId = targetHabbo.getHabboInfo().getId(); + boolean targetBlocksFriendRequests = targetHabbo.getHabboStats().blockFriendRequests; + + // Making friends with yourself would be very pathetic, we try to avoid that + if (targetId == this.client.getHabbo().getHabboInfo().getId()) + return; + + // Target Habbo exists + // Check if Habbo is accepting friend requests + if (targetBlocksFriendRequests) { + this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.TARGET_NOT_ACCEPTING_REQUESTS)); + return; + } + + // You can only have x friends + if (this.client.getHabbo().getMessenger().getFriends().values().size() >= this.client.getHabbo().getHabboStats().maxFriends && !this.client.getHabbo().hasPermission("acc_infinite_friends")) { + this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.FRIEND_LIST_OWN_FULL)); + return; + } + + // Check if targets friendlist is full + if (targetHabbo.getMessenger().getFriends().values().size() >= targetHabbo.getHabboStats().maxFriends && !targetHabbo.hasPermission("acc_infinite_friends")) { + this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.FRIEND_LIST_TARGET_FULL)); + return; + } + + // Allow plugins to cancel the request + if (Emulator.getPluginManager().fireEvent(new UserRequestFriendshipEvent(this.client.getHabbo(), username, targetHabbo)).isCancelled()) { + this.client.sendResponse(new FriendRequestErrorComposer(2)); + return; + } + + if(targetHabbo.isOnline()) { + targetHabbo.getClient().sendResponse(new FriendRequestComposer(this.client.getHabbo())); + } + + Messenger.makeFriendRequest(this.client.getHabbo().getHabboInfo().getId(), targetId); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/InviteFriendsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/InviteFriendsEvent.java new file mode 100644 index 0000000..a262474 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/InviteFriendsEvent.java @@ -0,0 +1,36 @@ +package com.eu.habbo.messages.incoming.friends; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.friends.RoomInviteComposer; + +public class InviteFriendsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboStats().allowTalk()) { + int[] userIds = new int[this.packet.readInt()]; + + for (int i = 0; i < userIds.length; i++) { + userIds[i] = this.packet.readInt(); + } + + String message = this.packet.readString(); + + message = Emulator.getGameEnvironment().getWordFilter().filter(message, this.client.getHabbo()); + + for (int i : userIds) { + if (i == 0) + continue; + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(i); + + if (habbo != null) { + if (!habbo.getHabboStats().blockRoomInvites) { + habbo.getClient().sendResponse(new RoomInviteComposer(this.client.getHabbo().getHabboInfo().getId(), message)); + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/RemoveFriendEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/RemoveFriendEvent.java new file mode 100644 index 0000000..27bc05e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/RemoveFriendEvent.java @@ -0,0 +1,38 @@ +package com.eu.habbo.messages.incoming.friends; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.messenger.Messenger; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.friends.RemoveFriendComposer; +import gnu.trove.list.array.TIntArrayList; + +public class RemoveFriendEvent extends MessageHandler { + + private final TIntArrayList removedFriends; + + public RemoveFriendEvent() { + this.removedFriends = new TIntArrayList(); + } + + @Override + public void handle() throws Exception { + int count = this.packet.readInt(); + for (int i = 0; i < count; i++) { + int habboId = this.packet.readInt(); + this.removedFriends.add(habboId); + + Messenger.unfriend(this.client.getHabbo().getHabboInfo().getId(), habboId); + this.client.getHabbo().getMessenger().removeBuddy(habboId); + + Habbo habbo = Emulator.getGameServer().getGameClientManager().getHabbo(habboId); + + if (habbo != null) { + habbo.getMessenger().removeBuddy(this.client.getHabbo()); + habbo.getClient().sendResponse(new RemoveFriendComposer(this.client.getHabbo().getHabboInfo().getId())); + } + } + + this.client.sendResponse(new RemoveFriendComposer(this.removedFriends)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/RequestFriendRequestsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/RequestFriendRequestsEvent.java new file mode 100644 index 0000000..27c70b8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/RequestFriendRequestsEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.friends; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.friends.LoadFriendRequestsComposer; + +public class RequestFriendRequestsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new LoadFriendRequestsComposer(this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/RequestFriendsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/RequestFriendsEvent.java new file mode 100644 index 0000000..c039726 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/RequestFriendsEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.incoming.friends; + +import com.eu.habbo.messages.incoming.MessageHandler; + +public class RequestFriendsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + + + //this.client.sendResponse(new FriendsComposer(this.client.getHabbo())); + + //this.client.sendResponse(new MessengerInitComposer(this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/RequestInitFriendsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/RequestInitFriendsEvent.java new file mode 100644 index 0000000..2ce35cf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/RequestInitFriendsEvent.java @@ -0,0 +1,18 @@ +package com.eu.habbo.messages.incoming.friends; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.friends.FriendsComposer; +import com.eu.habbo.messages.outgoing.friends.MessengerInitComposer; + +import java.util.ArrayList; + +public class RequestInitFriendsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + ArrayList messages = new ArrayList<>(); + messages.add(new MessengerInitComposer(this.client.getHabbo()).compose()); + messages.addAll(FriendsComposer.getMessagesForBuddyList(this.client.getHabbo().getMessenger().getFriends().values())); + this.client.sendResponses(messages); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/SearchUserEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/SearchUserEvent.java new file mode 100644 index 0000000..d4b0175 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/SearchUserEvent.java @@ -0,0 +1,39 @@ +package com.eu.habbo.messages.incoming.friends; + +import com.eu.habbo.habbohotel.messenger.Messenger; +import com.eu.habbo.habbohotel.messenger.MessengerBuddy; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.friends.UserSearchResultComposer; +import gnu.trove.set.hash.THashSet; + +import java.util.concurrent.ConcurrentHashMap; + +public class SearchUserEvent extends MessageHandler { + public static ConcurrentHashMap> cachedResults = new ConcurrentHashMap<>(); + + @Override + public void handle() throws Exception { + if (System.currentTimeMillis() - this.client.getHabbo().getHabboStats().lastUsersSearched < 3000) + return; + + String username = this.packet.readString().replace(" ", "").toLowerCase(); + + if (username.isEmpty()) + return; + + if (username.length() > 15) { + username = username.substring(0, 15); + } + + if (this.client.getHabbo().getMessenger() != null) { + THashSet buddies = cachedResults.get(username); + + if (buddies == null) { + buddies = Messenger.searchUsers(username); + cachedResults.put(username, buddies); + } + + this.client.sendResponse(new UserSearchResultComposer(buddies, this.client.getHabbo().getMessenger().getFriends(username), this.client.getHabbo())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/StalkFriendEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/StalkFriendEvent.java new file mode 100644 index 0000000..af3cf0c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/friends/StalkFriendEvent.java @@ -0,0 +1,48 @@ +package com.eu.habbo.messages.incoming.friends; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.messenger.MessengerBuddy; +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.friends.StalkErrorComposer; +import com.eu.habbo.messages.outgoing.rooms.ForwardToRoomComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserWhisperComposer; + +public class StalkFriendEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int friendId = this.packet.readInt(); + + MessengerBuddy buddy = this.client.getHabbo().getMessenger().getFriend(friendId); + + if (buddy == null) { + this.client.sendResponse(new StalkErrorComposer(StalkErrorComposer.NOT_IN_FRIEND_LIST)); + return; + } + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(friendId); + + if (habbo == null || !habbo.isOnline()) { + this.client.sendResponse(new StalkErrorComposer(StalkErrorComposer.FRIEND_OFFLINE)); + return; + } + + if (habbo.getHabboStats().blockFollowing && !this.client.getHabbo().hasPermission("acc_can_stalk")) { + this.client.sendResponse(new StalkErrorComposer(StalkErrorComposer.FRIEND_BLOCKED_STALKING)); + return; + } + + if (habbo.getHabboInfo().getCurrentRoom() == null || habbo.getHabboInfo().isInvisibleInRooms()) { + this.client.sendResponse(new StalkErrorComposer(StalkErrorComposer.FRIEND_NOT_IN_ROOM)); + return; + } + + if (habbo.getHabboInfo().getCurrentRoom() != this.client.getHabbo().getHabboInfo().getCurrentRoom()) { + this.client.sendResponse(new ForwardToRoomComposer(habbo.getHabboInfo().getCurrentRoom().getId())); + } else { + this.client.sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(Emulator.getTexts().getValue("stalk.failed.same.room").replace("%user%", habbo.getHabboInfo().getUsername()), this.client.getHabbo(), this.client.getHabbo(), RoomChatMessageBubbles.ALERT))); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterEvent.java new file mode 100644 index 0000000..921ac12 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterEvent.java @@ -0,0 +1,9 @@ +package com.eu.habbo.messages.incoming.gamecenter; + +import com.eu.habbo.messages.incoming.MessageHandler; + +public class GameCenterEvent extends MessageHandler { + @Override + public void handle() throws Exception { + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterJoinGameEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterJoinGameEvent.java new file mode 100644 index 0000000..db00af3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterJoinGameEvent.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.incoming.gamecenter; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.gamecenter.GameCenterAchievementsConfigurationComposer; +import com.eu.habbo.messages.outgoing.gamecenter.basejump.BaseJumpJoinQueueComposer; +import com.eu.habbo.messages.outgoing.gamecenter.basejump.BaseJumpLoadGameComposer; +import com.eu.habbo.messages.outgoing.gamecenter.basejump.BaseJumpLoadGameURLComposer; + +public class GameCenterJoinGameEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int gameId = this.packet.readInt(); + + if (gameId == 3) //BaseJump + { + this.client.sendResponse(new GameCenterAchievementsConfigurationComposer()); + this.client.sendResponse(new BaseJumpLoadGameURLComposer()); + this.client.sendResponse(new BaseJumpLoadGameComposer(this.client, 3)); + } else if (gameId == 4) { + this.client.sendResponse(new BaseJumpJoinQueueComposer(4)); + this.client.sendResponse(new BaseJumpLoadGameURLComposer()); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterLeaveGameEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterLeaveGameEvent.java new file mode 100644 index 0000000..6236f2f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterLeaveGameEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.gamecenter; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.gamecenter.basejump.BaseJumpUnloadGameComposer; + +public class GameCenterLeaveGameEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new BaseJumpUnloadGameComposer()); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterLoadGameEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterLoadGameEvent.java new file mode 100644 index 0000000..acfc2e8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterLoadGameEvent.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.incoming.gamecenter; + +import com.eu.habbo.messages.incoming.MessageHandler; + +public class GameCenterLoadGameEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int gameId = this.packet.readInt(); + + if (gameId == 3) { + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterRequestAccountStatusEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterRequestAccountStatusEvent.java new file mode 100644 index 0000000..b476dc3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterRequestAccountStatusEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.gamecenter; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.gamecenter.GameCenterAccountInfoComposer; + +public class GameCenterRequestAccountStatusEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new GameCenterAccountInfoComposer(this.packet.readInt(), 10)); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterRequestGameStatusEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterRequestGameStatusEvent.java new file mode 100644 index 0000000..f2efab0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterRequestGameStatusEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.gamecenter; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.gamecenter.GameCenterGameComposer; + +public class GameCenterRequestGameStatusEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new GameCenterGameComposer(this.packet.readInt(), GameCenterGameComposer.OK)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterRequestGamesEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterRequestGamesEvent.java new file mode 100644 index 0000000..cedfaba --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/gamecenter/GameCenterRequestGamesEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.gamecenter; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.gamecenter.GameCenterAchievementsConfigurationComposer; + +public class GameCenterRequestGamesEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new GameCenterAchievementsConfigurationComposer()); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guardians/GuardianAcceptRequestEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guardians/GuardianAcceptRequestEvent.java new file mode 100644 index 0000000..1f48b58 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guardians/GuardianAcceptRequestEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.guardians; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class GuardianAcceptRequestEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Emulator.getGameEnvironment().getGuideManager().acceptTicket(this.client.getHabbo(), this.packet.readBoolean()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guardians/GuardianNoUpdatesWantedEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guardians/GuardianNoUpdatesWantedEvent.java new file mode 100644 index 0000000..8dfecac --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guardians/GuardianNoUpdatesWantedEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.messages.incoming.guardians; + +import com.eu.habbo.messages.incoming.MessageHandler; + +public class GuardianNoUpdatesWantedEvent extends MessageHandler { + @Override + public void handle() throws Exception { + //TODO: Add dont care about ticket updates. + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guardians/GuardianVoteEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guardians/GuardianVoteEvent.java new file mode 100644 index 0000000..95cdebf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guardians/GuardianVoteEvent.java @@ -0,0 +1,34 @@ +package com.eu.habbo.messages.incoming.guardians; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuardianTicket; +import com.eu.habbo.habbohotel.guides.GuardianVoteType; +import com.eu.habbo.messages.incoming.MessageHandler; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class GuardianVoteEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + int voteType = this.packet.readInt(); + + GuardianTicket ticket = Emulator.getGameEnvironment().getGuideManager().getTicketForGuardian(this.client.getHabbo()); + + if (ticket != null) { + GuardianVoteType type = GuardianVoteType.NOT_VOTED; + + if (voteType == 0) { + type = GuardianVoteType.ACCEPTABLY; + } else if (voteType == 1) { + type = GuardianVoteType.BADLY; + } else if (voteType == 2) { + type = GuardianVoteType.AWFULLY; + } else { + log.error("Uknown vote type: " + voteType); + } + + ticket.vote(this.client.getHabbo(), type); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideCancelHelpRequestEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideCancelHelpRequestEvent.java new file mode 100644 index 0000000..172c743 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideCancelHelpRequestEvent.java @@ -0,0 +1,17 @@ +package com.eu.habbo.messages.incoming.guides; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuideTour; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class GuideCancelHelpRequestEvent extends MessageHandler { + @Override + public void handle() throws Exception { + GuideTour tour = Emulator.getGameEnvironment().getGuideManager().getGuideTourByNoob(this.client.getHabbo()); + + if (tour != null) { + tour.end(); + Emulator.getGameEnvironment().getGuideManager().endSession(tour); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideCloseHelpRequestEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideCloseHelpRequestEvent.java new file mode 100644 index 0000000..84be74d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideCloseHelpRequestEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.messages.incoming.guides; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuideTour; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class GuideCloseHelpRequestEvent extends MessageHandler { + @Override + public void handle() throws Exception { + GuideTour tour = Emulator.getGameEnvironment().getGuideManager().getGuideTourByHabbo(this.client.getHabbo()); + + if (tour != null) { + Emulator.getGameEnvironment().getGuideManager().endSession(tour); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideHandleHelpRequestEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideHandleHelpRequestEvent.java new file mode 100644 index 0000000..9089caf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideHandleHelpRequestEvent.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.incoming.guides; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuideTour; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class GuideHandleHelpRequestEvent extends MessageHandler { + @Override + public void handle() throws Exception { + GuideTour tour = Emulator.getGameEnvironment().getGuideManager().getGuideTourByHelper(this.client.getHabbo()); + + if (tour == null) { + return; + } + + boolean accepted = this.packet.readBoolean(); + + if (!accepted) { + Emulator.getGameEnvironment().getGuideManager().declineTour(tour); + } else { + Emulator.getGameEnvironment().getGuideManager().startSession(tour, this.client.getHabbo()); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideInviteUserEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideInviteUserEvent.java new file mode 100644 index 0000000..9c60efb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideInviteUserEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.incoming.guides; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuideTour; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guides.GuideSessionInvitedToGuideRoomComposer; + +public class GuideInviteUserEvent extends MessageHandler { + @Override + public void handle() throws Exception { + GuideTour tour = Emulator.getGameEnvironment().getGuideManager().getGuideTourByHelper(this.client.getHabbo()); + + if (tour != null) { + ServerMessage message = new GuideSessionInvitedToGuideRoomComposer(this.client.getHabbo().getHabboInfo().getCurrentRoom()).compose(); + tour.getNoob().getClient().sendResponse(message); + tour.getHelper().getClient().sendResponse(message); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideRecommendHelperEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideRecommendHelperEvent.java new file mode 100644 index 0000000..9ecf446 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideRecommendHelperEvent.java @@ -0,0 +1,18 @@ +package com.eu.habbo.messages.incoming.guides; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuideTour; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class GuideRecommendHelperEvent extends MessageHandler { + @Override + public void handle() throws Exception { + boolean recommend = this.packet.readBoolean(); + + GuideTour tour = Emulator.getGameEnvironment().getGuideManager().getGuideTourByNoob(this.client.getHabbo()); + + if (tour != null) { + Emulator.getGameEnvironment().getGuideManager().recommend(tour, recommend); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideReportHelperEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideReportHelperEvent.java new file mode 100644 index 0000000..2b51c31 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideReportHelperEvent.java @@ -0,0 +1,47 @@ +package com.eu.habbo.messages.incoming.guides; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuideTour; +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.habbohotel.modtool.ModToolTicketType; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guides.GuideSessionDetachedComposer; +import com.eu.habbo.messages.outgoing.guides.GuideSessionEndedComposer; +import com.eu.habbo.messages.outgoing.modtool.ModToolReportReceivedAlertComposer; + +public class GuideReportHelperEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String message = this.packet.readString(); + + GuideTour tour = Emulator.getGameEnvironment().getGuideManager().getGuideTourByHabbo(this.client.getHabbo()); + + if (tour != null) { + Habbo reported = tour.getHelper(); + + if (reported == this.client.getHabbo()) { + reported = tour.getNoob(); + } + + ModToolIssue issue = new ModToolIssue(this.client.getHabbo().getHabboInfo().getId(), + this.client.getHabbo().getHabboInfo().getUsername(), + reported.getHabboInfo().getId(), + reported.getHabboInfo().getUsername(), + 0, + message, + ModToolTicketType.GUIDE_SYSTEM); + + + Emulator.getGameEnvironment().getModToolManager().addTicket(issue); + Emulator.getGameEnvironment().getModToolManager().updateTicketToMods(issue); + this.client.sendResponse(new ModToolReportReceivedAlertComposer(ModToolReportReceivedAlertComposer.REPORT_RECEIVED, message)); + + this.client.sendResponse(new GuideSessionDetachedComposer()); + this.client.sendResponse(new GuideSessionEndedComposer(GuideSessionEndedComposer.HELP_CASE_CLOSED)); + + reported.getClient().sendResponse(new GuideSessionDetachedComposer()); + reported.getClient().sendResponse(new GuideSessionEndedComposer(GuideSessionEndedComposer.HELP_CASE_CLOSED)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideUserMessageEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideUserMessageEvent.java new file mode 100644 index 0000000..fb84a36 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideUserMessageEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.incoming.guides; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuideChatMessage; +import com.eu.habbo.habbohotel.guides.GuideTour; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guides.GuideSessionMessageComposer; + +public class GuideUserMessageEvent extends MessageHandler { + @Override + public void handle() throws Exception { + GuideTour tour = Emulator.getGameEnvironment().getGuideManager().getGuideTourByHabbo(this.client.getHabbo()); + + if (tour != null) { + GuideChatMessage chatMessage = new GuideChatMessage(this.client.getHabbo().getHabboInfo().getId(), this.packet.readString(), Emulator.getIntUnixTimestamp()); + tour.addMessage(chatMessage); + ServerMessage serverMessage = new GuideSessionMessageComposer(chatMessage).compose(); + tour.getHelper().getClient().sendResponse(serverMessage); + tour.getNoob().getClient().sendResponse(serverMessage); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideUserTypingEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideUserTypingEvent.java new file mode 100644 index 0000000..2446ca4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideUserTypingEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.incoming.guides; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuideTour; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guides.GuideSessionPartnerIsTypingComposer; + +public class GuideUserTypingEvent extends MessageHandler { + @Override + public void handle() throws Exception { + boolean typing = this.packet.readBoolean(); + + GuideTour tour = Emulator.getGameEnvironment().getGuideManager().getGuideTourByHabbo(this.client.getHabbo()); + + if (tour != null) { + if (tour.getHelper() == this.client.getHabbo()) { + tour.getNoob().getClient().sendResponse(new GuideSessionPartnerIsTypingComposer(typing)); + } else { + tour.getHelper().getClient().sendResponse(new GuideSessionPartnerIsTypingComposer(typing)); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideVisitUserEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideVisitUserEvent.java new file mode 100644 index 0000000..70a1042 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/GuideVisitUserEvent.java @@ -0,0 +1,17 @@ +package com.eu.habbo.messages.incoming.guides; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuideTour; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guides.GuideSessionRequesterRoomComposer; + +public class GuideVisitUserEvent extends MessageHandler { + @Override + public void handle() throws Exception { + GuideTour tour = Emulator.getGameEnvironment().getGuideManager().getGuideTourByHelper(this.client.getHabbo()); + + if (tour != null) { + this.client.sendResponse(new GuideSessionRequesterRoomComposer(tour.getNoob().getHabboInfo().getCurrentRoom())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/RequestGuideAssistanceEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/RequestGuideAssistanceEvent.java new file mode 100644 index 0000000..e51dc16 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/RequestGuideAssistanceEvent.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.incoming.guides; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuideTour; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guides.GuideSessionErrorComposer; + +public class RequestGuideAssistanceEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int type = this.packet.readInt(); + String message = this.packet.readString(); + + GuideTour activeTour = Emulator.getGameEnvironment().getGuideManager().getGuideTourByHabbo(this.client.getHabbo()); + + if (activeTour != null) { + this.client.sendResponse(new GuideSessionErrorComposer(GuideSessionErrorComposer.SOMETHING_WRONG_REQUEST)); + return; + } + + GuideTour tour = new GuideTour(this.client.getHabbo(), message); + tour.setStartTime(Emulator.getIntUnixTimestamp()); + + Emulator.getGameEnvironment().getGuideManager().findHelper(tour); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/RequestGuideToolEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/RequestGuideToolEvent.java new file mode 100644 index 0000000..2c954c2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guides/RequestGuideToolEvent.java @@ -0,0 +1,42 @@ +package com.eu.habbo.messages.incoming.guides; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guides.GuideToolsComposer; + +public class RequestGuideToolEvent extends MessageHandler { + @Override + public void handle() throws Exception { + boolean onDuty = this.packet.readBoolean(); + + if (onDuty) { + boolean tourRequests = this.packet.readBoolean(); + boolean helperRequests = this.packet.readBoolean(); + boolean bullyReports = this.packet.readBoolean(); + + if (!this.client.getHabbo().hasPermission(Permission.ACC_HELPER_USE_GUIDE_TOOL)) + return; + + if (helperRequests && !this.client.getHabbo().hasPermission(Permission.ACC_HELPER_GIVE_GUIDE_TOURS)) + helperRequests = false; + + if (bullyReports && !this.client.getHabbo().hasPermission(Permission.ACC_HELPER_JUDGE_CHAT_REVIEWS)) + bullyReports = false; + + if (helperRequests) { + Emulator.getGameEnvironment().getGuideManager().setOnGuide(this.client.getHabbo(), onDuty); + } + + if (bullyReports) { + Emulator.getGameEnvironment().getGuideManager().setOnGuardian(this.client.getHabbo(), onDuty); + } + + this.client.sendResponse(new GuideToolsComposer(onDuty)); + } else { + Emulator.getGameEnvironment().getGuideManager().setOnGuide(this.client.getHabbo(), onDuty); + Emulator.getGameEnvironment().getGuideManager().setOnGuardian(this.client.getHabbo(), onDuty); + this.client.sendResponse(new GuideToolsComposer(onDuty)); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GetHabboGuildBadgesMessageEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GetHabboGuildBadgesMessageEvent.java new file mode 100644 index 0000000..8ca7b6e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GetHabboGuildBadgesMessageEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.messages.incoming.MessageHandler; + +public class GetHabboGuildBadgesMessageEvent extends MessageHandler { + @Override + public void handle() throws Exception { + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildAcceptMembershipEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildAcceptMembershipEvent.java new file mode 100644 index 0000000..068aba2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildAcceptMembershipEvent.java @@ -0,0 +1,63 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.habbohotel.guilds.GuildRank; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildAcceptMemberErrorComposer; +import com.eu.habbo.messages.outgoing.guilds.GuildInfoComposer; +import com.eu.habbo.messages.outgoing.guilds.GuildRefreshMembersListComposer; +import com.eu.habbo.plugin.events.guilds.GuildAcceptedMembershipEvent; + +public class GuildAcceptMembershipEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + int userId = this.packet.readInt(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + + if (guild != null) { + GuildMember groupMember = Emulator.getGameEnvironment().getGuildManager().getGuildMember(guild, this.client.getHabbo()); + if (userId == this.client.getHabbo().getHabboInfo().getId() || guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || groupMember.getRank().equals(GuildRank.ADMIN) || groupMember.getRank().equals(GuildRank.OWNER) || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) { + if (habbo != null) { + if (habbo.getHabboStats().hasGuild(guild.getId())) { + this.client.sendResponse(new GuildAcceptMemberErrorComposer(guild.getId(), GuildAcceptMemberErrorComposer.ALREADY_ACCEPTED)); + return; + } else { + //Check the user has requested + GuildMember member = Emulator.getGameEnvironment().getGuildManager().getGuildMember(guild, habbo); + if (member == null || member.getRank().type != GuildRank.REQUESTED.type) { + this.client.sendResponse(new GuildAcceptMemberErrorComposer(guild.getId(), GuildAcceptMemberErrorComposer.NO_LONGER_MEMBER)); + return; + } else { + GuildAcceptedMembershipEvent event = new GuildAcceptedMembershipEvent(guild, userId, habbo); + Emulator.getPluginManager().fireEvent(event); + if (!event.isCancelled()) { + habbo.getHabboStats().addGuild(guild.getId()); + Emulator.getGameEnvironment().getGuildManager().joinGuild(guild, this.client, habbo.getHabboInfo().getId(), true); + guild.decreaseRequestCount(); + guild.increaseMemberCount(); + this.client.sendResponse(new GuildRefreshMembersListComposer(guild)); + Room room = habbo.getHabboInfo().getCurrentRoom(); + if (room != null) { + if (room.getGuildId() == guildId) { + habbo.getClient().sendResponse(new GuildInfoComposer(guild, habbo.getClient(), false, Emulator.getGameEnvironment().getGuildManager().getGuildMember(guildId, userId))); + room.refreshRightsForHabbo(habbo); + } + } + } + } + } + } else { + Emulator.getGameEnvironment().getGuildManager().joinGuild(guild, this.client, userId, true); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeBadgeEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeBadgeEvent.java new file mode 100644 index 0000000..965202d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeBadgeEvent.java @@ -0,0 +1,66 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.guilds.GuildChangedBadgeEvent; + +public class GuildChangeBadgeEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + if (guild != null) { + if (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(guild.getRoomId()); + + if (room == null || room.getId() != guild.getRoomId()) + return; + + int count = this.packet.readInt(); + + String badge = ""; + + byte base = 1; + + while (base < count) { + int id = this.packet.readInt(); + int color = this.packet.readInt(); + int pos = this.packet.readInt(); + + if (base == 1) { + badge += "b"; + } else { + badge += "s"; + } + + badge += (id < 100 ? "0" : "") + (id < 10 ? "0" : "") + id + (color < 10 ? "0" : "") + color + "" + pos; + + base += 3; + } + + if (guild.getBadge().toLowerCase().equals(badge.toLowerCase())) + return; + + GuildChangedBadgeEvent badgeEvent = new GuildChangedBadgeEvent(guild, badge); + Emulator.getPluginManager().fireEvent(badgeEvent); + + if (badgeEvent.isCancelled()) + return; + + guild.setBadge(badgeEvent.badge); + guild.needsUpdate = true; + + if (Emulator.getConfig().getBoolean("imager.internal.enabled")) { + Emulator.getBadgeImager().generate(guild); + } + + room.refreshGuild(guild); + Emulator.getThreading().run(guild); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeColorsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeColorsEvent.java new file mode 100644 index 0000000..fee7830 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeColorsEvent.java @@ -0,0 +1,42 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.guilds.GuildChangedColorsEvent; + +public class GuildChangeColorsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (guild != null) { + if (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) { + GuildChangedColorsEvent colorsEvent = new GuildChangedColorsEvent(guild, this.packet.readInt(), this.packet.readInt()); + Emulator.getPluginManager().fireEvent(colorsEvent); + + if (colorsEvent.isCancelled()) + return; + + if (guild.getColorOne() != colorsEvent.colorOne || guild.getColorTwo() != colorsEvent.colorTwo) { + guild.setColorOne(colorsEvent.colorOne); + guild.setColorTwo(colorsEvent.colorTwo); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(guild.getRoomId()); + + if (room != null && room.getUserCount() > 0) { + room.refreshGuild(guild); + + room.refreshGuildColors(guild); + } + guild.needsUpdate = true; + Emulator.getThreading().run(guild); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeNameDescEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeNameDescEvent.java new file mode 100644 index 0000000..7942b2c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeNameDescEvent.java @@ -0,0 +1,44 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.guilds.GuildChangedNameEvent; + +public class GuildChangeNameDescEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (guild != null) { + if (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) { + GuildChangedNameEvent nameEvent = new GuildChangedNameEvent(guild, this.packet.readString(), this.packet.readString()); + Emulator.getPluginManager().fireEvent(nameEvent); + + if (nameEvent.isCancelled()) + return; + + if (guild.getName().equals(nameEvent.name) && guild.getDescription().equals(nameEvent.description)) + return; + + if(nameEvent.name.length() > 29 || nameEvent.description.length() > 254) + return; + + guild.setName(nameEvent.name); + guild.setDescription(nameEvent.description); + guild.needsUpdate = true; + guild.run(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(guild.getRoomId()); + + if (room != null && !room.getCurrentHabbos().isEmpty()) { + room.refreshGuild(guild); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeSettingsEvent.java new file mode 100644 index 0000000..d21df54 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeSettingsEvent.java @@ -0,0 +1,40 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildState; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.guilds.GuildChangedSettingsEvent; + +public class GuildChangeSettingsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (guild != null) { + if (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) { + GuildChangedSettingsEvent settingsEvent = new GuildChangedSettingsEvent(guild, this.packet.readInt(), this.packet.readInt() == 0); + Emulator.getPluginManager().fireEvent(settingsEvent); + + if (settingsEvent.isCancelled()) + return; + + guild.setState(GuildState.valueOf(settingsEvent.state)); + guild.setRights(settingsEvent.rights); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(guild.getRoomId()); + if(room != null) { + room.refreshGuild(guild); + } + + guild.needsUpdate = true; + + Emulator.getThreading().run(guild); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildConfirmRemoveMemberEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildConfirmRemoveMemberEvent.java new file mode 100644 index 0000000..ba56938 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildConfirmRemoveMemberEvent.java @@ -0,0 +1,33 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.habbohotel.guilds.GuildRank; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildConfirmRemoveMemberComposer; + +public class GuildConfirmRemoveMemberEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + int userId = this.packet.readInt(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (guild != null) { + GuildMember member = Emulator.getGameEnvironment().getGuildManager().getGuildMember(guild, this.client.getHabbo()); + if (userId == this.client.getHabbo().getHabboInfo().getId() || guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || (member != null && member.getRank().equals(GuildRank.OWNER) || member.getRank().equals(GuildRank.ADMIN)) || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) { + Room room = Emulator.getGameEnvironment().getRoomManager().loadRoom(guild.getRoomId()); + int count = 0; + if (room != null) { + count = room.getUserFurniCount(userId); + } + this.client.sendResponse(new GuildConfirmRemoveMemberComposer(userId, count)); + } + } + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildDeclineMembershipEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildDeclineMembershipEvent.java new file mode 100644 index 0000000..885e771 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildDeclineMembershipEvent.java @@ -0,0 +1,46 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.habbohotel.guilds.GuildRank; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildInfoComposer; +import com.eu.habbo.messages.outgoing.guilds.GuildMembersComposer; +import com.eu.habbo.messages.outgoing.guilds.GuildRefreshMembersListComposer; +import com.eu.habbo.plugin.events.guilds.GuildDeclinedMembershipEvent; + +public class GuildDeclineMembershipEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + int userId = this.packet.readInt(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (guild != null) { + GuildMember member = Emulator.getGameEnvironment().getGuildManager().getGuildMember(guild, this.client.getHabbo()); + if (userId == this.client.getHabbo().getHabboInfo().getId() || guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || member.getRank().equals(GuildRank.ADMIN)|| member.getRank().equals(GuildRank.OWNER) || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) { + guild.decreaseRequestCount(); + Emulator.getGameEnvironment().getGuildManager().removeMember(guild, userId); + this.client.sendResponse(new GuildMembersComposer(guild, Emulator.getGameEnvironment().getGuildManager().getGuildMembers(guild, 0, 0, ""), this.client.getHabbo(), 0, 0, "", true, Emulator.getGameEnvironment().getGuildManager().getGuildMembersCount(guild, 0, 0, ""))); + this.client.sendResponse(new GuildRefreshMembersListComposer(guild)); + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + Emulator.getPluginManager().fireEvent(new GuildDeclinedMembershipEvent(guild, userId, habbo, this.client.getHabbo())); + + if (habbo != null) { + Room room = habbo.getHabboInfo().getCurrentRoom(); + if (room != null) { + if (room.getGuildId() == guildId) { + habbo.getClient().sendResponse(new GuildInfoComposer(guild, habbo.getClient(), false, null)); + } + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildDeleteEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildDeleteEvent.java new file mode 100644 index 0000000..739eabc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildDeleteEvent.java @@ -0,0 +1,46 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildFavoriteRoomUserUpdateComposer; +import com.eu.habbo.messages.outgoing.guilds.RemoveGuildFromRoomComposer; +import com.eu.habbo.messages.outgoing.rooms.RoomDataComposer; +import com.eu.habbo.plugin.events.guilds.GuildDeletedEvent; +import gnu.trove.set.hash.THashSet; + +public class GuildDeleteEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (guild != null) { + if (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) //TODO Add staff permission override. + { + THashSet members = Emulator.getGameEnvironment().getGuildManager().getGuildMembers(guild.getId()); + + for (GuildMember member : members) { + Habbo habbo = Emulator.getGameServer().getGameClientManager().getHabbo(member.getUserId()); + if (habbo != null) + if (habbo.getHabboInfo().getCurrentRoom() != null && habbo.getRoomUnit() != null) + habbo.getHabboInfo().getCurrentRoom().sendComposer(new GuildFavoriteRoomUserUpdateComposer(habbo.getRoomUnit(), null).compose()); + } + + Emulator.getGameEnvironment().getGuildManager().deleteGuild(guild); + Emulator.getPluginManager().fireEvent(new GuildDeletedEvent(guild, this.client.getHabbo())); + Emulator.getGameEnvironment().getRoomManager().getRoom(guild.getRoomId()).sendComposer(new RemoveGuildFromRoomComposer(guildId).compose()); + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) { + if (guild.getRoomId() == this.client.getHabbo().getHabboInfo().getCurrentRoom().getId()) { + this.client.sendResponse(new RoomDataComposer(this.client.getHabbo().getHabboInfo().getCurrentRoom(), this.client.getHabbo(), false, false)); + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildRemoveAdminEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildRemoveAdminEvent.java new file mode 100644 index 0000000..d017a5a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildRemoveAdminEvent.java @@ -0,0 +1,47 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildInfoComposer; +import com.eu.habbo.messages.outgoing.guilds.GuildMemberUpdateComposer; +import com.eu.habbo.plugin.events.guilds.GuildRemovedAdminEvent; + +public class GuildRemoveAdminEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (guild != null) { + if (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) { + int userId = this.packet.readInt(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(guild.getRoomId()); + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + + GuildRemovedAdminEvent removedAdminEvent = new GuildRemovedAdminEvent(guild, userId, habbo); + Emulator.getPluginManager().fireEvent(removedAdminEvent); + + if (removedAdminEvent.isCancelled()) + return; + + Emulator.getGameEnvironment().getGuildManager().removeAdmin(guild, userId); + + if (habbo != null) { + habbo.getClient().sendResponse(new GuildInfoComposer(guild, this.client, false, Emulator.getGameEnvironment().getGuildManager().getGuildMember(guild.getId(), userId))); + + if (room != null && habbo.getHabboInfo().getCurrentRoom() != null && habbo.getHabboInfo().getCurrentRoom() == room) room.refreshRightsForHabbo(habbo); + } + GuildMember guildMember = Emulator.getGameEnvironment().getGuildManager().getGuildMember(guildId, userId); + + this.client.sendResponse(new GuildMemberUpdateComposer(guild, guildMember)); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildRemoveFavoriteEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildRemoveFavoriteEvent.java new file mode 100644 index 0000000..6f64afa --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildRemoveFavoriteEvent.java @@ -0,0 +1,31 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildFavoriteRoomUserUpdateComposer; +import com.eu.habbo.messages.outgoing.users.UserProfileComposer; +import com.eu.habbo.plugin.events.guilds.GuildRemovedFavoriteEvent; + +public class GuildRemoveFavoriteEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + + if (this.client.getHabbo().getHabboStats().hasGuild(guildId)) { + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + GuildRemovedFavoriteEvent favoriteEvent = new GuildRemovedFavoriteEvent(guild, this.client.getHabbo()); + Emulator.getPluginManager().fireEvent(favoriteEvent); + if (favoriteEvent.isCancelled()) + return; + + this.client.getHabbo().getHabboStats().guild = 0; + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null && guild != null) { + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new GuildFavoriteRoomUserUpdateComposer(this.client.getHabbo().getRoomUnit(), null).compose()); + } + + this.client.sendResponse(new UserProfileComposer(this.client.getHabbo(), this.client)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildRemoveMemberEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildRemoveMemberEvent.java new file mode 100644 index 0000000..dcde989 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildRemoveMemberEvent.java @@ -0,0 +1,66 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.habbohotel.guilds.GuildRank; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildFavoriteRoomUserUpdateComposer; +import com.eu.habbo.messages.outgoing.guilds.GuildInfoComposer; +import com.eu.habbo.messages.outgoing.guilds.GuildRefreshMembersListComposer; +import com.eu.habbo.plugin.events.guilds.GuildRemovedMemberEvent; + +public class GuildRemoveMemberEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + int userId = this.packet.readInt(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + + if (guild != null) { + GuildMember member = Emulator.getGameEnvironment().getGuildManager().getGuildMember(guild, this.client.getHabbo()); + if (userId == this.client.getHabbo().getHabboInfo().getId() || guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || member.getRank().equals(GuildRank.OWNER) || member.getRank().equals(GuildRank.ADMIN) || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + GuildRemovedMemberEvent removedMemberEvent = new GuildRemovedMemberEvent(guild, userId, habbo); + Emulator.getPluginManager().fireEvent(removedMemberEvent); + if (removedMemberEvent.isCancelled()) + return; + + Emulator.getGameEnvironment().getGuildManager().removeMember(guild, userId); + guild.decreaseMemberCount(); + + if (userId != this.client.getHabbo().getHabboInfo().getId()) { + this.client.sendResponse(new GuildRefreshMembersListComposer(guild)); + } + + Room room = Emulator.getGameEnvironment().getRoomManager().loadRoom(guild.getRoomId()); + + if (habbo != null) { + habbo.getHabboStats().removeGuild(guild.getId()); + if (habbo.getHabboStats().guild == guildId) + habbo.getHabboStats().guild = 0; + + if (room != null) { + if (habbo.getHabboInfo().getCurrentRoom() != null && habbo.getRoomUnit() != null) + habbo.getHabboInfo().getCurrentRoom().sendComposer(new GuildFavoriteRoomUserUpdateComposer(habbo.getRoomUnit(), null).compose()); + if (habbo.getHabboInfo().getCurrentRoom() == room) + room.refreshRightsForHabbo(habbo); + } + + habbo.getClient().sendResponse(new GuildInfoComposer(guild, habbo.getClient(), false, null)); + } + + if (room != null) { + if (room.getGuildId() == guildId) { + room.ejectUserFurni(userId); + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildSetAdminEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildSetAdminEvent.java new file mode 100644 index 0000000..7e60d6c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildSetAdminEvent.java @@ -0,0 +1,47 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildMemberUpdateComposer; +import com.eu.habbo.plugin.events.guilds.GuildGivenAdminEvent; + +public class GuildSetAdminEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + int userId = this.packet.readInt(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (guild != null) { + if (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) { + Emulator.getGameEnvironment().getGuildManager().setAdmin(guild, userId); + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + + GuildGivenAdminEvent adminEvent = new GuildGivenAdminEvent(guild, userId, habbo, this.client.getHabbo()); + Emulator.getPluginManager().fireEvent(adminEvent); + if (adminEvent.isCancelled()) + return; + + if (habbo != null) { + Room room = habbo.getHabboInfo().getCurrentRoom(); + if (room != null) { + if (room.getGuildId() == guildId) { + room.refreshRightsForHabbo(habbo); + } + } + } + + GuildMember guildMember = Emulator.getGameEnvironment().getGuildManager().getGuildMember(guildId, userId); + + this.client.sendResponse(new GuildMemberUpdateComposer(guild, guildMember)); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildSetFavoriteEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildSetFavoriteEvent.java new file mode 100644 index 0000000..0837320 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildSetFavoriteEvent.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildFavoriteRoomUserUpdateComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUsersAddGuildBadgeComposer; +import com.eu.habbo.messages.outgoing.users.UserProfileComposer; +import com.eu.habbo.plugin.events.guilds.GuildFavoriteSetEvent; + +public class GuildSetFavoriteEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (this.client.getHabbo().getHabboStats().hasGuild(guildId)) { + GuildFavoriteSetEvent favoriteSetEvent = new GuildFavoriteSetEvent(guild, this.client.getHabbo()); + Emulator.getPluginManager().fireEvent(favoriteSetEvent); + + if (favoriteSetEvent.isCancelled()) + return; + + this.client.getHabbo().getHabboStats().guild = guildId; + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) { + if (guild != null) { + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUsersAddGuildBadgeComposer(guild).compose()); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new GuildFavoriteRoomUserUpdateComposer(this.client.getHabbo().getRoomUnit(), guild).compose()); + } + } + + this.client.sendResponse(new UserProfileComposer(this.client.getHabbo(), this.client)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildBuyEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildBuyEvent.java new file mode 100644 index 0000000..19a0309 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildBuyEvent.java @@ -0,0 +1,115 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.AlertPurchaseFailedComposer; +import com.eu.habbo.messages.outgoing.catalog.PurchaseOKComposer; +import com.eu.habbo.messages.outgoing.guilds.GuildBoughtComposer; +import com.eu.habbo.messages.outgoing.guilds.GuildEditFailComposer; +import com.eu.habbo.messages.outgoing.guilds.GuildInfoComposer; +import com.eu.habbo.plugin.events.guilds.GuildPurchasedEvent; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RequestGuildBuyEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String name = this.packet.readString(); + String description = this.packet.readString(); + + if(name.length() > 29 || description.length() > 254) + return; + + if (Emulator.getConfig().getBoolean("catalog.guild.hc_required", true) && !this.client.getHabbo().getHabboStats().hasActiveClub()) { + this.client.sendResponse(new GuildEditFailComposer(GuildEditFailComposer.HC_REQUIRED)); + return; + } + + if (!this.client.getHabbo().hasPermission(Permission.ACC_INFINITE_CREDITS)) { + int guildPrice = Emulator.getConfig().getInt("catalog.guild.price"); + if (this.client.getHabbo().getHabboInfo().getCredits() >= guildPrice) { + this.client.getHabbo().giveCredits(-guildPrice); + } else { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + return; + } + } + + int roomId = this.packet.readInt(); + + Room r = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId); + + if (r != null) { + if (r.hasGuild()) { + this.client.sendResponse(new GuildEditFailComposer(GuildEditFailComposer.ROOM_ALREADY_IN_USE)); + return; + } + + if (r.getOwnerId() == this.client.getHabbo().getHabboInfo().getId()) { + if (r.getGuildId() == 0) { + int colorOne = this.packet.readInt(); + int colorTwo = this.packet.readInt(); + + int count = this.packet.readInt(); + + String badge = ""; + + byte base = 1; + + while (base < count) { + int id = this.packet.readInt(); + int color = this.packet.readInt(); + int pos = this.packet.readInt(); + + if (base == 1) { + badge += "b"; + } else { + badge += "s"; + } + + badge += (id < 100 ? "0" : "") + (id < 10 ? "0" : "") + id + (color < 10 ? "0" : "") + color + "" + pos; + + base += 3; + } + + if(name.length() > 29){ + this.client.sendResponse(new GuildEditFailComposer(GuildEditFailComposer.INVALID_GUILD_NAME)); + return; + } + if(description.length() > 254){ + return; + } + Guild guild = Emulator.getGameEnvironment().getGuildManager().createGuild(this.client.getHabbo(), roomId, r.getName(), name, description, badge, colorOne, colorTwo); + + r.setGuildId(guild.getId()); + r.removeAllRights(); + r.setNeedsUpdate(true); + + if (Emulator.getConfig().getBoolean("imager.internal.enabled")) { + Emulator.getBadgeImager().generate(guild); + } + + this.client.sendResponse(new PurchaseOKComposer()); + this.client.sendResponse(new GuildBoughtComposer(guild)); + for (Habbo habbo : r.getHabbos()) { + habbo.getClient().sendResponse(new GuildInfoComposer(guild, habbo.getClient(), false, null)); + } + r.refreshGuild(guild); + + Emulator.getPluginManager().fireEvent(new GuildPurchasedEvent(guild, this.client.getHabbo())); + + Emulator.getGameEnvironment().getGuildManager().addGuild(guild); + } + } else { + String message = Emulator.getTexts().getValue("scripter.warning.guild.buy.owner").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()).replace("%roomname%", r.getName().replace("%owner%", r.getOwnerName())); + ScripterManager.scripterDetected(this.client, message); + log.info(message); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildBuyRoomsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildBuyRoomsEvent.java new file mode 100644 index 0000000..6ca7a4e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildBuyRoomsEvent.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildBuyRoomsComposer; +import gnu.trove.set.hash.THashSet; + +import java.util.List; + +public class RequestGuildBuyRoomsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + List rooms = Emulator.getGameEnvironment().getRoomManager().getRoomsForHabbo(this.client.getHabbo()); + + THashSet roomList = new THashSet(); + + for (Room room : rooms) { + if (room.getGuildId() == 0) + roomList.add(room); + } + + this.client.sendResponse(new GuildBuyRoomsComposer(roomList)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildFurniWidgetEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildFurniWidgetEvent.java new file mode 100644 index 0000000..18dc0b9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildFurniWidgetEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildFurniWidgetComposer; + +public class RequestGuildFurniWidgetEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + int guildId = this.packet.readInt(); + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) { + HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId); + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (item != null && guild != null) + this.client.sendResponse(new GuildFurniWidgetComposer(this.client.getHabbo(), guild, item)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildInfoEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildInfoEvent.java new file mode 100644 index 0000000..d3a0692 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildInfoEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildInfoComposer; + +public class RequestGuildInfoEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + boolean newWindow = this.packet.readBoolean(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (guild != null) { + this.client.sendResponse(new GuildInfoComposer(guild, this.client, newWindow, Emulator.getGameEnvironment().getGuildManager().getGuildMember(guild, this.client.getHabbo()))); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildJoinEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildJoinEvent.java new file mode 100644 index 0000000..811dca2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildJoinEvent.java @@ -0,0 +1,39 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildState; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildInfoComposer; +import com.eu.habbo.messages.outgoing.guilds.GuildJoinErrorComposer; + +public class RequestGuildJoinEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + + if (this.client.getHabbo().getHabboStats().hasGuild(guildId)) + return; + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (guild == null) + return; + + if (guild.getState() == GuildState.CLOSED || guild.getState() == GuildState.LARGE_CLOSED) { + this.client.sendResponse(new GuildJoinErrorComposer(GuildJoinErrorComposer.GROUP_CLOSED)); + return; + } + + Emulator.getGameEnvironment().getGuildManager().joinGuild(guild, this.client, 0, false); + this.client.sendResponse(new GuildInfoComposer(guild, this.client, false, Emulator.getGameEnvironment().getGuildManager().getGuildMember(guild, this.client.getHabbo()))); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null || room.getGuildId() != guildId) + return; + + room.refreshRightsForHabbo(this.client.getHabbo()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildManageEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildManageEvent.java new file mode 100644 index 0000000..ccb6ce8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildManageEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildManageComposer; + +public class RequestGuildManageEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(this.packet.readInt()); + + this.client.sendResponse(new GuildManageComposer(guild)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildMembersEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildMembersEvent.java new file mode 100644 index 0000000..2423a90 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildMembersEvent.java @@ -0,0 +1,31 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.habbohotel.guilds.GuildRank; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildMembersComposer; + +public class RequestGuildMembersEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int groupId = this.packet.readInt(); + int pageId = this.packet.readInt(); + String query = this.packet.readString(); + int levelId = this.packet.readInt(); + + Guild g = Emulator.getGameEnvironment().getGuildManager().getGuild(groupId); + + if (g != null) { + boolean isAdmin = this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN); + if (!isAdmin && this.client.getHabbo().getHabboStats().hasGuild(g.getId())) { + GuildMember member = Emulator.getGameEnvironment().getGuildManager().getGuildMember(g, this.client.getHabbo()); + isAdmin = member != null && (member.getRank().equals(GuildRank.OWNER) || member.getRank().equals(GuildRank.ADMIN)); + } + + this.client.sendResponse(new GuildMembersComposer(g, Emulator.getGameEnvironment().getGuildManager().getGuildMembers(g, pageId, levelId, query), this.client.getHabbo(), pageId, levelId, query, isAdmin, Emulator.getGameEnvironment().getGuildManager().getGuildMembersCount(g, pageId, levelId, query))); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildPartsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildPartsEvent.java new file mode 100644 index 0000000..3934076 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestGuildPartsEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildPartsComposer; + +public class RequestGuildPartsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new GuildPartsComposer()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestOwnGuildsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestOwnGuildsEvent.java new file mode 100644 index 0000000..1a89d70 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/RequestOwnGuildsEvent.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.incoming.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.GuildListComposer; +import gnu.trove.set.hash.THashSet; + +public class RequestOwnGuildsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + THashSet guilds = new THashSet(); + + for (int i : this.client.getHabbo().getHabboStats().guilds) { + if (i == 0) + continue; + + Guild g = Emulator.getGameEnvironment().getGuildManager().getGuild(i); + + if (g != null) { + guilds.add(g); + } + } + + this.client.sendResponse(new GuildListComposer(guilds, this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumDataEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumDataEvent.java new file mode 100644 index 0000000..ab78d2c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumDataEvent.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.incoming.guilds.forums; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.forums.GuildForumDataComposer; + +public class GuildForumDataEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = packet.readInt(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (guild == null) + return; + + this.client.sendResponse(new GuildForumDataComposer(guild, this.client.getHabbo())); + + if (!Emulator.getGameEnvironment().getGuildManager().hasViewedForum(this.client.getHabbo().getHabboInfo().getId(), guildId)) { + Emulator.getGameEnvironment().getGuildManager().addView(this.client.getHabbo().getHabboInfo().getId(), guildId); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumListEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumListEvent.java new file mode 100644 index 0000000..bc5eea6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumListEvent.java @@ -0,0 +1,96 @@ +package com.eu.habbo.messages.incoming.guilds.forums; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.forums.GuildForumListComposer; +import com.eu.habbo.messages.outgoing.handshake.ConnectionErrorComposer; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Set; + +@Slf4j +public class GuildForumListEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + int mode = this.packet.readInt(); + int offset = this.packet.readInt(); + int amount = this.packet.readInt(); + + Set guilds = null; + switch (mode) { + case 0: // most active + guilds = getActiveForums(); + break; + + case 1: // most viewed + guilds = Emulator.getGameEnvironment().getGuildManager().getMostViewed(); + break; + + case 2: // my groups + guilds = getMyForums(this.client.getHabbo().getHabboInfo().getId()); + break; + } + + if (guilds != null) { + this.client.sendResponse(new GuildForumListComposer(guilds, this.client.getHabbo(), mode, offset)); + } + } + + private THashSet getActiveForums() { + THashSet guilds = new THashSet(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT `guilds`.`id`, SUM(`guilds_forums_threads`.`posts_count`) AS `post_count` " + + "FROM `guilds_forums_threads` " + + "LEFT JOIN `guilds` ON `guilds`.`id` = `guilds_forums_threads`.`guild_id` " + + "WHERE `guilds`.`read_forum` = 'EVERYONE' AND `guilds_forums_threads`.`created_at` > ? " + + "GROUP BY `guilds`.`id` " + + "ORDER BY `post_count` DESC LIMIT 100")) { + statement.setInt(1, Emulator.getIntUnixTimestamp() - 7 * 24 * 60 * 60); + ResultSet set = statement.executeQuery(); + + while (set.next()) { + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(set.getInt("id")); + + if (guild != null) { + guilds.add(guild); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + this.client.sendResponse(new ConnectionErrorComposer(500)); + } + + return guilds; + } + + private THashSet getMyForums(int userId) { + THashSet guilds = new THashSet(); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT `guilds`.`id` FROM `guilds_members` " + + "LEFT JOIN `guilds` ON `guilds`.`id` = `guilds_members`.`guild_id` " + + "WHERE `guilds_members`.`user_id` = ? AND `guilds`.`forum` = '1'")) { + statement.setInt(1, userId); + ResultSet set = statement.executeQuery(); + + while (set.next()) { + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(set.getInt("id")); + + if (guild != null) { + guilds.add(guild); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + this.client.sendResponse(new ConnectionErrorComposer(500)); + } + + return guilds; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateMessageEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateMessageEvent.java new file mode 100644 index 0000000..6febac4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateMessageEvent.java @@ -0,0 +1,77 @@ +package com.eu.habbo.messages.incoming.guilds.forums; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.habbohotel.guilds.GuildRank; +import com.eu.habbo.habbohotel.guilds.forums.ForumThread; +import com.eu.habbo.habbohotel.guilds.forums.ForumThreadComment; +import com.eu.habbo.habbohotel.guilds.forums.ForumThreadState; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.guilds.forums.PostUpdateMessageComposer; +import com.eu.habbo.messages.outgoing.handshake.ConnectionErrorComposer; + + +public class GuildForumModerateMessageEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = packet.readInt(); + int threadId = packet.readInt(); + int messageId = packet.readInt(); + int state = packet.readInt(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + ForumThread thread = ForumThread.getById(threadId); + + if (guild == null || thread == null) { + this.client.sendResponse(new ConnectionErrorComposer(404)); + return; + } + + ForumThreadComment comment = thread.getCommentById(messageId); + if (comment == null) { + this.client.sendResponse(new ConnectionErrorComposer(404)); + return; + } + + boolean hasStaffPermissions = this.client.getHabbo().hasPermission(Permission.ACC_MODTOOL_TICKET_Q); + + GuildMember member = Emulator.getGameEnvironment().getGuildManager().getGuildMember(guildId, this.client.getHabbo().getHabboInfo().getId()); + if (member == null) { + this.client.sendResponse(new ConnectionErrorComposer(401)); + return; + } + + boolean isGuildAdministrator = (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || member.getRank().equals(GuildRank.ADMIN)); + + if (!isGuildAdministrator && !hasStaffPermissions) { + this.client.sendResponse(new ConnectionErrorComposer(403)); + return; + } + + if (state == ForumThreadState.HIDDEN_BY_GUILD_ADMIN.getStateId() && !hasStaffPermissions) { + this.client.sendResponse(new ConnectionErrorComposer(403)); + return; + } + + comment.setState(ForumThreadState.fromValue(state)); + comment.setAdminId(this.client.getHabbo().getHabboInfo().getId()); + this.client.sendResponse(new PostUpdateMessageComposer(guild.getId(), thread.getThreadId(), comment)); + + Emulator.getThreading().run(comment); + + switch (state) { + case 10: + case 20: + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FORUMS_MESSAGE_HIDDEN.key).compose()); + break; + case 1: + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FORUMS_MESSAGE_RESTORED.key).compose()); + break; + } + + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateThreadEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateThreadEvent.java new file mode 100644 index 0000000..5a83d41 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateThreadEvent.java @@ -0,0 +1,65 @@ +package com.eu.habbo.messages.incoming.guilds.forums; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.habbohotel.guilds.GuildRank; +import com.eu.habbo.habbohotel.guilds.forums.ForumThread; +import com.eu.habbo.habbohotel.guilds.forums.ForumThreadState; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.guilds.forums.GuildForumThreadMessagesComposer; +import com.eu.habbo.messages.outgoing.guilds.forums.GuildForumThreadsComposer; +import com.eu.habbo.messages.outgoing.handshake.ConnectionErrorComposer; + + +public class GuildForumModerateThreadEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = packet.readInt(); + int threadId = packet.readInt(); + int state = packet.readInt(); + // STATE 20 - HIDDEN_BY_GUILD_ADMIN = HIDDEN BY GUILD ADMINS/ HOTEL MODERATORS + // STATE 1 = VISIBLE THREAD + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + ForumThread thread = ForumThread.getById(threadId); + + if (guild == null || thread == null) { + this.client.sendResponse(new ConnectionErrorComposer(404)); + return; + } + + GuildMember member = Emulator.getGameEnvironment().getGuildManager().getGuildMember(guildId, this.client.getHabbo().getHabboInfo().getId()); + boolean hasStaffPerms = this.client.getHabbo().hasPermission(Permission.ACC_MODTOOL_TICKET_Q); // check for if they have staff perm + boolean isGuildAdmin = (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || member.getRank().equals(GuildRank.ADMIN)); + + + if (member == null) { + this.client.sendResponse(new ConnectionErrorComposer(401)); + return; + } + if (!isGuildAdmin && !hasStaffPerms) { + this.client.sendResponse(new ConnectionErrorComposer(403)); + return; + } + + thread.setState(ForumThreadState.fromValue(state)); // sets state as defined in the packet + thread.run(); + + switch (state) { + case 10: + case 20: + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FORUMS_THREAD_HIDDEN.key).compose()); + break; + case 1: + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FORUMS_THREAD_RESTORED.key).compose()); + break; + } + + this.client.sendResponse(new GuildForumThreadMessagesComposer(thread)); + this.client.sendResponse(new GuildForumThreadsComposer(guild, 0)); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumPostThreadEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumPostThreadEvent.java new file mode 100644 index 0000000..5d3db9e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumPostThreadEvent.java @@ -0,0 +1,99 @@ +package com.eu.habbo.messages.incoming.guilds.forums; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.habbohotel.guilds.GuildRank; +import com.eu.habbo.habbohotel.guilds.forums.ForumThread; +import com.eu.habbo.habbohotel.guilds.forums.ForumThreadComment; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.forums.GuildForumAddCommentComposer; +import com.eu.habbo.messages.outgoing.guilds.forums.GuildForumThreadMessagesComposer; +import com.eu.habbo.messages.outgoing.handshake.ConnectionErrorComposer; + + +public class GuildForumPostThreadEvent extends MessageHandler { + + @Override + public int getRatelimit() { + return 1000; + } + + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + int threadId = this.packet.readInt(); + String subject = this.packet.readString(); + String message = this.packet.readString(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (guild == null) { + this.client.sendResponse(new ConnectionErrorComposer(404)); + return; + } + + if (message.length() < 10 || message.length() > 4000 || (threadId == 0 && (subject.length() < 10 || subject.length() > 120))) { + this.client.sendResponse(new ConnectionErrorComposer(400)); + return; + } + + boolean isStaff = this.client.getHabbo().hasPermission(Permission.ACC_MODTOOL_TICKET_Q); + + GuildMember member = Emulator.getGameEnvironment().getGuildManager().getGuildMember(guildId, this.client.getHabbo().getHabboInfo().getId()); + + ForumThread thread = ForumThread.getById(threadId); + + if (threadId == 0) { + if (!((guild.canPostThreads().state == 0) + || (guild.canPostThreads().state == 1 && member != null) + || (guild.canPostThreads().state == 2 && member != null && (member.getRank().type < GuildRank.MEMBER.type)) + || (guild.canPostThreads().state == 3 && guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId()) + || isStaff)) { + this.client.sendResponse(new ConnectionErrorComposer(403)); + return; + } + + + thread = ForumThread.create(guild, this.client.getHabbo(), subject, message); + + if (thread == null) { + this.client.sendResponse(new ConnectionErrorComposer(500)); + return; + } + + this.client.getHabbo().getHabboStats().forumPostsCount += 1; + thread.setPostsCount(thread.getPostsCount() + 1); + this.client.sendResponse(new GuildForumThreadMessagesComposer(thread)); + return; + } + + if (thread == null) { + this.client.sendResponse(new ConnectionErrorComposer(404)); + return; + } + + + if (!((guild.canPostMessages().state == 0) + || (guild.canPostMessages().state == 1 && member != null) + || (guild.canPostMessages().state == 2 && member != null && (member.getRank().type < GuildRank.MEMBER.type)) + || (guild.canPostMessages().state == 3 && guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId()) + || isStaff)) { + this.client.sendResponse(new ConnectionErrorComposer(403)); + return; + } + + ForumThreadComment comment = ForumThreadComment.create(thread, this.client.getHabbo(), message); + + if (comment != null) { + thread.addComment(comment); + thread.setUpdatedAt(Emulator.getIntUnixTimestamp()); + this.client.getHabbo().getHabboStats().forumPostsCount += 1; + thread.setPostsCount(thread.getPostsCount() + 1); + this.client.sendResponse(new GuildForumAddCommentComposer(comment)); + } else { + this.client.sendResponse(new ConnectionErrorComposer(500)); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadUpdateEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadUpdateEvent.java new file mode 100644 index 0000000..5611b93 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadUpdateEvent.java @@ -0,0 +1,69 @@ +package com.eu.habbo.messages.incoming.guilds.forums; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.habbohotel.guilds.GuildRank; +import com.eu.habbo.habbohotel.guilds.SettingsState; +import com.eu.habbo.habbohotel.guilds.forums.ForumThread; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.guilds.forums.GuildForumThreadsComposer; +import com.eu.habbo.messages.outgoing.guilds.forums.ThreadUpdatedMessageComposer; +import com.eu.habbo.messages.outgoing.handshake.ConnectionErrorComposer; + +public class GuildForumThreadUpdateEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = this.packet.readInt(); + int threadId = this.packet.readInt(); + boolean isPinned = this.packet.readBoolean(); + boolean isLocked = this.packet.readBoolean(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + ForumThread thread = ForumThread.getById(threadId); + + if (guild == null || thread == null) { + this.client.sendResponse(new ConnectionErrorComposer(404)); + return; + } + + boolean isStaff = this.client.getHabbo().hasPermission(Permission.ACC_MODTOOL_TICKET_Q); + + GuildMember member = Emulator.getGameEnvironment().getGuildManager().getGuildMember(guildId, this.client.getHabbo().getHabboInfo().getId()); + if (member == null) { + this.client.sendResponse(new ConnectionErrorComposer(401)); + return; + } + + boolean isAdmin = (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || member.getRank().type < GuildRank.MEMBER.type); + + if ((guild.canModForum() == SettingsState.OWNER && guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() && !isStaff) || (guild.canModForum() == SettingsState.ADMINS && !isAdmin && !isStaff)) { + this.client.sendResponse(new ConnectionErrorComposer(403)); + return; + } + + boolean pinChanged = isPinned != thread.isPinned(); + if (pinChanged) { + this.client.sendResponse(new BubbleAlertComposer(isPinned ? BubbleAlertKeys.FORUMS_THREAD_PINNED.key : BubbleAlertKeys.FORUMS_THREAD_UNPINNED.key).compose()); + } + + if (isLocked != thread.isLocked()) { + this.client.sendResponse(new BubbleAlertComposer(isLocked ? BubbleAlertKeys.FORUMS_THREAD_LOCKED.key : BubbleAlertKeys.FORUMS_THREAD_UNLOCKED.key).compose()); + } + + thread.setPinned(isPinned); + thread.setLocked(isLocked); + + thread.run(); + + + this.client.sendResponse(new ThreadUpdatedMessageComposer(guild, thread, this.client.getHabbo(), isPinned, isLocked)); + + if (pinChanged) { + this.client.sendResponse(new GuildForumThreadsComposer(guild, 0)); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadsEvent.java new file mode 100644 index 0000000..a184c7c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadsEvent.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.incoming.guilds.forums; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.guilds.forums.GuildForumDataComposer; +import com.eu.habbo.messages.outgoing.guilds.forums.GuildForumThreadsComposer; +import com.eu.habbo.messages.outgoing.handshake.ConnectionErrorComposer; + +public class GuildForumThreadsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = packet.readInt(); + int index = packet.readInt(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (guild == null) { + this.client.sendResponse(new ConnectionErrorComposer(404)); + return; + } + + this.client.sendResponse(new GuildForumDataComposer(guild, this.client.getHabbo())); + this.client.sendResponse(new GuildForumThreadsComposer(guild, index)); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadsMessagesEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadsMessagesEvent.java new file mode 100644 index 0000000..c4a3ffe --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadsMessagesEvent.java @@ -0,0 +1,47 @@ +package com.eu.habbo.messages.incoming.guilds.forums; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.habbohotel.guilds.GuildRank; +import com.eu.habbo.habbohotel.guilds.GuildState; +import com.eu.habbo.habbohotel.guilds.forums.ForumThread; +import com.eu.habbo.habbohotel.guilds.forums.ForumThreadState; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.guilds.forums.GuildForumCommentsComposer; +import com.eu.habbo.messages.outgoing.guilds.forums.GuildForumDataComposer; +import com.eu.habbo.messages.outgoing.handshake.ConnectionErrorComposer; + + + +public class GuildForumThreadsMessagesEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = packet.readInt(); + int threadId = packet.readInt(); + int index = packet.readInt(); // 40 + int limit = packet.readInt(); // 20 + + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + ForumThread thread = ForumThread.getById(threadId); + boolean hasStaffPermissions = this.client.getHabbo().hasPermission(Permission.ACC_MODTOOL_TICKET_Q); + if (guild == null || thread == null) { + this.client.sendResponse(new ConnectionErrorComposer(404)); + return; + } + GuildMember member = Emulator.getGameEnvironment().getGuildManager().getGuildMember(guildId, this.client.getHabbo().getHabboInfo().getId()); + boolean isGuildAdministrator = (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || member.getRank().equals(GuildRank.ADMIN)); + + if (thread.getState() != ForumThreadState.HIDDEN_BY_GUILD_ADMIN || hasStaffPermissions || isGuildAdministrator) { + this.client.sendResponse(new GuildForumCommentsComposer(guildId, threadId, index, thread.getComments(limit, index))); + this.client.sendResponse(new GuildForumDataComposer(guild, this.client.getHabbo())); + } + else { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FORUMS_ACCESS_DENIED.key).compose()); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumUpdateSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumUpdateSettingsEvent.java new file mode 100644 index 0000000..e5e6504 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumUpdateSettingsEvent.java @@ -0,0 +1,46 @@ +package com.eu.habbo.messages.incoming.guilds.forums; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.SettingsState; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.guilds.forums.GuildForumDataComposer; +import com.eu.habbo.messages.outgoing.handshake.ConnectionErrorComposer; + +public class GuildForumUpdateSettingsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int guildId = packet.readInt(); + int canRead = packet.readInt(); + int postMessages = packet.readInt(); + int postThreads = packet.readInt(); + int modForum = packet.readInt(); + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId); + + if (guild == null) { + this.client.sendResponse(new ConnectionErrorComposer(404)); + return; + } + + if (guild.getOwnerId() != this.client.getHabbo().getHabboInfo().getId()) { + this.client.sendResponse(new ConnectionErrorComposer(403)); + return; + } + + guild.setReadForum(SettingsState.fromValue(canRead)); + guild.setPostMessages(SettingsState.fromValue(postMessages)); + guild.setPostThreads(SettingsState.fromValue(postThreads)); + guild.setModForum(SettingsState.fromValue(modForum)); + + guild.needsUpdate = true; + + Emulator.getThreading().run(guild); + + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FORUMS_FORUM_SETTINGS_UPDATED.key).compose()); + + this.client.sendResponse(new GuildForumDataComposer(guild, this.client.getHabbo())); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/CompleteDiffieHandshakeEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/CompleteDiffieHandshakeEvent.java new file mode 100644 index 0000000..f4c218e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/CompleteDiffieHandshakeEvent.java @@ -0,0 +1,34 @@ +package com.eu.habbo.messages.incoming.handshake; + +import com.eu.habbo.Emulator; +import com.eu.habbo.crypto.HabboRC4; +import com.eu.habbo.messages.NoAuthMessage; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.handshake.CompleteDiffieHandshakeComposer; +import com.eu.habbo.networking.gameserver.decoders.GameByteDecryption; +import com.eu.habbo.networking.gameserver.encoders.GameByteEncryption; +import com.eu.habbo.networking.gameserver.GameServerAttributes; + +@NoAuthMessage +public class CompleteDiffieHandshakeEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + if (this.client.getEncryption() == null) { + Emulator.getGameServer().getGameClientManager().disposeClient(this.client); + return; + } + + byte[] sharedKey = this.client.getEncryption().getDiffie().getSharedKey(this.packet.readString()); + + this.client.setHandshakeFinished(true); + this.client.sendResponse(new CompleteDiffieHandshakeComposer(this.client.getEncryption().getDiffie().getPublicKey())); + + this.client.getChannel().attr(GameServerAttributes.CRYPTO_CLIENT).set(new HabboRC4(sharedKey)); + this.client.getChannel().attr(GameServerAttributes.CRYPTO_SERVER).set(new HabboRC4(sharedKey)); + + this.client.getChannel().pipeline().addFirst(new GameByteDecryption()); + this.client.getChannel().pipeline().addFirst(new GameByteEncryption()); + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/InitDiffieHandshakeEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/InitDiffieHandshakeEvent.java new file mode 100644 index 0000000..3f0a382 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/InitDiffieHandshakeEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.incoming.handshake; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.NoAuthMessage; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.handshake.InitDiffieHandshakeComposer; + +@NoAuthMessage +public class InitDiffieHandshakeEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + if (this.client.getEncryption() == null) { + Emulator.getGameServer().getGameClientManager().disposeClient(this.client); + return; + } + + this.client.sendResponse(new InitDiffieHandshakeComposer( + this.client.getEncryption().getDiffie().getSignedPrime(), + this.client.getEncryption().getDiffie().getSignedGenerator())); + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/IsFirstLoginOfDayComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/IsFirstLoginOfDayComposer.java new file mode 100644 index 0000000..39fa17e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/IsFirstLoginOfDayComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.incoming.handshake; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class IsFirstLoginOfDayComposer extends MessageComposer { + private final boolean isFirstLoginOfDay; + + public IsFirstLoginOfDayComposer(boolean isFirstLoginOfDay) { + this.isFirstLoginOfDay = isFirstLoginOfDay; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.IsFirstLoginOfDayComposer); + this.response.appendBoolean(this.isFirstLoginOfDay); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/MachineIDEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/MachineIDEvent.java new file mode 100644 index 0000000..69d13a6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/MachineIDEvent.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.incoming.handshake; + +import com.eu.habbo.messages.NoAuthMessage; +import com.eu.habbo.messages.incoming.MessageHandler; + +@NoAuthMessage +public class MachineIDEvent extends MessageHandler { + + private static final int HASH_LENGTH = 64; + + @Override + public void handle() throws Exception { + String storedMachineId = this.packet.readString(); + String clientFingerprint = this.packet.readString(); + String capabilities = this.packet.readString(); + if (storedMachineId.length() > HASH_LENGTH) { + storedMachineId = storedMachineId.substring(0, HASH_LENGTH); + } + this.client.setMachineId(storedMachineId); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/PingEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/PingEvent.java new file mode 100644 index 0000000..b4ff08f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/PingEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.handshake; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.handshake.PongComposer; + +public class PingEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new PongComposer(this.packet.readInt())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/ReleaseVersionEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/ReleaseVersionEvent.java new file mode 100644 index 0000000..6327b69 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/ReleaseVersionEvent.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.incoming.handshake; + +import com.eu.habbo.messages.NoAuthMessage; +import com.eu.habbo.messages.incoming.MessageHandler; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@NoAuthMessage +public class ReleaseVersionEvent extends MessageHandler { + public static boolean isReady = false; + + private static final Logger LOGGER = LoggerFactory.getLogger(SecureLoginEvent.class); + + @Override + public void handle() throws Exception { + + // niet per se nodig + this.client.finishedReleaseEvent(); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java new file mode 100644 index 0000000..14f523c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java @@ -0,0 +1,238 @@ +package com.eu.habbo.messages.incoming.handshake; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.messenger.Messenger; +import com.eu.habbo.habbohotel.modtool.ModToolSanctionItem; +import com.eu.habbo.habbohotel.modtool.ModToolSanctions; +import com.eu.habbo.habbohotel.navigation.NavigatorSavedSearch; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.RoomManager; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.eu.habbo.habbohotel.users.clothingvalidation.ClothingValidationManager; +import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionHabboClub; +import com.eu.habbo.messages.NoAuthMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.gamecenter.GameCenterAccountInfoComposer; +import com.eu.habbo.messages.outgoing.gamecenter.GameCenterGameListComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.GenericAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.MessagesForYouComposer; +import com.eu.habbo.messages.outgoing.habboway.nux.NewUserIdentityComposer; +import com.eu.habbo.messages.outgoing.handshake.EnableNotificationsComposer; +import com.eu.habbo.messages.outgoing.handshake.SecureLoginOKComposer; +import com.eu.habbo.messages.outgoing.handshake.AvailabilityStatusMessageComposer; +import com.eu.habbo.messages.outgoing.handshake.PingComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryAchievementsComposer; +import com.eu.habbo.messages.outgoing.inventory.UserEffectsListComposer; +import com.eu.habbo.messages.outgoing.modtool.CfhTopicsMessageComposer; +import com.eu.habbo.messages.outgoing.modtool.ModToolComposer; +import com.eu.habbo.messages.outgoing.modtool.ModToolSanctionInfoComposer; +import com.eu.habbo.messages.outgoing.navigator.*; +import com.eu.habbo.messages.outgoing.unknown.BuildersClubExpiredComposer; +import com.eu.habbo.messages.outgoing.mysterybox.MysteryBoxKeysComposer; +import com.eu.habbo.messages.outgoing.users.*; +import com.eu.habbo.plugin.events.emulator.SSOAuthenticationEvent; +import com.eu.habbo.plugin.events.users.UserExecuteCommandEvent; +import com.eu.habbo.plugin.events.users.UserLoginEvent; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.Date; + +@NoAuthMessage +@Slf4j +public class SecureLoginEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + if (!this.client.getChannel().isOpen()) { + Emulator.getGameServer().getGameClientManager().disposeClient(this.client); + return; + } + + if (!this.client.didFinishReleaseEvent()) { + Emulator.getGameServer().getGameClientManager().disposeClient(this.client); + return; + } + + if (!Emulator.isReady) + return; + + if (Emulator.getConfig().getBoolean("encryption.forced", false) && Emulator.getCrypto().isEnabled() && !this.client.isHandshakeFinished()) { + Emulator.getGameServer().getGameClientManager().disposeClient(this.client); + log.warn("Encryption is forced and TLS Handshake isn't finished! Closed connection..."); + return; + } + + String sso = this.packet.readString().replace(" ", ""); + + if (Emulator.getPluginManager().fireEvent(new SSOAuthenticationEvent(sso)).isCancelled()) { + Emulator.getGameServer().getGameClientManager().disposeClient(this.client); + log.info("SSO Authentication is cancelled by a plugin. Closed connection..."); + return; + } + + if (sso.isEmpty()) { + Emulator.getGameServer().getGameClientManager().disposeClient(this.client); + log.debug("Client is trying to connect without SSO ticket! Closed connection..."); + return; + } + + if (this.client.getHabbo() == null) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().loadHabbo(sso); + if (habbo != null) { + try { + + habbo.setClient(this.client); + this.client.setHabbo(habbo); + if(!this.client.getHabbo().connect()) { + Emulator.getGameServer().getGameClientManager().disposeClient(this.client); + return; + } + + if (this.client.getHabbo().getHabboInfo() == null) { + Emulator.getGameServer().getGameClientManager().disposeClient(this.client); + return; + } + + if (this.client.getHabbo().getHabboInfo().getRank() == null) { + throw new NullPointerException(habbo.getHabboInfo().getUsername() + " has a NON EXISTING RANK!"); + } + + Emulator.getThreading().run(habbo); + Emulator.getGameEnvironment().getHabboManager().addHabbo(habbo); + } catch (Exception e) { + log.error("Caught exception", e); + Emulator.getGameServer().getGameClientManager().disposeClient(this.client); + return; + } + + if(ClothingValidationManager.VALIDATE_ON_LOGIN) { + String validated = ClothingValidationManager.validateLook(this.client.getHabbo()); + if(!validated.equals(this.client.getHabbo().getHabboInfo().getLook())) { + this.client.getHabbo().getHabboInfo().setLook(validated); + } + } + + ArrayList messages = new ArrayList<>(); + + messages.add(new SecureLoginOKComposer().compose()); + + int roomIdToEnter = 0; + + if (!this.client.getHabbo().getHabboStats().nux || Emulator.getConfig().getBoolean("retro.style.homeroom") && this.client.getHabbo().getHabboInfo().getHomeRoom() != 0) + roomIdToEnter = this.client.getHabbo().getHabboInfo().getHomeRoom(); + else if (!this.client.getHabbo().getHabboStats().nux || Emulator.getConfig().getBoolean("retro.style.homeroom") && RoomManager.HOME_ROOM_ID > 0) + roomIdToEnter = RoomManager.HOME_ROOM_ID; + + messages.add(new UserHomeRoomComposer(this.client.getHabbo().getHabboInfo().getHomeRoom(), roomIdToEnter).compose()); + messages.add(new UserEffectsListComposer(habbo, this.client.getHabbo().getInventory().getEffectsComponent().effects.values()).compose()); + messages.add(new UserClothesComposer(this.client.getHabbo()).compose()); + messages.add(new NewUserIdentityComposer(habbo).compose()); + messages.add(new UserPermissionsComposer(this.client.getHabbo()).compose()); + messages.add(new AvailabilityStatusMessageComposer(true, false, true).compose()); + messages.add(new PingComposer().compose()); + messages.add(new EnableNotificationsComposer(Emulator.getConfig().getBoolean("bubblealerts.enabled", true)).compose()); + messages.add(new UserAchievementScoreComposer(this.client.getHabbo()).compose()); + messages.add(new IsFirstLoginOfDayComposer(true).compose()); + messages.add(new MysteryBoxKeysComposer().compose()); + messages.add(new BuildersClubExpiredComposer().compose()); + messages.add(new CfhTopicsMessageComposer().compose()); + messages.add(new FavoriteRoomsCountComposer(this.client.getHabbo()).compose()); + messages.add(new GameCenterGameListComposer().compose()); + messages.add(new GameCenterAccountInfoComposer(3, 100).compose()); + messages.add(new GameCenterAccountInfoComposer(0, 100).compose()); + + messages.add(new UserClubComposer(this.client.getHabbo(), SubscriptionHabboClub.HABBO_CLUB, UserClubComposer.RESPONSE_TYPE_LOGIN).compose()); + + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + messages.add(new ModToolComposer(this.client.getHabbo()).compose()); + } + + this.client.sendResponses(messages); + + //Hardcoded + //this.client.sendResponse(new ForumsTestComposer()); + this.client.sendResponse(new InventoryAchievementsComposer()); + + ModToolSanctions modToolSanctions = Emulator.getGameEnvironment().getModToolSanctions(); + + if (Emulator.getConfig().getBoolean("hotel.sanctions.enabled")) { + THashMap> modToolSanctionItemsHashMap = Emulator.getGameEnvironment().getModToolSanctions().getSanctions(habbo.getHabboInfo().getId()); + ArrayList modToolSanctionItems = modToolSanctionItemsHashMap.get(habbo.getHabboInfo().getId()); + + if (modToolSanctionItems != null && modToolSanctionItems.size() > 0) { + ModToolSanctionItem item = modToolSanctionItems.get(modToolSanctionItems.size() - 1); + + if (item.sanctionLevel > 0 && item.probationTimestamp != 0 && item.probationTimestamp > Emulator.getIntUnixTimestamp()) { + this.client.sendResponse(new ModToolSanctionInfoComposer(this.client.getHabbo())); + } else if (item.sanctionLevel > 0 && item.probationTimestamp != 0 && item.probationTimestamp <= Emulator.getIntUnixTimestamp()) { + modToolSanctions.updateSanction(item.id, 0); + } + + if (item.tradeLockedUntil > 0 && item.tradeLockedUntil <= Emulator.getIntUnixTimestamp()) { + modToolSanctions.updateTradeLockedUntil(item.id, 0); + habbo.getHabboStats().setAllowTrade(true); + } else if (item.tradeLockedUntil > 0 && item.tradeLockedUntil > Emulator.getIntUnixTimestamp()) { + habbo.getHabboStats().setAllowTrade(false); + } + + if (item.isMuted && item.muteDuration <= Emulator.getIntUnixTimestamp()) { + modToolSanctions.updateMuteDuration(item.id, 0); + habbo.unMute(); + } else if (item.isMuted && item.muteDuration > Emulator.getIntUnixTimestamp()) { + Date muteDuration = new Date((long) item.muteDuration * 1000); + long diff = muteDuration.getTime() - Emulator.getDate().getTime(); + habbo.mute(Math.toIntExact(diff), false); + } + } + } + + UserLoginEvent userLoginEvent = new UserLoginEvent(habbo, this.client.getHabbo().getHabboInfo().getIpLogin()); + Emulator.getPluginManager().fireEvent(userLoginEvent); + + if(userLoginEvent.isCancelled()) { + Emulator.getGameServer().getGameClientManager().disposeClient(this.client); + return; + } + + if (Emulator.getConfig().getBoolean("hotel.welcome.alert.enabled")) { + final Habbo finalHabbo = habbo; + Emulator.getThreading().run(() -> { + if (Emulator.getConfig().getBoolean("hotel.welcome.alert.oldstyle")) { + SecureLoginEvent.this.client.sendResponse(new MessagesForYouComposer(HabboManager.WELCOME_MESSAGE.replace("%username%", finalHabbo.getHabboInfo().getUsername()).replace("%user%", finalHabbo.getHabboInfo().getUsername()).split("
"))); + } else { + SecureLoginEvent.this.client.sendResponse(new GenericAlertComposer(HabboManager.WELCOME_MESSAGE.replace("%username%", finalHabbo.getHabboInfo().getUsername()).replace("%user%", finalHabbo.getHabboInfo().getUsername()))); + } + }, Emulator.getConfig().getInt("hotel.welcome.alert.delay", 5000)); + } + + if(SubscriptionHabboClub.HC_PAYDAY_ENABLED) { + SubscriptionHabboClub.processUnclaimed(habbo); + } + + SubscriptionHabboClub.processClubBadge(habbo); + + Messenger.checkFriendSizeProgress(habbo); + + if (!habbo.getHabboStats().hasGottenDefaultSavedSearches) { + habbo.getHabboStats().hasGottenDefaultSavedSearches = true; + Emulator.getThreading().run(habbo.getHabboStats()); + + habbo.getHabboInfo().addSavedSearch(new NavigatorSavedSearch("official-root", "")); + habbo.getHabboInfo().addSavedSearch(new NavigatorSavedSearch("my", "")); + habbo.getHabboInfo().addSavedSearch(new NavigatorSavedSearch("favorites", "")); + + this.client.sendResponse(new NewNavigatorSavedSearchesComposer(this.client.getHabbo().getHabboInfo().getSavedSearches())); + } + } else { + Emulator.getGameServer().getGameClientManager().disposeClient(this.client); + log.warn("Someone tried to login with a non-existing SSO token! Closed connection..."); + } + } else { + Emulator.getGameServer().getGameClientManager().disposeClient(this.client); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/UsernameEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/UsernameEvent.java new file mode 100644 index 0000000..c217e94 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/UsernameEvent.java @@ -0,0 +1,112 @@ +package com.eu.habbo.messages.incoming.handshake; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarCampaign; +import com.eu.habbo.habbohotel.catalog.TargetOffer; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.TargetedOfferComposer; +import com.eu.habbo.messages.outgoing.events.calendar.AdventCalendarDataComposer; +import com.eu.habbo.messages.outgoing.habboway.nux.NuxAlertComposer; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.Timestamp; +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.Calendar; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +import static java.time.temporal.ChronoUnit.DAYS; + +public class UsernameEvent extends MessageHandler { + @Override + public void handle() throws Exception { + boolean calendar = false; + if (!this.client.getHabbo().getHabboStats().getAchievementProgress().containsKey(Emulator.getGameEnvironment().getAchievementManager().getAchievement("Login"))) { + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("Login")); + calendar = true; + } else { + + long daysBetween = DAYS.between(new Date((long) this.client.getHabbo().getHabboInfo().getLastOnline() * 1000L).toInstant(), new Date().toInstant()); + + + Date lastLogin = new Date(this.client.getHabbo().getHabboInfo().getLastOnline()); + Calendar c1 = Calendar.getInstance(); + c1.add(Calendar.DAY_OF_YEAR, -1); + + Calendar c2 = Calendar.getInstance(); + c2.setTime(lastLogin); + + if (daysBetween == 1) { + if (this.client.getHabbo().getHabboStats().getAchievementProgress().get(Emulator.getGameEnvironment().getAchievementManager().getAchievement("Login")) == this.client.getHabbo().getHabboStats().loginStreak) { + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("Login")); + } + this.client.getHabbo().getHabboStats().loginStreak++; + calendar = true; + } else if (daysBetween >= 1) { + calendar = true; + } else { + if (((lastLogin.getTime() / 1000) - Emulator.getIntUnixTimestamp()) > 86400) { + this.client.getHabbo().getHabboStats().loginStreak = 0; + } + } + } + + if (!this.client.getHabbo().getHabboStats().getAchievementProgress().containsKey(Emulator.getGameEnvironment().getAchievementManager().getAchievement("RegistrationDuration"))) { + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("RegistrationDuration"), 0); + } else { + int daysRegistered = ((Emulator.getIntUnixTimestamp() - this.client.getHabbo().getHabboInfo().getAccountCreated()) / 86400); + + int days = this.client.getHabbo().getHabboStats().getAchievementProgress( + Emulator.getGameEnvironment().getAchievementManager().getAchievement("RegistrationDuration") + ); + + if (daysRegistered - days > 0) { + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("RegistrationDuration"), daysRegistered - days); + } + } + + if (!this.client.getHabbo().getHabboStats().getAchievementProgress().containsKey(Emulator.getGameEnvironment().getAchievementManager().getAchievement("TraderPass"))) { + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("TraderPass")); + } + + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement achievementQueueStatement = connection.prepareStatement("SELECT * FROM users_achievements_queue WHERE user_id = ?")) { + achievementQueueStatement.setInt(1, this.client.getHabbo().getHabboInfo().getId()); + + try (ResultSet achievementSet = achievementQueueStatement.executeQuery()) { + while (achievementSet.next()) { + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement(achievementSet.getInt("achievement_id")), achievementSet.getInt("amount")); + } + } + + try (PreparedStatement deleteStatement = connection.prepareStatement("DELETE FROM users_achievements_queue WHERE user_id = ?")) { + deleteStatement.setInt(1, this.client.getHabbo().getHabboInfo().getId()); + deleteStatement.execute(); + } + } + if (Emulator.getConfig().getBoolean("hotel.calendar.enabled")) { + CalendarCampaign campaign = Emulator.getGameEnvironment().getCalendarManager().getCalendarCampaign(Emulator.getConfig().getValue("hotel.calendar.default")); + if(campaign != null){ + long daysBetween = DAYS.between(new Timestamp(campaign.getStartTimestamp() * 1000L).toInstant(), new Date().toInstant()); + if(daysBetween >= 0) { + this.client.sendResponse(new AdventCalendarDataComposer(campaign.getName(), campaign.getImage(), campaign.getTotalDays(), (int) daysBetween, this.client.getHabbo().getHabboStats().calendarRewardsClaimed, campaign.getLockExpired())); + this.client.sendResponse(new NuxAlertComposer("openView/calendar")); + } + }; + } + + if (TargetOffer.ACTIVE_TARGET_OFFER_ID > 0) { + TargetOffer offer = Emulator.getGameEnvironment().getCatalogManager().getTargetOffer(TargetOffer.ACTIVE_TARGET_OFFER_ID); + + if (offer != null) { + this.client.sendResponse(new TargetedOfferComposer(this.client.getHabbo(), offer)); + } + } + + this.client.getHabbo().getHabboInfo().setLastOnline(Emulator.getIntUnixTimestamp()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/helper/MySanctionStatusEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/helper/MySanctionStatusEvent.java new file mode 100644 index 0000000..8608708 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/helper/MySanctionStatusEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.helper; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.ModToolSanctionInfoComposer; + +public class MySanctionStatusEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + this.client.sendResponse(new ModToolSanctionInfoComposer(this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/helper/RequestTalentTrackEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/helper/RequestTalentTrackEvent.java new file mode 100644 index 0000000..6c85194 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/helper/RequestTalentTrackEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.messages.incoming.helper; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.TalentTrackType; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.achievements.talenttrack.TalentTrackComposer; + +public class RequestTalentTrackEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (Emulator.getConfig().getBoolean("hotel.talenttrack.enabled")) { + this.client.sendResponse(new TalentTrackComposer(this.client.getHabbo(), TalentTrackType.valueOf(this.packet.readString().toUpperCase()))); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewClaimBadgeRewardEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewClaimBadgeRewardEvent.java new file mode 100644 index 0000000..64389be --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewClaimBadgeRewardEvent.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.incoming.hotelview; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.habbohotel.users.inventory.BadgesComponent; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.users.AddUserBadgeComposer; + +public class HotelViewClaimBadgeRewardEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String request = this.packet.readString(); + + if (Emulator.getConfig().getBoolean("hotelview.badgereward." + request + ".enabled")) { + String badgeCode = Emulator.getConfig().getValue("hotelview.badgereward." + request + "badge"); + + if (!badgeCode.isEmpty()) { + if (!this.client.getHabbo().getInventory().getBadgesComponent().hasBadge(badgeCode)) { + HabboBadge badge = BadgesComponent.createBadge(badgeCode, this.client.getHabbo()); + this.client.sendResponse(new AddUserBadgeComposer(badge)); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewDataEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewDataEvent.java new file mode 100644 index 0000000..e1bc5e4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewDataEvent.java @@ -0,0 +1,35 @@ +package com.eu.habbo.messages.incoming.hotelview; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.hotelview.HotelViewDataComposer; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class HotelViewDataEvent extends MessageHandler { + @Override + public void handle() { + + try { + String data = this.packet.readString(); + if (data.contains(";")) { + String[] d = data.split(";"); + + for (String s : d) { + if (s.contains(",")) { + this.client.sendResponse(new HotelViewDataComposer(s, s.split(",")[s.split(",").length - 1])); + } else { + this.client.sendResponse(new HotelViewDataComposer(data, s)); + } + + break; + } + + //this.client.sendResponse(new HotelViewDataComposer("2013-05-08 13:0", "gamesmaker")); + } else { + this.client.sendResponse(new HotelViewDataComposer(data, data.split(",")[data.split(",").length - 1])); + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewEvent.java new file mode 100644 index 0000000..67dddaa --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewEvent.java @@ -0,0 +1,33 @@ +package com.eu.habbo.messages.incoming.hotelview; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.hotelview.HotelViewComposer; + +public class HotelViewEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.getHabbo().getHabboInfo().setLoadingRoom(0); + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) { + Emulator.getGameEnvironment().getRoomManager().leaveRoom(this.client.getHabbo(), this.client.getHabbo().getHabboInfo().getCurrentRoom()); + } + + if (this.client.getHabbo().getHabboInfo().getRoomQueueId() != 0) { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.client.getHabbo().getHabboInfo().getRoomQueueId()); + + if (room != null) { + room.removeFromQueue(this.client.getHabbo()); + } else { + this.client.getHabbo().getHabboInfo().setRoomQueueId(0); + } + this.client.sendResponse(new HotelViewComposer()); + } + + if (this.client.getHabbo().getRoomUnit() != null) { + this.client.getHabbo().getRoomUnit().clearWalking(); + this.client.getHabbo().getRoomUnit().setInRoom(false); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewRequestBadgeRewardEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewRequestBadgeRewardEvent.java new file mode 100644 index 0000000..edbefbd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewRequestBadgeRewardEvent.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.incoming.hotelview; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.hotelview.HotelViewBadgeButtonConfigComposer; + +public class HotelViewRequestBadgeRewardEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String badge = this.packet.readString(); + this.client.sendResponse(new HotelViewBadgeButtonConfigComposer(Emulator.getConfig().getValue("hotelview.badgereward." + badge + ".badge"), Emulator.getConfig().getBoolean("hotelview.badgereward." + badge + ".enabled"))); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewRequestBonusRareEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewRequestBonusRareEvent.java new file mode 100644 index 0000000..37c9db1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewRequestBonusRareEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.hotelview; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.hotelview.BonusRareComposer; + +public class HotelViewRequestBonusRareEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new BonusRareComposer(this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewRequestLTDAvailabilityEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewRequestLTDAvailabilityEvent.java new file mode 100644 index 0000000..99dc88c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewRequestLTDAvailabilityEvent.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.incoming.hotelview; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.hotelview.HotelViewNextLTDAvailableComposer; + +public class HotelViewRequestLTDAvailabilityEvent extends MessageHandler { + public static boolean ENABLED = false; + public static int TIMESTAMP; + public static int ITEM_ID; + public static int PAGE_ID; + public static String ITEM_NAME; + + @Override + public void handle() throws Exception { + if (ENABLED) { + int timeremaining = Math.max(TIMESTAMP - Emulator.getIntUnixTimestamp(), -1); + this.client.sendResponse(new HotelViewNextLTDAvailableComposer( + timeremaining, + timeremaining > 0 ? -1 : ITEM_ID, + timeremaining > 0 ? -1 : PAGE_ID, + timeremaining > 0 ? "" : ITEM_NAME)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewRequestSecondsUntilEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewRequestSecondsUntilEvent.java new file mode 100644 index 0000000..c7a6be2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewRequestSecondsUntilEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.incoming.hotelview; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.hotelview.HotelViewSecondsUntilComposer; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +public class HotelViewRequestSecondsUntilEvent extends MessageHandler { + private static DateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd hh:mm"); + + @Override + public void handle() throws Exception { + String date = this.packet.readString(); + int secondsUntil = Math.max(0, (int) (dateFormat.parse(date).getTime() / 1000) - Emulator.getIntUnixTimestamp()); + + this.client.sendResponse(new HotelViewSecondsUntilComposer(date, secondsUntil)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/RequestNewsListEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/RequestNewsListEvent.java new file mode 100644 index 0000000..d3928dc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/hotelview/RequestNewsListEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.messages.incoming.hotelview; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.hotelview.HallOfFameComposer; +import com.eu.habbo.messages.outgoing.hotelview.HotelViewDataComposer; +import com.eu.habbo.messages.outgoing.hotelview.NewsListComposer; + +public class RequestNewsListEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new HotelViewDataComposer("2013-05-08 13:0", "gamesmaker")); + this.client.sendResponse(new HallOfFameComposer(Emulator.getGameEnvironment().getHotelViewManager().getHallOfFame())); + this.client.sendResponse(new NewsListComposer()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryBadgesEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryBadgesEvent.java new file mode 100644 index 0000000..a0d2350 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryBadgesEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.inventory; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.inventory.InventoryBadgesComposer; + +public class RequestInventoryBadgesEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new InventoryBadgesComposer(this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryBotsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryBotsEvent.java new file mode 100644 index 0000000..276dd00 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryBotsEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.inventory; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.inventory.InventoryBotsComposer; + +public class RequestInventoryBotsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new InventoryBotsComposer(this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryItemsDelete.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryItemsDelete.java new file mode 100644 index 0000000..36724fb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryItemsDelete.java @@ -0,0 +1,63 @@ +package com.eu.habbo.messages.incoming.inventory; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.inventory.RemoveHabboItemComposer; +import com.eu.habbo.threading.runnables.QueryDeleteHabboItems; +import gnu.trove.map.hash.TIntObjectHashMap; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +@Slf4j +public class RequestInventoryItemsDelete extends MessageHandler { + public int getRatelimit() { + return 500; + } + + public void handle() { + int itemId = this.packet.readInt(); + int amount = this.packet.readInt(); + HabboItem habboItem = this.client.getHabbo().getInventory().getItemsComponent().getHabboItem(itemId); + if (habboItem == null) + return; + Item item = habboItem.getBaseItem(); + if (item == null) + return; + if (!hasFurnitureInInventory(this.client.getHabbo(), item, Math.abs(amount))) + return; + final Habbo habbo = this.client.getHabbo(); + if (habbo == null) + return; + + List toRemove = IntStream.range(0, Math.abs(amount)) + .mapToObj(i -> habbo.getInventory().getItemsComponent().getAndRemoveHabboItem(item)) + .filter(removeItem -> removeItem != null) + .collect(Collectors.toList()); + + TIntObjectHashMap toRemoveMap = new TIntObjectHashMap<>(); + toRemove.forEach(removeItem -> toRemoveMap.put(removeItem.getId(), removeItem)); + + toRemoveMap.forEachValue(mapHabboItem -> { + habbo.getClient().sendResponse(new RemoveHabboItemComposer(mapHabboItem.getGiftAdjustedId())); + return true; + }); + + habbo.getClient().sendResponse(new InventoryRefreshComposer()); + Emulator.getThreading().run(new QueryDeleteHabboItems(toRemoveMap)); + } + + private boolean hasFurnitureInInventory(Habbo habbo, Item item, Integer amount) { + long count = habbo.getInventory().getItemsComponent().getItemsAsValueCollection().stream() + .filter(habboItem -> habboItem.getBaseItem().getId() == item.getId()) + .count(); + + return count >= amount; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryItemsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryItemsEvent.java new file mode 100644 index 0000000..5a1cc07 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryItemsEvent.java @@ -0,0 +1,62 @@ +package com.eu.habbo.messages.incoming.inventory; + +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.inventory.InventoryItemsComposer; +import gnu.trove.iterator.TIntObjectIterator; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import lombok.extern.slf4j.Slf4j; +import java.util.NoSuchElementException; + +@Slf4j +public class RequestInventoryItemsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int totalItems = this.client.getHabbo().getInventory().getItemsComponent().getItems().size(); + + if (totalItems == 0) { + this.client.sendResponse(new InventoryItemsComposer(0, 1, new TIntObjectHashMap<>())); + return; + } + + int totalFragments = (int) Math.ceil((double) totalItems / 1000.0); + + if (totalFragments == 0) { + totalFragments = 1; + } + + synchronized (this.client.getHabbo().getInventory().getItemsComponent().getItems()) { + TIntObjectMap items = new TIntObjectHashMap<>(); + + TIntObjectIterator iterator = this.client.getHabbo().getInventory().getItemsComponent().getItems().iterator(); + + int count = 0; + int fragmentNumber = 0; + + for (int i = this.client.getHabbo().getInventory().getItemsComponent().getItems().size(); i-- > 0; ) { + + if (count == 0) { + fragmentNumber++; + } + + try { + iterator.advance(); + items.put(iterator.key(), iterator.value()); + count++; + } catch (NoSuchElementException e) { + log.error("Caught exception", e); + break; + } + + if (count == 1000) { + this.client.sendResponse(new InventoryItemsComposer(fragmentNumber, totalFragments, items)); + count = 0; + items.clear(); + } + } + + if(count > 0 && items.size() > 0) this.client.sendResponse(new InventoryItemsComposer(fragmentNumber, totalFragments, items)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryPetsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryPetsEvent.java new file mode 100644 index 0000000..e370acc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryPetsEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.inventory; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.inventory.InventoryPetsComposer; + +public class RequestInventoryPetsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new InventoryPetsComposer(this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolAlertEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolAlertEvent.java new file mode 100644 index 0000000..09b4ebb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolAlertEvent.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.support.SupportUserAlertedReason; + +public class ModToolAlertEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + Habbo alertedUser = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.packet.readInt()); + + if (alertedUser != null) + Emulator.getGameEnvironment().getModToolManager().alert(this.client.getHabbo(), alertedUser, this.packet.readString(), SupportUserAlertedReason.ALERT); + } else { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.modtools.kick").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolChangeRoomSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolChangeRoomSettingsEvent.java new file mode 100644 index 0000000..a84022d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolChangeRoomSettingsEvent.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class ModToolChangeRoomSettingsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.packet.readInt()); + + if (room != null) { + final boolean lockDoor = this.packet.readInt() == 1; + final boolean changeTitle = this.packet.readInt() == 1; + final boolean kickUsers = this.packet.readInt() == 1; + + Emulator.getGameEnvironment().getModToolManager().roomAction(room, this.client.getHabbo(), kickUsers, lockDoor, changeTitle); + } + } else { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.modtools.roomsettings").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolCloseTicketEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolCloseTicketEvent.java new file mode 100644 index 0000000..9326623 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolCloseTicketEvent.java @@ -0,0 +1,42 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class ModToolCloseTicketEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + int state = this.packet.readInt(); + int something = this.packet.readInt(); + int ticketId = this.packet.readInt(); + + ModToolIssue issue = Emulator.getGameEnvironment().getModToolManager().getTicket(ticketId); + + if (issue == null || issue.modId != this.client.getHabbo().getHabboInfo().getId()) + return; + + Habbo sender = Emulator.getGameEnvironment().getHabboManager().getHabbo(issue.senderId); + + switch (state) { + case 1: + Emulator.getGameEnvironment().getModToolManager().closeTicketAsUseless(issue, sender); + break; + + case 2: + Emulator.getGameEnvironment().getModToolManager().closeTicketAsAbusive(issue, sender); + break; + + case 3: + Emulator.getGameEnvironment().getModToolManager().closeTicketAsHandled(issue, sender); + break; + } + } else { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.modtools.ticket.close").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolIssueChangeTopicEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolIssueChangeTopicEvent.java new file mode 100644 index 0000000..efa0e85 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolIssueChangeTopicEvent.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.threading.runnables.UpdateModToolIssue; + +public class ModToolIssueChangeTopicEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + int ticketId = this.packet.readInt(); + int unknownInt = this.packet.readInt(); + int categoryId = this.packet.readInt(); + + ModToolIssue issue = Emulator.getGameEnvironment().getModToolManager().getTicket(ticketId); + + if (issue != null) { + issue.category = categoryId; + new UpdateModToolIssue(issue).run(); + Emulator.getGameEnvironment().getModToolManager().updateTicketToMods(issue); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolIssueDefaultSanctionEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolIssueDefaultSanctionEvent.java new file mode 100644 index 0000000..3a0f770 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolIssueDefaultSanctionEvent.java @@ -0,0 +1,46 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.*; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class ModToolIssueDefaultSanctionEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + int issueId = this.packet.readInt(); + int unknown = this.packet.readInt(); + int category = this.packet.readInt(); + + ModToolIssue issue = Emulator.getGameEnvironment().getModToolManager().getTicket(issueId); + + if (issue.modId == this.client.getHabbo().getHabboInfo().getId()) { + CfhTopic modToolCategory = Emulator.getGameEnvironment().getModToolManager().getCfhTopic(category); + + if (modToolCategory != null) { + ModToolPreset defaultSanction = modToolCategory.defaultSanction; + + if (defaultSanction != null) { + Habbo target = Emulator.getGameEnvironment().getHabboManager().getHabbo(issue.reportedId); + + if (defaultSanction.banLength > 0) { + Emulator.getGameEnvironment().getModToolManager().ban(issue.reportedId, this.client.getHabbo(), defaultSanction.message, defaultSanction.banLength * 86400, ModToolBanType.ACCOUNT, modToolCategory.id); + } else if (defaultSanction.muteLength > 0) { + + if (target != null) { + target.mute(defaultSanction.muteLength * 86400, false); + } + } + } + } + + issue.state = ModToolTicketState.CLOSED; + Emulator.getGameEnvironment().getModToolManager().updateTicketToMods(issue); + } else { + this.client.getHabbo().alert(Emulator.getTexts().getValue("supporttools.not_ticket_owner")); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolKickEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolKickEvent.java new file mode 100644 index 0000000..3e1e234 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolKickEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class ModToolKickEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Emulator.getGameEnvironment().getModToolManager().kick(this.client.getHabbo(), Emulator.getGameEnvironment().getHabboManager().getHabbo(this.packet.readInt()), this.packet.readString()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolPickTicketEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolPickTicketEvent.java new file mode 100644 index 0000000..172ad65 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolPickTicketEvent.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.habbohotel.modtool.ModToolTicketState; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.ModToolIssueInfoComposer; + +public class ModToolPickTicketEvent extends MessageHandler { + public static boolean send = false; + + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + this.packet.readInt(); + ModToolIssue issue = Emulator.getGameEnvironment().getModToolManager().getTicket(this.packet.readInt()); + + if (issue != null) { + if (issue.state == ModToolTicketState.PICKED) { + this.client.sendResponse(new ModToolIssueInfoComposer(issue)); + this.client.getHabbo().alert(Emulator.getTexts().getValue("support.ticket.picked.failed")); + + return; + } + + //this.client.sendResponse(new ModToolIssueInfoComposer(issue)); + Emulator.getGameEnvironment().getModToolManager().pickTicket(issue, this.client.getHabbo()); + } else { + this.client.getHabbo().alert(Emulator.getTexts().getValue("support.ticket.picked.failed")); + } + } else { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.modtools.ticket.pick").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolReleaseTicketEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolReleaseTicketEvent.java new file mode 100644 index 0000000..e0a155d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolReleaseTicketEvent.java @@ -0,0 +1,39 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.habbohotel.modtool.ModToolTicketState; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class ModToolReleaseTicketEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + int count = this.packet.readInt(); + + while (count != 0) { + count--; + + int ticketId = this.packet.readInt(); + + ModToolIssue issue = Emulator.getGameEnvironment().getModToolManager().getTicket(ticketId); + + if (issue == null) + continue; + + if (issue.modId != this.client.getHabbo().getHabboInfo().getId()) + continue; + + issue.modId = 0; + issue.modName = ""; + issue.state = ModToolTicketState.OPEN; + + Emulator.getGameEnvironment().getModToolManager().updateTicketToMods(issue); + } + } else { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.modtools.ticket.release").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestIssueChatlogEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestIssueChatlogEvent.java new file mode 100644 index 0000000..4eb2756 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestIssueChatlogEvent.java @@ -0,0 +1,76 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.forums.ForumThread; +import com.eu.habbo.habbohotel.modtool.*; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.ModToolIssueChatlogComposer; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class ModToolRequestIssueChatlogEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + ModToolIssue issue = Emulator.getGameEnvironment().getModToolManager().getTicket(this.packet.readInt()); + + if (issue != null) { + List chatlog = new ArrayList<>(); + ModToolIssueChatlogType chatlogType = ModToolIssueChatlogType.CHAT; + + if (issue.type == ModToolTicketType.IM) { + chatlog = Emulator.getGameEnvironment().getModToolManager().getMessengerChatlog(issue.reportedId, issue.senderId); + chatlogType = ModToolIssueChatlogType.IM; + } else if (issue.type == ModToolTicketType.DISCUSSION) { + if (issue.commentId == -1) { + chatlogType = ModToolIssueChatlogType.FORUM_THREAD; + + ForumThread thread = ForumThread.getById(issue.threadId); + + if (thread != null) { + chatlog = thread.getComments().stream().map(c -> new ModToolChatLog(c.getCreatedAt(), c.getHabbo().getHabboInfo().getId(), c.getHabbo().getHabboInfo().getUsername(), c.getMessage())).collect(Collectors.toList()); + } + } else { + chatlogType = ModToolIssueChatlogType.FORUM_COMMENT; + + ForumThread thread = ForumThread.getById(issue.threadId); + + if (thread != null) { + chatlog = thread.getComments().stream().map(c -> new ModToolChatLog(c.getCreatedAt(), c.getHabbo().getHabboInfo().getId(), c.getHabbo().getHabboInfo().getUsername(), c.getMessage(), c.getCommentId() == issue.commentId)).collect(Collectors.toList()); + } + } + } else if (issue.type == ModToolTicketType.PHOTO) { + if (issue.photoItem != null) { + chatlogType = ModToolIssueChatlogType.PHOTO; + + chatlog = Emulator.getGameEnvironment().getModToolManager().getRoomChatlog(issue.roomId); + } + } else { + chatlogType = ModToolIssueChatlogType.CHAT; + + if (issue.roomId > 0) { + chatlog = Emulator.getGameEnvironment().getModToolManager().getRoomChatlog(issue.roomId); + } else { + chatlog = new ArrayList<>(); + chatlog.addAll(Emulator.getGameEnvironment().getModToolManager().getUserChatlog(issue.reportedId)); + chatlog.addAll(Emulator.getGameEnvironment().getModToolManager().getUserChatlog(issue.senderId)); + } + } + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(issue.roomId); + String roomName = ""; + + if (room != null) { + roomName = room.getName(); + } + this.client.sendResponse(new ModToolIssueChatlogComposer(issue, chatlog, roomName, chatlogType)); + } + } else { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.modtools.chatlog").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestRoomChatlogEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestRoomChatlogEvent.java new file mode 100644 index 0000000..5f58f50 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestRoomChatlogEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.ModToolRoomChatlogComposer; + +public class ModToolRequestRoomChatlogEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + this.packet.readInt(); + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.packet.readInt()); + + if (room != null) + this.client.sendResponse(new ModToolRoomChatlogComposer(room, Emulator.getGameEnvironment().getModToolManager().getRoomChatlog(room.getId()))); + } else { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.modtools.chatlog").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestRoomInfoEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestRoomInfoEvent.java new file mode 100644 index 0000000..5f14055 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestRoomInfoEvent.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.ModToolRoomInfoComposer; + +public class ModToolRequestRoomInfoEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + int roomId = this.packet.readInt(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId); + + if (room != null) { + this.client.sendResponse(new ModToolRoomInfoComposer(room)); + } + } else { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.modtools.roominfo").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestRoomUserChatlogEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestRoomUserChatlogEvent.java new file mode 100644 index 0000000..6fec0a9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestRoomUserChatlogEvent.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.ModToolRoomChatlogComposer; + +public class ModToolRequestRoomUserChatlogEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + int userId = this.packet.readInt(); + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + + if (habbo != null) { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + this.client.sendResponse(new ModToolRoomChatlogComposer(room, Emulator.getGameEnvironment().getModToolManager().getRoomChatlog(room.getId()))); + } + } + } else { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.chatlog").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestRoomVisitsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestRoomVisitsEvent.java new file mode 100644 index 0000000..348cb10 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestRoomVisitsEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.ModToolUserRoomVisitsComposer; + +public class ModToolRequestRoomVisitsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + int userId = this.packet.readInt(); + + HabboInfo habboInfo = Emulator.getGameEnvironment().getHabboManager().getHabboInfo(userId); + + if (habboInfo != null) { + this.client.sendResponse(new ModToolUserRoomVisitsComposer(habboInfo, Emulator.getGameEnvironment().getModToolManager().getUserRoomVisits(userId))); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestUserChatlogEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestUserChatlogEvent.java new file mode 100644 index 0000000..ad55465 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestUserChatlogEvent.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.ModToolUserChatlogComposer; + +public class ModToolRequestUserChatlogEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + int userId = this.packet.readInt(); + String username = HabboManager.getOfflineHabboInfo(userId).getUsername(); + + this.client.sendResponse(new ModToolUserChatlogComposer(Emulator.getGameEnvironment().getModToolManager().getUserRoomVisitsAndChatlogs(userId), userId, username)); + } else { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.chatlog").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestUserInfoEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestUserInfoEvent.java new file mode 100644 index 0000000..25f6840 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRequestUserInfoEvent.java @@ -0,0 +1,18 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolManager; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class ModToolRequestUserInfoEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + ModToolManager.requestUserInfo(this.client, this.packet); + } else { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.userinfo").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRoomAlertEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRoomAlertEvent.java new file mode 100644 index 0000000..8631a3e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolRoomAlertEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class ModToolRoomAlertEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + int type = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + if (room != null) { + room.alert(this.packet.readString()); + } + } else { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.roomalert").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolSanctionAlertEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolSanctionAlertEvent.java new file mode 100644 index 0000000..c0f8bae --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolSanctionAlertEvent.java @@ -0,0 +1,53 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolBanType; +import com.eu.habbo.habbohotel.modtool.ModToolSanctionItem; +import com.eu.habbo.habbohotel.modtool.ModToolSanctions; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.ModToolIssueHandledComposer; +import gnu.trove.map.hash.THashMap; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +public class ModToolSanctionAlertEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int userId = this.packet.readInt(); + String message = this.packet.readString(); + int cfhTopic = this.packet.readInt(); + + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + + if (habbo != null) { + ModToolSanctions modToolSanctions = Emulator.getGameEnvironment().getModToolSanctions(); + + if (Emulator.getConfig().getBoolean("hotel.sanctions.enabled")) { + THashMap> modToolSanctionItemsHashMap = Emulator.getGameEnvironment().getModToolSanctions().getSanctions(habbo.getHabboInfo().getId()); + ArrayList modToolSanctionItems = modToolSanctionItemsHashMap.get(habbo.getHabboInfo().getId()); + + if (modToolSanctionItems != null && !modToolSanctionItems.isEmpty()) { + ModToolSanctionItem item = modToolSanctionItems.get(modToolSanctionItems.size() - 1); + + if (item != null && item.probationTimestamp > 0 && item.probationTimestamp >= Emulator.getIntUnixTimestamp()) { + modToolSanctions.run(userId, this.client.getHabbo(), item.sanctionLevel, cfhTopic, message, 0, false, 0); + } else { + modToolSanctions.run(userId, this.client.getHabbo(), item.sanctionLevel, cfhTopic, message, 0, false, 0); + } + } else { + modToolSanctions.run(userId, this.client.getHabbo(), 0, cfhTopic, message, 0, false, 0); + } + } else { + habbo.alert(message); + } + } else { + this.client.sendResponse(new ModToolIssueHandledComposer(Emulator.getTexts().getValue("generic.user.not_found").replace("%user%", Emulator.getConfig().getValue("hotel.player.name")))); + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolSanctionBanEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolSanctionBanEvent.java new file mode 100644 index 0000000..c303503 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolSanctionBanEvent.java @@ -0,0 +1,77 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolBanType; +import com.eu.habbo.habbohotel.modtool.ModToolSanctionItem; +import com.eu.habbo.habbohotel.modtool.ModToolSanctions; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.messages.incoming.MessageHandler; +import gnu.trove.map.hash.THashMap; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +public class ModToolSanctionBanEvent extends MessageHandler { + public static final int BAN_18_HOURS = 3; + public static final int BAN_7_DAYS = 4; + public static final int BAN_30_DAYS_STEP_1 = 5; + public static final int BAN_30_DAYS_STEP_2 = 7; + public static final int BAN_100_YEARS = 6; + public static final int BAN_AVATAR_ONLY_100_YEARS = 106; + + public final int DAY_IN_SECONDS = 24 * 60 * 60; + + @Override + public void handle() throws Exception { + int userId = this.packet.readInt(); + String message = this.packet.readString(); + int cfhTopic = this.packet.readInt(); + int banType = this.packet.readInt(); + boolean unknown = this.packet.readBoolean(); + + int duration = 0; + + switch (banType) { + case BAN_18_HOURS: + duration = 18 * 60 * 60; + break; + case BAN_7_DAYS: + duration = 7 * this.DAY_IN_SECONDS; + break; + case BAN_30_DAYS_STEP_1: + case BAN_30_DAYS_STEP_2: + duration = 30 * this.DAY_IN_SECONDS; + break; + case BAN_100_YEARS: + case BAN_AVATAR_ONLY_100_YEARS: + duration = Emulator.getIntUnixTimestamp(); + } + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + ModToolSanctions modToolSanctions = Emulator.getGameEnvironment().getModToolSanctions(); + + if (Emulator.getConfig().getBoolean("hotel.sanctions.enabled")) { + THashMap> modToolSanctionItemsHashMap = Emulator.getGameEnvironment().getModToolSanctions().getSanctions(userId); + ArrayList modToolSanctionItems = modToolSanctionItemsHashMap.get(userId); + + if (modToolSanctionItems != null && !modToolSanctionItemsHashMap.isEmpty()) { + ModToolSanctionItem item = modToolSanctionItems.get(modToolSanctionItems.size() - 1); + + if (item.probationTimestamp > 0 && item.probationTimestamp >= Emulator.getIntUnixTimestamp()) { + modToolSanctions.run(userId, this.client.getHabbo(), item.sanctionLevel, cfhTopic, message, 0, false, 0); + } else { + modToolSanctions.run(userId, this.client.getHabbo(), item.sanctionLevel, cfhTopic, message, 0, false, 0); + } + } else { + modToolSanctions.run(userId, this.client.getHabbo(), 0, cfhTopic, message, 0, false, 0); + } + } else { + Emulator.getGameEnvironment().getModToolManager().ban(userId, this.client.getHabbo(), message, duration, ModToolBanType.ACCOUNT, cfhTopic); + } + + } else { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.modtools.ban").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername())); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolSanctionMuteEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolSanctionMuteEvent.java new file mode 100644 index 0000000..c99eee6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolSanctionMuteEvent.java @@ -0,0 +1,65 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolBanType; +import com.eu.habbo.habbohotel.modtool.ModToolSanctionItem; +import com.eu.habbo.habbohotel.modtool.ModToolSanctionLevelItem; +import com.eu.habbo.habbohotel.modtool.ModToolSanctions; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.ModToolIssueHandledComposer; +import gnu.trove.map.hash.THashMap; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; + +public class ModToolSanctionMuteEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int userId = this.packet.readInt(); + String message = this.packet.readString(); + int cfhTopic = this.packet.readInt(); + + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + + if (habbo != null) { + ModToolSanctions modToolSanctions = Emulator.getGameEnvironment().getModToolSanctions(); + + if (Emulator.getConfig().getBoolean("hotel.sanctions.enabled")) { + THashMap> modToolSanctionItemsHashMap = Emulator.getGameEnvironment().getModToolSanctions().getSanctions(habbo.getHabboInfo().getId()); + ArrayList modToolSanctionItems = modToolSanctionItemsHashMap.get(habbo.getHabboInfo().getId()); + + if (modToolSanctionItems != null && !modToolSanctionItemsHashMap.isEmpty()) { + ModToolSanctionItem item = modToolSanctionItems.get(modToolSanctionItems.size() - 1); + + if (item.probationTimestamp > 0 && item.probationTimestamp >= Emulator.getIntUnixTimestamp()) { + ModToolSanctionLevelItem modToolSanctionLevelItem = modToolSanctions.getSanctionLevelItem(item.sanctionLevel); + + int muteDurationTimestamp = Math.toIntExact(new Date( System.currentTimeMillis() + (modToolSanctionLevelItem.sanctionHourLength * 60 * 60)).getTime() / 1000); + + modToolSanctions.run(userId, this.client.getHabbo(), item.sanctionLevel, cfhTopic, message, 0, true, muteDurationTimestamp); + } else { + ModToolSanctionLevelItem modToolSanctionLevelItem = modToolSanctions.getSanctionLevelItem(item.sanctionLevel); + + int muteDurationTimestamp = Math.toIntExact(new Date( System.currentTimeMillis() + (modToolSanctionLevelItem.sanctionHourLength * 60 * 60)).getTime() / 1000); + + modToolSanctions.run(userId, this.client.getHabbo(), item.sanctionLevel, cfhTopic, message, 0, true, muteDurationTimestamp); + } + } else { + modToolSanctions.run(userId, this.client.getHabbo(), 0, cfhTopic, message, 0, false, 0); + } + } else { + habbo.mute(60 * 60, false); + habbo.alert(message); + this.client.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_mute.muted").replace("%user%", habbo.getHabboInfo().getUsername())); + } + } else { + this.client.sendResponse(new ModToolIssueHandledComposer(Emulator.getTexts().getValue("generic.user.not_found").replace("%user%", Emulator.getConfig().getValue("hotel.player.name")))); + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolSanctionTradeLockEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolSanctionTradeLockEvent.java new file mode 100644 index 0000000..48e14a3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolSanctionTradeLockEvent.java @@ -0,0 +1,54 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolSanctionItem; +import com.eu.habbo.habbohotel.modtool.ModToolSanctions; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.ModToolIssueHandledComposer; +import gnu.trove.map.hash.THashMap; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +public class ModToolSanctionTradeLockEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int userId = this.packet.readInt(); + String message = this.packet.readString(); + int duration = this.packet.readInt(); + int cfhTopic = this.packet.readInt(); + + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + + if (habbo != null) { + ModToolSanctions modToolSanctions = Emulator.getGameEnvironment().getModToolSanctions(); + + if (Emulator.getConfig().getBoolean("hotel.sanctions.enabled")) { + THashMap> modToolSanctionItemsHashMap = Emulator.getGameEnvironment().getModToolSanctions().getSanctions(userId); + ArrayList modToolSanctionItems = modToolSanctionItemsHashMap.get(userId); + + if (modToolSanctionItems != null && !modToolSanctionItems.isEmpty()) { + ModToolSanctionItem item = modToolSanctionItems.get(modToolSanctionItems.size() - 1); + + if (item.probationTimestamp > 0 && item.probationTimestamp >= Emulator.getIntUnixTimestamp()) { + modToolSanctions.run(userId, this.client.getHabbo(), item.sanctionLevel, cfhTopic, message, duration, false, 0); + } else { + modToolSanctions.run(userId, this.client.getHabbo(), item.sanctionLevel, cfhTopic, message, duration, false, 0); + } + } else { + modToolSanctions.run(userId, this.client.getHabbo(), 0, cfhTopic, message, duration, false, 0); + } + } else { + habbo.getHabboStats().setAllowTrade(false); + habbo.alert(message); + } + } else { + this.client.sendResponse(new ModToolIssueHandledComposer(Emulator.getTexts().getValue("generic.user.not_found").replace("%user%", Emulator.getConfig().getValue("hotel.player.name")))); + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolWarnEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolWarnEvent.java new file mode 100644 index 0000000..e5f0b10 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ModToolWarnEvent.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.support.SupportUserAlertedReason; + +public class ModToolWarnEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) { + Habbo alertedUser = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.packet.readInt()); + + if (alertedUser != null) + Emulator.getGameEnvironment().getModToolManager().alert(this.client.getHabbo(), alertedUser, this.packet.readString(), SupportUserAlertedReason.CAUTION); + } else { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.modtools.kick").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportBullyEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportBullyEvent.java new file mode 100644 index 0000000..f2207f2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportBullyEvent.java @@ -0,0 +1,55 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuardianTicket; +import com.eu.habbo.habbohotel.modtool.ModToolChatLog; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.BullyReportedMessageComposer; +import com.eu.habbo.messages.outgoing.modtool.HelperRequestDisabledComposer; + +import java.util.ArrayList; + +public class ReportBullyEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboStats().allowTalk()) { + this.client.sendResponse(new HelperRequestDisabledComposer()); + return; + } + + int userId = this.packet.readInt(); + int roomId = this.packet.readInt(); + + if (userId == this.client.getHabbo().getHabboInfo().getId()) { + return; + } + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId); + + if (room != null) { + Habbo habbo = room.getHabbo(userId); + + if (habbo != null) { + GuardianTicket ticket = Emulator.getGameEnvironment().getGuideManager().getOpenReportedHabboTicket(habbo); + + if (ticket != null) { + this.client.sendResponse(new BullyReportedMessageComposer(BullyReportedMessageComposer.ALREADY_REPORTED)); + return; + } + + ArrayList chatLog = Emulator.getGameEnvironment().getModToolManager().getRoomChatlog(roomId); + + if (chatLog.isEmpty()) { + this.client.sendResponse(new BullyReportedMessageComposer(BullyReportedMessageComposer.NO_CHAT)); + return; + } + + Emulator.getGameEnvironment().getGuideManager().addGuardianTicket(new GuardianTicket(this.client.getHabbo(), habbo, chatLog)); + + this.client.sendResponse(new BullyReportedMessageComposer(BullyReportedMessageComposer.RECEIVED)); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportCommentEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportCommentEvent.java new file mode 100644 index 0000000..b21849b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportCommentEvent.java @@ -0,0 +1,43 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.forums.ForumThread; +import com.eu.habbo.habbohotel.modtool.CfhTopic; +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.habbohotel.modtool.ModToolTicketType; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.ModToolReportReceivedAlertComposer; +import com.eu.habbo.threading.runnables.InsertModToolIssue; + +public class ReportCommentEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int groupId = this.packet.readInt(); + int threadId = this.packet.readInt(); + int commentId = this.packet.readInt(); + int topicId = this.packet.readInt(); + String message = this.packet.readString(); + + CfhTopic topic = Emulator.getGameEnvironment().getModToolManager().getCfhTopic(topicId); + + if (topic == null) return; + + ForumThread thread = ForumThread.getById(threadId); + + if (thread == null) return; + + Habbo opener = Emulator.getGameEnvironment().getHabboManager().getHabbo(thread.getOpenerId()); + + ModToolIssue issue = new ModToolIssue(this.client.getHabbo().getHabboInfo().getId(), this.client.getHabbo().getHabboInfo().getUsername(), thread.getOpenerId(), opener == null ? "" : opener.getHabboInfo().getUsername(), 0, message, ModToolTicketType.DISCUSSION); + issue.category = topicId; + issue.groupId = groupId; + issue.threadId = threadId; + issue.commentId = commentId; + new InsertModToolIssue(issue).run(); + + this.client.sendResponse(new ModToolReportReceivedAlertComposer(ModToolReportReceivedAlertComposer.REPORT_RECEIVED, message)); + Emulator.getGameEnvironment().getModToolManager().addTicket(issue); + Emulator.getGameEnvironment().getModToolManager().updateTicketToMods(issue); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportEvent.java new file mode 100644 index 0000000..22a81fc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportEvent.java @@ -0,0 +1,120 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuardianTicket; +import com.eu.habbo.habbohotel.modtool.*; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.*; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserIgnoredComposer; +import com.eu.habbo.threading.runnables.InsertModToolIssue; + +import java.util.ArrayList; +import java.util.List; + +public class ReportEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (!this.client.getHabbo().getHabboStats().allowTalk()) { + this.client.sendResponse(new HelperRequestDisabledComposer()); + return; + } + + String message = this.packet.readString(); + int topic = this.packet.readInt(); + int userId = this.packet.readInt(); + int roomId = this.packet.readInt(); + int messageCount = this.packet.readInt(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId); + List issues = Emulator.getGameEnvironment().getModToolManager().openTicketsForHabbo(this.client.getHabbo()); + if (!issues.isEmpty()) { + //this.client.sendResponse(new GenericAlertComposer("You've got still a pending ticket. Wait till the moderators are done reviewing your ticket.")); + this.client.sendResponse(new ReportRoomFormComposer(issues)); + return; + } + + CfhTopic cfhTopic = Emulator.getGameEnvironment().getModToolManager().getCfhTopic(topic); + + if (userId != -1) { + Habbo reported = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + + if (reported != null) { + if (cfhTopic != null && cfhTopic.action == CfhActionType.GUARDIANS && Emulator.getGameEnvironment().getGuideManager().activeGuardians()) { + GuardianTicket ticket = Emulator.getGameEnvironment().getGuideManager().getOpenReportedHabboTicket(reported); + + if (ticket != null) { + this.client.sendResponse(new BullyReportedMessageComposer(BullyReportedMessageComposer.ALREADY_REPORTED)); + return; + } + + ArrayList chatLog = Emulator.getGameEnvironment().getModToolManager().getRoomChatlog(roomId); + + if (chatLog.isEmpty()) { + this.client.sendResponse(new BullyReportedMessageComposer(BullyReportedMessageComposer.NO_CHAT)); + return; + } + + Emulator.getGameEnvironment().getGuideManager().addGuardianTicket(new GuardianTicket(this.client.getHabbo(), reported, chatLog)); + + this.client.sendResponse(new BullyReportedMessageComposer(BullyReportedMessageComposer.RECEIVED)); + } else { + ModToolIssue issue = new ModToolIssue(this.client.getHabbo().getHabboInfo().getId(), this.client.getHabbo().getHabboInfo().getUsername(), reported.getHabboInfo().getId(), reported.getHabboInfo().getUsername(), roomId, message, ModToolTicketType.NORMAL); + issue.category = topic; + new InsertModToolIssue(issue).run(); + + Emulator.getGameEnvironment().getModToolManager().addTicket(issue); + Emulator.getGameEnvironment().getModToolManager().updateTicketToMods(issue); + this.client.sendResponse(new ModToolReportReceivedAlertComposer(ModToolReportReceivedAlertComposer.REPORT_RECEIVED, cfhTopic.reply)); + + if (cfhTopic != null) { + if (cfhTopic.action != CfhActionType.MODS) { + Emulator.getThreading().run(() -> { + if (issue.state == ModToolTicketState.OPEN) { + if (cfhTopic.action == CfhActionType.AUTO_IGNORE) { + if (ReportEvent.this.client.getHabbo().getHabboStats().ignoreUser(ReportEvent.this.client, reported.getHabboInfo().getId())) { + ReportEvent.this.client.sendResponse(new RoomUserIgnoredComposer(reported, RoomUserIgnoredComposer.IGNORED)); + } + } + + ReportEvent.this.client.sendResponse(new ModToolIssueHandledComposer(cfhTopic.reply).compose()); + Emulator.getGameEnvironment().getModToolManager().closeTicketAsHandled(issue, null); + } + }, 30 * 1000); + } + } + } + } + } else { + ModToolIssue issue = new ModToolIssue(this.client.getHabbo().getHabboInfo().getId(), this.client.getHabbo().getHabboInfo().getUsername(), room != null ? room.getOwnerId() : 0, room != null ? room.getOwnerName() : "", roomId, message, ModToolTicketType.ROOM); + issue.category = topic; + new InsertModToolIssue(issue).run(); + + this.client.sendResponse(new ModToolReportReceivedAlertComposer(ModToolReportReceivedAlertComposer.REPORT_RECEIVED, message)); + Emulator.getGameEnvironment().getModToolManager().addTicket(issue); + Emulator.getGameEnvironment().getModToolManager().updateTicketToMods(issue); + + if (cfhTopic != null) { + if (cfhTopic.action != CfhActionType.MODS) { + Emulator.getThreading().run(() -> { + if (issue.state == ModToolTicketState.OPEN) { + if (cfhTopic.action == CfhActionType.AUTO_IGNORE) { + if (ReportEvent.this.client.getHabbo().getHabboStats().ignoreUser(ReportEvent.this.client, issue.reportedId)) { + Habbo reported = Emulator.getGameEnvironment().getHabboManager().getHabbo(issue.reportedId); + if (reported != null) { + ReportEvent.this.client.sendResponse(new RoomUserIgnoredComposer(reported, RoomUserIgnoredComposer.IGNORED)); + } + } + } + + ReportEvent.this.client.sendResponse(new ModToolIssueHandledComposer(cfhTopic.reply).compose()); + Emulator.getGameEnvironment().getModToolManager().closeTicketAsHandled(issue, null); + } + }, 30 * 1000); + } + } + + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportFriendPrivateChatEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportFriendPrivateChatEvent.java new file mode 100644 index 0000000..81d83c8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportFriendPrivateChatEvent.java @@ -0,0 +1,54 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolChatLog; +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.habbohotel.modtool.ModToolTicketType; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.HelperRequestDisabledComposer; +import com.eu.habbo.threading.runnables.InsertModToolIssue; + +import java.util.ArrayList; + +public class ReportFriendPrivateChatEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (!this.client.getHabbo().getHabboStats().allowTalk()) { + this.client.sendResponse(new HelperRequestDisabledComposer()); + return; + } + + String message = this.packet.readString(); + int category = this.packet.readInt(); + int userId = this.packet.readInt(); + int count = this.packet.readInt(); + ArrayList chatLogs = new ArrayList<>(); + + HabboInfo info; + Habbo target = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + if (target != null) { + info = target.getHabboInfo(); + } else { + info = HabboManager.getOfflineHabboInfo(userId); + } + + if (info != null) { + for (int i = 0; i < count; i++) { + int chatUserId = this.packet.readInt(); + String username = this.packet.readInt() == info.getId() ? info.getUsername() : this.client.getHabbo().getHabboInfo().getUsername(); + + chatLogs.add(new ModToolChatLog(0, chatUserId, username, this.packet.readString())); + } + } + + ModToolIssue issue = new ModToolIssue(this.client.getHabbo().getHabboInfo().getId(), this.client.getHabbo().getHabboInfo().getUsername(), userId, info.getUsername(), 0, message, ModToolTicketType.IM); + issue.category = category; + issue.chatLogs = chatLogs; + new InsertModToolIssue(issue).run(); + Emulator.getGameEnvironment().getModToolManager().addTicket(issue); + Emulator.getGameEnvironment().getModToolManager().updateTicketToMods(issue); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportPhotoEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportPhotoEvent.java new file mode 100644 index 0000000..c929941 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportPhotoEvent.java @@ -0,0 +1,57 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionExternalImage; +import com.eu.habbo.habbohotel.modtool.CfhTopic; +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.habbohotel.modtool.ModToolTicketType; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.ModToolReportReceivedAlertComposer; +import com.eu.habbo.threading.runnables.InsertModToolIssue; +import com.google.gson.JsonParser; + +public class ReportPhotoEvent extends MessageHandler { + @Override + public void handle() throws Exception { + boolean hasExtradataId = this.packet.readShort() != 0; + + this.packet.getBuffer().resetReaderIndex(); + + if (hasExtradataId) { + String extradataId = this.packet.readString(); + } + + int roomId = this.packet.readInt(); + int reportedUserId = this.packet.readInt(); + int topicId = this.packet.readInt(); + int itemId = this.packet.readInt(); + + CfhTopic topic = Emulator.getGameEnvironment().getModToolManager().getCfhTopic(topicId); + + if (topic == null) return; + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId); + + if (room == null) return; + + HabboItem item = room.getHabboItem(itemId); + + if (item == null || !(item instanceof InteractionExternalImage)) return; + + HabboInfo photoOwner = Emulator.getGameEnvironment().getHabboManager().getHabboInfo(item.getUserId()); + + if (photoOwner == null) return; + + ModToolIssue issue = new ModToolIssue(this.client.getHabbo().getHabboInfo().getId(), this.client.getHabbo().getHabboInfo().getUsername(), photoOwner.getId(), photoOwner.getUsername(), roomId, "", ModToolTicketType.PHOTO); + issue.photoItem = item; + + new InsertModToolIssue(issue).run(); + + this.client.sendResponse(new ModToolReportReceivedAlertComposer(ModToolReportReceivedAlertComposer.REPORT_RECEIVED, "")); + Emulator.getGameEnvironment().getModToolManager().addTicket(issue); + Emulator.getGameEnvironment().getModToolManager().updateTicketToMods(issue); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportThreadEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportThreadEvent.java new file mode 100644 index 0000000..50bcab8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/ReportThreadEvent.java @@ -0,0 +1,41 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.forums.ForumThread; +import com.eu.habbo.habbohotel.modtool.CfhTopic; +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.habbohotel.modtool.ModToolTicketType; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.ModToolReportReceivedAlertComposer; +import com.eu.habbo.threading.runnables.InsertModToolIssue; + +public class ReportThreadEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int groupId = this.packet.readInt(); + int threadId = this.packet.readInt(); + int topicId = this.packet.readInt(); + String message = this.packet.readString(); + + CfhTopic topic = Emulator.getGameEnvironment().getModToolManager().getCfhTopic(topicId); + + if (topic == null) return; + + ForumThread thread = ForumThread.getById(threadId); + + if (thread == null) return; + + Habbo opener = Emulator.getGameEnvironment().getHabboManager().getHabbo(thread.getOpenerId()); + + ModToolIssue issue = new ModToolIssue(this.client.getHabbo().getHabboInfo().getId(), this.client.getHabbo().getHabboInfo().getUsername(), thread.getOpenerId(), opener == null ? "" : opener.getHabboInfo().getUsername(), 0, message, ModToolTicketType.DISCUSSION); + issue.category = topicId; + issue.groupId = groupId; + issue.threadId = threadId; + new InsertModToolIssue(issue).run(); + + this.client.sendResponse(new ModToolReportReceivedAlertComposer(ModToolReportReceivedAlertComposer.REPORT_RECEIVED, message)); + Emulator.getGameEnvironment().getModToolManager().addTicket(issue); + Emulator.getGameEnvironment().getModToolManager().updateTicketToMods(issue); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/RequestReportRoomEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/RequestReportRoomEvent.java new file mode 100644 index 0000000..0dc7800 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/RequestReportRoomEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.ReportRoomFormComposer; + +public class RequestReportRoomEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new ReportRoomFormComposer(Emulator.getGameEnvironment().getModToolManager().openTicketsForHabbo(this.client.getHabbo()))); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/RequestReportUserBullyingEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/RequestReportUserBullyingEvent.java new file mode 100644 index 0000000..e8c8875 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/RequestReportUserBullyingEvent.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuardianTicket; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.modtool.BullyReportRequestComposer; + +import java.util.Calendar; + +public class RequestReportUserBullyingEvent extends MessageHandler { + @Override + public void handle() throws Exception { + GuardianTicket ticket = Emulator.getGameEnvironment().getGuideManager().getRecentTicket(this.client.getHabbo()); + + if (ticket != null) { + if (ticket.inProgress()) { + this.client.sendResponse(new BullyReportRequestComposer(BullyReportRequestComposer.ONGOING_HELPER_CASE, 1)); + return; + } + + if ((Calendar.getInstance().getTime().getTime() / 1000) - ticket.getDate().getTime() < Emulator.getConfig().getInt("guardians.reporting.cooldown")) { + this.client.sendResponse(new BullyReportRequestComposer(BullyReportRequestComposer.TOO_RECENT, 1)); + return; + } + } + + this.client.sendResponse(new BullyReportRequestComposer(BullyReportRequestComposer.START_REPORT, 0)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/StartSafetyQuizEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/StartSafetyQuizEvent.java new file mode 100644 index 0000000..572dfdc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/modtool/StartSafetyQuizEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.incoming.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class StartSafetyQuizEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String quizName = this.packet.readString(); + + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SafetyQuizGraduate")); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/AddSavedSearchEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/AddSavedSearchEvent.java new file mode 100644 index 0000000..78be576 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/AddSavedSearchEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.habbohotel.navigation.NavigatorSavedSearch; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.NewNavigatorSavedSearchesComposer; + +public class AddSavedSearchEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String searchCode = this.packet.readString(); + String filter = this.packet.readString(); + + if (searchCode.length() > 255) searchCode = searchCode.substring(0, 255); + if (filter.length() > 255) filter = filter.substring(0, 255); + + this.client.getHabbo().getHabboInfo().addSavedSearch(new NavigatorSavedSearch(searchCode, filter)); + + this.client.sendResponse(new NewNavigatorSavedSearchesComposer(this.client.getHabbo().getHabboInfo().getSavedSearches())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/DeleteSavedSearchEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/DeleteSavedSearchEvent.java new file mode 100644 index 0000000..8429ffe --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/DeleteSavedSearchEvent.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.habbohotel.navigation.NavigatorSavedSearch; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.NewNavigatorSavedSearchesComposer; + +public class DeleteSavedSearchEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int searchId = this.packet.readInt(); + + NavigatorSavedSearch search = null; + for (NavigatorSavedSearch savedSearch : this.client.getHabbo().getHabboInfo().getSavedSearches()) { + if (savedSearch.getId() == searchId) { + search = savedSearch; + break; + } + } + + if (search == null) return; + + this.client.getHabbo().getHabboInfo().deleteSavedSearch(search); + + this.client.sendResponse(new NewNavigatorSavedSearchesComposer(this.client.getHabbo().getHabboInfo().getSavedSearches())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/NavigatorCategoryListModeEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/NavigatorCategoryListModeEvent.java new file mode 100644 index 0000000..3b3e6c4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/NavigatorCategoryListModeEvent.java @@ -0,0 +1,18 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.navigation.ListMode; +import com.eu.habbo.habbohotel.rooms.RoomCategory; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class NavigatorCategoryListModeEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String category = this.packet.readString(); + int viewMode = this.packet.readInt(); + + RoomCategory roomCategory = Emulator.getGameEnvironment().getRoomManager().getCategory(category); + this.client.getHabbo().getHabboStats().navigatorWindowSettings.setListMode( + roomCategory != null ? roomCategory.getCaptionSave() : category, viewMode == 1 ? ListMode.THUMBNAILS : ListMode.LIST); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/NavigatorCollapseCategoryEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/NavigatorCollapseCategoryEvent.java new file mode 100644 index 0000000..549c278 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/NavigatorCollapseCategoryEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.habbohotel.navigation.DisplayMode; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class NavigatorCollapseCategoryEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String category = this.packet.readString(); + this.client.getHabbo().getHabboStats().navigatorWindowSettings.setDisplayMode(category, DisplayMode.COLLAPSED); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/NavigatorUncollapseCategoryEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/NavigatorUncollapseCategoryEvent.java new file mode 100644 index 0000000..2a2eb7c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/NavigatorUncollapseCategoryEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.habbohotel.navigation.DisplayMode; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class NavigatorUncollapseCategoryEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String category = this.packet.readString(); + this.client.getHabbo().getHabboStats().navigatorWindowSettings.setDisplayMode(category, DisplayMode.VISIBLE); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/NewNavigatorActionEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/NewNavigatorActionEvent.java new file mode 100644 index 0000000..4febfc1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/NewNavigatorActionEvent.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.ForwardToRoomComposer; +import com.eu.habbo.messages.outgoing.users.UserHomeRoomComposer; + +import java.util.ArrayList; +import java.util.Collections; + +public class NewNavigatorActionEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String data = this.packet.readString(); + + if (data.equals("random_friending_room")) { + ArrayList rooms = Emulator.getGameEnvironment().getRoomManager().getActiveRooms(); + if (!rooms.isEmpty()) { + Collections.shuffle(rooms); + this.client.sendResponse(new ForwardToRoomComposer(rooms.get(0).getId())); + } + } else if (data.equalsIgnoreCase("predefined_noob_lobby")) { + this.client.sendResponse(new ForwardToRoomComposer(Emulator.getConfig().getInt("hotel.room.nooblobby"))); + } else { + this.client.sendResponse(new UserHomeRoomComposer(this.client.getHabbo().getHabboInfo().getHomeRoom(), this.client.getHabbo().getHabboInfo().getHomeRoom())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestCanCreateRoomEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestCanCreateRoomEvent.java new file mode 100644 index 0000000..b2b9371 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestCanCreateRoomEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.RoomManager; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.CanCreateRoomComposer; + +public class RequestCanCreateRoomEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int count = Emulator.getGameEnvironment().getRoomManager().getRoomsForHabbo(this.client.getHabbo()).size(); + int max = this.client.getHabbo().getHabboStats().hasActiveClub() ? RoomManager.MAXIMUM_ROOMS_HC : RoomManager.MAXIMUM_ROOMS_USER; + this.client.sendResponse(new CanCreateRoomComposer(count, max)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestCreateRoomEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestCreateRoomEvent.java new file mode 100644 index 0000000..6226ae5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestCreateRoomEvent.java @@ -0,0 +1,61 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomCategory; +import com.eu.habbo.habbohotel.rooms.RoomManager; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.CanCreateRoomComposer; +import com.eu.habbo.messages.outgoing.navigator.RoomCreatedComposer; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RequestCreateRoomEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String name = this.packet.readString(); + String description = this.packet.readString(); + String modelName = this.packet.readString(); + int categoryId = this.packet.readInt(); + int maxUsers = this.packet.readInt(); + int tradeType = this.packet.readInt(); + + if (!Emulator.getGameEnvironment().getRoomManager().layoutExists(modelName)) { + log.error("[SCRIPTER] Incorrect layout name \"" + modelName + "\". " + this.client.getHabbo().getHabboInfo().getUsername()); + return; + } + + RoomCategory category = Emulator.getGameEnvironment().getRoomManager().getCategory(categoryId); + + if (category == null || category.getMinRank() > this.client.getHabbo().getHabboInfo().getRank().getId()) { + log.error("[SCRIPTER] Incorrect rank or non existing category ID: \"" + categoryId + "\"." + this.client.getHabbo().getHabboInfo().getUsername()); + return; + } + + if (maxUsers > 250) + return; + + if (tradeType > 2) + return; + + if (name.trim().length() < 3 || name.length() > 25 || !Emulator.getGameEnvironment().getWordFilter().filter(name, this.client.getHabbo()).equals(name)) + return; + + if (description.length() > 128 || !Emulator.getGameEnvironment().getWordFilter().filter(description, this.client.getHabbo()).equals(description)) + return; + + int count = Emulator.getGameEnvironment().getRoomManager().getRoomsForHabbo(this.client.getHabbo()).size(); + int max = this.client.getHabbo().getHabboStats().hasActiveClub() ? RoomManager.MAXIMUM_ROOMS_HC : RoomManager.MAXIMUM_ROOMS_USER; + + if (count >= max) { + this.client.sendResponse(new CanCreateRoomComposer(count, max)); + return; + } + + final Room room = Emulator.getGameEnvironment().getRoomManager().createRoomForHabbo(this.client.getHabbo(), name, description, modelName, maxUsers, categoryId, tradeType); + + if (room != null) { + this.client.sendResponse(new RoomCreatedComposer(room)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestDeleteRoomEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestDeleteRoomEvent.java new file mode 100644 index 0000000..0e973dd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestDeleteRoomEvent.java @@ -0,0 +1,118 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.RideablePet; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.inventory.AddPetComposer; +import com.eu.habbo.plugin.events.navigator.NavigatorRoomDeletedEvent; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +public class RequestDeleteRoomEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int roomId = this.packet.readInt(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId); + + if (room != null) { + if (room.isOwner(this.client.getHabbo())) { + if (room.getId() == this.client.getHabbo().getHabboInfo().getHomeRoom()) { + return; + } + + if (Emulator.getPluginManager().fireEvent(new NavigatorRoomDeletedEvent(this.client.getHabbo(), room)).isCancelled()) { + return; + } + + room.ejectAll(); + room.ejectUserFurni(room.getOwnerId()); + + List bots = new ArrayList<>(room.getCurrentBots().valueCollection()); + for (Bot bot : bots) { + Emulator.getGameEnvironment().getBotManager().pickUpBot(bot, null); + } + + List pets = new ArrayList<>(room.getCurrentPets().valueCollection()); + for (Pet pet : pets) { + if (pet instanceof RideablePet) { + RideablePet rideablePet = (RideablePet) pet; + if (rideablePet.getRider() != null) { + rideablePet.getRider().getHabboInfo().dismountPet(true); + } + } + + pet.removeFromRoom(); + Emulator.getThreading().run(pet); + + Habbo owner = Emulator.getGameEnvironment().getHabboManager().getHabbo(pet.getUserId()); + + if (owner != null) { + owner.getClient().sendResponse(new AddPetComposer(pet)); + owner.getInventory().getPetsComponent().addPet(pet); + } + } + + if (room.getGuildId() > 0) { + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(room.getGuildId()); + + if (guild != null) { + Emulator.getGameEnvironment().getGuildManager().deleteGuild(guild); + } + } + + room.preventUnloading = false; + room.dispose(); + Emulator.getGameEnvironment().getRoomManager().uncacheRoom(room); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("DELETE FROM rooms WHERE id = ? LIMIT 1")) { + statement.setInt(1, roomId); + statement.execute(); + } + + if (room.hasCustomLayout()) { + try (PreparedStatement stmt = connection.prepareStatement("DELETE FROM room_models_custom WHERE id = ? LIMIT 1")) { + stmt.setInt(1, roomId); + stmt.execute(); + } + } + + Emulator.getGameEnvironment().getRoomManager().unloadRoom(room); + + try (PreparedStatement rights = connection.prepareStatement("DELETE FROM room_rights WHERE room_id = ?")) { + rights.setInt(1, roomId); + rights.execute(); + } + + try (PreparedStatement votes = connection.prepareStatement("DELETE FROM room_votes WHERE room_id = ?")) { + votes.setInt(1, roomId); + votes.execute(); + } + + try (PreparedStatement filter = connection.prepareStatement("DELETE FROM room_wordfilter WHERE room_id = ?")) { + filter.setInt(1, roomId); + filter.execute(); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } else { + String message = Emulator.getTexts().getValue("scripter.warning.room.delete").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()).replace("%roomname%", room.getName()).replace("%roomowner%", room.getOwnerName()); + ScripterManager.scripterDetected(this.client, message); + log.info(message); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestHighestScoreRoomsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestHighestScoreRoomsEvent.java new file mode 100644 index 0000000..d74a8ae --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestHighestScoreRoomsEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.PrivateRoomsComposer; + +public class RequestHighestScoreRoomsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new PrivateRoomsComposer(Emulator.getGameEnvironment().getRoomManager().getRoomsByScore())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestMyRoomsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestMyRoomsEvent.java new file mode 100644 index 0000000..9347614 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestMyRoomsEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.PrivateRoomsComposer; + +public class RequestMyRoomsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new PrivateRoomsComposer(Emulator.getGameEnvironment().getRoomManager().getRoomsForHabbo(this.client.getHabbo()))); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestNavigatorSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestNavigatorSettingsEvent.java new file mode 100644 index 0000000..0369a07 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestNavigatorSettingsEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.NewNavigatorSettingsComposer; + +public class RequestNavigatorSettingsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + + + this.client.sendResponse(new NewNavigatorSettingsComposer(this.client.getHabbo().getHabboStats().navigatorWindowSettings)); + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestNewNavigatorDataEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestNewNavigatorDataEvent.java new file mode 100644 index 0000000..6bc2a21 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestNewNavigatorDataEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.*; + +public class RequestNewNavigatorDataEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new NewNavigatorSettingsComposer(this.client.getHabbo().getHabboStats().navigatorWindowSettings)); + this.client.sendResponse(new NewNavigatorMetaDataComposer()); + this.client.sendResponse(new NewNavigatorLiftedRoomsComposer()); + this.client.sendResponse(new NewNavigatorCollapsedCategoriesComposer()); + this.client.sendResponse(new NewNavigatorSavedSearchesComposer(this.client.getHabbo().getHabboInfo().getSavedSearches())); + this.client.sendResponse(new NewNavigatorEventCategoriesComposer()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestNewNavigatorRoomsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestNewNavigatorRoomsEvent.java new file mode 100644 index 0000000..4f41cd6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestNewNavigatorRoomsEvent.java @@ -0,0 +1,170 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.navigation.*; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomCategory; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.NewNavigatorSearchResultsComposer; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; +import java.util.*; + +@Slf4j +public class RequestNewNavigatorRoomsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String view = this.packet.readString(); + String query = this.packet.readString(); + + if (view.equals("query")) view = "hotel_view"; + if (view.equals("groups")) view = "hotel_view"; + + NavigatorFilter filter = Emulator.getGameEnvironment().getNavigatorManager().filters.get(view); + RoomCategory category = Emulator.getGameEnvironment().getRoomManager().getCategoryBySafeCaption(view); + + if (filter == null) { + List rooms = Emulator.getGameEnvironment().getNavigatorManager().getRoomsForCategory(view, this.client.getHabbo()); + + if (rooms != null) { + List resultLists = new ArrayList<>(); + resultLists.add(new SearchResultList(0, view, query, SearchAction.NONE, this.client.getHabbo().getHabboStats().navigatorWindowSettings.getListModeForCategory(view, ListMode.LIST), this.client.getHabbo().getHabboStats().navigatorWindowSettings.getDisplayModeForCategory(view, DisplayMode.VISIBLE), rooms, true, true, DisplayOrder.ACTIVITY, -1)); + this.client.sendResponse(new NewNavigatorSearchResultsComposer(view, query, resultLists)); + return; + } + } + + String filterField = "anything"; + String part = query; + NavigatorFilterField field = Emulator.getGameEnvironment().getNavigatorManager().filterSettings.get(filterField); + if (filter != null) { + if (query.contains(":")) { + String[] parts = query.split(":"); + + if (parts.length > 1) { + filterField = parts[0]; + part = parts[1]; + } else { + filterField = parts[0].replace(":", ""); + if (!Emulator.getGameEnvironment().getNavigatorManager().filterSettings.containsKey(filterField)) { + filterField = "anything"; + } + } + } + + if (Emulator.getGameEnvironment().getNavigatorManager().filterSettings.get(filterField) != null) { + field = Emulator.getGameEnvironment().getNavigatorManager().filterSettings.get(filterField); + } + } + + if (field == null || query.isEmpty()) { + if (filter == null) + return; + + List resultLists = filter.getResult(this.client.getHabbo()); + Collections.sort(resultLists); + + if (!query.isEmpty()) { + resultLists = toQueryResults(resultLists); + } + + this.client.sendResponse(new NewNavigatorSearchResultsComposer(view, query, resultLists)); + return; + } + + if (filter == null) { + filter = Emulator.getGameEnvironment().getNavigatorManager().filters.get("hotel_view"); + } + + if (category == null) { + category = Emulator.getGameEnvironment().getRoomManager().getCategoryBySafeCaption("hotel_view"); + } + + if (filter == null) + return; + + try { + List resultLists2 = (ArrayList)((ArrayList)filter.getResult(this.client.getHabbo(), field, part, category != null ? category.getId() : -1)).clone(); + List resultLists = new ArrayList<>(); + for(SearchResultList searchResultList : resultLists2) { + List rooms = new ArrayList<>(); + rooms.addAll(searchResultList.rooms); + resultLists.add(new SearchResultList(searchResultList.order, searchResultList.code, searchResultList.query, searchResultList.action, searchResultList.mode, searchResultList.hidden, rooms, searchResultList.filter, searchResultList.showInvisible, searchResultList.displayOrder, searchResultList.categoryOrder)); + } + filter.filter(field.field, part, resultLists); + resultLists = toQueryResults(resultLists); + this.client.sendResponse(new NewNavigatorSearchResultsComposer(view, query, resultLists)); + } catch (Exception e) { + log.error("Caught exception", e); + } + + /* + try + { + + List resultLists = new ArrayList<>(filter.getResult(this.client.getHabbo(), field, part, category != null ? category.getId() : -1)); + filter.filter(field.field, part, resultLists); + + Collections.sort(resultLists); + this.client.sendResponse(new NewNavigatorSearchResultsComposer(view, query, resultLists)); + } + catch (Exception e) + { + log.error("Caught exception", e); + } + */ + } + + private ArrayList toQueryResults(List resultLists) { + ArrayList nList = new ArrayList<>(); + THashMap searchRooms = new THashMap<>(); + + for (SearchResultList li : resultLists) { + for (Room room : li.rooms) { + searchRooms.put(room.getId(), room); + } + } + + SearchResultList list = new SearchResultList(0, "query", "", SearchAction.NONE, ListMode.LIST, DisplayMode.VISIBLE, new ArrayList(searchRooms.values()), true, this.client.getHabbo().hasPermission(Permission.ACC_ENTERANYROOM) || this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER), DisplayOrder.ACTIVITY, -1); + nList.add(list); + return nList; + } + + private void filter(List resultLists, NavigatorFilter filter, String part) { + List toRemove = new ArrayList<>(); + Map> filteredRooms = new HashMap<>(); + + for (NavigatorFilterField field : Emulator.getGameEnvironment().getNavigatorManager().filterSettings.values()) { + for (SearchResultList result : resultLists) { + if (result.filter) { + List rooms = new ArrayList<>(result.rooms.subList(0, result.rooms.size())); + filter.filterRooms(field.field, part, rooms); + + if (!filteredRooms.containsKey(result.order)) { + filteredRooms.put(result.order, new HashMap<>()); + } + + for (Room room : rooms) { + filteredRooms.get(result.order).put(room.getId(), room); + } + } + } + } + + for (Map.Entry> set : filteredRooms.entrySet()) { + for (SearchResultList resultList : resultLists) { + if (resultList.filter) { + resultList.rooms.clear(); + resultList.rooms.addAll(set.getValue().values()); + + if (resultList.rooms.isEmpty()) { + toRemove.add(resultList); + } + } + } + } + + resultLists.removeAll(toRemove); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestPopularRoomsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestPopularRoomsEvent.java new file mode 100644 index 0000000..b0e0d10 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestPopularRoomsEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.PrivateRoomsComposer; + +public class RequestPopularRoomsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new PrivateRoomsComposer(Emulator.getGameEnvironment().getRoomManager().getActiveRooms(-1))); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestPromotedRoomsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestPromotedRoomsEvent.java new file mode 100644 index 0000000..5f89e60 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestPromotedRoomsEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.PrivateRoomsComposer; + +public class RequestPromotedRoomsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new PrivateRoomsComposer(Emulator.getGameEnvironment().getRoomManager().getRoomsPromoted())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestPublicRoomsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestPublicRoomsEvent.java new file mode 100644 index 0000000..2961d89 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestPublicRoomsEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.messages.incoming.MessageHandler; + +public class RequestPublicRoomsEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestRoomCategoriesEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestRoomCategoriesEvent.java new file mode 100644 index 0000000..94b644f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestRoomCategoriesEvent.java @@ -0,0 +1,17 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.RoomCategory; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.RoomCategoriesComposer; + +import java.util.List; + +public class RequestRoomCategoriesEvent extends MessageHandler { + @Override + public void handle() throws Exception { + List roomCategoryList = Emulator.getGameEnvironment().getRoomManager().roomCategoriesForHabbo(this.client.getHabbo()); + this.client.sendResponse(new RoomCategoriesComposer(roomCategoryList)); + //this.client.sendResponse(new NewNavigatorEventCategoriesComposer()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestTagsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestTagsEvent.java new file mode 100644 index 0000000..87e538d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestTagsEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.TagsComposer; + +public class RequestTagsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new TagsComposer(Emulator.getGameEnvironment().getRoomManager().getTags())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SaveWindowSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SaveWindowSettingsEvent.java new file mode 100644 index 0000000..2910d0c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SaveWindowSettingsEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.habbohotel.users.HabboNavigatorWindowSettings; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class SaveWindowSettingsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + HabboNavigatorWindowSettings windowSettings = this.client.getHabbo().getHabboStats().navigatorWindowSettings; + + windowSettings.x = this.packet.readInt(); + windowSettings.y = this.packet.readInt(); + + windowSettings.width = this.packet.readInt(); + windowSettings.height = this.packet.readInt(); + + boolean openSearches = this.packet.readBoolean(); + windowSettings.openSearches = openSearches; + + int unknownVar = this.packet.readInt(); + int unknown = unknownVar; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsByTagEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsByTagEvent.java new file mode 100644 index 0000000..0d572ed --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsByTagEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.PrivateRoomsComposer; + +public class SearchRoomsByTagEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String tag = this.packet.readString(); + + this.client.sendResponse(new PrivateRoomsComposer(Emulator.getGameEnvironment().getRoomManager().getRoomsWithTag(tag))); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsEvent.java new file mode 100644 index 0000000..7c910c5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsEvent.java @@ -0,0 +1,67 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.permissions.Rank; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.PrivateRoomsComposer; +import com.eu.habbo.plugin.events.navigator.NavigatorSearchResultEvent; +import gnu.trove.map.hash.THashMap; + +import java.util.ArrayList; + +public class SearchRoomsEvent extends MessageHandler { + public final static THashMap> cachedResults = new THashMap<>(4); + + @Override + public void handle() throws Exception { + String name = this.packet.readString(); + + String prefix = ""; + String query = name; + ArrayList rooms; + + ServerMessage message = null; + if (cachedResults.containsKey(this.client.getHabbo().getHabboInfo().getRank())) { + message = cachedResults.get(this.client.getHabbo().getHabboInfo().getRank()).get((name + "\t" + query).toLowerCase()); + } else { + cachedResults.put(this.client.getHabbo().getHabboInfo().getRank(), new THashMap<>()); + } + + if (message == null) { + if (name.startsWith("owner:")) { + query = name.split("owner:")[1]; + prefix = "owner:"; + rooms = (ArrayList) Emulator.getGameEnvironment().getRoomManager().getRoomsForHabbo(name); + } else if (name.startsWith("tag:")) { + query = name.split("tag:")[1]; + prefix = "tag:"; + rooms = Emulator.getGameEnvironment().getRoomManager().getRoomsWithTag(name); + } else if (name.startsWith("group:")) { + query = name.split("group:")[1]; + prefix = "group:"; + rooms = Emulator.getGameEnvironment().getRoomManager().getGroupRoomsWithName(name); + } else { + rooms = Emulator.getGameEnvironment().getRoomManager().getRoomsWithName(name); + } + + message = new PrivateRoomsComposer(rooms).compose(); + THashMap map = cachedResults.get(this.client.getHabbo().getHabboInfo().getRank()); + + if (map == null) { + map = new THashMap<>(1); + } + + map.put((name + "\t" + query).toLowerCase(), message); + cachedResults.put(this.client.getHabbo().getHabboInfo().getRank(), map); + + NavigatorSearchResultEvent event = new NavigatorSearchResultEvent(this.client.getHabbo(), prefix, query, rooms); + if (Emulator.getPluginManager().fireEvent(event).isCancelled()) { + return; + } + } + + this.client.sendResponse(message); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsFriendsNowEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsFriendsNowEvent.java new file mode 100644 index 0000000..ec7e1cf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsFriendsNowEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.PrivateRoomsComposer; + +public class SearchRoomsFriendsNowEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new PrivateRoomsComposer(Emulator.getGameEnvironment().getRoomManager().getRoomsFriendsNow(this.client.getHabbo()))); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsFriendsOwnEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsFriendsOwnEvent.java new file mode 100644 index 0000000..786434b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsFriendsOwnEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.PrivateRoomsComposer; + +public class SearchRoomsFriendsOwnEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new PrivateRoomsComposer(Emulator.getGameEnvironment().getRoomManager().getRoomsFriendsOwn(this.client.getHabbo()))); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsInGroupEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsInGroupEvent.java new file mode 100644 index 0000000..6e3d1d9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsInGroupEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.PrivateRoomsComposer; + +public class SearchRoomsInGroupEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new PrivateRoomsComposer(Emulator.getGameEnvironment().getRoomManager().getRoomsInGroup(this.client.getHabbo()))); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsMyFavouriteEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsMyFavouriteEvent.java new file mode 100644 index 0000000..452a55f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsMyFavouriteEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.PrivateRoomsComposer; + +public class SearchRoomsMyFavouriteEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new PrivateRoomsComposer(Emulator.getGameEnvironment().getRoomManager().getRoomsFavourite(this.client.getHabbo()))); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsVisitedEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsVisitedEvent.java new file mode 100644 index 0000000..41cb356 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsVisitedEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.PrivateRoomsComposer; + +public class SearchRoomsVisitedEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new PrivateRoomsComposer(Emulator.getGameEnvironment().getRoomManager().getRoomsVisited(this.client.getHabbo(), false, 25))); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsWithRightsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsWithRightsEvent.java new file mode 100644 index 0000000..c123d10 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/navigator/SearchRoomsWithRightsEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.navigator; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.navigator.PrivateRoomsComposer; + +public class SearchRoomsWithRightsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new PrivateRoomsComposer(Emulator.getGameEnvironment().getRoomManager().getRoomsWithRights(this.client.getHabbo()))); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/polls/AnswerPollEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/polls/AnswerPollEvent.java new file mode 100644 index 0000000..d331bb3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/polls/AnswerPollEvent.java @@ -0,0 +1,67 @@ +package com.eu.habbo.messages.incoming.polls; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.polls.Poll; +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.users.AddUserBadgeComposer; +import com.eu.habbo.messages.outgoing.wired.WiredRewardAlertComposer; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class AnswerPollEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + int pollId = this.packet.readInt(); + int questionId = this.packet.readInt(); + int count = this.packet.readInt(); + String answers = this.packet.readString(); + + StringBuilder answer = new StringBuilder(); + for (int i = 0; i < count; i++) { + answer.append(":").append(answers); + } + + if(answer.length() <= 0) return; + + if (pollId == 0 && questionId <= 0) { + this.client.getHabbo().getHabboInfo().getCurrentRoom().handleWordQuiz(this.client.getHabbo(), answer.toString()); + return; + } + + answer = new StringBuilder(answer.substring(1)); + + Poll poll = Emulator.getGameEnvironment().getPollManager().getPoll(pollId); + + if (poll != null) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO polls_answers(poll_id, user_id, question_id, answer) VALUES(?, ?, ?, ?) ON DUPLICATE KEY UPDATE answer=VALUES(answer)")) { + statement.setInt(1, pollId); + statement.setInt(2, this.client.getHabbo().getHabboInfo().getId()); + statement.setInt(3, questionId); + statement.setString(4, answer.toString()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + if (poll.lastQuestionId == questionId) { + if (poll.badgeReward.length() > 0) { + if (!this.client.getHabbo().getInventory().getBadgesComponent().hasBadge(poll.badgeReward)) { + HabboBadge badge = new HabboBadge(0, poll.badgeReward, 0, this.client.getHabbo()); + Emulator.getThreading().run(badge); + this.client.getHabbo().getInventory().getBadgesComponent().addBadge(badge); + this.client.sendResponse(new AddUserBadgeComposer(badge)); + this.client.sendResponse(new WiredRewardAlertComposer(WiredRewardAlertComposer.REWARD_RECEIVED_BADGE)); + } else { + this.client.sendResponse(new WiredRewardAlertComposer(WiredRewardAlertComposer.REWARD_ALREADY_RECEIVED)); + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/polls/CancelPollEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/polls/CancelPollEvent.java new file mode 100644 index 0000000..75cf05a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/polls/CancelPollEvent.java @@ -0,0 +1,34 @@ +package com.eu.habbo.messages.incoming.polls; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.polls.Poll; +import com.eu.habbo.messages.incoming.MessageHandler; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class CancelPollEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + int pollId = this.packet.readInt(); + + + Poll poll = Emulator.getGameEnvironment().getPollManager().getPoll(pollId); + + if (poll != null) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO polls_answers (poll_id, user_id, question_id, answer) VALUES (?, ?, ?, ?)")) { + statement.setInt(1, pollId); + statement.setInt(2, this.client.getHabbo().getHabboInfo().getId()); + statement.setInt(3, 0); + statement.setString(4, ""); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/polls/GetPollDataEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/polls/GetPollDataEvent.java new file mode 100644 index 0000000..491b20d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/polls/GetPollDataEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.messages.incoming.polls; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.polls.Poll; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.polls.PollQuestionsComposer; + +public class GetPollDataEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int pollId = this.packet.readInt(); + + Poll poll = Emulator.getGameEnvironment().getPollManager().getPoll(pollId); + + if (poll != null) { + this.client.sendResponse(new PollQuestionsComposer(poll)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/HandleDoorbellEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/HandleDoorbellEvent.java new file mode 100644 index 0000000..e521a7c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/HandleDoorbellEvent.java @@ -0,0 +1,34 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.hotelview.HotelViewComposer; +import com.eu.habbo.messages.outgoing.rooms.HideDoorbellComposer; +import com.eu.habbo.messages.outgoing.rooms.RoomAccessDeniedComposer; + +public class HandleDoorbellEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null && this.client.getHabbo().getHabboInfo().getCurrentRoom().hasRights(this.client.getHabbo())) { + String username = this.packet.readString(); + boolean accepted = this.packet.readBoolean(); + + Habbo habbo = Emulator.getGameServer().getGameClientManager().getHabbo(username); + + if (habbo != null && habbo.getHabboInfo().getRoomQueueId() == this.client.getHabbo().getHabboInfo().getCurrentRoom().getId()) { + this.client.getHabbo().getHabboInfo().getCurrentRoom().removeFromQueue(habbo); + + if (accepted) { + habbo.getClient().sendResponse(new HideDoorbellComposer("")); + Emulator.getGameEnvironment().getRoomManager().enterRoom(habbo, this.client.getHabbo().getHabboInfo().getCurrentRoom().getId(), "", true); + } else { + habbo.getClient().sendResponse(new RoomAccessDeniedComposer("")); + habbo.getClient().sendResponse(new HotelViewComposer()); + } + habbo.getHabboInfo().setRoomQueueId(0); + } + + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestHeightmapEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestHeightmapEvent.java new file mode 100644 index 0000000..e6311df --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestHeightmapEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class RequestHeightmapEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getLoadingRoom() > 0) { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.client.getHabbo().getHabboInfo().getLoadingRoom()); + + if (room != null) { + Emulator.getGameEnvironment().getRoomManager().enterRoom(this.client.getHabbo(), room); + + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomDataEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomDataEvent.java new file mode 100644 index 0000000..a4ba2fd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomDataEvent.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.RoomDataComposer; + +public class RequestRoomDataEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = Emulator.getGameEnvironment().getRoomManager().loadRoom(this.packet.readInt()); + + int something = this.packet.readInt(); + int something2 = this.packet.readInt(); + if (room != null) { + boolean unknown = true; + + if (something == 0 && something2 == 1) { + unknown = false; + } + + //this.client.getHabbo().getHabboInfo().getCurrentRoom() != room + this.client.sendResponse(new RoomDataComposer(room, this.client.getHabbo(), true, unknown)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomHeightmapEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomHeightmapEvent.java new file mode 100644 index 0000000..294f287 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomHeightmapEvent.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.RoomHeightMapComposer; +import com.eu.habbo.messages.outgoing.rooms.RoomRelativeMapComposer; + +public class RequestRoomHeightmapEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getLoadingRoom() > 0) { + Room room = Emulator.getGameEnvironment().getRoomManager().loadRoom(this.client.getHabbo().getHabboInfo().getLoadingRoom()); + + if (room != null && room.getLayout() != null) { + this.client.sendResponse(new RoomRelativeMapComposer(room)); + + this.client.sendResponse(new RoomHeightMapComposer(room)); + + Emulator.getGameEnvironment().getRoomManager().enterRoom(this.client.getHabbo(), room); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomLoadEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomLoadEvent.java new file mode 100644 index 0000000..93c904b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomLoadEvent.java @@ -0,0 +1,32 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class RequestRoomLoadEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + int roomId = this.packet.readInt(); + String password = this.packet.readString(); + + if (this.client.getHabbo().getHabboInfo().getLoadingRoom() == 0 && this.client.getHabbo().getHabboStats().roomEnterTimestamp + 1000 < System.currentTimeMillis()) { + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + if (room != null) { + Emulator.getGameEnvironment().getRoomManager().logExit(this.client.getHabbo()); + + room.removeHabbo(this.client.getHabbo(), true); + + this.client.getHabbo().getHabboInfo().setCurrentRoom(null); + } + + if (this.client.getHabbo().getRoomUnit() != null && this.client.getHabbo().getRoomUnit().isTeleporting) { + this.client.getHabbo().getRoomUnit().isTeleporting = false; + } + + Emulator.getGameEnvironment().getRoomManager().enterRoom(this.client.getHabbo(), roomId, password); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomRightsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomRightsEvent.java new file mode 100644 index 0000000..bd6841a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomRightsEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.RoomRightsListComposer; + +public class RequestRoomRightsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + if (room.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER)) { + this.client.sendResponse(new RoomRightsListComposer(room)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomSettingsEvent.java new file mode 100644 index 0000000..e025d33 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomSettingsEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.RoomSettingsComposer; + +public class RequestRoomSettingsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int roomId = this.packet.readInt(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId); + + if (room != null) + this.client.sendResponse(new RoomSettingsComposer(room)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomWordFilterEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomWordFilterEvent.java new file mode 100644 index 0000000..3d54bfe --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomWordFilterEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.RoomFilterWordsComposer; + +public class RequestRoomWordFilterEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.packet.readInt()); + + if (room != null && room.hasRights(this.client.getHabbo())) { + this.client.sendResponse(new RoomFilterWordsComposer(room)); + + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModRoomFilterSeen")); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomBackgroundEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomBackgroundEvent.java new file mode 100644 index 0000000..a53c8f1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomBackgroundEvent.java @@ -0,0 +1,44 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.furniture.FurnitureRoomTonerEvent; + +public class RoomBackgroundEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + if (room == null) + return; + + if (room.hasRights(this.client.getHabbo()) || this.client.getHabbo().hasPermission(Permission.ACC_PLACEFURNI)) { + HabboItem item = room.getHabboItem(itemId); + + if (item == null) + return; + + int hue = this.packet.readInt(); + int saturation = this.packet.readInt(); + int brightness = this.packet.readInt(); + + FurnitureRoomTonerEvent event = (FurnitureRoomTonerEvent) Emulator.getPluginManager().fireEvent(new FurnitureRoomTonerEvent(item, this.client.getHabbo(), hue, saturation, brightness)); + + if (event.isCancelled()) + return; + + hue = event.hue % 256; + saturation = event.saturation % 256; + brightness = event.brightness % 256; + + item.setExtradata(item.getExtradata().split(":")[0] + ":" + hue + ":" + saturation + ":" + brightness); + item.needsUpdate(true); + Emulator.getThreading().run(item); + room.updateItem(item); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomFavoriteEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomFavoriteEvent.java new file mode 100644 index 0000000..9eaef83 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomFavoriteEvent.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.FavoriteRoomChangedComposer; + +public class RoomFavoriteEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int roomId = this.packet.readInt(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId); + + boolean added = true; + if (room != null) { + if (this.client.getHabbo().getHabboStats().hasFavoriteRoom(roomId)) { + this.client.getHabbo().getHabboStats().removeFavoriteRoom(roomId); + added = false; + } else { + if (!this.client.getHabbo().getHabboStats().addFavoriteRoom(roomId)) { + return; + } + } + + this.client.sendResponse(new FavoriteRoomChangedComposer(roomId, added)); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomMuteEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomMuteEvent.java new file mode 100644 index 0000000..a71e254 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomMuteEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.RoomMutedComposer; + +public class RoomMuteEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + if (room.isOwner(this.client.getHabbo())) { + room.setMuted(!room.isMuted()); + this.client.sendResponse(new RoomMutedComposer(room)); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomPlacePaintEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomPlacePaintEvent.java new file mode 100644 index 0000000..7485505 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomPlacePaintEvent.java @@ -0,0 +1,52 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.inventory.RemoveHabboItemComposer; +import com.eu.habbo.messages.outgoing.rooms.RoomPaintComposer; + +public class RoomPlacePaintEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() == null) + return; + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || room.hasRights(this.client.getHabbo()) || this.client.getHabbo().hasPermission(Permission.ACC_PLACEFURNI)) { + int itemId = this.packet.readInt(); + HabboItem item = this.client.getHabbo().getInventory().getItemsComponent().getHabboItem(itemId); + + if (item == null) { + this.client.sendResponse(new RemoveHabboItemComposer(itemId)); + return; + } + + if (item.getBaseItem().getName().equals("floor")) { + room.setFloorPaint(item.getExtradata()); + + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("RoomDecoFloor")); + } else if (item.getBaseItem().getName().equals("wallpaper")) { + room.setWallPaint(item.getExtradata()); + + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("RoomDecoWallpaper")); + } else if (item.getBaseItem().getName().equals("landscape")) { + room.setBackgroundPaint(item.getExtradata()); + + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("RoomDecoLandscape")); + } else + return; + + this.client.getHabbo().getInventory().getItemsComponent().removeHabboItem(item); + room.setNeedsUpdate(true); + room.sendComposer(new RoomPaintComposer(item.getBaseItem().getName(), item.getExtradata()).compose()); + item.needsDelete(true); + Emulator.getThreading().run(item); + this.client.sendResponse(new RemoveHabboItemComposer(itemId)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomRemoveAllRightsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomRemoveAllRightsEvent.java new file mode 100644 index 0000000..5bf9dc0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomRemoveAllRightsEvent.java @@ -0,0 +1,40 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomRightLevels; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.RoomRightsComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserRemoveRightsComposer; +import gnu.trove.procedure.TIntProcedure; + +public class RoomRemoveAllRightsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + final Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null || room.getId() != this.packet.readInt()) + return; + + if (room.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER)) { + room.getRights().forEach(new TIntProcedure() { + @Override + public boolean execute(int value) { + Habbo habbo = room.getHabbo(value); + + if (habbo != null) { + room.sendComposer(new RoomUserRemoveRightsComposer(room, value).compose()); + habbo.getRoomUnit().removeStatus(RoomUnitStatus.FLAT_CONTROL); + habbo.getClient().sendResponse(new RoomRightsComposer(RoomRightLevels.NONE)); + } + + return true; + } + }); + + room.removeAllRights(); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomRemoveRightsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomRemoveRightsEvent.java new file mode 100644 index 0000000..1e23d53 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomRemoveRightsEvent.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class RoomRemoveRightsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int roomId = this.packet.readInt(); + + Emulator.getGameEnvironment().getRoomManager().getRoom(roomId).removeRights(this.client.getHabbo().getHabboInfo().getId()); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomRequestBannedUsersEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomRequestBannedUsersEvent.java new file mode 100644 index 0000000..609e7b4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomRequestBannedUsersEvent.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.RoomBannedUsersComposer; + +public class RoomRequestBannedUsersEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int roomId = this.packet.readInt(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId); + + if (room != null) { + this.client.sendResponse(new RoomBannedUsersComposer(room)); + } + + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModChatFloodFilterSeen")); + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModChatHearRangeSeen")); + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModChatScrollSpeedSeen")); + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModDoorModeSeen")); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomSettingsSaveEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomSettingsSaveEvent.java new file mode 100644 index 0000000..5032065 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomSettingsSaveEvent.java @@ -0,0 +1,134 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomCategory; +import com.eu.habbo.habbohotel.rooms.RoomState; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.*; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RoomSettingsSaveEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + int roomId = this.packet.readInt(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId); + + if (room != null) { + if (room.isOwner(this.client.getHabbo())) { + String name = this.packet.readString(); + + if (name.trim().isEmpty() || name.length() > 60) { + this.client.sendResponse(new RoomEditSettingsErrorComposer(room.getId(), RoomEditSettingsErrorComposer.ROOM_NAME_MISSING, "")); + return; + } + + if (!Emulator.getGameEnvironment().getWordFilter().filter(name, this.client.getHabbo()).equals(name)) { + this.client.sendResponse(new RoomEditSettingsErrorComposer(room.getId(), RoomEditSettingsErrorComposer.ROOM_NAME_BADWORDS, "")); + return; + } + + String description = this.packet.readString(); + + if (description.length() > 255) { + return; + } + + if (!Emulator.getGameEnvironment().getWordFilter().filter(description, this.client.getHabbo()).equals(description)) { + this.client.sendResponse(new RoomEditSettingsErrorComposer(room.getId(), RoomEditSettingsErrorComposer.ROOM_DESCRIPTION_BADWORDS, "")); + return; + } + + RoomState state = RoomState.values()[this.packet.readInt() % RoomState.values().length]; + + String password = this.packet.readString(); + if (state == RoomState.PASSWORD && password.isEmpty() && (room.getPassword() == null || room.getPassword().isEmpty())) { + this.client.sendResponse(new RoomEditSettingsErrorComposer(room.getId(), RoomEditSettingsErrorComposer.PASSWORD_REQUIRED, "")); + return; + } + + int usersMax = this.packet.readInt(); + int categoryId = this.packet.readInt(); + StringBuilder tags = new StringBuilder(); + int count = Math.min(this.packet.readInt(), 2); + for (int i = 0; i < count; i++) { + String tag = this.packet.readString(); + + if (tag.length() > 15) { + this.client.sendResponse(new RoomEditSettingsErrorComposer(room.getId(), RoomEditSettingsErrorComposer.TAGS_TOO_LONG, "")); + return; + } + tags.append(tag).append(";"); + } + + if (!Emulator.getGameEnvironment().getWordFilter().filter(tags.toString(), this.client.getHabbo()).equals(tags.toString())) { + this.client.sendResponse(new RoomEditSettingsErrorComposer(room.getId(), RoomEditSettingsErrorComposer.ROOM_TAGS_BADWWORDS, "")); + return; + } + + + if (tags.length() > 0) { + for (String s : Emulator.getConfig().getValue("hotel.room.tags.staff").split(";")) { + if (tags.toString().contains(s)) { + this.client.sendResponse(new RoomEditSettingsErrorComposer(room.getId(), RoomEditSettingsErrorComposer.RESTRICTED_TAGS, "1")); + return; + } + } + } + + room.setName(name); + room.setDescription(description); + room.setState(state); + if (!password.isEmpty()) room.setPassword(password); + room.setUsersMax(usersMax); + + + if (Emulator.getGameEnvironment().getRoomManager().hasCategory(categoryId, this.client.getHabbo())) + room.setCategory(categoryId); + else { + RoomCategory category = Emulator.getGameEnvironment().getRoomManager().getCategory(categoryId); + + String message; + + if (category == null) { + message = Emulator.getTexts().getValue("scripter.warning.roomsettings.category.nonexisting").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()); + } else { + message = Emulator.getTexts().getValue("scripter.warning.roomsettings.category.permission").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()).replace("%category%", Emulator.getGameEnvironment().getRoomManager().getCategory(categoryId) + ""); + } + + ScripterManager.scripterDetected(this.client, message); + log.info(message); + } + + + room.setTags(tags.toString()); + room.setTradeMode(this.packet.readInt()); + room.setAllowPets(this.packet.readBoolean()); + room.setAllowPetsEat(this.packet.readBoolean()); + room.setAllowWalkthrough(this.packet.readBoolean()); + room.setHideWall(this.packet.readBoolean()); + room.setWallSize(this.packet.readInt()); + room.setFloorSize(this.packet.readInt()); + room.setMuteOption(this.packet.readInt()); + room.setKickOption(this.packet.readInt()); + room.setBanOption(this.packet.readInt()); + room.setChatMode(this.packet.readInt()); + room.setChatWeight(this.packet.readInt()); + room.setChatSpeed(this.packet.readInt()); + room.setChatDistance(Math.abs(this.packet.readInt())); + room.setChatProtection(this.packet.readInt()); + room.setNeedsUpdate(true); + + room.sendComposer(new RoomThicknessComposer(room).compose()); + room.sendComposer(new RoomChatSettingsComposer(room).compose()); + room.sendComposer(new RoomSettingsUpdatedComposer(room).compose()); + this.client.sendResponse(new RoomSettingsSavedComposer(room)); + //TODO Find packet for update room name. + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomStaffPickEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomStaffPickEvent.java new file mode 100644 index 0000000..0e3e320 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomStaffPickEvent.java @@ -0,0 +1,45 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.navigation.NavigatorPublicCategory; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.RoomDataComposer; + +public class RoomStaffPickEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().hasPermission(Permission.ACC_STAFF_PICK)) { + int roomId = this.packet.readInt(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId); + + if (room != null) { + room.setStaffPromotedRoom(!room.isStaffPromotedRoom()); + room.setNeedsUpdate(true); + + NavigatorPublicCategory publicCategory = Emulator.getGameEnvironment().getNavigatorManager().publicCategories.get(Emulator.getConfig().getInt("hotel.navigator.staffpicks.categoryid")); + if (room.isStaffPromotedRoom()) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(room.getOwnerId()); + + if (habbo != null) { + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("Spr")); + } + + if (publicCategory != null) { + publicCategory.addRoom(room); + } + } else { + if (publicCategory != null) { + publicCategory.removeRoom(room); + } + } + + this.client.sendResponse(new RoomDataComposer(room, this.client.getHabbo(), true, false)); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomUnFavoriteEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomUnFavoriteEvent.java new file mode 100644 index 0000000..2b23d0c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomUnFavoriteEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.FavoriteRoomChangedComposer; + +public class RoomUnFavoriteEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int roomId = this.packet.readInt(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId); + + if (room != null) { + if (this.client.getHabbo().getHabboStats().hasFavoriteRoom(roomId)) { + this.client.getHabbo().getHabboStats().removeFavoriteRoom(roomId); + } + + this.client.sendResponse(new FavoriteRoomChangedComposer(roomId, false)); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomVoteEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomVoteEvent.java new file mode 100644 index 0000000..57e3dc8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomVoteEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class RoomVoteEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Emulator.getGameEnvironment().getRoomManager().voteForRoom(this.client.getHabbo(), this.client.getHabbo().getHabboInfo().getCurrentRoom()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomWordFilterModifyEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomWordFilterModifyEvent.java new file mode 100644 index 0000000..be680d5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/RoomWordFilterModifyEvent.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class RoomWordFilterModifyEvent extends MessageHandler { + @Override + public void handle() throws Exception { + final int roomId = this.packet.readInt(); + final boolean add = this.packet.readBoolean(); + String word = this.packet.readString(); + + if (word.length() > 25) { + word = word.substring(0, 24); + } + + // Get current room of user. + final Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + if (room == null || room.getId() != roomId) { + return; + } + + // Check if owner. + if (!room.isOwner(this.client.getHabbo())) { + ScripterManager.scripterDetected(this.client, String.format("User (%s) tried to change wordfilter for a not owned room.", this.client.getHabbo().getHabboInfo().getUsername())); + return; + } + + // Modify word filter. + if (add) { + room.addToWordFilter(word); + } else { + room.removeFromWordFilter(word); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/SetHomeRoomEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/SetHomeRoomEvent.java new file mode 100644 index 0000000..7a39e00 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/SetHomeRoomEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.messages.incoming.rooms; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.users.UserHomeRoomComposer; + +public class SetHomeRoomEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int roomId = this.packet.readInt(); + + if (roomId != this.client.getHabbo().getHabboInfo().getHomeRoom()) { + this.client.getHabbo().getHabboInfo().setHomeRoom(roomId); + this.client.sendResponse(new UserHomeRoomComposer(this.client.getHabbo().getHabboInfo().getHomeRoom(), 0)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotPickupEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotPickupEvent.java new file mode 100644 index 0000000..ea04d57 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotPickupEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.messages.incoming.rooms.bots; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class BotPickupEvent extends MessageHandler { + + + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + Emulator.getGameEnvironment().getBotManager().pickUpBot(this.packet.readInt(), this.client.getHabbo()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotPlaceEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotPlaceEvent.java new file mode 100644 index 0000000..4b9e9c9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotPlaceEvent.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.incoming.rooms.bots; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class BotPlaceEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + Bot bot = this.client.getHabbo().getInventory().getBotsComponent().getBot(this.packet.readInt()); + + if (bot == null) + return; + + int x = this.packet.readInt(); + int y = this.packet.readInt(); + + Emulator.getGameEnvironment().getBotManager().placeBot(bot, this.client.getHabbo(), this.client.getHabbo().getHabboInfo().getCurrentRoom(), room.getLayout().getTile((short) x, (short) y)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotSaveSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotSaveSettingsEvent.java new file mode 100644 index 0000000..bb5da19 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotSaveSettingsEvent.java @@ -0,0 +1,170 @@ +package com.eu.habbo.messages.incoming.rooms.bots; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.bots.BotManager; +import com.eu.habbo.habbohotel.permissions.Permission; +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.RoomUserDanceComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserNameChangedComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUsersComposer; +import com.eu.habbo.plugin.events.bots.BotSavedChatEvent; +import com.eu.habbo.plugin.events.bots.BotSavedLookEvent; +import com.eu.habbo.plugin.events.bots.BotSavedNameEvent; +import org.jsoup.Jsoup; + +import java.util.ArrayList; + +public class BotSaveSettingsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + if (room.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER)) { + int botId = this.packet.readInt(); + + Bot bot = room.getBot(Math.abs(botId)); + + if (bot == null) + return; + + int settingId = this.packet.readInt(); + + switch (settingId) { + case 1: + BotSavedLookEvent lookEvent = new BotSavedLookEvent(bot, + this.client.getHabbo().getHabboInfo().getGender(), + this.client.getHabbo().getHabboInfo().getLook(), + this.client.getHabbo().getRoomUnit().getEffectId()); + Emulator.getPluginManager().fireEvent(lookEvent); + + if (lookEvent.isCancelled()) + break; + + bot.setFigure(lookEvent.newLook); + bot.setGender(lookEvent.gender); + bot.setEffect(lookEvent.effect, -1); + bot.needsUpdate(true); + break; + + case 2: + String messageString = this.packet.readString(); + + if (messageString.length() > 5112) + break; + + String[] data = messageString.split(";#;"); + + ArrayList chat = new ArrayList<>(); + int totalChatLength = 0; + for (int i = 0; i < data.length - 3 && totalChatLength <= 120; i++) { + for (String s : data[i].split("\r")) { + String filtered = Jsoup.parse(s).text(); + int count = 0; + while (!filtered.equalsIgnoreCase(s)) { + if (count >= 5) { + bot.clearChat(); + return; + } + s = filtered; + filtered = Jsoup.parse(s).text(); + count++; + } + + String result = Emulator.getGameEnvironment().getWordFilter().filter(s, null); + + if (!result.isEmpty()) { + if (!this.client.getHabbo().hasPermission(Permission.ACC_CHAT_NO_FILTER)) { + result = Emulator.getGameEnvironment().getWordFilter().filter(result, this.client.getHabbo()); + } + + result = result.substring(0, Math.min(BotManager.MAXIMUM_CHAT_LENGTH - totalChatLength, result.length())); + chat.add(result); + totalChatLength += result.length(); + } + } + } + + int chatSpeed = 7; + + try { + chatSpeed = Integer.valueOf(data[data.length - 2]); + if (chatSpeed < BotManager.MINIMUM_CHAT_SPEED) { + chatSpeed = BotManager.MINIMUM_CHAT_SPEED; + } + } catch (Exception e) { + //Invalid chatspeed. Use 7. + } + + BotSavedChatEvent chatEvent = new BotSavedChatEvent(bot, Boolean.valueOf(data[data.length - 3]), Boolean.valueOf(data[data.length - 1]), chatSpeed, chat); + Emulator.getPluginManager().fireEvent(chatEvent); + + if (chatEvent.isCancelled()) + break; + + bot.setChatAuto(chatEvent.autoChat); + bot.setChatRandom(chatEvent.randomChat); + bot.setChatDelay((short) chatEvent.chatDelay); + bot.clearChat(); + bot.addChatLines(chat); + bot.needsUpdate(true); + break; + + case 3: + bot.setCanWalk(!bot.canWalk()); + bot.needsUpdate(true); + break; + + case 4: + bot.getRoomUnit().setDanceType(DanceType.values()[(bot.getRoomUnit().getDanceType().getType() + 1) % DanceType.values().length]); + room.sendComposer(new RoomUserDanceComposer(bot.getRoomUnit()).compose()); + bot.needsUpdate(true); + break; + + case 5: + String name = this.packet.readString(); + boolean invalidName = name.length() > BotManager.MAXIMUM_NAME_LENGTH || name.contains("<") || name.contains(">"); + if (!invalidName) { + String filteredName = Emulator.getGameEnvironment().getWordFilter().filter(name, null); + invalidName = !name.equalsIgnoreCase(filteredName); + if (!invalidName) { + BotSavedNameEvent nameEvent = new BotSavedNameEvent(bot, name); + + Emulator.getPluginManager().fireEvent(nameEvent); + + if (nameEvent.isCancelled()) + break; + + bot.setName(nameEvent.name); + bot.needsUpdate(true); + room.sendComposer(new RoomUserNameChangedComposer(bot.getRoomUnit().getId(), bot.getRoomUnit().getId(), nameEvent.name).compose()); + } + } + + if (invalidName) { + this.client.sendResponse(new BotErrorComposer(BotErrorComposer.ROOM_ERROR_BOTS_NAME_NOT_ACCEPT)); + } + break; + case 9: + String motto = this.packet.readString(); + + if(motto.length() > Emulator.getConfig().getInt("motto.max_length", 38)) break; + + bot.setMotto(motto); + bot.needsUpdate(true); + room.sendComposer(new RoomUsersComposer(bot).compose()); + break; + } + + if (bot.needsUpdate()) { + Emulator.getThreading().run(bot); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotSettingsEvent.java new file mode 100644 index 0000000..1a5cbda --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotSettingsEvent.java @@ -0,0 +1,28 @@ +package com.eu.habbo.messages.incoming.rooms.bots; + +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.BotSettingsComposer; + +public class BotSettingsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + if (room.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER)) { + int botId = this.packet.readInt(); + + Bot bot = room.getBot(Math.abs(botId)); + + if (bot == null) + return; + + this.client.sendResponse(new BotSettingsComposer(bot, this.packet.readInt())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/AdvertisingSaveEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/AdvertisingSaveEvent.java new file mode 100644 index 0000000..b25f379 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/AdvertisingSaveEvent.java @@ -0,0 +1,52 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionCustomValues; +import com.eu.habbo.habbohotel.items.interactions.InteractionRoomAds; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import gnu.trove.map.hash.THashMap; + +import java.util.Map; + +public class AdvertisingSaveEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + if (room == null) + return; + + if (!room.hasRights(this.client.getHabbo())) + return; + + HabboItem item = room.getHabboItem(this.packet.readInt()); + if (item == null) + return; + + if (item instanceof InteractionRoomAds && !this.client.getHabbo().hasPermission("acc_ads_background")) { + this.client.getHabbo().alert(Emulator.getTexts().getValue("hotel.error.roomads.nopermission")); + return; + } + if (item instanceof InteractionCustomValues) { + THashMap oldValues = new THashMap<>(((InteractionCustomValues) item).values); + int count = this.packet.readInt(); + for (int i = 0; i < count / 2; i++) { + String key = this.packet.readString(); + String value = this.packet.readString(); + + if (!Emulator.getConfig().getBoolean("camera.use.https")) { + value = value.replace("https://", "http://"); + } + + ((InteractionCustomValues) item).values.put(key, value); + } + + item.setExtradata(((InteractionCustomValues) item).toExtraData()); + item.needsUpdate(true); + Emulator.getThreading().run(item); + room.updateItem(item); + ((InteractionCustomValues) item).onCustomValuesSaved(room, this.client, oldValues); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/CloseDiceEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/CloseDiceEvent.java new file mode 100644 index 0000000..37ceeed --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/CloseDiceEvent.java @@ -0,0 +1,38 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionDice; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomLayout; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class CloseDiceEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + HabboItem item = room.getHabboItem(itemId); + + if (item != null) { + if (item instanceof InteractionDice) { + if (RoomLayout.tilesAdjecent(room.getLayout().getTile(item.getX(), item.getY()), this.client.getHabbo().getRoomUnit().getCurrentLocation())) { + if (!item.getExtradata().equals("-1")) { + item.setExtradata("0"); + item.needsUpdate(true); + Emulator.getThreading().run(item); + room.updateItem(item); + } + } + } else { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.packet.closedice").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()).replace("%id%", item.getId() + "").replace("%itemname%", item.getBaseItem().getName())); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/FootballGateSaveLookEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/FootballGateSaveLookEvent.java new file mode 100644 index 0000000..aa4d2f3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/FootballGateSaveLookEvent.java @@ -0,0 +1,36 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.habbohotel.items.interactions.games.football.InteractionFootballGate; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class FootballGateSaveLookEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null || this.client.getHabbo().getHabboInfo().getId() != room.getOwnerId()) + return; + + HabboItem item = room.getHabboItem(this.packet.readInt()); + if (!(item instanceof InteractionFootballGate)) + return; + + String gender = this.packet.readString(); + String look = this.packet.readString(); + + switch (gender.toLowerCase()) { + default: + case "m": + ((InteractionFootballGate) item).setFigureM(look); + room.updateItem(item); + break; + + case "f": + ((InteractionFootballGate) item).setFigureF(look); + room.updateItem(item); + break; + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MannequinSaveLookEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MannequinSaveLookEvent.java new file mode 100644 index 0000000..6713af8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MannequinSaveLookEvent.java @@ -0,0 +1,47 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class MannequinSaveLookEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Habbo habbo = this.client.getHabbo(); + Room room = habbo.getHabboInfo().getCurrentRoom(); + + if (room == null || !room.isOwner(habbo)) + return; + + HabboItem item = room.getHabboItem(this.packet.readInt()); + if (item == null) + return; + + String[] data = item.getExtradata().split(":"); + //TODO: Only clothing not whole body part. + + StringBuilder look = new StringBuilder(); + + for (String s : habbo.getHabboInfo().getLook().split("\\.")) { + if (!s.contains("hr") && !s.contains("hd") && !s.contains("he") && !s.contains("ea") && !s.contains("ha") && !s.contains("fa")) { + look.append(s).append("."); + } + } + + if (look.length() > 0) { + look = new StringBuilder(look.substring(0, look.length() - 1)); + } + + if (data.length == 3) { + item.setExtradata(habbo.getHabboInfo().getGender().name().toLowerCase() + ":" + look + ":" + data[2]); + } else { + item.setExtradata(habbo.getHabboInfo().getGender().name().toLowerCase() + ":" + look + ":" + habbo.getHabboInfo().getUsername() + "'s look."); + } + + item.needsUpdate(true); + Emulator.getThreading().run(item); + room.updateItem(item); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MannequinSaveNameEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MannequinSaveNameEvent.java new file mode 100644 index 0000000..c5c9420 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MannequinSaveNameEvent.java @@ -0,0 +1,35 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class MannequinSaveNameEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + if (room == null || !room.isOwner(this.client.getHabbo())) + return; + + HabboItem item = room.getHabboItem(this.packet.readInt()); + if (item == null) + return; + + String[] data = item.getExtradata().split(":"); + String name = this.packet.readString(); + + if (name.length() < 3 || name.length() > 15) { + name = Emulator.getTexts().getValue("hotel.mannequin.name.default", "My look"); + } + + if (data.length == 3) { + item.setExtradata(this.client.getHabbo().getHabboInfo().getGender().name().toUpperCase() + ":" + data[1] + ":" + name); + } else { + item.setExtradata(this.client.getHabbo().getHabboInfo().getGender().name().toUpperCase() + ":" + this.client.getHabbo().getHabboInfo().getLook() + ":" + name); + } + item.needsUpdate(true); + Emulator.getThreading().run(item); + room.updateItem(item); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoodLightSaveSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoodLightSaveSettingsEvent.java new file mode 100644 index 0000000..c4e9c2c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoodLightSaveSettingsEvent.java @@ -0,0 +1,64 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionMoodLight; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomMoodlightData; +import com.eu.habbo.habbohotel.rooms.RoomRightLevels; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.items.MoodLightDataComposer; + +import java.util.Arrays; +import java.util.List; + +public class MoodLightSaveSettingsEvent extends MessageHandler { + public static List MOODLIGHT_AVAILABLE_COLORS = Arrays.asList("#74F5F5,#0053F7,#E759DE,#EA4532,#F2F851,#82F349,#000000".split(",")); + public static int MIN_BRIGHTNESS = (int) Math.floor(0.3 * 0xFF); + + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (!(room.getGuildId() > 0 && room.getGuildRightLevel(this.client.getHabbo()).isEqualOrGreaterThan(RoomRightLevels.GUILD_RIGHTS)) && !room.hasRights(this.client.getHabbo())) + return; + + int id = this.packet.readInt(); + int backgroundOnly = this.packet.readInt(); + String color = this.packet.readString(); + int brightness = this.packet.readInt(); + boolean apply = this.packet.readBoolean(); + + if (Emulator.getConfig().getBoolean("moodlight.color_check.enabled", true) && !MOODLIGHT_AVAILABLE_COLORS.contains(color)) { + ScripterManager.scripterDetected(this.client, "User tried to set a moodlight to a non-whitelisted color: " + color); + return; + } + + if (brightness > 0xFF || brightness < MIN_BRIGHTNESS) { + ScripterManager.scripterDetected(this.client, "User tried to set a moodlight's brightness to out-of-bounds ([76, 255]): " + brightness); + return; + } + + for (RoomMoodlightData data : room.getMoodlightData().valueCollection()) { + if (data.getId() == id) { + data.setBackgroundOnly(backgroundOnly == 2); + data.setColor(color); + data.setIntensity(brightness); + if (apply) data.enable(); + + for (HabboItem item : room.getRoomSpecialTypes().getItemsOfType(InteractionMoodLight.class)) { + item.setExtradata(data.toString()); + item.needsUpdate(true); + room.updateItem(item); + Emulator.getThreading().run(item); + } + } else if (apply) { + data.disable(); + } + } + + room.setNeedsUpdate(true); + this.client.sendResponse(new MoodLightDataComposer(room.getMoodlightData())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoodLightSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoodLightSettingsEvent.java new file mode 100644 index 0000000..bd1cc10 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoodLightSettingsEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.items.MoodLightDataComposer; + +public class MoodLightSettingsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) + this.client.sendResponse(new MoodLightDataComposer(this.client.getHabbo().getHabboInfo().getCurrentRoom().getMoodlightData())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoodLightTurnOnEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoodLightTurnOnEvent.java new file mode 100644 index 0000000..00b1d96 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoodLightTurnOnEvent.java @@ -0,0 +1,39 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionMoodLight; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomMoodlightData; +import com.eu.habbo.habbohotel.rooms.RoomRightLevels; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class MoodLightTurnOnEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (!(room.getGuildId() > 0 && room.getGuildRightLevel(this.client.getHabbo()).isEqualOrGreaterThan(RoomRightLevels.GUILD_RIGHTS)) && !room.hasRights(this.client.getHabbo())) + return; + + for (HabboItem moodLight : room.getRoomSpecialTypes().getItemsOfType(InteractionMoodLight.class)) { + // enabled ? 2 : 1, preset id, background only ? 2 : 1, color, intensity + + String extradata = "2,1,2,#FF00FF,255"; + for (RoomMoodlightData data : room.getMoodlightData().valueCollection()) { + if (data.isEnabled()) { + extradata = data.toString(); + break; + } + } + + RoomMoodlightData adjusted = RoomMoodlightData.fromString(extradata); + if (RoomMoodlightData.fromString(moodLight.getExtradata()).isEnabled()) adjusted.disable(); + moodLight.setExtradata(adjusted.toString()); + + moodLight.needsUpdate(true); + room.updateItem(moodLight); + Emulator.getThreading().run(moodLight); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoveWallItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoveWallItemEvent.java new file mode 100644 index 0000000..1039707 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoveWallItemEvent.java @@ -0,0 +1,40 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.FurnitureMovementError; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomRightLevels; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; + +public class MoveWallItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + if (!room.hasRights(this.client.getHabbo()) && !this.client.getHabbo().hasPermission(Permission.ACC_PLACEFURNI) && !(room.getGuildId() > 0 && room.getGuildRightLevel(this.client.getHabbo()).isEqualOrGreaterThan(RoomRightLevels.GUILD_RIGHTS))) { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, FurnitureMovementError.NO_RIGHTS.errorCode)); + return; + } + + int itemId = this.packet.readInt(); + String wallPosition = this.packet.readString(); + + if (itemId <= 0 || wallPosition.length() <= 13) + return; + + HabboItem item = room.getHabboItem(itemId); + + if (item == null) + return; + + item.setWallPosition(wallPosition); + item.needsUpdate(true); + room.updateItem(item); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItDeleteEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItDeleteEvent.java new file mode 100644 index 0000000..821f92c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItDeleteEvent.java @@ -0,0 +1,34 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionExternalImage; +import com.eu.habbo.habbohotel.items.interactions.InteractionPostIt; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.items.RemoveWallItemComposer; +import com.eu.habbo.threading.runnables.QueryDeleteHabboItem; + +public class PostItDeleteEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + HabboItem item = room.getHabboItem(itemId); + + if (item instanceof InteractionPostIt || item instanceof InteractionExternalImage) { + if (item.getUserId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER)) { + item.setRoomId(0); + room.removeHabboItem(item); + room.sendComposer(new RemoveWallItemComposer(item).compose()); + Emulator.getThreading().run(new QueryDeleteHabboItem(item.getId())); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItPlaceEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItPlaceEvent.java new file mode 100644 index 0000000..67f1d20 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItPlaceEvent.java @@ -0,0 +1,57 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.items.interactions.InteractionPostIt; +import com.eu.habbo.habbohotel.items.interactions.InteractionStickyPole; +import com.eu.habbo.habbohotel.rooms.FurnitureMovementError; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.inventory.RemoveHabboItemComposer; +import com.eu.habbo.messages.outgoing.rooms.items.AddWallItemComposer; + +public class PostItPlaceEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + String location = this.packet.readString(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + if (room.hasRights(this.client.getHabbo()) || !room.getRoomSpecialTypes().getItemsOfType(InteractionStickyPole.class).isEmpty()) { + HabboItem item = this.client.getHabbo().getInventory().getItemsComponent().getHabboItem(itemId); + + if (item instanceof InteractionPostIt) { + if (room.getPostItNotes().size() < Room.MAXIMUM_POSTITNOTES) { + room.addHabboItem(item); + item.setExtradata("FFFF33"); + item.setRoomId(this.client.getHabbo().getHabboInfo().getCurrentRoom().getId()); + item.setWallPosition(location); + item.setUserId(this.client.getHabbo().getHabboInfo().getId()); + item.needsUpdate(true); + room.sendComposer(new AddWallItemComposer(item, this.client.getHabbo().getHabboInfo().getUsername()).compose()); + this.client.getHabbo().getInventory().getItemsComponent().removeHabboItem(item); + this.client.sendResponse(new RemoveHabboItemComposer(item.getGiftAdjustedId())); + item.setFromGift(false); + Emulator.getThreading().run(item); + + if (room.getOwnerId() != this.client.getHabbo().getHabboInfo().getId()) { + AchievementManager.progressAchievement(room.getOwnerId(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("NotesReceived")); + AchievementManager.progressAchievement(this.client.getHabbo().getHabboInfo().getId(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("NotesLeft")); + } + + } + else { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, FurnitureMovementError.MAX_STICKIES.errorCode)); + } + + //this.client.sendResponse(new PostItStickyPoleOpenComposer(item)); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItRequestDataEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItRequestDataEvent.java new file mode 100644 index 0000000..7a1d3d2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItRequestDataEvent.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.habbohotel.items.interactions.InteractionPostIt; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.items.PostItDataComposer; + +public class PostItRequestDataEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + HabboItem item = room.getHabboItem(itemId); + + if (item instanceof InteractionPostIt) { + this.client.sendResponse(new PostItDataComposer((InteractionPostIt) item)); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItSaveDataEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItSaveDataEvent.java new file mode 100644 index 0000000..d2aeda4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItSaveDataEvent.java @@ -0,0 +1,60 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.PostItColor; +import com.eu.habbo.habbohotel.items.interactions.InteractionPostIt; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +import java.util.Arrays; +import java.util.List; + +public class PostItSaveDataEvent extends MessageHandler { + private static List COLORS = Arrays.asList("9CCEFF", "FF9CFF", "9CFF9C", "FFFF33", "FF9C9D", "FFCD9C", "C3B1E1", "DBDEFB", "FFFFFF", "282828"); + + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + String color = this.packet.readString(); + String text = this.packet.readString().replace(((char) 9) + "", ""); + + if (text.length() > Emulator.getConfig().getInt("postit.charlimit")) { + ScripterManager.scripterDetected(this.client, Emulator.getTexts().getValue("scripter.warning.sticky.size").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()).replace("%amount%", text.length() + "").replace("%limit%", Emulator.getConfig().getInt("postit.charlimit") + "")); + return; + } + + if (!COLORS.contains(color)) { + return; + } + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + HabboItem item = room.getHabboItem(itemId); + + if (!(item instanceof InteractionPostIt)) + return; + + if (!color.equalsIgnoreCase(PostItColor.YELLOW.hexColor) && !room.hasRights(this.client.getHabbo())) { + if (!text.startsWith(item.getExtradata().replace(item.getExtradata().split(" ")[0], ""))) { + return; + } + } else { + if (!room.hasRights(this.client.getHabbo())) + return; + } + + if (color.isEmpty()) + color = PostItColor.YELLOW.hexColor; + + item.setUserId(room.getOwnerId()); + item.setExtradata(color + " " + text); + item.needsUpdate(true); + room.updateItem(item); + Emulator.getThreading().run(item); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RedeemClothingEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RedeemClothingEvent.java new file mode 100644 index 0000000..ee38587 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RedeemClothingEvent.java @@ -0,0 +1,67 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.ClothItem; +import com.eu.habbo.habbohotel.items.interactions.InteractionClothing; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.rooms.UpdateStackHeightComposer; +import com.eu.habbo.messages.outgoing.rooms.items.RemoveFloorItemComposer; +import com.eu.habbo.messages.outgoing.users.UserClothesComposer; +import com.eu.habbo.threading.runnables.QueryDeleteHabboItem; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class RedeemClothingEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null && + this.client.getHabbo().getHabboInfo().getCurrentRoom().hasRights(this.client.getHabbo())) { + HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId); + + if (item != null && item.getUserId() == this.client.getHabbo().getHabboInfo().getId()) { + if (item instanceof InteractionClothing) { + ClothItem clothing = Emulator.getGameEnvironment().getCatalogManager().getClothing(item.getBaseItem().getName()); + + if (clothing != null) { + if (!this.client.getHabbo().getInventory().getWardrobeComponent().getClothing().contains(clothing.id)) { + item.setRoomId(0); + RoomTile tile = this.client.getHabbo().getHabboInfo().getCurrentRoom().getLayout().getTile(item.getX(), item.getY()); + this.client.getHabbo().getHabboInfo().getCurrentRoom().removeHabboItem(item); + this.client.getHabbo().getHabboInfo().getCurrentRoom().updateTile(tile); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new UpdateStackHeightComposer(tile.x, tile.y, tile.z, tile.relativeHeight()).compose()); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RemoveFloorItemComposer(item, true).compose()); + Emulator.getThreading().run(new QueryDeleteHabboItem(item.getId())); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO users_clothing (user_id, clothing_id) VALUES (?, ?)")) { + statement.setInt(1, this.client.getHabbo().getHabboInfo().getId()); + statement.setInt(2, clothing.id); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.client.getHabbo().getInventory().getWardrobeComponent().getClothing().add(clothing.id); + this.client.getHabbo().getInventory().getWardrobeComponent().getClothingSets().addAll(clothing.setId); + this.client.sendResponse(new UserClothesComposer(this.client.getHabbo())); + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FIGURESET_REDEEMED.key)); + + } else { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FIGURESET_OWNED_ALREADY.key)); + } + } else { + log.error("[Catalog] No definition in catalog_clothing found for clothing name " + item.getBaseItem().getName() + ". Could not redeem clothing!"); + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RedeemItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RedeemItemEvent.java new file mode 100644 index 0000000..4135293 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RedeemItemEvent.java @@ -0,0 +1,138 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.UpdateStackHeightComposer; +import com.eu.habbo.messages.outgoing.rooms.items.RemoveFloorItemComposer; +import com.eu.habbo.messages.outgoing.users.UserCreditsComposer; +import com.eu.habbo.messages.outgoing.users.UserCurrencyComposer; +import com.eu.habbo.plugin.events.furniture.FurnitureRedeemedEvent; +import com.eu.habbo.threading.runnables.QueryDeleteHabboItem; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RedeemItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + HabboItem item = room.getHabboItem(itemId); + + if (item != null && this.client.getHabbo().getHabboInfo().getId() == item.getUserId()) { + boolean furnitureRedeemEventRegistered = Emulator.getPluginManager().isRegistered(FurnitureRedeemedEvent.class, true); + FurnitureRedeemedEvent furniRedeemEvent = new FurnitureRedeemedEvent(item, this.client.getHabbo(), 0, FurnitureRedeemedEvent.CREDITS); + + if (item.getBaseItem().getName().startsWith("CF_") || item.getBaseItem().getName().startsWith("CFC_") || item.getBaseItem().getName().startsWith("DF_") || item.getBaseItem().getName().startsWith("PF_") || item.getBaseItem().getName().startsWith("nft_credit_")) { + if ((item.getBaseItem().getName().startsWith("CF_") || item.getBaseItem().getName().startsWith("CFC_")) && !item.getBaseItem().getName().contains("_diamond_")) { + int credits; + try { + credits = Integer.valueOf(item.getBaseItem().getName().split("_")[1]); + } catch (Exception e) { + log.error("Failed to parse redeemable furniture: " + item.getBaseItem().getName() + ". Must be in format of CF_"); + return; + } + + furniRedeemEvent = new FurnitureRedeemedEvent(item, this.client.getHabbo(), credits, FurnitureRedeemedEvent.CREDITS); + } else if (item.getBaseItem().getName().startsWith("PF_")) { + int pixels; + + try { + pixels = Integer.valueOf(item.getBaseItem().getName().split("_")[1]); + } catch (Exception e) { + log.error("Failed to parse redeemable pixel furniture: " + item.getBaseItem().getName() + ". Must be in format of PF_"); + return; + } + + furniRedeemEvent = new FurnitureRedeemedEvent(item, this.client.getHabbo(), pixels, FurnitureRedeemedEvent.PIXELS); + } else if (item.getBaseItem().getName().startsWith("nft_credit_")) { + int points; + + try { + points = Integer.valueOf(item.getBaseItem().getName().split("_")[2]); + } catch (Exception e) { + log.error("Failed to parse redeemable points furniture: " + item.getBaseItem().getName() + ". Must be in format of ntf_credit_."); + return; + } + furniRedeemEvent = new FurnitureRedeemedEvent(item, this.client.getHabbo(), points, FurnitureRedeemedEvent.NFT); + + } else if (item.getBaseItem().getName().startsWith("DF_")) { + int pointsType; + int points; + + try { + pointsType = Integer.valueOf(item.getBaseItem().getName().split("_")[1]); + } catch (Exception e) { + log.error("Failed to parse redeemable points furniture: " + item.getBaseItem().getName() + ". Must be in format of DF__ where equals integer representation of seasonal currency."); + return; + } + + try { + points = Integer.valueOf(item.getBaseItem().getName().split("_")[2]); + } catch (Exception e) { + log.error("Failed to parse redeemable points furniture: " + item.getBaseItem().getName() + ". Must be in format of DF__ where equals integer representation of seasonal currency."); + return; + } + + furniRedeemEvent = new FurnitureRedeemedEvent(item, this.client.getHabbo(), points, pointsType); + }else if (item.getBaseItem().getName().startsWith("CF_diamond_")) { + int points; + + try { + points = Integer.valueOf(item.getBaseItem().getName().split("_")[2]); + } catch (Exception e) { + log.error("Failed to parse redeemable diamonds furniture: " + item.getBaseItem().getName() + ". Must be in format of CF_diamond_"); + return; + } + + furniRedeemEvent = new FurnitureRedeemedEvent(item, this.client.getHabbo(), points, FurnitureRedeemedEvent.DIAMONDS); + } + + if (furnitureRedeemEventRegistered) { + Emulator.getPluginManager().fireEvent(furniRedeemEvent); + + if (furniRedeemEvent.isCancelled()) + return; + } + + if (furniRedeemEvent.amount < 1) + return; + + if (room.getHabboItem(item.getId()) == null) // plugins may cause a lag between which time the item can be removed from the room + return; + + room.removeHabboItem(item); + room.sendComposer(new RemoveFloorItemComposer(item).compose()); + RoomTile t = room.getLayout().getTile(item.getX(), item.getY()); + t.setStackHeight(room.getStackHeight(item.getX(), item.getY(), false)); + room.updateTile(t); + room.sendComposer(new UpdateStackHeightComposer(item.getX(), item.getY(), t.z, t.relativeHeight()).compose()); + Emulator.getThreading().run(new QueryDeleteHabboItem(item.getId())); + + switch (furniRedeemEvent.currencyID) { + case FurnitureRedeemedEvent.CREDITS: + this.client.getHabbo().giveCredits(furniRedeemEvent.amount); + break; + + case FurnitureRedeemedEvent.DIAMONDS: + this.client.getHabbo().givePoints(furniRedeemEvent.amount); + break; + + case FurnitureRedeemedEvent.PIXELS: + this.client.getHabbo().givePixels(furniRedeemEvent.amount); + break; + + default: + this.client.getHabbo().givePoints(furniRedeemEvent.currencyID, furniRedeemEvent.amount); + break; + } + } + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPickupItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPickupItemEvent.java new file mode 100644 index 0000000..c3585ec --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPickupItemEvent.java @@ -0,0 +1,42 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.habbohotel.items.interactions.InteractionPostIt; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class RoomPickupItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int category = this.packet.readInt(); //10 = floorItem and 20 = wallItem + int itemId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + HabboItem item = room.getHabboItem(itemId); + + if (item == null) + return; + + if (item instanceof InteractionPostIt) + return; + + if (item.getUserId() == this.client.getHabbo().getHabboInfo().getId()) { + room.pickUpItem(item, this.client.getHabbo()); + } else { + if (room.hasRights(this.client.getHabbo())) { + if (this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER)) { + item.setUserId(this.client.getHabbo().getHabboInfo().getId()); + } else if (this.client.getHabbo().getHabboInfo().getId() != room.getOwnerId() && item.getUserId() == room.getOwnerId()) { + return; + } + + room.ejectUserItem(item); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPlaceItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPlaceItemEvent.java new file mode 100644 index 0000000..0f29318 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPlaceItemEvent.java @@ -0,0 +1,118 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.habbohotel.items.FurnitureType; +import com.eu.habbo.habbohotel.items.interactions.*; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.inventory.RemoveHabboItemComposer; + +public class RoomPlaceItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String[] values = this.packet.readString().split(" "); + + int itemId = -1; + + if (values.length != 0) itemId = Integer.parseInt(values[0]); + + if (!this.client.getHabbo().getRoomUnit().isInRoom()) { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, FurnitureMovementError.NO_RIGHTS.errorCode)); + return; + } + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + if (room == null) { + return; + } + + HabboItem rentSpace = null; + if (this.client.getHabbo().getHabboStats().isRentingSpace()) { + rentSpace = room.getHabboItem(this.client.getHabbo().getHabboStats().rentedItemId); + } + + HabboItem item = this.client.getHabbo().getInventory().getItemsComponent().getHabboItem(itemId); + + if (item == null || item.getBaseItem().getInteractionType().getType() == InteractionPostIt.class) + return; + + if (room.getId() != item.getRoomId() && item.getRoomId() != 0) + return; + + //TODO move this to canStackAt() though find a way to handle the different bubble alert keys + if (item instanceof InteractionMoodLight && !room.getRoomSpecialTypes().getItemsOfType(InteractionMoodLight.class).isEmpty()) { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, FurnitureMovementError.MAX_DIMMERS.errorCode)); + return; + } + if (item instanceof InteractionJukeBox && !room.getRoomSpecialTypes().getItemsOfType(InteractionJukeBox.class).isEmpty()) { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, FurnitureMovementError.MAX_SOUNDFURNI.errorCode)); + return; + } + + if (item.getBaseItem().getType() == FurnitureType.FLOOR) { + short x = Short.parseShort(values[1]); + short y = Short.parseShort(values[2]); + int rotation = Integer.parseInt(values[3]); + + RoomTile tile = room.getLayout().getTile(x, y); + + if(tile == null) + { + String userName = this.client.getHabbo().getHabboInfo().getUsername(); + int roomId = room.getId(); + ScripterManager.scripterDetected(this.client, "User [" + userName + "] tried to place a furni with itemId [" + itemId + "] at a tile which is not existing in room [" + roomId + "], tile: [" + x + "," + y + "]"); + return; + } + + HabboItem buildArea = null; + for (HabboItem area : room.getRoomSpecialTypes().getItemsOfType(InteractionBuildArea.class)) { + if (((InteractionBuildArea) area).inSquare(tile)) { + buildArea = area; + } + } + + if ((rentSpace != null || buildArea != null) && !room.hasRights(this.client.getHabbo())) { + if (item instanceof InteractionRoller || + item instanceof InteractionStackHelper || + item instanceof InteractionWired || + item instanceof InteractionBackgroundToner || + item instanceof InteractionRoomAds || + item instanceof InteractionCannon || + item instanceof InteractionPuzzleBox || + item.getBaseItem().getType() == FurnitureType.WALL) { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, FurnitureMovementError.NO_RIGHTS.errorCode)); + return; + } + if (rentSpace != null && !RoomLayout.squareInSquare(RoomLayout.getRectangle(rentSpace.getX(), rentSpace.getY(), rentSpace.getBaseItem().getWidth(), rentSpace.getBaseItem().getLength(), rentSpace.getRotation()), RoomLayout.getRectangle(x, y, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), rotation))) { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, FurnitureMovementError.NO_RIGHTS.errorCode)); + return; + } + } + FurnitureMovementError error = room.canPlaceFurnitureAt(item, this.client.getHabbo(), tile, rotation); + + if (!error.equals(FurnitureMovementError.NONE)) { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, error.errorCode)); + return; + } + + error = room.placeFloorFurniAt(item, tile, rotation, this.client.getHabbo()); + if (!error.equals(FurnitureMovementError.NONE)) { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, error.errorCode)); + return; + } + } else { + FurnitureMovementError error = room.placeWallFurniAt(item, values[1] + " " + values[2] + " " + values[3], this.client.getHabbo()); + if (!error.equals(FurnitureMovementError.NONE)) { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, error.errorCode)); + return; + } + } + + this.client.sendResponse(new RemoveHabboItemComposer(item.getGiftAdjustedId())); + this.client.getHabbo().getInventory().getItemsComponent().removeHabboItem(item.getId()); + item.setFromGift(false); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RotateMoveItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RotateMoveItemEvent.java new file mode 100644 index 0000000..22a6b1e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RotateMoveItemEvent.java @@ -0,0 +1,42 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.habbohotel.rooms.FurnitureMovementError; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.rooms.items.FloorItemUpdateComposer; + +public class RotateMoveItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + int furniId = this.packet.readInt(); + HabboItem item = room.getHabboItem(furniId); + if (item == null) return; + + int x = this.packet.readInt(); + int y = this.packet.readInt(); + int rotation = this.packet.readInt(); + RoomTile tile = room.getLayout().getTile((short) x, (short) y); + + FurnitureMovementError error = room.canPlaceFurnitureAt(item, this.client.getHabbo(), tile, rotation); + if (!error.equals(FurnitureMovementError.NONE)) { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, error.errorCode)); + this.client.sendResponse(new FloorItemUpdateComposer(item)); + return; + } + + error = room.moveFurniTo(item, tile, rotation, this.client.getHabbo()); + if (!error.equals(FurnitureMovementError.NONE)) { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, error.errorCode)); + this.client.sendResponse(new FloorItemUpdateComposer(item)); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/SavePostItStickyPoleEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/SavePostItStickyPoleEvent.java new file mode 100644 index 0000000..a5465df --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/SavePostItStickyPoleEvent.java @@ -0,0 +1,60 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.commands.CommandHandler; +import com.eu.habbo.habbohotel.items.PostItColor; +import com.eu.habbo.habbohotel.items.interactions.InteractionPostIt; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import lombok.extern.slf4j.Slf4j; + +import java.time.LocalDate; + +@Slf4j +public class SavePostItStickyPoleEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + this.packet.readString(); + String color = this.packet.readString(); + if (itemId == -1234) { + if (this.client.getHabbo().hasPermission("cmd_multi")) { + String[] commands = this.packet.readString().split("\r"); + + for (String command : commands) { + command = command.replace("
", "\r"); + CommandHandler.handleCommand(this.client, command); + } + } else { + log.info("Scripter Alert! " + this.client.getHabbo().getHabboInfo().getUsername() + " | " + this.packet.readString()); + } + } else { + String text = this.packet.readString(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + HabboItem sticky = room.getHabboItem(itemId); + + if (sticky != null) { + if (sticky.getUserId() == this.client.getHabbo().getHabboInfo().getId()) { + sticky.setUserId(room.getOwnerId()); + + if (color.equalsIgnoreCase(PostItColor.YELLOW.hexColor)) { + color = PostItColor.randomColorNotYellow().hexColor; + } + if (!InteractionPostIt.STICKYPOLE_PREFIX_TEXT.isEmpty()) { + text = InteractionPostIt.STICKYPOLE_PREFIX_TEXT.replace("\\r", "\r").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()).replace("%timestamp%", LocalDate.now().toString()) + text; + } + + sticky.setUserId(room.getOwnerId()); + sticky.setExtradata(color + " " + text); + sticky.needsUpdate(true); + room.updateItem(sticky); + Emulator.getThreading().run(sticky); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/SetStackHelperHeightEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/SetStackHelperHeightEvent.java new file mode 100644 index 0000000..dce3144 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/SetStackHelperHeightEvent.java @@ -0,0 +1,59 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.habbohotel.items.interactions.InteractionStackHelper; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.UpdateStackHeightComposer; +import com.eu.habbo.messages.outgoing.rooms.items.UpdateStackHeightTileHeightComposer; +import gnu.trove.set.hash.THashSet; + +public class SetStackHelperHeightEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() == null) + return; + + if (this.client.getHabbo().getHabboInfo().getId() == this.client.getHabbo().getHabboInfo().getCurrentRoom().getOwnerId() || this.client.getHabbo().getHabboInfo().getCurrentRoom().hasRights(this.client.getHabbo())) { + HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId); + + if (item instanceof InteractionStackHelper) { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + RoomTile itemTile = room.getLayout().getTile(item.getX(), item.getY()); + double stackerHeight = this.packet.readInt(); + + THashSet tiles = room.getLayout().getTilesAt(itemTile, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation()); + if (stackerHeight == -100) { + for (RoomTile tile : tiles) { + double stackheight = room.getStackHeight(tile.x, tile.y, false, item) * 100; + if (stackheight > stackerHeight) { + stackerHeight = stackheight; + } + } + } else { + stackerHeight = Math.min(Math.max(stackerHeight, itemTile.z * 100), Room.MAXIMUM_FURNI_HEIGHT * 100); + } + + double height = 0; + if (stackerHeight >= 0) { + height = stackerHeight / 100.0D; + } + + for (RoomTile tile : tiles) { + tile.setStackHeight(height); + } + + item.setZ(height); + item.setExtradata((int) (height * 100) + ""); + item.needsUpdate(true); + this.client.getHabbo().getHabboInfo().getCurrentRoom().updateItem(item); + this.client.getHabbo().getHabboInfo().getCurrentRoom().updateTiles(tiles); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new UpdateStackHeightComposer(room, tiles).compose()); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new UpdateStackHeightTileHeightComposer(item, (int) ((height) * 100)).compose()); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/ToggleFloorItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/ToggleFloorItemEvent.java new file mode 100644 index 0000000..0770e1e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/ToggleFloorItemEvent.java @@ -0,0 +1,138 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionDice; +import com.eu.habbo.habbohotel.items.interactions.InteractionWired; +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionMonsterPlantSeed; +import com.eu.habbo.habbohotel.pets.MonsterplantPet; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.items.RemoveFloorItemComposer; +import com.eu.habbo.messages.outgoing.rooms.pets.PetPackageComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import com.eu.habbo.plugin.Event; +import com.eu.habbo.plugin.events.furniture.FurniturePickedUpEvent; +import com.eu.habbo.plugin.events.furniture.FurnitureToggleEvent; +import com.eu.habbo.threading.runnables.QueryDeleteHabboItem; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ToggleFloorItemEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + try { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + int itemId = this.packet.readInt(); + int state = this.packet.readInt(); + + HabboItem item = room.getHabboItem(itemId); + + if (item == null || item instanceof InteractionDice) + return; + + Event furnitureToggleEvent = new FurnitureToggleEvent(item, this.client.getHabbo(), state); + Emulator.getPluginManager().fireEvent(furnitureToggleEvent); + + if (furnitureToggleEvent.isCancelled()) + return; + + /* + if (item.getBaseItem().getName().equalsIgnoreCase("totem_planet")) { + THashSet items = room.getItemsAt(room.getLayout().getTile(item.getX(), item.getY())); + HabboItem totemLeg = null; + HabboItem totemHead = null; + + for (HabboItem totemItem : items) { + if (totemLeg != null && totemHead != null) { + break; + } + if (totemItem.getBaseItem().getName().equalsIgnoreCase("totem_leg")) { + totemLeg = totemItem; + } + if (totemItem.getBaseItem().getName().equalsIgnoreCase("totem_head")) { + totemHead = totemItem; + } + } + + if (totemHead != null && totemLeg != null) { + if (item.getExtradata().equals("2")) { + if (totemLeg.getExtradata() == null || totemHead.getExtradata() == null) + return; + + if (totemLeg.getExtradata().equals("2") && totemHead.getExtradata().equals("5")) { + room.giveEffect(this.client.getHabbo(), 23, -1); + return; + } + + if (totemLeg.getExtradata().equals("10") && totemHead.getExtradata().equals("9")) { + room.giveEffect(this.client.getHabbo(), 26, -1); + return; + } + } else if (item.getExtradata().equals("0")) { + if (totemLeg.getExtradata().equals("7") && totemHead.getExtradata().equals("10")) { + room.giveEffect(this.client.getHabbo(), 24, -1); + return; + } + + } else if (item.getExtradata().equals("1")) { + if (totemLeg.getExtradata().equals("9") && totemHead.getExtradata().equals("12")) { + room.giveEffect(this.client.getHabbo(), 25, -1); + return; + } + } + } + }*/ + + //Do not move to onClick(). Wired could trigger it. + if (item instanceof InteractionMonsterPlantSeed) { + Emulator.getThreading().run(new QueryDeleteHabboItem(item.getId())); + int rarity = 0; + + boolean isRare = item.getBaseItem().getName().contains("rare"); + + if ((!item.getExtradata().isEmpty() && Integer.valueOf(item.getExtradata()) - 1 < 0) || item.getExtradata().isEmpty()) { + rarity = isRare ? InteractionMonsterPlantSeed.randomGoldenRarityLevel() : InteractionMonsterPlantSeed.randomRarityLevel(); + } + else { + try { + rarity = Integer.valueOf(item.getExtradata()) - 1; + } catch (Exception e) { + } + } + MonsterplantPet pet = Emulator.getGameEnvironment().getPetManager().createMonsterplant(room, this.client.getHabbo(), isRare, room.getLayout().getTile(item.getX(), item.getY()), rarity); + room.sendComposer(new RemoveFloorItemComposer(item, true).compose()); + room.removeHabboItem(item); + room.updateTile(room.getLayout().getTile(item.getX(), item.getY())); + room.placePet(pet, item.getX(), item.getY(), item.getZ(), item.getRotation()); + pet.cycle(); + room.sendComposer(new RoomUserStatusComposer(pet.getRoomUnit()).compose()); + return; + } + + if ( + (item.getBaseItem().getName().equalsIgnoreCase("val11_present") || + item.getBaseItem().getName().equalsIgnoreCase("gnome_box") || + item.getBaseItem().getName().equalsIgnoreCase("leprechaun_box") || + item.getBaseItem().getName().equalsIgnoreCase("velociraptor_egg") || + item.getBaseItem().getName().equalsIgnoreCase("pterosaur_egg") || + item.getBaseItem().getName().equalsIgnoreCase("petbox_epic")) && room.getCurrentPets().size() < Room.MAXIMUM_PETS) { + this.client.sendResponse(new PetPackageComposer(item)); + return; + } + + item.onClick(this.client, room, new Object[]{state}); + + if (item instanceof InteractionWired) { + this.client.getHabbo().getRoomUnit().setGoalLocation(this.client.getHabbo().getRoomUnit().getCurrentLocation()); + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/ToggleWallItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/ToggleWallItemEvent.java new file mode 100644 index 0000000..d4020ed --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/ToggleWallItemEvent.java @@ -0,0 +1,40 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.Event; +import com.eu.habbo.plugin.events.furniture.FurnitureToggleEvent; + +public class ToggleWallItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + int itemId = this.packet.readInt(); + int state = this.packet.readInt(); + + HabboItem item = room.getHabboItem(itemId); + + if (item == null) + return; + + Event furnitureToggleEvent = new FurnitureToggleEvent(item, this.client.getHabbo(), state); + Emulator.getPluginManager().fireEvent(furnitureToggleEvent); + + if (furnitureToggleEvent.isCancelled()) + return; + + if (item.getBaseItem().getName().equalsIgnoreCase("poster")) + return; + + item.needsUpdate(true); + item.onClick(this.client, room, new Object[]{state}); + room.updateItem(item); + Emulator.getThreading().run(item); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/TriggerColorWheelEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/TriggerColorWheelEvent.java new file mode 100644 index 0000000..58df4ab --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/TriggerColorWheelEvent.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.habbohotel.items.interactions.InteractionColorWheel; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class TriggerColorWheelEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + HabboItem item = room.getHabboItem(itemId); + + if (item instanceof InteractionColorWheel) { + item.onClick(this.client, room, null); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/TriggerDiceEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/TriggerDiceEvent.java new file mode 100644 index 0000000..bc5c91c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/TriggerDiceEvent.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.habbohotel.items.interactions.InteractionDice; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomLayout; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class TriggerDiceEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) { + return; + } + + HabboItem item = room.getHabboItem(itemId); + + if (item != null) { + if (item instanceof InteractionDice) { + if (RoomLayout.tilesAdjecent(room.getLayout().getTile(item.getX(), item.getY()), this.client.getHabbo().getRoomUnit().getCurrentLocation())) { + item.onClick(this.client, room, new Object[]{}); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/TriggerOneWayGateEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/TriggerOneWayGateEvent.java new file mode 100644 index 0000000..04c9bfd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/TriggerOneWayGateEvent.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.habbohotel.items.interactions.InteractionOneWayGate; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class TriggerOneWayGateEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() == null) + return; + + int itemId = this.packet.readInt(); + HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId); + + if (item == null) + return; + + if (item instanceof InteractionOneWayGate) { + if (!item.getExtradata().equals("0") || this.client.getHabbo().getRoomUnit().isTeleporting) + return; + + item.onClick(this.client, this.client.getHabbo().getHabboInfo().getCurrentRoom(), null); + } + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/UseRandomStateItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/UseRandomStateItemEvent.java new file mode 100644 index 0000000..4dc0b88 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/UseRandomStateItemEvent.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.incoming.rooms.items; + +import com.eu.habbo.habbohotel.items.interactions.InteractionRandomState; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class UseRandomStateItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + try { + int itemId = this.packet.readInt(); + int state = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + HabboItem item = room.getHabboItem(itemId); + + if (item == null || !(item instanceof InteractionRandomState)) + return; + + InteractionRandomState randomStateItem = (InteractionRandomState)item; + randomStateItem.onRandomStateClick(this.client, room); + } catch (Exception e) { + log.error("Caught exception", e); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxAddSoundTrackEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxAddSoundTrackEvent.java new file mode 100644 index 0000000..4934e1c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxAddSoundTrackEvent.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.incoming.rooms.items.jukebox; + +import com.eu.habbo.habbohotel.items.interactions.InteractionMusicDisc; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class JukeBoxAddSoundTrackEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (!this.client.getHabbo().getHabboInfo().getCurrentRoom().hasRights(this.client.getHabbo())) return; + + int itemId = this.packet.readInt(); + int slotId = this.packet.readInt(); + + Habbo habbo = this.client.getHabbo(); + + if (habbo != null) { + HabboItem item = habbo.getInventory().getItemsComponent().getHabboItem(itemId); + + if (item instanceof InteractionMusicDisc && item.getRoomId() == 0) { + this.client.getHabbo().getHabboInfo().getCurrentRoom().getTraxManager().addSong((InteractionMusicDisc) item, habbo); + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxEventOne.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxEventOne.java new file mode 100644 index 0000000..ad2929f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxEventOne.java @@ -0,0 +1,16 @@ +package com.eu.habbo.messages.incoming.rooms.items.jukebox; + +import com.eu.habbo.habbohotel.rooms.TraxManager; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.items.jukebox.JukeBoxMySongsComposer; +import com.eu.habbo.messages.outgoing.rooms.items.jukebox.JukeBoxPlayListComposer; + +public class JukeBoxEventOne extends MessageHandler { + @Override + public void handle() throws Exception { + TraxManager traxManager = this.client.getHabbo().getHabboInfo().getCurrentRoom().getTraxManager(); + this.client.sendResponse(new JukeBoxPlayListComposer(traxManager.getSongs(), traxManager.totalLength())); + this.client.sendResponse(new JukeBoxMySongsComposer(traxManager.myList(this.client.getHabbo()))); + this.client.getHabbo().getHabboInfo().getCurrentRoom().getTraxManager().updateCurrentPlayingSong(this.client.getHabbo()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxEventTwo.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxEventTwo.java new file mode 100644 index 0000000..15c53b0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxEventTwo.java @@ -0,0 +1,16 @@ +package com.eu.habbo.messages.incoming.rooms.items.jukebox; + +import com.eu.habbo.habbohotel.rooms.TraxManager; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.items.jukebox.JukeBoxMySongsComposer; +import com.eu.habbo.messages.outgoing.rooms.items.jukebox.JukeBoxPlayListComposer; + +public class JukeBoxEventTwo extends MessageHandler { + @Override + public void handle() throws Exception { + TraxManager traxManager = this.client.getHabbo().getHabboInfo().getCurrentRoom().getTraxManager(); + this.client.sendResponse(new JukeBoxPlayListComposer(traxManager.getSongs(), traxManager.totalLength())); + this.client.sendResponse(new JukeBoxMySongsComposer(traxManager.myList(this.client.getHabbo()))); + this.client.getHabbo().getHabboInfo().getCurrentRoom().getTraxManager().updateCurrentPlayingSong(this.client.getHabbo()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxRemoveSoundTrackEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxRemoveSoundTrackEvent.java new file mode 100644 index 0000000..0c63186 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxRemoveSoundTrackEvent.java @@ -0,0 +1,17 @@ +package com.eu.habbo.messages.incoming.rooms.items.jukebox; + +import com.eu.habbo.habbohotel.items.interactions.InteractionMusicDisc; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class JukeBoxRemoveSoundTrackEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int index = this.packet.readInt(); + + InteractionMusicDisc musicDisc = this.client.getHabbo().getHabboInfo().getCurrentRoom().getTraxManager().getSongs().get(index); + + if (musicDisc != null) { + this.client.getHabbo().getHabboInfo().getCurrentRoom().getTraxManager().removeSong(musicDisc.getId()); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxRequestPlayListEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxRequestPlayListEvent.java new file mode 100644 index 0000000..7b04f1a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/jukebox/JukeBoxRequestPlayListEvent.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.incoming.rooms.items.jukebox; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.TraxManager; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.items.jukebox.JukeBoxMySongsComposer; +import com.eu.habbo.messages.outgoing.rooms.items.jukebox.JukeBoxPlayListComposer; + +public class JukeBoxRequestPlayListEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + if(room == null) { + return; + } + TraxManager traxManager = room.getTraxManager(); + this.client.sendResponse(new JukeBoxPlayListComposer(traxManager.getSongs(), traxManager.totalLength())); + this.client.sendResponse(new JukeBoxMySongsComposer(traxManager.myList(this.client.getHabbo()))); + room.getTraxManager().updateCurrentPlayingSong(this.client.getHabbo()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/lovelock/LoveLockStartConfirmEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/lovelock/LoveLockStartConfirmEvent.java new file mode 100644 index 0000000..d4588cd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/lovelock/LoveLockStartConfirmEvent.java @@ -0,0 +1,48 @@ +package com.eu.habbo.messages.incoming.rooms.items.lovelock; + +import com.eu.habbo.habbohotel.items.interactions.InteractionLoveLock; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.items.lovelock.LoveLockFurniFinishedComposer; +import com.eu.habbo.messages.outgoing.rooms.items.lovelock.LoveLockFurniFriendConfirmedComposer; + +public class LoveLockStartConfirmEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + if (this.packet.readBoolean()) { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() == null) + return; + + HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId); + + if (item == null) + return; + + if (item instanceof InteractionLoveLock) { + int userId = 0; + + if (((InteractionLoveLock) item).userOneId == this.client.getHabbo().getHabboInfo().getId() && ((InteractionLoveLock) item).userTwoId != 0) { + userId = ((InteractionLoveLock) item).userTwoId; + } else if (((InteractionLoveLock) item).userOneId != 0 && ((InteractionLoveLock) item).userTwoId == this.client.getHabbo().getHabboInfo().getId()) { + userId = ((InteractionLoveLock) item).userOneId; + } + + if (userId > 0) { + Habbo habbo = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabbo(userId); + + if (habbo != null) { + habbo.getClient().sendResponse(new LoveLockFurniFriendConfirmedComposer((InteractionLoveLock) item)); + + habbo.getClient().sendResponse(new LoveLockFurniFinishedComposer((InteractionLoveLock) item)); + this.client.sendResponse(new LoveLockFurniFinishedComposer((InteractionLoveLock) item)); + + ((InteractionLoveLock) item).lock(habbo, this.client.getHabbo(), this.client.getHabbo().getHabboInfo().getCurrentRoom()); + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/rentablespace/RentSpaceCancelEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/rentablespace/RentSpaceCancelEvent.java new file mode 100644 index 0000000..bc6bd3d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/rentablespace/RentSpaceCancelEvent.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.incoming.rooms.items.rentablespace; + +import com.eu.habbo.habbohotel.items.interactions.InteractionRentableSpace; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class RentSpaceCancelEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + HabboItem item = room.getHabboItem(itemId); + + if (room.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || + this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER)) { + if (item instanceof InteractionRentableSpace) { + ((InteractionRentableSpace) item).endRent(); + + room.updateItem(item); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/rentablespace/RentSpaceEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/rentablespace/RentSpaceEvent.java new file mode 100644 index 0000000..1df3bd2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/rentablespace/RentSpaceEvent.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.incoming.rooms.items.rentablespace; + +import com.eu.habbo.habbohotel.items.interactions.InteractionRentableSpace; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class RentSpaceEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + HabboItem item = room.getHabboItem(itemId); + + if (!(item instanceof InteractionRentableSpace)) + return; + + ((InteractionRentableSpace) item).rent(this.client.getHabbo()); + + room.updateItem(item); + + ((InteractionRentableSpace) item).sendRentWidget(this.client.getHabbo()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestPlaylistChange.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestPlaylistChange.java new file mode 100644 index 0000000..3a367df --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestPlaylistChange.java @@ -0,0 +1,55 @@ +package com.eu.habbo.messages.incoming.rooms.items.youtube; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.YoutubeManager; +import com.eu.habbo.habbohotel.items.interactions.InteractionYoutubeTV; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.items.youtube.YoutubeVideoComposer; +import com.eu.habbo.threading.runnables.YoutubeAdvanceVideo; + +import java.util.Optional; + +public class YoutubeRequestPlaylistChange extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + String playlistId = this.packet.readString(); + + Habbo habbo = this.client.getHabbo(); + + if (habbo == null) return; + + + Room room = habbo.getHabboInfo().getCurrentRoom(); + + if (room == null) return; + if (!room.isOwner(habbo) && !habbo.hasPermission(Permission.ACC_ANYROOMOWNER)) return; + + + HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId); + + if (item == null || !(item instanceof InteractionYoutubeTV)) return; + + Optional playlist = Emulator.getGameEnvironment().getItemManager().getYoutubeManager().getPlaylistsForItemId(item.getBaseItem().getId()).stream().filter(p -> p.getId().equals(playlistId)).findAny(); + + if (playlist.isPresent()) { + YoutubeManager.YoutubeVideo video = playlist.get().getVideos().get(0); + if (video == null) return; + + ((InteractionYoutubeTV) item).currentVideo = video; + ((InteractionYoutubeTV) item).currentPlaylist = playlist.get(); + + ((InteractionYoutubeTV) item).cancelAdvancement(); + + room.updateItem(item); + room.sendComposer(new YoutubeVideoComposer(itemId, video, true, 0).compose()); + ((InteractionYoutubeTV) item).autoAdvance = Emulator.getThreading().run(new YoutubeAdvanceVideo((InteractionYoutubeTV) item), video.getDuration() * 1000); + + item.needsUpdate(true); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestPlaylists.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestPlaylists.java new file mode 100644 index 0000000..9f855bd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestPlaylists.java @@ -0,0 +1,40 @@ +package com.eu.habbo.messages.incoming.rooms.items.youtube; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.YoutubeManager; +import com.eu.habbo.habbohotel.items.interactions.InteractionYoutubeTV; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.handshake.ConnectionErrorComposer; +import com.eu.habbo.messages.outgoing.rooms.items.youtube.YoutubeDisplayListComposer; +import lombok.extern.slf4j.Slf4j; + + +import java.util.ArrayList; + +@Slf4j +public class YoutubeRequestPlaylists extends MessageHandler { + + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) { + HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId); + + if (item instanceof InteractionYoutubeTV) { + InteractionYoutubeTV tv = (InteractionYoutubeTV) item; + + ArrayList playlists = Emulator.getGameEnvironment().getItemManager().getYoutubeManager().getPlaylistsForItemId(item.getBaseItem().getId()); + + if (playlists == null) { + log.error("No YouTube playlists set for base item #" + item.getBaseItem().getId()); + this.client.sendResponse(new ConnectionErrorComposer(1000)); + return; + } + + this.client.sendResponse(new YoutubeDisplayListComposer(itemId, playlists, tv.currentPlaylist)); + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestStateChange.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestStateChange.java new file mode 100644 index 0000000..b9010e5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestStateChange.java @@ -0,0 +1,109 @@ +package com.eu.habbo.messages.incoming.rooms.items.youtube; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionYoutubeTV; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.items.youtube.YoutubeStateChangeComposer; +import com.eu.habbo.messages.outgoing.rooms.items.youtube.YoutubeVideoComposer; +import com.eu.habbo.threading.runnables.YoutubeAdvanceVideo; + +public class YoutubeRequestStateChange extends MessageHandler { + public enum YoutubeState { + PREVIOUS(0), + NEXT(1), + PAUSE(2), + RESUME(3); + + private int state; + + YoutubeState(int state) { + this.state = state; + } + + public int getState() { + return state; + } + + public static YoutubeState getByState(int state) { + switch (state) { + case 0: + return PREVIOUS; + case 1: + return NEXT; + case 2: + return PAUSE; + case 3: + return RESUME; + default: + return null; + } + } + } + + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + YoutubeState state = YoutubeState.getByState(this.packet.readInt()); + + if (state == null) return; + + Habbo habbo = this.client.getHabbo(); + + if (habbo == null) return; + + + Room room = habbo.getHabboInfo().getCurrentRoom(); + + if (room == null) return; + if (!room.isOwner(habbo) && !habbo.hasPermission(Permission.ACC_ANYROOMOWNER)) return; + + + HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId); + + if (!(item instanceof InteractionYoutubeTV)) return; + + InteractionYoutubeTV tv = (InteractionYoutubeTV) item; + + if(tv.currentPlaylist == null || tv.currentPlaylist.getVideos().isEmpty()) return; + + switch (state) { + case PAUSE: + tv.playing = false; + tv.offset += Emulator.getIntUnixTimestamp() - tv.startedWatchingAt; + if (tv.autoAdvance != null) tv.autoAdvance.cancel(true); + room.sendComposer(new YoutubeStateChangeComposer(tv.getId(), 2).compose()); + break; + case RESUME: + tv.playing = true; + tv.startedWatchingAt = Emulator.getIntUnixTimestamp(); + tv.autoAdvance = Emulator.getThreading().run(new YoutubeAdvanceVideo(tv), (tv.currentVideo.getDuration() - tv.offset) * 1000); + room.sendComposer(new YoutubeStateChangeComposer(tv.getId(), 1).compose()); + break; + case PREVIOUS: + int previousIndex = tv.currentPlaylist.getVideos().indexOf(tv.currentVideo) - 1; + if (previousIndex < 0) previousIndex = tv.currentPlaylist.getVideos().size() - 1; + tv.currentVideo = tv.currentPlaylist.getVideos().get(previousIndex); + break; + case NEXT: + int nextIndex = tv.currentPlaylist.getVideos().indexOf(tv.currentVideo) + 1; + if (nextIndex >= tv.currentPlaylist.getVideos().size()) nextIndex = 0; + tv.currentVideo = tv.currentPlaylist.getVideos().get(nextIndex); + break; + } + + if (state == YoutubeState.PREVIOUS || state == YoutubeState.NEXT) { + room.sendComposer(new YoutubeVideoComposer(tv.getId(), tv.currentVideo, true, 0).compose()); + + tv.cancelAdvancement(); + tv.autoAdvance = Emulator.getThreading().run(new YoutubeAdvanceVideo(tv), tv.currentVideo.getDuration() * 1000); + tv.startedWatchingAt = Emulator.getIntUnixTimestamp(); + tv.offset = 0; + tv.playing = true; + room.updateItem(tv); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/BreedMonsterplantsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/BreedMonsterplantsEvent.java new file mode 100644 index 0000000..9ce4441 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/BreedMonsterplantsEvent.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.incoming.rooms.pets; + +import com.eu.habbo.habbohotel.pets.MonsterplantPet; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class BreedMonsterplantsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int unknownInt = this.packet.readInt(); //Something state. 2 = accept + + if (unknownInt == 0) { + Pet petOne = this.client.getHabbo().getHabboInfo().getCurrentRoom().getPet(this.packet.readInt()); + Pet petTwo = this.client.getHabbo().getHabboInfo().getCurrentRoom().getPet(this.packet.readInt()); + + if (petOne == null || petTwo == null || petOne == petTwo) { + //TODO Add error + return; + } + + if (petOne instanceof MonsterplantPet && petTwo instanceof MonsterplantPet) { + ((MonsterplantPet) petOne).breed((MonsterplantPet) petTwo); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/CompostMonsterplantEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/CompostMonsterplantEvent.java new file mode 100644 index 0000000..e900667 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/CompostMonsterplantEvent.java @@ -0,0 +1,55 @@ +package com.eu.habbo.messages.incoming.rooms.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.pets.MonsterplantPet; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.items.AddFloorItemComposer; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class CompostMonsterplantEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + int petId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + Pet pet = room.getPet(petId); + + if (pet != null) { + if (pet instanceof MonsterplantPet) { + if (pet.getUserId() == this.client.getHabbo().getHabboInfo().getId()) { + if (((MonsterplantPet) pet).isDead()) { + Item baseItem = Emulator.getGameEnvironment().getItemManager().getItem("mnstr_compost"); + + if (baseItem != null) { + HabboItem compost = Emulator.getGameEnvironment().getItemManager().createItem(pet.getUserId(), baseItem, 0, 0, ""); + compost.setX(pet.getRoomUnit().getX()); + compost.setY(pet.getRoomUnit().getY()); + compost.setZ(pet.getRoomUnit().getZ()); + compost.setRotation(pet.getRoomUnit().getBodyRotation().getValue()); + room.addHabboItem(compost); + room.sendComposer(new AddFloorItemComposer(compost, this.client.getHabbo().getHabboInfo().getUsername()).compose()); + } + + pet.removeFromRoom(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM users_pets WHERE id = ? LIMIT 1")) { + statement.setInt(1, pet.getId()); + statement.executeUpdate(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/ConfirmPetBreedingEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/ConfirmPetBreedingEvent.java new file mode 100644 index 0000000..13a1e20 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/ConfirmPetBreedingEvent.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.incoming.rooms.pets; + +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetBreedingNest; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class ConfirmPetBreedingEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + String name = this.packet.readString(); + int petOneId = this.packet.readInt(); + int petTwoId = this.packet.readInt(); + + HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId); + + if (item instanceof InteractionPetBreedingNest) { + ((InteractionPetBreedingNest) item).breed(this.client.getHabbo(), name, petOneId, petTwoId); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/HorseRemoveSaddleEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/HorseRemoveSaddleEvent.java new file mode 100644 index 0000000..06344f9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/HorseRemoveSaddleEvent.java @@ -0,0 +1,65 @@ +package com.eu.habbo.messages.incoming.rooms.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.pets.HorsePet; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.rooms.pets.RoomPetHorseFigureComposer; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class HorseRemoveSaddleEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + Pet pet = room.getPet(this.packet.readInt()); + + if (pet == null || !(pet instanceof HorsePet) || pet.getUserId() != this.client.getHabbo().getHabboInfo().getId()) return; + + HorsePet horse = (HorsePet) pet; + + if (!horse.hasSaddle()) return; + + int saddleItemId = horse.getSaddleItemId(); + + if (saddleItemId == 0) { // backwards compatibility: horses could be missing the saddle item ID + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT id FROM items_base WHERE item_name LIKE 'horse_saddle%' LIMIT 1")) { + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + saddleItemId = set.getInt("id"); + } else { + log.error("There is no viable fallback saddle item for old horses with no saddle item ID. Horse pet ID: " + horse.getId()); + return; + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + Item saddleItem = Emulator.getGameEnvironment().getItemManager().getItem(saddleItemId); + + if (saddleItem == null) return; + + horse.hasSaddle(false); + horse.needsUpdate = true; + Emulator.getThreading().run(pet); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomPetHorseFigureComposer(horse).compose()); + + HabboItem saddle = Emulator.getGameEnvironment().getItemManager().createItem(this.client.getHabbo().getHabboInfo().getId(), saddleItem, 0, 0, ""); + + this.client.getHabbo().getInventory().getItemsComponent().addItem(saddle); + + this.client.sendResponse(new AddHabboItemComposer(saddle)); + this.client.sendResponse(new InventoryRefreshComposer()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/MovePetEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/MovePetEvent.java new file mode 100644 index 0000000..2038450 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/MovePetEvent.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.incoming.rooms.pets; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; + +public class MovePetEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Pet pet = this.client.getHabbo().getHabboInfo().getCurrentRoom().getPet(this.packet.readInt()); + + if (pet != null) { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + if (room != null && room.hasRights(this.client.getHabbo())) { + if (pet.getRoomUnit() != null) { + int x = this.packet.readInt(); + int y = this.packet.readInt(); + + RoomTile tile = room.getLayout().getTile((short) x, (short) y); + + if (tile != null) { + pet.getRoomUnit().setLocation(tile); + pet.getRoomUnit().setPreviousLocation(tile); + pet.getRoomUnit().setZ(tile.z); + pet.getRoomUnit().setRotation(RoomUserRotation.fromValue(this.packet.readInt())); + pet.getRoomUnit().setPreviousLocationZ(pet.getRoomUnit().getZ()); + room.sendComposer(new RoomUserStatusComposer(pet.getRoomUnit()).compose()); + pet.needsUpdate = true; + } + } + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetPackageNameEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetPackageNameEvent.java new file mode 100644 index 0000000..9fa2f4c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetPackageNameEvent.java @@ -0,0 +1,81 @@ +package com.eu.habbo.messages.incoming.rooms.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.AlertPurchaseFailedComposer; +import com.eu.habbo.messages.outgoing.rooms.UpdateStackHeightComposer; +import com.eu.habbo.messages.outgoing.rooms.items.RemoveFloorItemComposer; +import com.eu.habbo.messages.outgoing.rooms.pets.PetPackageNameValidationComposer; +import com.eu.habbo.threading.runnables.QueryDeleteHabboItem; + +public class PetPackageNameEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + String name = this.packet.readString(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + HabboItem item = room.getHabboItem(itemId); + if (item != null) { + if (item.getUserId() == this.client.getHabbo().getHabboInfo().getId()) { + if (name.matches("^[a-zA-Z0-9]*$")) { + Pet pet = null; + + if (item.getBaseItem().getName().equalsIgnoreCase("val11_present")) { + pet = Emulator.getGameEnvironment().getPetManager().createPet(11, name, this.client); + } + + if (item.getBaseItem().getName().equalsIgnoreCase("gnome_box")) { + pet = Emulator.getGameEnvironment().getPetManager().createGnome(name, room, this.client.getHabbo()); + } + + if (item.getBaseItem().getName().equalsIgnoreCase("leprechaun_box")) { + pet = Emulator.getGameEnvironment().getPetManager().createLeprechaun(name, room, this.client.getHabbo()); + } + + if (item.getBaseItem().getName().equalsIgnoreCase("velociraptor_egg")) { + pet = Emulator.getGameEnvironment().getPetManager().createPet(34, name, this.client); + } + + if (item.getBaseItem().getName().equalsIgnoreCase("pterosaur_egg")) { + pet = Emulator.getGameEnvironment().getPetManager().createPet(33, name, this.client); + } + + if (item.getBaseItem().getName().equalsIgnoreCase("petbox_epic")) { + pet = Emulator.getGameEnvironment().getPetManager().createPet(32, name, this.client); + } + + if (pet != null) { + room.placePet(pet, item.getX(), item.getY(), item.getZ(), item.getRotation()); + pet.setUserId(this.client.getHabbo().getHabboInfo().getId()); + pet.needsUpdate = true; + pet.getRoomUnit().setLocation(room.getLayout().getTile(item.getX(), item.getY())); + pet.getRoomUnit().setZ(item.getZ()); + Emulator.getThreading().run(new QueryDeleteHabboItem(item.getId())); + room.removeHabboItem(item); + room.sendComposer(new RemoveFloorItemComposer(item).compose()); + RoomTile tile = room.getLayout().getTile(item.getX(), item.getY()); + room.updateTile(room.getLayout().getTile(item.getX(), item.getY())); + room.sendComposer(new UpdateStackHeightComposer(tile.x, tile.y, tile.z, tile.relativeHeight()).compose()); + item.setUserId(0); + } else { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + } + } else { + this.client.sendResponse(new PetPackageNameValidationComposer(itemId, PetPackageNameValidationComposer.CONTAINS_INVALID_CHARS, name.replaceAll("^[a-zA-Z0-9]*$", ""))); + return; + } + } + } + } + + + this.client.sendResponse(new PetPackageNameValidationComposer(itemId, PetPackageNameValidationComposer.CLOSE_WIDGET, "")); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetPickupEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetPickupEvent.java new file mode 100644 index 0000000..211375c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetPickupEvent.java @@ -0,0 +1,56 @@ +package com.eu.habbo.messages.incoming.rooms.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.permissions.Permission; +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.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.inventory.AddPetComposer; + +public class PetPickupEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int petId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + Pet pet = room.getPet(petId); + + if (pet != null) { + if (this.client.getHabbo().getHabboInfo().getId() == pet.getId() || room.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER)) { + if (!this.client.getHabbo().hasPermission(Permission.ACC_UNLIMITED_PETS) && this.client.getHabbo().getInventory().getPetsComponent().getPets().size() >= PetManager.MAXIMUM_PET_INVENTORY_SIZE) { + this.client.getHabbo().alert(Emulator.getTexts().getValue("error.pets.max.inventory").replace("%amount%", PetManager.MAXIMUM_PET_INVENTORY_SIZE + "")); + return; + } + + if (pet instanceof RideablePet) { + RideablePet rideablePet = (RideablePet) pet; + if (rideablePet.getRider() != null) { + rideablePet.getRider().getHabboInfo().dismountPet(true); + } + } + + pet.removeFromRoom(); + Emulator.getThreading().run(pet); + + if (this.client.getHabbo().getHabboInfo().getId() == pet.getUserId()) { + this.client.sendResponse(new AddPetComposer(pet)); + this.client.getHabbo().getInventory().getPetsComponent().addPet(pet); + } else { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(pet.getUserId()); + + if (habbo != null) { + habbo.getClient().sendResponse(new AddPetComposer(pet)); + habbo.getInventory().getPetsComponent().addPet(pet); + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetPlaceEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetPlaceEvent.java new file mode 100644 index 0000000..2af5c3a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetPlaceEvent.java @@ -0,0 +1,93 @@ +package com.eu.habbo.messages.incoming.rooms.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.generic.alerts.PetErrorComposer; +import com.eu.habbo.messages.outgoing.inventory.RemovePetComposer; +import com.eu.habbo.messages.outgoing.rooms.pets.RoomPetComposer; + +public class PetPlaceEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + if (this.client.getHabbo().getHabboInfo().getId() != room.getOwnerId() && !room.isAllowPets() && !(this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER) || this.client.getHabbo().hasPermission(Permission.ACC_PLACEFURNI))) { + this.client.sendResponse(new PetErrorComposer(PetErrorComposer.ROOM_ERROR_PETS_FORBIDDEN_IN_FLAT)); + return; + } + + int petId = this.packet.readInt(); + + Pet pet = this.client.getHabbo().getInventory().getPetsComponent().getPet(petId); + + if (pet == null) { + return; + } + if (room.getCurrentPets().size() >= Room.MAXIMUM_PETS && !this.client.getHabbo().hasPermission(Permission.ACC_UNLIMITED_PETS)) { + this.client.sendResponse(new PetErrorComposer(PetErrorComposer.ROOM_ERROR_MAX_PETS)); + return; + } + + int x = this.packet.readInt(); + int y = this.packet.readInt(); + + RoomTile tile; + RoomTile playerTile = this.client.getHabbo().getRoomUnit().getCurrentLocation(); + + if ((x == 0 && y == 0) || !room.isOwner(this.client.getHabbo())) { + //Place the pet in front of the player. + tile = room.getLayout().getTileInFront(this.client.getHabbo().getRoomUnit().getCurrentLocation(), this.client.getHabbo().getRoomUnit().getBodyRotation().getValue()); + + if (tile == null || !tile.isWalkable()) { + this.client.sendResponse(new PetErrorComposer(PetErrorComposer.ROOM_ERROR_PETS_NO_FREE_TILES)); + } + + //Check if tile exists and is walkable. Else place it in the current location the Habbo is standing. + if (tile == null || !tile.isWalkable()) { + tile = playerTile; + + //If the current tile is not walkable, place it at the door. + if (tile == null || !tile.isWalkable()) { + tile = room.getLayout().getDoorTile(); + } + } + } else { + tile = room.getLayout().getTile((short) x, (short) y); + } + + if (tile == null || !tile.isWalkable() || !tile.getAllowStack()) { + this.client.sendResponse(new PetErrorComposer(PetErrorComposer.ROOM_ERROR_PETS_SELECTED_TILE_NOT_FREE)); + return; + } + + pet.setRoom(room); + RoomUnit roomUnit = pet.getRoomUnit(); + + if (roomUnit == null) { + roomUnit = new RoomUnit(); + } + + roomUnit.setPathFinderRoom(room); + + roomUnit.setLocation(tile); + roomUnit.setZ(tile.getStackHeight()); + roomUnit.setStatus(RoomUnitStatus.SIT, "0"); + roomUnit.setRoomUnitType(RoomUnitType.PET); + if (playerTile != null) { + roomUnit.lookAtPoint(playerTile); + } + pet.setRoomUnit(roomUnit); + room.addPet(pet); + pet.needsUpdate = true; + Emulator.getThreading().run(pet); + room.sendComposer(new RoomPetComposer(pet).compose()); + this.client.getHabbo().getInventory().getPetsComponent().removePet(pet); + this.client.sendResponse(new RemovePetComposer(pet)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetRideEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetRideEvent.java new file mode 100644 index 0000000..fd3a315 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetRideEvent.java @@ -0,0 +1,57 @@ +package com.eu.habbo.messages.incoming.rooms.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.RideablePet; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.threading.runnables.RoomUnitRidePet; + +import java.util.List; + +public class PetRideEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int petId = this.packet.readInt(); + Habbo habbo = this.client.getHabbo(); + Room room = habbo.getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + Pet pet = room.getPet(petId); + + if (!(pet instanceof RideablePet)) + return; + + RideablePet rideablePet = (RideablePet) pet; + + //dismount + if (habbo.getHabboInfo().getRiding() != null) { + habbo.getHabboInfo().dismountPet(); + return; + } + + // someone is already on it + if (rideablePet.getRider() != null) + return; + + // check if able to ride + if (!rideablePet.anyoneCanRide() && habbo.getHabboInfo().getId() != rideablePet.getUserId()) + return; + + List availableTiles = room.getLayout().getWalkableTilesAround(pet.getRoomUnit().getCurrentLocation()); + + // if cant reach it then cancel + if (availableTiles.isEmpty()) + return; + + RoomTile goalTile = availableTiles.get(0); + habbo.getRoomUnit().setGoalLocation(goalTile); + Emulator.getThreading().run(new RoomUnitRidePet(rideablePet, habbo, goalTile)); + rideablePet.getRoomUnit().setWalkTimeOut(3 + Emulator.getIntUnixTimestamp()); + rideablePet.getRoomUnit().stopWalking(); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetRideSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetRideSettingsEvent.java new file mode 100644 index 0000000..791a628 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetRideSettingsEvent.java @@ -0,0 +1,35 @@ +package com.eu.habbo.messages.incoming.rooms.pets; + +import com.eu.habbo.habbohotel.pets.HorsePet; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.RideablePet; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.pets.RoomPetHorseFigureComposer; + +public class PetRideSettingsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int petId = this.packet.readInt(); + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() == null) + return; + + Pet pet = this.client.getHabbo().getHabboInfo().getCurrentRoom().getPet(petId); + + if (pet == null || pet.getUserId() != this.client.getHabbo().getHabboInfo().getId() || !(pet instanceof RideablePet)) + return; + + RideablePet rideablePet = ((RideablePet) pet); + + rideablePet.setAnyoneCanRide(!rideablePet.anyoneCanRide()); + rideablePet.needsUpdate = true; + + if (!rideablePet.anyoneCanRide() && rideablePet.getRider() != null && rideablePet.getRider().getHabboInfo().getId() != this.client.getHabbo().getHabboInfo().getId()) { + rideablePet.getRider().getHabboInfo().dismountPet(); + } + + if (pet instanceof HorsePet) { + this.client.sendResponse(new RoomPetHorseFigureComposer((HorsePet) pet)); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetUseItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetUseItemEvent.java new file mode 100644 index 0000000..ff31e8e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetUseItemEvent.java @@ -0,0 +1,149 @@ +package com.eu.habbo.messages.incoming.rooms.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.pets.HorsePet; +import com.eu.habbo.habbohotel.pets.MonsterplantPet; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.items.RemoveFloorItemComposer; +import com.eu.habbo.messages.outgoing.rooms.pets.PetStatusUpdateComposer; +import com.eu.habbo.messages.outgoing.rooms.pets.RoomPetHorseFigureComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import com.eu.habbo.threading.runnables.QueryDeleteHabboItem; + +public class PetUseItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + if (room == null) + return; + + HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId); + + if (item == null) + return; + + int petId = this.packet.readInt(); + Pet pet = this.client.getHabbo().getHabboInfo().getCurrentRoom().getPet(petId); + + if (pet instanceof HorsePet) { + if (item.getBaseItem().getName().toLowerCase().startsWith("horse_dye")) { + int race = Integer.valueOf(item.getBaseItem().getName().split("_")[2]); + int raceType = (race * 4) - 2; + + if (race >= 13 && race <= 17) + raceType = ((2 + race) * 4) + 1; + + if (race == 0) + raceType = 0; + + pet.setRace(raceType); + ((HorsePet) pet).needsUpdate = true; + } else if (item.getBaseItem().getName().toLowerCase().startsWith("horse_hairdye")) { + int splittedHairdye = Integer.valueOf(item.getBaseItem().getName().toLowerCase().split("_")[2]); + int newHairdye = 48; + + if (splittedHairdye == 0) { + newHairdye = -1; + } else if (splittedHairdye == 1) { + newHairdye = 1; + } else if (splittedHairdye >= 13 && splittedHairdye <= 17) { + newHairdye = 68 + splittedHairdye; + } else { + newHairdye += splittedHairdye; + } + + ((HorsePet) pet).setHairColor(newHairdye); + ((HorsePet) pet).needsUpdate = true; + } else if (item.getBaseItem().getName().toLowerCase().startsWith("horse_hairstyle")) { + int splittedHairstyle = Integer.valueOf(item.getBaseItem().getName().toLowerCase().split("_")[2]); + int newHairstyle = 100; + + if (splittedHairstyle == 0) { + newHairstyle = -1; + } else { + newHairstyle += splittedHairstyle; + } + + ((HorsePet) pet).setHairStyle(newHairstyle); + ((HorsePet) pet).needsUpdate = true; + } else if (item.getBaseItem().getName().toLowerCase().startsWith("horse_saddle")) { + ((HorsePet) pet).hasSaddle(true); + ((HorsePet) pet).setSaddleItemId(item.getBaseItem().getId()); + ((HorsePet) pet).needsUpdate = true; + } + + if (((HorsePet) pet).needsUpdate) { + Emulator.getThreading().run(pet); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomPetHorseFigureComposer((HorsePet) pet).compose()); + + room.removeHabboItem(item); + room.sendComposer(new RemoveFloorItemComposer(item, true).compose()); + item.setRoomId(0); + Emulator.getGameEnvironment().getItemManager().deleteItem(item); + } + } else if (pet instanceof MonsterplantPet) { + if (item.getBaseItem().getName().equalsIgnoreCase("mnstr_revival")) { + if (((MonsterplantPet) pet).isDead()) { + ((MonsterplantPet) pet).setDeathTimestamp(Emulator.getIntUnixTimestamp() + MonsterplantPet.timeToLive); + pet.getRoomUnit().clearStatus(); + pet.getRoomUnit().setStatus(RoomUnitStatus.GESTURE, "rev"); + ((MonsterplantPet) pet).packetUpdate = true; + + this.client.getHabbo().getHabboInfo().getCurrentRoom().removeHabboItem(item); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RemoveFloorItemComposer(item).compose()); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserStatusComposer(pet.getRoomUnit()).compose()); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new PetStatusUpdateComposer(pet).compose()); + this.client.getHabbo().getHabboInfo().getCurrentRoom().updateTiles(room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation())); + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("MonsterPlantHealer")); + pet.getRoomUnit().removeStatus(RoomUnitStatus.GESTURE); + Emulator.getThreading().run(new QueryDeleteHabboItem(item.getId())); + } + } else if (item.getBaseItem().getName().equalsIgnoreCase("mnstr_fert")) { + if (!((MonsterplantPet) pet).isFullyGrown()) { + pet.setCreated(pet.getCreated() - MonsterplantPet.growTime); + pet.getRoomUnit().clearStatus(); + pet.cycle(); + pet.getRoomUnit().setStatus(RoomUnitStatus.GESTURE, "spd"); + pet.getRoomUnit().setStatus(RoomUnitStatus.fromString("grw" + ((MonsterplantPet) pet).getGrowthStage()), ""); + this.client.getHabbo().getHabboInfo().getCurrentRoom().removeHabboItem(item); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RemoveFloorItemComposer(item).compose()); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserStatusComposer(pet.getRoomUnit()).compose()); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new PetStatusUpdateComposer(pet).compose()); + this.client.getHabbo().getHabboInfo().getCurrentRoom().updateTiles(room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation())); + pet.getRoomUnit().removeStatus(RoomUnitStatus.GESTURE); + pet.cycle(); + Emulator.getThreading().run(new QueryDeleteHabboItem(item.getId())); + } + } else if (item.getBaseItem().getName().startsWith("mnstr_rebreed")) { + if (((MonsterplantPet) pet).isFullyGrown() && !((MonsterplantPet) pet).canBreed()) { + if ( + (item.getBaseItem().getName().equalsIgnoreCase("mnstr_rebreed") && ((MonsterplantPet) pet).getRarity() <= 5) || + (item.getBaseItem().getName().equalsIgnoreCase("mnstr_rebreed_2") && ((MonsterplantPet) pet).getRarity() >= 6 && ((MonsterplantPet) pet).getRarity() <= 8) || + (item.getBaseItem().getName().equalsIgnoreCase("mnstr_rebreed_3") && ((MonsterplantPet) pet).getRarity() >= 9) + ) + + { + ((MonsterplantPet) pet).setCanBreed(true); + pet.getRoomUnit().clearStatus(); + pet.getRoomUnit().setStatus(RoomUnitStatus.GESTURE, "reb"); + + this.client.getHabbo().getHabboInfo().getCurrentRoom().removeHabboItem(item); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RemoveFloorItemComposer(item).compose()); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserStatusComposer(pet.getRoomUnit()).compose()); + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new PetStatusUpdateComposer(pet).compose()); + this.client.getHabbo().getHabboInfo().getCurrentRoom().updateTiles(room.getLayout().getTilesAt(room.getLayout().getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation())); + pet.getRoomUnit().removeStatus(RoomUnitStatus.GESTURE); + Emulator.getThreading().run(new QueryDeleteHabboItem(item.getId())); + } + } + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/RequestPetInformationEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/RequestPetInformationEvent.java new file mode 100644 index 0000000..e1d8688 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/RequestPetInformationEvent.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.incoming.rooms.pets; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.pets.PetInformationComposer; + +public class RequestPetInformationEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int petId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + Pet pet = room.getPet(petId); + + if (pet != null) { + this.client.sendResponse(new PetInformationComposer(pet, room, this.client.getHabbo())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/RequestPetTrainingPanelEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/RequestPetTrainingPanelEvent.java new file mode 100644 index 0000000..bac9fd2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/RequestPetTrainingPanelEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.incoming.rooms.pets; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.pets.PetTrainingPanelComposer; + +public class RequestPetTrainingPanelEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int petId = this.packet.readInt(); + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() == null) + return; + + Pet pet = this.client.getHabbo().getHabboInfo().getCurrentRoom().getPet(petId); + + if (pet != null) + this.client.sendResponse(new PetTrainingPanelComposer(pet)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/ScratchPetEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/ScratchPetEvent.java new file mode 100644 index 0000000..501b690 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/ScratchPetEvent.java @@ -0,0 +1,31 @@ +package com.eu.habbo.messages.incoming.rooms.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.MonsterplantPet; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class ScratchPetEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + final int petId = this.packet.readInt(); + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() == null) { + return; + } + + final Pet pet = this.client.getHabbo().getHabboInfo().getCurrentRoom().getPet(petId); + + if (pet == null) { + return; + } + + if (this.client.getHabbo().getHabboStats().petRespectPointsToGive > 0 || pet instanceof MonsterplantPet) { + pet.scratched(this.client.getHabbo()); + + // Update the stats to the database. + Emulator.getThreading().run(pet); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/StopBreedingEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/StopBreedingEvent.java new file mode 100644 index 0000000..5d19000 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/StopBreedingEvent.java @@ -0,0 +1,18 @@ +package com.eu.habbo.messages.incoming.rooms.pets; + +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetBreedingNest; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class StopBreedingEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId); + + if (item instanceof InteractionPetBreedingNest) { + ((InteractionPetBreedingNest) item).stopBreeding(this.client.getHabbo()); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/ToggleMonsterplantBreedableEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/ToggleMonsterplantBreedableEvent.java new file mode 100644 index 0000000..3cbc2d0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/ToggleMonsterplantBreedableEvent.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.incoming.rooms.pets; + +import com.eu.habbo.habbohotel.pets.MonsterplantPet; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class ToggleMonsterplantBreedableEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int petId = this.packet.readInt(); + + Pet pet = this.client.getHabbo().getHabboInfo().getCurrentRoom().getPet(petId); + + if (pet != null) { + if (pet.getUserId() == this.client.getHabbo().getHabboInfo().getId()) { + if (pet instanceof MonsterplantPet) { + ((MonsterplantPet) pet).setPubliclyBreedable(((MonsterplantPet) pet).isPubliclyBreedable()); + } + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/promotions/BuyRoomPromotionEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/promotions/BuyRoomPromotionEvent.java new file mode 100644 index 0000000..a157cf1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/promotions/BuyRoomPromotionEvent.java @@ -0,0 +1,72 @@ +package com.eu.habbo.messages.incoming.rooms.promotions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomRightLevels; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.catalog.AlertPurchaseFailedComposer; +import com.eu.habbo.messages.outgoing.catalog.PurchaseOKComposer; +import com.eu.habbo.messages.outgoing.navigator.NewNavigatorEventCategoriesComposer; +import com.eu.habbo.messages.outgoing.rooms.promotions.RoomPromotionMessageComposer; + +public class BuyRoomPromotionEvent extends MessageHandler { + public static String ROOM_PROMOTION_BADGE = "RADZZ"; + + @Override + public void handle() throws Exception { + int pageId = this.packet.readInt(); + int itemId = this.packet.readInt(); + int roomId = this.packet.readInt(); + String title = this.packet.readString(); + boolean extendedPromotion = this.packet.readBoolean(); + String description = this.packet.readString(); + int categoryId = this.packet.readInt(); + + if (NewNavigatorEventCategoriesComposer.CATEGORIES.stream().noneMatch(c -> c.getId() == categoryId)) + return; + + CatalogPage page = Emulator.getGameEnvironment().getCatalogManager().getCatalogPage(pageId); + + if (page == null || !page.getLayout().equals("roomads")) + return; + + CatalogItem item = page.getCatalogItem(itemId); + if (item != null) { + if (this.client.getHabbo().getHabboInfo().canBuy(item)) { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId); + + if (!(room.isOwner(this.client.getHabbo()) || room.hasRights(this.client.getHabbo()) || room.getGuildRightLevel(this.client.getHabbo()).equals(RoomRightLevels.GUILD_ADMIN))) { + return; + } + + if (room.isPromoted()) { + room.getPromotion().addEndTimestamp(120 * 60); + } else { + room.createPromotion(title, description, categoryId); + } + + if (room.isPromoted()) { + if (!this.client.getHabbo().hasPermission(Permission.ACC_INFINITE_CREDITS)) { + this.client.getHabbo().giveCredits(-item.getCredits()); + } + + if (!this.client.getHabbo().hasPermission(Permission.ACC_INFINITE_POINTS)) { + this.client.getHabbo().givePoints(item.getPointsType(), -item.getPoints()); + } + + this.client.sendResponse(new PurchaseOKComposer()); + room.sendComposer(new RoomPromotionMessageComposer(room, room.getPromotion()).compose()); + + if (!this.client.getHabbo().getInventory().getBadgesComponent().hasBadge(BuyRoomPromotionEvent.ROOM_PROMOTION_BADGE)) { + this.client.getHabbo().addBadge(BuyRoomPromotionEvent.ROOM_PROMOTION_BADGE); + } + } else { + this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/promotions/RequestPromotionRoomsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/promotions/RequestPromotionRoomsEvent.java new file mode 100644 index 0000000..3ece738 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/promotions/RequestPromotionRoomsEvent.java @@ -0,0 +1,18 @@ +package com.eu.habbo.messages.incoming.rooms.promotions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.promotions.PromoteOwnRoomsListComposer; + +import java.util.List; + +public class RequestPromotionRoomsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + List roomsToShow = Emulator.getGameEnvironment().getRoomManager().getRoomsForHabbo(this.client.getHabbo()); + roomsToShow.addAll(Emulator.getGameEnvironment().getRoomManager().getRoomsWithRights(this.client.getHabbo())); + roomsToShow.addAll(Emulator.getGameEnvironment().getRoomManager().getRoomsWithAdminRights(this.client.getHabbo())); + this.client.sendResponse(new PromoteOwnRoomsListComposer(roomsToShow)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/promotions/UpdateRoomPromotionEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/promotions/UpdateRoomPromotionEvent.java new file mode 100644 index 0000000..22d8900 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/promotions/UpdateRoomPromotionEvent.java @@ -0,0 +1,39 @@ +package com.eu.habbo.messages.incoming.rooms.promotions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomPromotion; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.promotions.RoomPromotionMessageComposer; + + +public class UpdateRoomPromotionEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + + int id = this.packet.readInt(); + String promotionName = this.packet.readString(); + String promotionDescription = this.packet.readString(); + + Room room = Emulator.getGameEnvironment().getRoomManager().loadRoom(id); + + if (room == null || room.getOwnerId() != this.client.getHabbo().getHabboInfo().getId() || !this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER)) { + return; + } + + RoomPromotion roomPromotion = room.getPromotion(); + + if (roomPromotion != null) { + + roomPromotion.setTitle(promotionName); + roomPromotion.setDescription(promotionDescription); + + roomPromotion.needsUpdate = true; + roomPromotion.save(); + + room.sendComposer(new RoomPromotionMessageComposer(room, roomPromotion).compose()); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/IgnoreRoomUserEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/IgnoreRoomUserEvent.java new file mode 100644 index 0000000..8862103 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/IgnoreRoomUserEvent.java @@ -0,0 +1,31 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserIgnoredComposer; + +public class IgnoreRoomUserEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + String username = this.packet.readString(); + + Habbo habbo = room.getHabbo(username); + + if (habbo != null) { + if (habbo == this.client.getHabbo()) + return; + + if (this.client.getHabbo().getHabboStats().ignoreUser(this.client, habbo.getHabboInfo().getId())) { + this.client.sendResponse(new RoomUserIgnoredComposer(habbo, RoomUserIgnoredComposer.IGNORED)); + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModIgnoreSeen")); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RequestRoomUserTagsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RequestRoomUserTagsEvent.java new file mode 100644 index 0000000..1cd6777 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RequestRoomUserTagsEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserTagsComposer; + +public class RequestRoomUserTagsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int roomUnitId = this.packet.readInt(); + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) { + Habbo habbo = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboByRoomUnitId(roomUnitId); + + if (habbo != null) { + this.client.sendResponse(new RoomUserTagsComposer(habbo)); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserActionEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserActionEvent.java new file mode 100644 index 0000000..41c29f2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserActionEvent.java @@ -0,0 +1,56 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUserAction; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserActionComposer; +import com.eu.habbo.plugin.events.users.UserIdleEvent; + +public class RoomUserActionEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + if (room != null) { + Habbo habbo = this.client.getHabbo(); + + if (this.client.getHabbo().getRoomUnit().getCacheable().get("control") != null) { + habbo = (Habbo) this.client.getHabbo().getRoomUnit().getCacheable().get("control"); + + if (habbo.getHabboInfo().getCurrentRoom() != room) { + habbo.getRoomUnit().getCacheable().remove("controller"); + this.client.getHabbo().getRoomUnit().getCacheable().remove("control"); + habbo = this.client.getHabbo(); + } + } + + int action = this.packet.readInt(); + + if (action == 5) { + UserIdleEvent event = new UserIdleEvent(this.client.getHabbo(), UserIdleEvent.IdleReason.ACTION, true); + Emulator.getPluginManager().fireEvent(event); + + if (!event.isCancelled()) { + if (event.idle) { + room.idle(habbo); + } else { + room.unIdle(habbo); + } + } + } else { + UserIdleEvent event = new UserIdleEvent(this.client.getHabbo(), UserIdleEvent.IdleReason.ACTION, false); + Emulator.getPluginManager().fireEvent(event); + + if (!event.isCancelled()) { + if (!event.idle) { + room.unIdle(habbo); + } + } + + } + + room.sendComposer(new RoomUserActionComposer(habbo.getRoomUnit(), RoomUserAction.fromValue(action)).compose()); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserBanEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserBanEvent.java new file mode 100644 index 0000000..d806fd3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserBanEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.RoomManager; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class RoomUserBanEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int userId = this.packet.readInt(); + int roomId = this.packet.readInt(); + String banName = this.packet.readString(); + + Emulator.getGameEnvironment().getRoomManager().banUserFromRoom(this.client.getHabbo(), userId, roomId, RoomManager.RoomBanTypes.valueOf(banName)); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserDanceEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserDanceEvent.java new file mode 100644 index 0000000..bafd54d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserDanceEvent.java @@ -0,0 +1,47 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.DanceType; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDanceComposer; +import com.eu.habbo.plugin.events.users.UserIdleEvent; + +public class RoomUserDanceEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() == null) + return; + + int danceId = this.packet.readInt(); + if (danceId >= 0 && danceId <= 5) { + if (this.client.getHabbo().getRoomUnit().isInRoom()) { + + Habbo habbo = this.client.getHabbo(); + + if (this.client.getHabbo().getRoomUnit().getCacheable().get("control") != null) { + habbo = (Habbo) this.client.getHabbo().getRoomUnit().getCacheable().get("control"); + + if (habbo.getHabboInfo().getCurrentRoom() != this.client.getHabbo().getHabboInfo().getCurrentRoom()) { + habbo.getRoomUnit().getCacheable().remove("controller"); + this.client.getHabbo().getRoomUnit().getCacheable().remove("control"); + habbo = this.client.getHabbo(); + } + } + + habbo.getRoomUnit().setDanceType(DanceType.values()[danceId]); + + UserIdleEvent event = new UserIdleEvent(this.client.getHabbo(), UserIdleEvent.IdleReason.DANCE, false); + Emulator.getPluginManager().fireEvent(event); + + if (!event.isCancelled()) { + if (!event.idle) { + this.client.getHabbo().getHabboInfo().getCurrentRoom().unIdle(habbo); + } + } + + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserDanceComposer(habbo.getRoomUnit()).compose()); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserDropHandItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserDropHandItemEvent.java new file mode 100644 index 0000000..c57318c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserDropHandItemEvent.java @@ -0,0 +1,17 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserHandItemComposer; + +public class RoomUserDropHandItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + this.client.getHabbo().getRoomUnit().setHandItem(0); + if (room != null) { + room.unIdle(this.client.getHabbo()); + room.sendComposer(new RoomUserHandItemComposer(this.client.getHabbo().getRoomUnit()).compose()); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserGiveHandItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserGiveHandItemEvent.java new file mode 100644 index 0000000..9342e04 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserGiveHandItemEvent.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.threading.runnables.HabboGiveHandItemToHabbo; +import com.eu.habbo.threading.runnables.RoomUnitWalkToRoomUnit; + +import java.util.ArrayList; +import java.util.List; + +public class RoomUserGiveHandItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int userId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + Habbo target = room.getHabbo(userId); + + if (target != null) { + List executable = new ArrayList<>(); + executable.add(new HabboGiveHandItemToHabbo(this.client.getHabbo(), target)); + Emulator.getThreading().run(new RoomUnitWalkToRoomUnit(this.client.getHabbo().getRoomUnit(), target.getRoomUnit(), this.client.getHabbo().getHabboInfo().getCurrentRoom(), executable, executable)); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserGiveRespectEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserGiveRespectEvent.java new file mode 100644 index 0000000..d2a46a4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserGiveRespectEvent.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.users.UserRespectedEvent; + +public class RoomUserGiveRespectEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int userId = this.packet.readInt(); + + if (this.client.getHabbo().getHabboStats().respectPointsToGive > 0) { + Habbo target = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabbo(userId); + + if (Emulator.getPluginManager().isRegistered(UserRespectedEvent.class, false)) { + if (Emulator.getPluginManager().fireEvent(new UserRespectedEvent(target, this.client.getHabbo())).isCancelled()) + return; + } + + this.client.getHabbo().respect(target); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserGiveRightsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserGiveRightsEvent.java new file mode 100644 index 0000000..479b061 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserGiveRightsEvent.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.messenger.MessengerBuddy; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.users.UserRightsGivenEvent; + +public class RoomUserGiveRightsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int userId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + if (room.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER)) { + Habbo target = room.getHabbo(userId); + + if (target != null) { + if (!Emulator.getPluginManager().fireEvent(new UserRightsGivenEvent(this.client.getHabbo(), target)).isCancelled()) { + room.giveRights(target); + } + } else { + MessengerBuddy buddy = this.client.getHabbo().getMessenger().getFriend(userId); + + if (buddy != null) { + room.giveRights(userId); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserKickEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserKickEvent.java new file mode 100644 index 0000000..814b059 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserKickEvent.java @@ -0,0 +1,51 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserWhisperComposer; +import com.eu.habbo.plugin.events.users.UserKickEvent; + +public class RoomUserKickEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + int userId = this.packet.readInt(); + + Habbo target = room.getHabbo(userId); + + if (target == null) + return; + + if (target.hasPermission(Permission.ACC_UNKICKABLE)) { + this.client.sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(Emulator.getTexts().getValue("commands.error.cmd_kick.unkickable").replace("%username%", target.getHabboInfo().getUsername()), this.client.getHabbo(), this.client.getHabbo(), RoomChatMessageBubbles.ALERT))); + return; + } + + if (room.isOwner(target)) { + return; + } + + UserKickEvent event = new UserKickEvent(this.client.getHabbo(), target); + Emulator.getPluginManager().fireEvent(event); + + if (event.isCancelled()) + return; + + if (room.hasRights(this.client.getHabbo()) || this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER) || this.client.getHabbo().hasPermission(Permission.ACC_AMBASSADOR)) { + if (target.hasPermission(Permission.ACC_UNKICKABLE)) return; + + room.kickHabbo(target, true); + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModKickSeen")); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserLookAtPoint.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserLookAtPoint.java new file mode 100644 index 0000000..f4f7c00 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserLookAtPoint.java @@ -0,0 +1,58 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; + +public class RoomUserLookAtPoint extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + if (room == null) + return; + + Habbo habbo = this.client.getHabbo(); + + if (habbo.getRoomUnit().getCacheable().get("control") != null) { + habbo = (Habbo) this.client.getHabbo().getRoomUnit().getCacheable().get("control"); + + if (habbo.getHabboInfo().getCurrentRoom() != this.client.getHabbo().getHabboInfo().getCurrentRoom()) { + habbo.getRoomUnit().getCacheable().remove("controller"); + this.client.getHabbo().getRoomUnit().getCacheable().remove("control"); + habbo = this.client.getHabbo(); + } + } + + RoomUnit roomUnit = habbo.getRoomUnit(); + + if (!roomUnit.canWalk()) + return; + + if (roomUnit.isWalking() || roomUnit.hasStatus(RoomUnitStatus.MOVE)) + return; + + if (roomUnit.cmdLay || roomUnit.hasStatus(RoomUnitStatus.LAY)) + return; + + if (roomUnit.isIdle()) + return; + + int x = this.packet.readInt(); + int y = this.packet.readInt(); + + if (x == roomUnit.getX() && y == roomUnit.getY()) + return; + + RoomTile tile = habbo.getHabboInfo().getCurrentRoom().getLayout().getTile((short) x, (short) y); + + if (tile != null) { + roomUnit.lookAtPoint(tile); + roomUnit.statusUpdate(true); + //room.sendComposer(new RoomUserStatusComposer(roomUnit).compose()); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserMuteEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserMuteEvent.java new file mode 100644 index 0000000..8acca3b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserMuteEvent.java @@ -0,0 +1,32 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.users.MutedWhisperComposer; + +public class RoomUserMuteEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int userId = this.packet.readInt(); + int roomId = this.packet.readInt(); + int minutes = this.packet.readInt(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId); + + if (room != null) { + if (room.hasRights(this.client.getHabbo()) || this.client.getHabbo().hasPermission("cmd_mute") || this.client.getHabbo().hasPermission(Permission.ACC_AMBASSADOR)) { + Habbo habbo = room.getHabbo(userId); + + if (habbo != null) { + room.muteHabbo(habbo, minutes); + habbo.getClient().sendResponse(new MutedWhisperComposer(minutes * 60)); + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModMuteSeen")); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserRemoveRightsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserRemoveRightsEvent.java new file mode 100644 index 0000000..cc03c73 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserRemoveRightsEvent.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class RoomUserRemoveRightsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int amount = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + if (room.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER)) { + for (int i = 0; i < amount; i++) { + int userId = this.packet.readInt(); + + room.removeRights(userId); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserShoutEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserShoutEvent.java new file mode 100644 index 0000000..ac0d85a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserShoutEvent.java @@ -0,0 +1,43 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.habbohotel.rooms.RoomChatType; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.users.UserTalkEvent; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RoomUserShoutEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() == null) + return; + + if (!this.client.getHabbo().getHabboStats().allowTalk()) + return; + + + RoomChatMessage message = new RoomChatMessage(this); + + if (message.getMessage().length() <= RoomChatMessage.MAXIMUM_LENGTH) { + if (Emulator.getPluginManager().fireEvent(new UserTalkEvent(this.client.getHabbo(), message, RoomChatType.SHOUT)).isCancelled()) { + return; + } + + this.client.getHabbo().getHabboInfo().getCurrentRoom().talk(this.client.getHabbo(), message, RoomChatType.SHOUT); + + if (!message.isCommand) { + if (RoomChatMessage.SAVE_ROOM_CHATS) { + Emulator.getThreading().run(message); + } + } + } else { + String reportMessage = Emulator.getTexts().getValue("scripter.warning.chat.length").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()).replace("%length%", message.getMessage().length() + ""); + ScripterManager.scripterDetected(this.client, reportMessage); + log.info(reportMessage); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserSignEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserSignEvent.java new file mode 100644 index 0000000..3b2aaf9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserSignEvent.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionVoteCounter; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.users.UserSignEvent; + +public class RoomUserSignEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int signId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + UserSignEvent event = new UserSignEvent(this.client.getHabbo(), signId); + if (!Emulator.getPluginManager().fireEvent(event).isCancelled()) { + this.client.getHabbo().getRoomUnit().setStatus(RoomUnitStatus.SIGN, event.sign + ""); + this.client.getHabbo().getHabboInfo().getCurrentRoom().unIdle(this.client.getHabbo()); + + if(signId <= 10) { + + int userId = this.client.getHabbo().getHabboInfo().getId(); + for (HabboItem item : room.getFloorItems()) { + if (item instanceof InteractionVoteCounter) { + ((InteractionVoteCounter)item).vote(room, userId, signId); + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserSitEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserSitEvent.java new file mode 100644 index 0000000..f3c8df7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserSitEvent.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.users.UserIdleEvent; + +public class RoomUserSitEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) { + if (this.client.getHabbo().getRoomUnit().isWalking()) { + this.client.getHabbo().getRoomUnit().stopWalking(); + } + this.client.getHabbo().getHabboInfo().getCurrentRoom().makeSit(this.client.getHabbo()); + + UserIdleEvent event = new UserIdleEvent(this.client.getHabbo(), UserIdleEvent.IdleReason.WALKED, false); + Emulator.getPluginManager().fireEvent(event); + + if (!event.isCancelled()) { + if (!event.idle) { + this.client.getHabbo().getHabboInfo().getCurrentRoom().unIdle(this.client.getHabbo()); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserStartTypingEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserStartTypingEvent.java new file mode 100644 index 0000000..94f471a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserStartTypingEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserTypingComposer; + +public class RoomUserStartTypingEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() == null) { + return; + } + + if (this.client.getHabbo().getRoomUnit() == null) { + return; + } + + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserTypingComposer(this.client.getHabbo().getRoomUnit(), true).compose()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserStopTypingEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserStopTypingEvent.java new file mode 100644 index 0000000..0b9e02d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserStopTypingEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserTypingComposer; + +public class RoomUserStopTypingEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() == null) { + return; + } + + if (this.client.getHabbo().getRoomUnit() == null) { + return; + } + + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserTypingComposer(this.client.getHabbo().getRoomUnit(), false).compose()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserTalkEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserTalkEvent.java new file mode 100644 index 0000000..c1f365d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserTalkEvent.java @@ -0,0 +1,44 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.habbohotel.rooms.RoomChatType; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.users.UserTalkEvent; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RoomUserTalkEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + if (room == null) + return; + + if (!this.client.getHabbo().getHabboStats().allowTalk()) + return; + + RoomChatMessage message = new RoomChatMessage(this); + + if (message.getMessage().length() <= RoomChatMessage.MAXIMUM_LENGTH) { + if (Emulator.getPluginManager().fireEvent(new UserTalkEvent(this.client.getHabbo(), message, RoomChatType.TALK)).isCancelled()) { + return; + } + + room.talk(this.client.getHabbo(), message, RoomChatType.TALK); + + if (!message.isCommand) { + if (RoomChatMessage.SAVE_ROOM_CHATS) { + Emulator.getThreading().run(message); + } + } + } else { + String reportMessage = Emulator.getTexts().getValue("scripter.warning.chat.length").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()).replace("%length%", message.getMessage().length() + ""); + ScripterManager.scripterDetected(this.client, reportMessage); + log.info(reportMessage); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserWalkEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserWalkEvent.java new file mode 100644 index 0000000..45f28b6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserWalkEvent.java @@ -0,0 +1,164 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUnitOnRollerComposer; +import com.eu.habbo.plugin.events.users.UserIdleEvent; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RoomUserWalkEvent extends MessageHandler { + + @Override + public int getRatelimit() { + return 500; + } + + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) { + int x = this.packet.readInt(); // Position X + int y = this.packet.readInt(); // Position Y + + // Get Habbo object + Habbo habbo = this.client.getHabbo(); + + // Get Room Habbo object (Unique GUID?) + RoomUnit roomUnit = this.client.getHabbo().getRoomUnit(); + + // If habbo is teleporting, dont calculate a new path + if (roomUnit.isTeleporting) + return; + + // If habbo is being kicked dont calculate a new path + if (roomUnit.isKicked) + return; + + // If habbo has control (im assuming admin, do something else, but we dont care about this part here) + if (roomUnit.getCacheable().get("control") != null) { + habbo = (Habbo) roomUnit.getCacheable().get("control"); + + if (habbo.getHabboInfo().getCurrentRoom() != this.client.getHabbo().getHabboInfo().getCurrentRoom()) { + habbo.getRoomUnit().getCacheable().remove("controller"); + this.client.getHabbo().getRoomUnit().getCacheable().remove("control"); + habbo = this.client.getHabbo(); + } + } + + // Get room unit? + roomUnit = habbo.getRoomUnit(); + + // Get the room the habbo is in + Room room = habbo.getHabboInfo().getCurrentRoom(); + + try { + // If our room unit is not nullptr and we are in a room and we can walk, then calculate a new path + if (roomUnit != null && roomUnit.isInRoom() && roomUnit.canWalk()) { + // If we are not teleporting calcualte a new path + if (!roomUnit.cmdTeleport) { + // Don't calculate a new path if we are on a horse + if (habbo.getHabboInfo().getRiding() != null && habbo.getHabboInfo().getRiding().getTask() != null && habbo.getHabboInfo().getRiding().getTask().equals(PetTasks.JUMP)) + return; + + // Don't calulcate a new path if are already at the end position + if (x == roomUnit.getX() && y == roomUnit.getY()) + return; + + if (room == null || room.getLayout() == null) + return; + + // Reset idle status + if (roomUnit.isIdle()) { + UserIdleEvent event = new UserIdleEvent(habbo, UserIdleEvent.IdleReason.WALKED, false); + Emulator.getPluginManager().fireEvent(event); + + if (!event.isCancelled()) { + if (!event.idle) { + if (roomUnit.getRoom() != null) roomUnit.getRoom().unIdle(habbo); + roomUnit.resetIdleTimer(); + } + } + } + + // Get room height map + RoomTile tile = room.getLayout().getTile((short) x, (short) y); + + // this should never happen, if it does it would be a design flaw + if (tile == null) { + return; + } + + // Don't care + if (habbo.getRoomUnit().hasStatus(RoomUnitStatus.LAY)) { + if (room.getLayout().getTilesInFront(habbo.getRoomUnit().getCurrentLocation(), habbo.getRoomUnit().getBodyRotation().getValue(), 2).contains(tile)) + return; + } + if (room.canLayAt(tile.x, tile.y)) { + HabboItem bed = room.getTopItemAt(tile.x, tile.y); + + if (bed != null && bed.getBaseItem().allowLay()) { + RoomTile pillow = room.getLayout().getTile(bed.getX(), bed.getY()); + switch (bed.getRotation()) { + case 0: + case 4: + pillow = room.getLayout().getTile((short) x, bed.getY()); + break; + case 2: + case 8: + pillow = room.getLayout().getTile(bed.getX(), (short) y); + break; + } + + if (pillow != null && room.canLayAt(pillow.x, pillow.y)) { + roomUnit.setGoalLocation(pillow); + return; + } + } + } + + THashSet items = room.getItemsAt(tile); + + if (items.size() > 0) { + for (HabboItem item : items) { + RoomTile overriddenTile = item.getOverrideGoalTile(roomUnit, room, tile); + + if (overriddenTile == null) { + return; // null cancels the entire event + } + + if (!overriddenTile.equals(tile) && overriddenTile.isWalkable()) { + tile = overriddenTile; + break; + } + } + } + + // This is where we set the end location and begin finding a path + if (tile.isWalkable() || room.canSitOrLayAt(tile.x, tile.y)) { + if (roomUnit.getMoveBlockingTask() != null) roomUnit.getMoveBlockingTask().get(); + + roomUnit.setGoalLocation(tile); + } + } else { + RoomTile t = room.getLayout().getTile((short) x, (short) y); + room.sendComposer(new RoomUnitOnRollerComposer(roomUnit, t, room).compose()); + + if (habbo.getHabboInfo().getRiding() != null) { + room.sendComposer(new RoomUnitOnRollerComposer(habbo.getHabboInfo().getRiding().getRoomUnit(), t, room).compose()); + } + } + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserWhisperEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserWhisperEvent.java new file mode 100644 index 0000000..3250102 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserWhisperEvent.java @@ -0,0 +1,40 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.habbohotel.rooms.RoomChatType; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.users.UserTalkEvent; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RoomUserWhisperEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() == null) + return; + + RoomChatMessage chatMessage = new RoomChatMessage(this); + + if (chatMessage.getMessage().length() <= RoomChatMessage.MAXIMUM_LENGTH) { + if (!this.client.getHabbo().getHabboStats().allowTalk() || chatMessage.getTargetHabbo() == null) + return; + + if (Emulator.getPluginManager().fireEvent(new UserTalkEvent(this.client.getHabbo(), chatMessage, RoomChatType.WHISPER)).isCancelled()) { + return; + } + + this.client.getHabbo().getHabboInfo().getCurrentRoom().talk(this.client.getHabbo(), chatMessage, RoomChatType.WHISPER, true); + + if (RoomChatMessage.SAVE_ROOM_CHATS) { + Emulator.getThreading().run(chatMessage); + } + } else { + String reportMessage = Emulator.getTexts().getValue("scripter.warning.chat.length").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()).replace("%length%", chatMessage.getMessage().length() + ""); + ScripterManager.scripterDetected(this.client, reportMessage); + log.info(reportMessage); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/UnIgnoreRoomUserEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/UnIgnoreRoomUserEvent.java new file mode 100644 index 0000000..39f131e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/UnIgnoreRoomUserEvent.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserIgnoredComposer; + +public class UnIgnoreRoomUserEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + String username = this.packet.readString(); + + Habbo habbo = room.getHabbo(username); + + if (habbo != null) { + if (habbo.getHabboStats().allowTalk()) { + this.client.getHabbo().getHabboStats().unignoreUser(habbo.getHabboInfo().getId()); + this.client.sendResponse(new RoomUserIgnoredComposer(habbo, RoomUserIgnoredComposer.UNIGNORED)); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/UnbanRoomUserEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/UnbanRoomUserEvent.java new file mode 100644 index 0000000..a0eebff --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/UnbanRoomUserEvent.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.incoming.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class UnbanRoomUserEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int userId = this.packet.readInt(); + int roomId = this.packet.readInt(); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId); + + if (room != null) { + if (room.isOwner(this.client.getHabbo())) { + room.unbanHabbo(userId); + } + } + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeAcceptEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeAcceptEvent.java new file mode 100644 index 0000000..af4c137 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeAcceptEvent.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.incoming.trading; + +import com.eu.habbo.habbohotel.rooms.RoomTrade; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class TradeAcceptEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Habbo habbo = this.client.getHabbo(); + + if (habbo == null || habbo.getHabboInfo() == null || habbo.getHabboInfo().getCurrentRoom() == null) + return; + + RoomTrade trade = habbo.getHabboInfo().getCurrentRoom().getActiveTradeForHabbo(habbo); + + if (trade == null) + return; + + trade.accept(habbo, true); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeCancelEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeCancelEvent.java new file mode 100644 index 0000000..b02656b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeCancelEvent.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.incoming.trading; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTrade; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class TradeCancelEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Habbo habbo = this.client.getHabbo(); + Room room = habbo.getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + RoomTrade trade = room.getActiveTradeForHabbo(habbo); + + if (trade == null) + return; + + trade.stopTrade(habbo); + room.stopTrade(trade); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeCancelOfferItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeCancelOfferItemEvent.java new file mode 100644 index 0000000..94ee24a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeCancelOfferItemEvent.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.incoming.trading; + +import com.eu.habbo.habbohotel.rooms.RoomTrade; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class TradeCancelOfferItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + RoomTrade trade = this.client.getHabbo().getHabboInfo().getCurrentRoom().getActiveTradeForHabbo(this.client.getHabbo()); + if (trade != null) { + HabboItem item = trade.getRoomTradeUserForHabbo(this.client.getHabbo()).getItem(itemId); + + if (!trade.getRoomTradeUserForHabbo(this.client.getHabbo()).getAccepted() && item != null) { + trade.removeItem(this.client.getHabbo(), item); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeCloseEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeCloseEvent.java new file mode 100644 index 0000000..b6ff3e3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeCloseEvent.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.incoming.trading; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTrade; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class TradeCloseEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Habbo habbo = this.client.getHabbo(); + Room room = habbo.getHabboInfo().getCurrentRoom(); + + if (room == null) + return; + + RoomTrade trade = room.getActiveTradeForHabbo(habbo); + + if (trade == null) + return; + + trade.stopTrade(habbo); + room.stopTrade(trade); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeConfirmEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeConfirmEvent.java new file mode 100644 index 0000000..94fa15b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeConfirmEvent.java @@ -0,0 +1,18 @@ +package com.eu.habbo.messages.incoming.trading; + +import com.eu.habbo.habbohotel.rooms.RoomTrade; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class TradeConfirmEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Habbo habbo = this.client.getHabbo(); + RoomTrade trade = habbo.getHabboInfo().getCurrentRoom().getActiveTradeForHabbo(habbo); + + if (trade == null || !trade.getRoomTradeUserForHabbo(habbo).getAccepted()) + return; + + trade.confirm(habbo); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeOfferItemEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeOfferItemEvent.java new file mode 100644 index 0000000..85b521d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeOfferItemEvent.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.incoming.trading; + +import com.eu.habbo.habbohotel.rooms.RoomTrade; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class TradeOfferItemEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() == null) + return; + + RoomTrade trade = this.client.getHabbo().getHabboInfo().getCurrentRoom().getActiveTradeForHabbo(this.client.getHabbo()); + + if (trade == null) + return; + + HabboItem item = this.client.getHabbo().getInventory().getItemsComponent().getHabboItem(this.packet.readInt()); + + if (item == null || !item.getBaseItem().allowTrade()) + return; + + trade.offerItem(this.client.getHabbo(), item); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeOfferMultipleItemsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeOfferMultipleItemsEvent.java new file mode 100644 index 0000000..231a70c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeOfferMultipleItemsEvent.java @@ -0,0 +1,31 @@ +package com.eu.habbo.messages.incoming.trading; + +import com.eu.habbo.habbohotel.rooms.RoomTrade; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.incoming.MessageHandler; +import gnu.trove.set.hash.THashSet; + +public class TradeOfferMultipleItemsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() == null) + return; + + RoomTrade trade = this.client.getHabbo().getHabboInfo().getCurrentRoom().getActiveTradeForHabbo(this.client.getHabbo()); + + if (trade == null) + return; + + THashSet items = new THashSet<>(); + + int count = this.packet.readInt(); + for (int i = 0; i < count; i++) { + HabboItem item = this.client.getHabbo().getInventory().getItemsComponent().getHabboItem(this.packet.readInt()); + if (item != null && item.getBaseItem().allowTrade()) { + items.add(item); + } + } + + trade.offerMultipleItems(this.client.getHabbo(), items); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeStartEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeStartEvent.java new file mode 100644 index 0000000..a776adc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeStartEvent.java @@ -0,0 +1,65 @@ +package com.eu.habbo.messages.incoming.trading; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTrade; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.trading.TradeStartFailComposer; + +public class TradeStartEvent extends MessageHandler { + @Override + public void handle() throws Exception { + if (Emulator.getIntUnixTimestamp() - this.client.getHabbo().getHabboStats().lastTradeTimestamp > 10) { + this.client.getHabbo().getHabboStats().lastTradeTimestamp = Emulator.getIntUnixTimestamp(); + int userId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + if (room != null) { + if (userId >= 0 && userId != this.client.getHabbo().getRoomUnit().getId()) { + Habbo targetUser = room.getHabboByRoomUnitId(userId); + + boolean tradeAnywhere = this.client.getHabbo().hasPermission(Permission.ACC_TRADE_ANYWHERE); + + if (!RoomTrade.TRADING_ENABLED && !tradeAnywhere) { + this.client.sendResponse(new TradeStartFailComposer(TradeStartFailComposer.HOTEL_TRADING_NOT_ALLOWED)); + return; + } + + if ((room.getTradeMode() == 0 || (room.getTradeMode() == 1 && this.client.getHabbo().getHabboInfo().getId() != room.getOwnerId())) && !tradeAnywhere) { + this.client.sendResponse(new TradeStartFailComposer(TradeStartFailComposer.ROOM_TRADING_NOT_ALLOWED)); + return; + } + + if (targetUser == null) return; + + if (targetUser.getHabboStats().userIgnored(this.client.getHabbo().getHabboInfo().getId())) return; + + if (this.client.getHabbo().getRoomUnit().hasStatus(RoomUnitStatus.TRADING)) { + this.client.sendResponse(new TradeStartFailComposer(TradeStartFailComposer.YOU_ALREADY_TRADING)); + return; + } + + if (!this.client.getHabbo().getHabboStats().allowTrade()) { + this.client.sendResponse(new TradeStartFailComposer(TradeStartFailComposer.YOU_TRADING_OFF)); + return; + } + + if (targetUser.getRoomUnit().hasStatus(RoomUnitStatus.TRADING)) { + this.client.sendResponse(new TradeStartFailComposer(TradeStartFailComposer.TARGET_ALREADY_TRADING, targetUser.getHabboInfo().getUsername())); + return; + } + + if (!targetUser.getHabboStats().allowTrade()) { + this.client.sendResponse(new TradeStartFailComposer(TradeStartFailComposer.TARGET_TRADING_NOT_ALLOWED, targetUser.getHabboInfo().getUsername())); + return; + } + + room.startTrade(this.client.getHabbo(), targetUser); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeUnAcceptEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeUnAcceptEvent.java new file mode 100644 index 0000000..138c375 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/trading/TradeUnAcceptEvent.java @@ -0,0 +1,18 @@ +package com.eu.habbo.messages.incoming.trading; + +import com.eu.habbo.habbohotel.rooms.RoomTrade; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class TradeUnAcceptEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Habbo habbo = this.client.getHabbo(); + RoomTrade trade = habbo.getHabboInfo().getCurrentRoom().getActiveTradeForHabbo(habbo); + + if (trade == null) + return; + + trade.accept(habbo, false); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/unknown/RequestResolutionEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/unknown/RequestResolutionEvent.java new file mode 100644 index 0000000..a076e7c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/unknown/RequestResolutionEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.messages.incoming.unknown; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.events.resolution.NewYearResolutionComposer; + +public class RequestResolutionEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + int viewAll = this.packet.readInt(); + + if (viewAll == 0) { + this.client.sendResponse(new NewYearResolutionComposer()); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/unknown/UnknownEvent1.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/unknown/UnknownEvent1.java new file mode 100644 index 0000000..442406f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/unknown/UnknownEvent1.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.unknown; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.unknown.IgnoredUsersComposer; + +public class UnknownEvent1 extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new IgnoredUsersComposer()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/unknown/UnknownEvent2.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/unknown/UnknownEvent2.java new file mode 100644 index 0000000..417a56c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/unknown/UnknownEvent2.java @@ -0,0 +1,9 @@ +package com.eu.habbo.messages.incoming.unknown; + +import com.eu.habbo.messages.incoming.MessageHandler; + +public class UnknownEvent2 extends MessageHandler { + @Override + public void handle() throws Exception { + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/ActivateEffectEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/ActivateEffectEvent.java new file mode 100644 index 0000000..526da5f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/ActivateEffectEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.messages.incoming.MessageHandler; + +public class ActivateEffectEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int effectId = this.packet.readInt(); + + if (this.client.getHabbo().getInventory().getEffectsComponent().ownsEffect(effectId)) { + this.client.getHabbo().getInventory().getEffectsComponent().activateEffect(effectId); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/ChangeChatBubbleEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/ChangeChatBubbleEvent.java new file mode 100644 index 0000000..46f6ab5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/ChangeChatBubbleEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class ChangeChatBubbleEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int chatBubble = this.packet.readInt(); + + if (!this.client.getHabbo().hasPermission(Permission.ACC_ANYCHATCOLOR)) { + for (String s : Emulator.getConfig().getValue("commands.cmd_chatcolor.banned_numbers").split(";")) { + if (Integer.valueOf(s) == chatBubble) { + return; + } + } + } + + this.client.getHabbo().getHabboStats().chatColor = RoomChatMessageBubbles.getBubble(chatBubble); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/ChangeNameCheckUsernameEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/ChangeNameCheckUsernameEvent.java new file mode 100644 index 0000000..a287e65 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/ChangeNameCheckUsernameEvent.java @@ -0,0 +1,52 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserNameChangedComposer; +import com.eu.habbo.messages.outgoing.users.ChangeNameCheckResultComposer; + +import java.util.ArrayList; +import java.util.List; + +public class ChangeNameCheckUsernameEvent extends MessageHandler { + public static String VALID_CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-=!?@:,."; + + @Override + public void handle() throws Exception { + if (!this.client.getHabbo().getHabboStats().allowNameChange) + return; + + String name = this.packet.readString(); + + int errorCode = ChangeNameCheckResultComposer.AVAILABLE; + + List suggestions = new ArrayList<>(4); + if (name.length() < 3) { + errorCode = ChangeNameCheckResultComposer.TOO_SHORT; + } else if (name.length() > 15) { + errorCode = ChangeNameCheckResultComposer.TOO_LONG; + } else if (name.equalsIgnoreCase(this.client.getHabbo().getHabboInfo().getUsername()) || HabboManager.getOfflineHabboInfo(name) != null || ConfirmChangeNameEvent.changingUsernames.contains(name.toLowerCase())) { + errorCode = ChangeNameCheckResultComposer.TAKEN_WITH_SUGGESTIONS; + suggestions.add(name + Emulator.getRandom().nextInt(9999)); + suggestions.add(name + Emulator.getRandom().nextInt(9999)); + suggestions.add(name + Emulator.getRandom().nextInt(9999)); + suggestions.add(name + Emulator.getRandom().nextInt(9999)); + } else if (!Emulator.getGameEnvironment().getWordFilter().filter(name, this.client.getHabbo()).equalsIgnoreCase(name)) { + errorCode = ChangeNameCheckResultComposer.NOT_VALID; + } else { + String checkName = name; + for (char c : VALID_CHARACTERS.toCharArray()) { + checkName = checkName.replace(c + "", ""); + } + + if (!checkName.isEmpty()) { + errorCode = ChangeNameCheckResultComposer.NOT_VALID; + } else { + this.client.getHabbo().getHabboStats().changeNameChecked = name; + } + } + + this.client.sendResponse(new ChangeNameCheckResultComposer(errorCode, name, suggestions)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/ConfirmChangeNameEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/ConfirmChangeNameEvent.java new file mode 100644 index 0000000..4caa359 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/ConfirmChangeNameEvent.java @@ -0,0 +1,93 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.users.ChangeNameUpdatedComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserNameChangedComposer; +import com.eu.habbo.messages.outgoing.users.ChangeNameCheckResultComposer; +import com.eu.habbo.messages.outgoing.users.UserDataComposer; +import com.eu.habbo.plugin.events.users.UserNameChangedEvent; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +public class ConfirmChangeNameEvent extends MessageHandler { + + public static final List changingUsernames = new ArrayList<>(2); + + @Override + public void handle() throws Exception { + if (!this.client.getHabbo().getHabboStats().allowNameChange) + return; + + String name = this.packet.readString(); + + if (name.equalsIgnoreCase(this.client.getHabbo().getHabboInfo().getUsername())) { + this.client.getHabbo().getHabboStats().allowNameChange = false; + this.client.sendResponse(new ChangeNameUpdatedComposer(this.client.getHabbo())); + this.client.sendResponse(new RoomUserNameChangedComposer(this.client.getHabbo()).compose()); + this.client.sendResponse(new UserDataComposer(this.client.getHabbo())); + return; + } + + if (name.equals(this.client.getHabbo().getHabboStats().changeNameChecked)) { + HabboInfo habboInfo = HabboManager.getOfflineHabboInfo(name); + + if (habboInfo == null) { + synchronized (changingUsernames) { + if (changingUsernames.contains(name)) + return; + + changingUsernames.add(name); + } + + String oldName = this.client.getHabbo().getHabboInfo().getUsername(); + this.client.getHabbo().getHabboStats().allowNameChange = false; + this.client.getHabbo().getHabboInfo().setUsername(name); + this.client.getHabbo().getHabboInfo().run(); + + Emulator.getPluginManager().fireEvent(new UserNameChangedEvent(this.client.getHabbo(), oldName)); + for (Room room : Emulator.getGameEnvironment().getRoomManager().getRoomsForHabbo(this.client.getHabbo())) { + room.setOwnerName(name); + room.setNeedsUpdate(true); + room.save(); + } + + synchronized (changingUsernames) { + changingUsernames.remove(name); + } + + this.client.sendResponse(new ChangeNameUpdatedComposer(this.client.getHabbo())); + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) { + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserNameChangedComposer(this.client.getHabbo()).compose()); + } else { + this.client.sendResponse(new RoomUserNameChangedComposer(this.client.getHabbo()).compose()); + } + + this.client.getHabbo().getMessenger().connectionChanged(this.client.getHabbo(), true, this.client.getHabbo().getHabboInfo().getCurrentRoom() != null); + this.client.getHabbo().getClient().sendResponse(new UserDataComposer(this.client.getHabbo())); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO namechange_log (user_id, old_name, new_name, timestamp) VALUES (?, ?, ?, ?) ")) { + statement.setInt(1, this.client.getHabbo().getHabboInfo().getId()); + statement.setString(2, oldName); + statement.setString(3, name); + statement.setInt(4, Emulator.getIntUnixTimestamp()); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } else { + this.client.sendResponse(new ChangeNameCheckResultComposer(ChangeNameCheckResultComposer.TAKEN_WITH_SUGGESTIONS, name, new ArrayList<>())); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/EnableEffectEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/EnableEffectEvent.java new file mode 100644 index 0000000..29d894f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/EnableEffectEvent.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.messages.incoming.MessageHandler; + +public class EnableEffectEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int effectId = this.packet.readInt(); + + if (effectId > 0) { + if (this.client.getHabbo().getInventory().getEffectsComponent().ownsEffect(effectId)) { + this.client.getHabbo().getInventory().getEffectsComponent().enableEffect(effectId); + } + } else { + this.client.getHabbo().getInventory().getEffectsComponent().activatedEffect = 0; + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) { + this.client.getHabbo().getHabboInfo().getCurrentRoom().giveEffect(this.client.getHabbo().getRoomUnit(), 0, -1); + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/PerformanceLogMessageEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/PerformanceLogMessageEvent.java new file mode 100644 index 0000000..9002c35 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/PerformanceLogMessageEvent.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class PerformanceLogMessageEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + int timer = this.packet.readInt(); // kind of time since start of client + String externalInterface = this.packet.readString(); // available ExternalInterface + String flashVersion = this.packet.readString(); // _flashVersion + String userOs = this.packet.readString(); // user OS + String unknown1 = this.packet.readString(); // always an empty string, not assigned by client + boolean debuggerState = this.packet.readBoolean(); // _SafeStr_8266 Capabilities.isDebugger, false by default + int totalMemory = this.packet.readInt(); // System.totalMemory, Total Memory in KB + int unknown2 = this.packet.readInt(); // by default set to -1 + int averageUpdateIntervalGarbaged = this.packet.readInt(); // averageUpdateInterval.isGarbageMonitored + int averageUpdateInterval = this.packet.readInt(); // averageUpdateInterval + int slowUpdateLimit = this.packet.readInt(); // exceeded slowUpdateLimit + if (Emulator.debugging) { + log.info("Timer: " + timer + + ", ExternalInterface: " + externalInterface + + ", FlashVersion: " + flashVersion + + ", UserOS: " + userOs + + ", Unknown1 (Empty String): '" + unknown1 + "'" + + ", DebuggerState: " + debuggerState + + ", TotalMemory (KB): " + totalMemory + + ", Unknown2 (Default -1): " + unknown2 + + ", AverageUpdateIntervalGarbaged: " + averageUpdateIntervalGarbaged + + ", AverageUpdateInterval: " + averageUpdateInterval + + ", SlowUpdateLimit: " + slowUpdateLimit); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/PickNewUserGiftEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/PickNewUserGiftEvent.java new file mode 100644 index 0000000..979e6ac --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/PickNewUserGiftEvent.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.NewUserGift; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.users.UserPickGiftEvent; + +public class PickNewUserGiftEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int totalItems = this.packet.readInt(); //total items + int keyA = this.packet.readInt(); //key 1 + int keyB = this.packet.readInt(); //key 2 + int index = this.packet.readInt(); + + if (!Emulator.getPluginManager().fireEvent(new UserPickGiftEvent(this.client.getHabbo(), keyA, keyB, index)).isCancelled()) { + if (!this.client.getHabbo().getHabboStats().nuxReward && Emulator.getConfig().getBoolean("hotel.nux.gifts.enabled")){ + this.client.getHabbo().getHabboStats().nuxReward = true; + NewUserGift gift = Emulator.getGameEnvironment().getItemManager().getNewUserGift(index + 1); + + if (gift != null) { + gift.give(this.client.getHabbo()); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestClubCenterEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestClubCenterEvent.java new file mode 100644 index 0000000..80dede0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestClubCenterEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionHabboClub; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.users.UserClubComposer; + +public class RequestClubCenterEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(SubscriptionHabboClub.calculatePayday(this.client.getHabbo().getHabboInfo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestMeMenuSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestMeMenuSettingsEvent.java new file mode 100644 index 0000000..18aa4e2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestMeMenuSettingsEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.users.MeMenuSettingsComposer; + +public class RequestMeMenuSettingsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new MeMenuSettingsComposer(this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestProfileFriendsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestProfileFriendsEvent.java new file mode 100644 index 0000000..cc6a019 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestProfileFriendsEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.messenger.Messenger; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.users.ProfileFriendsComposer; + +public class RequestProfileFriendsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int userId = this.packet.readInt(); + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + + if (habbo != null) + this.client.sendResponse(new ProfileFriendsComposer(habbo)); + else + this.client.sendResponse(new ProfileFriendsComposer(Messenger.getFriends(userId), userId)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserCitizinShipEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserCitizinShipEvent.java new file mode 100644 index 0000000..81844d6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserCitizinShipEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.users.UserCitizinShipComposer; + +public class RequestUserCitizinShipEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new UserCitizinShipComposer(this.packet.readString())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserClubEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserClubEvent.java new file mode 100644 index 0000000..34fb490 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserClubEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.users.UserClubComposer; + +public class RequestUserClubEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String subscriptionType = this.packet.readString(); + this.client.sendResponse(new UserClubComposer(this.client.getHabbo(), subscriptionType)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserCreditsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserCreditsEvent.java new file mode 100644 index 0000000..e581fdb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserCreditsEvent.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.users.UserCreditsComposer; +import com.eu.habbo.messages.outgoing.users.UserCurrencyComposer; + +public class RequestUserCreditsEvent extends MessageHandler { + @Override + public void handle() { + this.client.sendResponse(new UserCreditsComposer(this.client.getHabbo())); + this.client.sendResponse(new UserCurrencyComposer(this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserDataEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserDataEvent.java new file mode 100644 index 0000000..4ac06b6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserDataEvent.java @@ -0,0 +1,64 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.RoomManager; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.ForwardToRoomComposer; +import com.eu.habbo.messages.outgoing.users.MeMenuSettingsComposer; +import com.eu.habbo.messages.outgoing.users.UserDataComposer; +import com.eu.habbo.messages.outgoing.users.UserPerksComposer; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; + +@Slf4j +public class RequestUserDataEvent extends MessageHandler { + + @Override + public void handle() throws Exception { + if (this.client.getHabbo() != null) { + //this.client.sendResponse(new TestComposer()); + + //this.client.sendResponse(new UserDataComposer(this.client.getHabbo())); + //this.client.sendResponse(new HotelViewComposer()); + //this.client.sendResponse(new UserHomeRoomComposer()); + //this.client.sendResponse(new UserPermissionsComposer(this.client.getHabbo())); + + //this.client.sendResponse(new UserCreditsComposer(this.client.getHabbo())); + //this.client.sendResponse(new UserCurrencyComposer(this.client.getHabbo())); + //this.client.sendResponse(new FavoriteRoomsCountComposer()); + + //this.client.sendResponse(new UserAchievementScoreComposer(this.client.getHabbo())); + //this.client.sendResponse(new UserClothesComposer()); + //this.client.sendResponse(new GenericAlertComposer(Emulator.getTexts().getValue("hotel.alert.message.welcome").replace("%user%", this.client.getHabbo().getHabboInfo().getUsername()), this.client.getHabbo())); + + + // + + ArrayList messages = new ArrayList<>(); + + + messages.add(new UserDataComposer(this.client.getHabbo()).compose()); + messages.add(new UserPerksComposer(this.client.getHabbo()).compose()); + + messages.add(new MeMenuSettingsComposer(this.client.getHabbo()).compose()); + + +// +// + +// +// +// + + + this.client.sendResponses(messages); + + + } else { + log.debug("Attempted to request user data where Habbo was null."); + Emulator.getGameServer().getGameClientManager().disposeClient(this.client); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserProfileEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserProfileEvent.java new file mode 100644 index 0000000..e95b7e7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserProfileEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.users.UserProfileComposer; + +public class RequestUserProfileEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int habboId = this.packet.readInt(); + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(habboId); + + if (habbo != null) + this.client.sendResponse(new UserProfileComposer(habbo, this.client)); + else + this.client.sendResponse(new UserProfileComposer(HabboManager.getOfflineHabboInfo(habboId), this.client)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserWardrobeEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserWardrobeEvent.java new file mode 100644 index 0000000..0e133e0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserWardrobeEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.users.UserWardrobeComposer; + +public class RequestUserWardrobeEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.sendResponse(new UserWardrobeComposer(this.client.getHabbo().getInventory().getWardrobeComponent())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestWearingBadgesEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestWearingBadgesEvent.java new file mode 100644 index 0000000..ade93a2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/RequestWearingBadgesEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.inventory.BadgesComponent; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.users.UserBadgesComposer; + +public class RequestWearingBadgesEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int userId = this.packet.readInt(); + Habbo habbo = Emulator.getGameServer().getGameClientManager().getHabbo(userId); + + if (habbo == null || habbo.getHabboInfo() == null || habbo.getInventory() == null || habbo.getInventory().getBadgesComponent() == null) + this.client.sendResponse(new UserBadgesComposer(BadgesComponent.getBadgesOfflineHabbo(userId), userId)); + else + this.client.sendResponse(new UserBadgesComposer(habbo.getInventory().getBadgesComponent().getWearingBadges(), habbo.getHabboInfo().getId())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveBlockCameraFollowEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveBlockCameraFollowEvent.java new file mode 100644 index 0000000..f1d6634 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveBlockCameraFollowEvent.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.users.UserSavedSettingsEvent; + +public class SaveBlockCameraFollowEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.getHabbo().getHabboStats().blockCameraFollow = this.packet.readBoolean(); + Emulator.getPluginManager().fireEvent(new UserSavedSettingsEvent(this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveIgnoreRoomInvitesEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveIgnoreRoomInvitesEvent.java new file mode 100644 index 0000000..b12024c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveIgnoreRoomInvitesEvent.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.users.UserSavedSettingsEvent; + +public class SaveIgnoreRoomInvitesEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.getHabbo().getHabboStats().blockRoomInvites = this.packet.readBoolean(); + Emulator.getPluginManager().fireEvent(new UserSavedSettingsEvent(this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveMottoEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveMottoEvent.java new file mode 100644 index 0000000..50d0f9a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveMottoEvent.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer; +import com.eu.habbo.plugin.events.users.UserSavedMottoEvent; + +public class SaveMottoEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String motto = this.packet.readString(); + UserSavedMottoEvent event = new UserSavedMottoEvent(this.client.getHabbo(), this.client.getHabbo().getHabboInfo().getMotto(), motto); + Emulator.getPluginManager().fireEvent(event); + motto = event.newMotto; + + if(motto.length() <= Emulator.getConfig().getInt("motto.max_length", 38)) { + this.client.getHabbo().getHabboInfo().setMotto(motto); + this.client.getHabbo().getHabboInfo().run(); + } + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) { + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserDataComposer(this.client.getHabbo()).compose()); + } else { + this.client.sendResponse(new RoomUserDataComposer(this.client.getHabbo())); + } + + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("Motto")); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SavePreferOldChatEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SavePreferOldChatEvent.java new file mode 100644 index 0000000..6fbc3b2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SavePreferOldChatEvent.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.users.UserSavedSettingsEvent; + +public class SavePreferOldChatEvent extends MessageHandler { + @Override + public void handle() throws Exception { + this.client.getHabbo().getHabboStats().preferOldChat = this.packet.readBoolean(); + Emulator.getPluginManager().fireEvent(new UserSavedSettingsEvent(this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveUserVolumesEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveUserVolumesEvent.java new file mode 100644 index 0000000..ff50cb9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveUserVolumesEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.users.UserSavedSettingsEvent; + +public class SaveUserVolumesEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int system = this.packet.readInt(); + int furni = this.packet.readInt(); + int trax = this.packet.readInt(); + + this.client.getHabbo().getHabboStats().volumeSystem = system; + this.client.getHabbo().getHabboStats().volumeFurni = furni; + this.client.getHabbo().getHabboStats().volumeTrax = trax; + + Emulator.getPluginManager().fireEvent(new UserSavedSettingsEvent(this.client.getHabbo())); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveWardrobeEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveWardrobeEvent.java new file mode 100644 index 0000000..9462542 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/SaveWardrobeEvent.java @@ -0,0 +1,34 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.habbohotel.users.inventory.WardrobeComponent; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.plugin.events.users.UserSavedWardrobeEvent; + +public class SaveWardrobeEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int slotId = this.packet.readInt(); + String look = this.packet.readString(); + String gender = this.packet.readString(); + + WardrobeComponent.WardrobeItem wardrobeItem; + if (this.client.getHabbo().getInventory().getWardrobeComponent().getLooks().containsKey(slotId)) { + wardrobeItem = this.client.getHabbo().getInventory().getWardrobeComponent().getLooks().get(slotId); + wardrobeItem.setGender(HabboGender.valueOf(gender)); + wardrobeItem.setLook(look); + wardrobeItem.setNeedsUpdate(true); + } else { + wardrobeItem = this.client.getHabbo().getInventory().getWardrobeComponent().createLook(this.client.getHabbo(), slotId, look); + wardrobeItem.setGender(HabboGender.valueOf(gender)); + wardrobeItem.setNeedsInsert(true); + this.client.getHabbo().getInventory().getWardrobeComponent().getLooks().put(slotId, wardrobeItem); + } + + UserSavedWardrobeEvent wardrobeEvent = new UserSavedWardrobeEvent(this.client.getHabbo(), wardrobeItem); + Emulator.getPluginManager().fireEvent(wardrobeEvent); + + Emulator.getThreading().run(wardrobeItem); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UpdateUIFlagsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UpdateUIFlagsEvent.java new file mode 100644 index 0000000..8983b29 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UpdateUIFlagsEvent.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.messages.incoming.MessageHandler; + +public class UpdateUIFlagsEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int flags = this.packet.readInt(); + + this.client.getHabbo().getHabboStats().uiFlags = flags; + this.client.getHabbo().getHabboStats().run(); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UserActivityEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UserActivityEvent.java new file mode 100644 index 0000000..4afb28f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UserActivityEvent.java @@ -0,0 +1,51 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class UserActivityEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String type = this.packet.readString(); + String value = this.packet.readString(); + String action = this.packet.readString(); + + switch (type) { + case "Quiz": + if (value.equalsIgnoreCase("7")) { + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SafetyQuizGraduate")); + } + } + + switch (action) { + case "forum.can.read.seen": + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModForumCanReadSeen")); + break; + case "forum.can.post.seen": + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModForumCanPostSeen")); + break; + case "forum.can.start.thread.seen": + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModForumCanPostThrdSeen")); + break; + case "forum.can.moderate.seen": + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModForumCanModerateSeen")); + break; + case "room.settings.doormode.seen": + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModDoorModeSeen")); + break; + case "room.settings.walkthrough.seen": + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModWalkthroughSeen")); + break; + case "room.settings.chat.scrollspeed.seen": + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModChatScrollSpeedSeen")); + break; + case "room.settings.chat.hearrange.seen": + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModChatHearRangeSeen")); + break; + case "room.settings.chat.floodfilter.seen": + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("SelfModChatFloodFilterSeen")); + break; + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UserNuxEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UserNuxEvent.java new file mode 100644 index 0000000..f29fe54 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UserNuxEvent.java @@ -0,0 +1,46 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.habboway.nux.NuxAlertComposer; + +import java.util.HashMap; +import java.util.Map; + +public class UserNuxEvent extends MessageHandler { + public static Map keys = new HashMap() { + { + this.put(1, "BOTTOM_BAR_RECEPTION"); + this.put(2, "BOTTOM_BAR_NAVIGATOR"); + this.put(3, "CHAT_INPUT"); + this.put(4, "CHAT_HISTORY_BUTTON"); + this.put(5, "MEMENU_CLOTHES"); + this.put(6, "BOTTOM_BAR_CATALOGUE"); + this.put(7, "CREDITS_BUTTON"); + this.put(8, "DUCKETS_BUTTON"); + this.put(9, "DIAMONDS_BUTTON"); + this.put(10, "FRIENDS_BAR_ALL_FRIENDS"); + this.put(11, "BOTTOM_BAR_NAVIGATOR"); + } + }; + + public static void handle(Habbo habbo) { + habbo.getHabboStats().nux = true; + int step = habbo.getHabboStats().nuxStep++; + + if (keys.containsKey(step)) { + habbo.getClient().sendResponse(new NuxAlertComposer("helpBubble/add/" + keys.get(step) + "/" + Emulator.getTexts().getValue("nux.step." + step))); + } else if (!habbo.getHabboStats().nuxReward) { + + + } else { + habbo.getClient().sendResponse(new NuxAlertComposer("nux/lobbyoffer/show")); + } + } + + @Override + public void handle() throws Exception { + handle(this.client.getHabbo()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UserSaveLookEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UserSaveLookEvent.java new file mode 100644 index 0000000..d278253 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UserSaveLookEvent.java @@ -0,0 +1,47 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.modtool.ScripterManager; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.habbohotel.users.clothingvalidation.ClothingValidationManager; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer; +import com.eu.habbo.messages.outgoing.users.UpdateUserLookComposer; +import com.eu.habbo.plugin.events.users.UserSavedLookEvent; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class UserSaveLookEvent extends MessageHandler { + @Override + public void handle() throws Exception { + String genderCode = this.packet.readString(); + HabboGender gender; + + try { + gender = HabboGender.valueOf(genderCode); + } catch (IllegalArgumentException e) { + String message = Emulator.getTexts().getValue("scripter.warning.look.gender").replace("%username%", this.client.getHabbo().getHabboInfo().getUsername()).replace("%gender%", genderCode); + ScripterManager.scripterDetected(this.client, message); + log.info(message); + return; + } + + String look = this.packet.readString(); + + UserSavedLookEvent lookEvent = new UserSavedLookEvent(this.client.getHabbo(), gender, look); + Emulator.getPluginManager().fireEvent(lookEvent); + if (lookEvent.isCancelled()) + return; + + this.client.getHabbo().getHabboInfo().setLook(ClothingValidationManager.VALIDATE_ON_CHANGE_LOOKS ? ClothingValidationManager.validateLook(this.client.getHabbo(), lookEvent.newLook, lookEvent.gender.name()) : lookEvent.newLook); + this.client.getHabbo().getHabboInfo().setGender(lookEvent.gender); + Emulator.getThreading().run(this.client.getHabbo().getHabboInfo()); + this.client.sendResponse(new UpdateUserLookComposer(this.client.getHabbo())); + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) { + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserDataComposer(this.client.getHabbo()).compose()); + } + + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("AvatarLooks")); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UserWearBadgeEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UserWearBadgeEvent.java new file mode 100644 index 0000000..19d7589 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/users/UserWearBadgeEvent.java @@ -0,0 +1,44 @@ +package com.eu.habbo.messages.incoming.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.habbohotel.users.inventory.BadgesComponent; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.users.UserBadgesComposer; + +import java.util.ArrayList; + +public class UserWearBadgeEvent extends MessageHandler { + @Override + public void handle() throws Exception { + BadgesComponent.resetSlots(this.client.getHabbo()); + + ArrayList updatedBadges = new ArrayList<>(); + ArrayList usedSlots = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + int slot = this.packet.readInt(); + if (slot < 1 || slot > 5) + return; + + String badgeId = this.packet.readString(); + + if (badgeId.length() == 0) + continue; + + HabboBadge badge = this.client.getHabbo().getInventory().getBadgesComponent().getBadge(badgeId); + if (badge != null && !updatedBadges.contains(badge) && !usedSlots.contains(slot)) { + usedSlots.add(slot); + badge.setSlot(slot); + badge.needsUpdate(true); + Emulator.getThreading().run(badge); + updatedBadges.add(badge); + } + } + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != null) { + this.client.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new UserBadgesComposer(updatedBadges, this.client.getHabbo().getHabboInfo().getId()).compose()); + } else { + this.client.sendResponse(new UserBadgesComposer(updatedBadges, this.client.getHabbo().getHabboInfo().getId())); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredApplySetConditionsEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredApplySetConditionsEvent.java new file mode 100644 index 0000000..1d9266f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredApplySetConditionsEvent.java @@ -0,0 +1,103 @@ +package com.eu.habbo.messages.incoming.wired; + +import com.eu.habbo.habbohotel.items.interactions.wired.interfaces.InteractionWiredMatchFurniSettings; +import com.eu.habbo.habbohotel.rooms.FurnitureMovementError; +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.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class WiredApplySetConditionsEvent extends MessageHandler { + + @Override + public int getRatelimit() { + return 500; + } + + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + // Executing Habbo has to be in a Room + if (!this.client.getHabbo().getRoomUnit().isInRoom()) { + this.client.sendResponse(new BubbleAlertComposer( + BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, + FurnitureMovementError.NO_RIGHTS.errorCode + )); + return; + } + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + + // Executing Habbo should be able to edit wireds + if (room.hasRights(this.client.getHabbo()) || room.isOwner(this.client.getHabbo())) { + + List wireds = new ArrayList<>(); + wireds.addAll(room.getRoomSpecialTypes().getConditions()); + wireds.addAll(room.getRoomSpecialTypes().getEffects()); + + // Find the item with the given ID in the room + Optional item = wireds.stream() + .filter(wired -> wired.getId() == itemId) + .findFirst(); + + // If the item exists + if (item.isPresent()) { + HabboItem wiredItem = item.get(); + + // The item should have settings to match furni state, position and rotation + if (wiredItem instanceof InteractionWiredMatchFurniSettings) { + + InteractionWiredMatchFurniSettings wired = (InteractionWiredMatchFurniSettings) wiredItem; + + // Try to apply the set settings to each item + wired.getMatchFurniSettings().forEach(setting -> { + HabboItem matchItem = room.getHabboItem(setting.item_id); + + // Match state + if (wired.shouldMatchState() && matchItem.allowWiredResetState()) { + if (!setting.state.equals(" ") && !matchItem.getExtradata().equals(setting.state)) { + matchItem.setExtradata(setting.state); + room.updateItemState(matchItem); + } + } + + RoomTile oldLocation = room.getLayout().getTile(matchItem.getX(), matchItem.getY()); + double oldZ = matchItem.getZ(); + + // Match Position & Rotation + if(wired.shouldMatchRotation() && !wired.shouldMatchPosition()) { + if(matchItem.getRotation() != setting.rotation && room.furnitureFitsAt(oldLocation, matchItem, setting.rotation, false) == FurnitureMovementError.NONE) { + room.moveFurniTo(matchItem, oldLocation, setting.rotation, null, true); + } + } + else if(wired.shouldMatchPosition()) { + boolean slideAnimation = !wired.shouldMatchRotation() || matchItem.getRotation() == setting.rotation; + RoomTile newLocation = room.getLayout().getTile((short) setting.x, (short) setting.y); + int newRotation = wired.shouldMatchRotation() ? setting.rotation : matchItem.getRotation(); + + if(newLocation != null && newLocation.state != RoomTileState.INVALID && (newLocation != oldLocation || newRotation != matchItem.getRotation()) && room.furnitureFitsAt(newLocation, matchItem, newRotation, true) == FurnitureMovementError.NONE) { + if(room.moveFurniTo(matchItem, newLocation, newRotation, null, !slideAnimation) == FurnitureMovementError.NONE) { + if(slideAnimation) { + room.sendComposer(new FloorItemOnRollerComposer(matchItem, null, oldLocation, oldZ, newLocation, matchItem.getZ(), 0, room).compose()); + } + } + } + } + }); + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredConditionSaveDataEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredConditionSaveDataEvent.java new file mode 100644 index 0000000..93972ee --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredConditionSaveDataEvent.java @@ -0,0 +1,33 @@ +package com.eu.habbo.messages.incoming.wired; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.wired.WiredSavedComposer; + +public class WiredConditionSaveDataEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + if (room.hasRights(this.client.getHabbo()) || room.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER) || this.client.getHabbo().hasPermission(Permission.ACC_MOVEROTATE)) { + InteractionWiredCondition condition = room.getRoomSpecialTypes().getCondition(itemId); + + if (condition != null) { + if (condition.saveData(this.packet)) { + this.client.sendResponse(new WiredSavedComposer()); + + condition.needsUpdate(true); + + Emulator.getThreading().run(condition); + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredEffectSaveDataEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredEffectSaveDataEvent.java new file mode 100644 index 0000000..fbf5122 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredEffectSaveDataEvent.java @@ -0,0 +1,39 @@ +package com.eu.habbo.messages.incoming.wired; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.generic.alerts.GenericErrorMessagesComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.UpdateFailedComposer; +import com.eu.habbo.messages.outgoing.wired.WiredSavedComposer; + +public class WiredEffectSaveDataEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + if (room.hasRights(this.client.getHabbo()) || room.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER) || this.client.getHabbo().hasPermission(Permission.ACC_MOVEROTATE)) { + InteractionWiredEffect effect = room.getRoomSpecialTypes().getEffect(itemId); + + try { + if (effect == null) + throw new WiredSaveException(String.format("Wired effect with item id %s not found in room", itemId)); + + if (effect.saveData(this.packet, this.client)) { + this.client.sendResponse(new WiredSavedComposer()); + effect.needsUpdate(true); + Emulator.getThreading().run(effect); + } + } + catch (WiredSaveException e) { + this.client.sendResponse(new UpdateFailedComposer(e.getMessage())); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredSaveException.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredSaveException.java new file mode 100644 index 0000000..74feda1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredSaveException.java @@ -0,0 +1,15 @@ +package com.eu.habbo.messages.incoming.wired; + +public class WiredSaveException extends Exception { + + private final String message; + + public WiredSaveException(String message) { + this.message = message; + } + + @Override + public String getMessage() { + return this.message; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredTriggerSaveDataEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredTriggerSaveDataEvent.java new file mode 100644 index 0000000..8f62f60 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredTriggerSaveDataEvent.java @@ -0,0 +1,33 @@ +package com.eu.habbo.messages.incoming.wired; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.incoming.MessageHandler; +import com.eu.habbo.messages.outgoing.wired.WiredSavedComposer; + +public class WiredTriggerSaveDataEvent extends MessageHandler { + @Override + public void handle() throws Exception { + int itemId = this.packet.readInt(); + + Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom(); + + if (room != null) { + if (room.hasRights(this.client.getHabbo()) || room.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER) || this.client.getHabbo().hasPermission(Permission.ACC_MOVEROTATE)) { + InteractionWiredTrigger trigger = room.getRoomSpecialTypes().getTrigger(itemId); + + if (trigger != null) { + if (trigger.saveData(this.packet)) { + this.client.sendResponse(new WiredSavedComposer()); + + trigger.needsUpdate(true); + + Emulator.getThreading().run(trigger); + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/MessageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/MessageComposer.java new file mode 100644 index 0000000..d55e8db --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/MessageComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing; + +import com.eu.habbo.messages.ServerMessage; + +public abstract class MessageComposer { + + private ServerMessage composed; + protected final ServerMessage response; + + protected MessageComposer() { + this.composed = null; + this.response = new ServerMessage(); + } + + protected abstract ServerMessage composeInternal(); + + public ServerMessage compose() { + if (this.composed == null) { + this.composed = this.composeInternal(); + } + + return this.composed; + } + +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/Outgoing.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/Outgoing.java new file mode 100644 index 0000000..173ec13 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/Outgoing.java @@ -0,0 +1,557 @@ +package com.eu.habbo.messages.outgoing; + +public class Outgoing { + public static final int PetStatusUpdateComposer = 1907;//error 404 + + public final static int CfhTopicsMessageComposer = 325; + public final static int FavoriteRoomsCountComposer = 151; + public final static int UserCurrencyComposer = 2018; + public final static int RedeemVoucherOKComposer = 3336; + public final static int RoomUserShoutComposer = 1036; + public final static int RoomUserStatusComposer = 1640; + public final static int RoomUserDataComposer = 3920; + public final static int RoomAddRightsListComposer = 2088; + public final static int RoomRemoveRightsListComposer = 1327; + public final static int RoomRightsListComposer = 1284; + public final static int RoomUserHandItemComposer = 1474; + public final static int RoomUsersComposer = 374; + public final static int FriendRequestComposer = 2219; + public final static int GuildBoughtComposer = 2808; + public final static int AddUserBadgeComposer = 2493; + public final static int RecyclerCompleteComposer = 468; + public final static int GuildBuyRoomsComposer = 2159; + public final static int FriendsComposer = 3130; + public final static int StalkErrorComposer = 3048; + public final static int TradeCloseWindowComposer = 1001; + public final static int RemoveFloorItemComposer = 2703; + public final static int InventoryPetsComposer = 3522; + public final static int UserCreditsComposer = 3475; + public final static int WiredTriggerDataComposer = 383; + public final static int TradeStoppedComposer = 1373; + public final static int ModToolUserChatlogComposer = 3377; + public final static int GuildInfoComposer = 1702; + public final static int UserPermissionsComposer = 411; + public final static int PetNameErrorComposer = 1503; + public final static int TradeStartFailComposer = 217; + public final static int AddHabboItemComposer = 2103; + public final static int InventoryBotsComposer = 3086; + public final static int CanCreateRoomComposer = 378; + public final static int MarketplaceBuyErrorComposer = 2032; + public final static int BonusRareComposer = 1533; + public final static int HotelViewComposer = 122; + public final static int UpdateFriendComposer = 2800; + public final static int FloorItemUpdateComposer = 3776; + public final static int RoomAccessDeniedComposer = 878; + public final static int GuildFurniWidgetComposer = 3293; + public final static int GiftConfigurationComposer = 2234; + public final static int UserClubComposer = 954; + public final static int InventoryBadgesComposer = 717; + public final static int RoomUserTypingComposer = 1717; + public final static int GuildJoinErrorComposer = 762; + public final static int RoomCategoriesComposer = 1562; + public final static int InventoryAchievementsComposer = 2501; + public final static int MarketplaceItemInfoComposer = 725; + public final static int RoomRelativeMapComposer = 2753; + public final static int ModToolComposerTwo = 2335; + public final static int ModToolComposerOne = 3192; + public final static int RoomRightsComposer = 780; + public final static int ObjectOnRollerComposer = 3207; + public final static int PollStartComposer = 3785; + public final static int GuildRefreshMembersListComposer = 2445; + public final static int UserPerksComposer = 2586; + public final static int UserCitizinShipComposer = 1203; + public final static int PublicRoomsComposer = -1;//error 404 + public final static int MarketplaceOffersComposer = 680; + public final static int ModToolComposer = 2696; + public final static int UserBadgesComposer = 1087; + public final static int GuildManageComposer = 3965; + public final static int RemoveFriendComposer = -1;//error 404 + public final static int InitDiffieHandshakeComposer = 1347; + public final static int CompleteDiffieHandshakeComposer = 3885; + public final static int UserDataComposer = 2725; + public final static int UserSearchResultComposer = 973; + public final static int ModToolUserRoomVisitsComposer = 1752; + public final static int RoomUserRespectComposer = 2815; + public final static int RoomChatSettingsComposer = 1191; + public final static int RemoveHabboItemComposer = 159; + public final static int RoomUserRemoveComposer = 2661; + public final static int RoomHeightMapComposer = 1301; + public final static int RoomPetHorseFigureComposer = 1924; + public final static int PetErrorComposer = 2913; + public final static int TradeUpdateComposer = 2024; + public final static int PrivateRoomsComposer = 52; + public final static int RoomModelComposer = 2031; + public final static int RoomScoreComposer = 482; + public final static int DoorbellAddUserComposer = 2309; + public final static int SecureLoginOKComposer = 2491; + public final static int AvailabilityStatusMessageComposer = 2033; + public final static int GuildMemberUpdateComposer = 265; + public final static int RoomFloorItemsComposer = 1778; + public final static int InventoryItemsComposer = 994; + public final static int RoomUserTalkComposer = 1446; + public final static int TradeStartComposer = 2505; + public final static int InventoryItemUpdateComposer = 104; + public final static int ModToolIssueUpdateComposer = 3150; + public final static int MeMenuSettingsComposer = 513; + public final static int ModToolRoomInfoComposer = 1333; + public final static int GuildListComposer = 420; + public final static int RecyclerLogicComposer = 3164; + public final static int UserHomeRoomComposer = 2875; + public final static int RoomUserDanceComposer = 2233; + public final static int RoomSettingsUpdatedComposer = 3297; + public final static int AlertPurchaseFailedComposer = 1404; + public final static int RoomDataComposer = 687; + public final static int TagsComposer = 2012; + public final static int InventoryRefreshComposer = 3151; // PRODUCTION-201611291003-338511768 + public final static int RemovePetComposer = 3253; // PRODUCTION-201611291003-338511768 + public final static int RemoveWallItemComposer = 3208; // PRODUCTION-201611291003-338511768 + public final static int TradeCompleteComposer = 2369; // PRODUCTION-201611291003-338511768 + public final static int NewsWidgetsComposer = 286; // PRODUCTION-201611291003-338511768 + public final static int WiredEffectDataComposer = 1434; // PRODUCTION-201611291003-338511768 + public final static int BubbleAlertComposer = 1992; // PRODUCTION-201611291003-338511768 + public final static int ReloadRecyclerComposer = 3433; // PRODUCTION-201611291003-338511768 + public final static int MoodLightDataComposer = 2710; // PRODUCTION-201611291003-338511768 + public final static int WiredRewardAlertComposer = 178; // PRODUCTION-201611291003-338511768 + public final static int CatalogPageComposer = 804; // PRODUCTION-201611291003-338511768 + public final static int CatalogModeComposer = 3828; // PRODUCTION-201611291003-338511768 + public final static int ChangeNameUpdateComposer = 118; // PRODUCTION-201611291003-338511768 + public final static int AddFloorItemComposer = 1534; // PRODUCTION-201611291003-338511768 + public final static int EnableNotificationsComposer = 3284; // PRODUCTION-201611291003-338511768 + public final static int HallOfFameComposer = 3005; // PRODUCTION-201611291003-338511768 + public final static int WiredSavedComposer = 1155; // PRODUCTION-201611291003-338511768 + public final static int RoomPaintComposer = 2454; // PRODUCTION-201611291003-338511768 + public final static int MarketplaceConfigComposer = 1823; // PRODUCTION-201611291003-338511768 + public final static int AddBotComposer = 1352; // PRODUCTION-201611291003-338511768 + public final static int FriendRequestErrorComposer = 892; // PRODUCTION-201611291003-338511768 + public final static int GuildMembersComposer = 1200; // PRODUCTION-201611291003-338511768 + public final static int RoomOpenComposer = 758; // PRODUCTION-201611291003-338511768 + public final static int ModToolRoomChatlogComposer = 3434; // PRODUCTION-201611291003-338511768 + public final static int DiscountComposer = 2347; // PRODUCTION-201611291003-338511768 + public final static int MarketplaceCancelSaleComposer = 3264; // PRODUCTION-201611291003-338511768 + public final static int RoomPetRespectComposer = 2788; // PRODUCTION-201611291003-338511768 + public final static int RoomSettingsComposer = 1498; // PRODUCTION-201611291003-338511768 + public final static int TalentTrackComposer = 3406; // PRODUCTION-201611291003-338511768 + public final static int CatalogPagesListComposer = 1032; // PRODUCTION-201611291003-338511768 + public final static int AlertLimitedSoldOutComposer = 377; // PRODUCTION-201611291003-338511768 + public final static int CatalogUpdatedComposer = 1866; // PRODUCTION-201611291003-338511768 + public final static int PurchaseOKComposer = 869; // PRODUCTION-201611291003-338511768 + public final static int WallItemUpdateComposer = 2009; // PRODUCTION-201611291003-338511768 + public final static int TradeAcceptedComposer = 2568; // PRODUCTION-201611291003-338511768 + public final static int AddWallItemComposer = 2187; // PRODUCTION-201611291003-338511768 + public final static int RoomEntryInfoComposer = -1; // PRODUCTION-201611291003-338511768 + public final static int HotelViewDataComposer = 1745; // PRODUCTION-201611291003-338511768 + public final static int PresentItemOpenedComposer = 56; // PRODUCTION-201611291003-338511768 + public final static int RoomUserRemoveRightsComposer = 84; // PRODUCTION-201611291003-338511768 + public final static int UserBCLimitsComposer = -1; // PRODUCTION-201611291003-338511768 + public final static int PetTrainingPanelComposer = 1164; // PRODUCTION-201611291003-338511768 + public final static int RoomPaneComposer = 749; // PRODUCTION-201611291003-338511768 + public final static int RedeemVoucherErrorComposer = 714; // PRODUCTION-201611291003-338511768 + public final static int RoomCreatedComposer = 1304; // PRODUCTION-201611291003-338511768 + public final static int GenericAlertComposer = 3801; // PRODUCTION-201611291003-338511768 + public final static int GroupPartsComposer = 2238; // PRODUCTION-201611291003-338511768 + public final static int ModToolIssueInfoComposer = 3609; // PRODUCTION-201611291003-338511768 + public final static int RoomUserWhisperComposer = 2704; // PRODUCTION-201611291003-338511768 + public final static int BotErrorComposer = 639; // PRODUCTION-201611291003-338511768 + public final static int FreezeLivesComposer = 2324; // PRODUCTION-201611291003-338511768 + public final static int LoadFriendRequestsComposer = 280; // PRODUCTION-201611291003-338511768 + public final static int MarketplaceSellItemComposer = 54; // PRODUCTION-201611291003-338511768 + public final static int ClubDataComposer = 2405; // PRODUCTION-201611291003-338511768 + public final static int ProfileFriendsComposer = 2016; // PRODUCTION-201611291003-338511768 + public final static int MarketplaceOwnItemsComposer = 3884; // PRODUCTION-201611291003-338511768 + public final static int RoomOwnerComposer = 339; // PRODUCTION-201611291003-338511768 + public final static int WiredConditionDataComposer = 1108; // PRODUCTION-201611291003-338511768 + public final static int ModToolUserInfoComposer = 2866; // PRODUCTION-201611291003-338511768 + public final static int UserWardrobeComposer = 3315; // PRODUCTION-201611291003-338511768 + public final static int RoomPetExperienceComposer = 2156; // PRODUCTION-201611291003-338511768 + public final static int FriendChatMessageComposer = 1587; // PRODUCTION-201611291003-338511768 + public final static int PetInformationComposer = 2901; // PRODUCTION-201611291003-338511768 + public final static int RoomThicknessComposer = 3547; // PRODUCTION-201611291003-338511768 + public final static int AddPetComposer = 2101; // PRODUCTION-201611291003-338511768 + public final static int UpdateStackHeightComposer = 558; // PRODUCTION-201611291003-338511768 + public final static int RemoveBotComposer = 233; // PRODUCTION-201611291003-338511768 + public final static int RoomEnterErrorComposer = 899; // PRODUCTION-201611291003-338511768 + public final static int PollQuestionsComposer = 2997; // PRODUCTION-201611291003-338511768 + public final static int GenericErrorMessages = 1600; // PRODUCTION-201611291003-338511768 + public final static int RoomWallItemsComposer = 1369; // PRODUCTION-201611291003-338511768 + public final static int RoomUserEffectComposer = 1167; // PRODUCTION-201611291003-338511768 + public final static int PetBreedsComposer = 3331; // PRODUCTION-201611291003-338511768 + public final static int ModToolIssueChatlogComposer = 607; // PRODUCTION-201611291003-338511768 + public final static int RoomUserActionComposer = 1631; // PRODUCTION-201611291003-338511768 + public final static int BotSettingsComposer = 1618; // PRODUCTION-201611291003-338511768 + public final static int UserProfileComposer = 3898; // PRODUCTION-201611291003-338511768 + public final static int MinimailCountComposer = 2803; // PRODUCTION-201611291003-338511768 + public final static int UserAchievementScoreComposer = 1968; // PRODUCTION-201611291003-338511768 + public final static int PetLevelUpComposer = 859; // PRODUCTION-201611291003-338511768 + public final static int UserPointsComposer = 2275; // PRODUCTION-201611291003-338511768 + public final static int ReportRoomFormComposer = 1121; // PRODUCTION-201611291003-338511768 + public final static int ModToolIssueHandledComposer = 934; // PRODUCTION-201611291003-338511768 + public final static int FloodCounterComposer = 566; // PRODUCTION-201611291003-338511768 + public final static int UpdateFailedComposer = 156; // PRODUCTION-201611291003-338511768 + public final static int FloorPlanEditorDoorSettingsComposer = 1664; // PRODUCTION-201611291003-338511768 + public final static int FloorPlanEditorBlockedTilesComposer = 3990; // PRODUCTION-201611291003-338511768 + public final static int BuildersClubExpiredComposer = 1452; // PRODUCTION-201611291003-338511768 + public final static int RoomSettingsSavedComposer = 948; // PRODUCTION-201611291003-338511768 + public final static int MessengerInitComposer = 1605; // PRODUCTION-201611291003-338511768 + public final static int UserClothesComposer = 1450; // PRODUCTION-201611291003-338511768 + public final static int UserEffectsListComposer = 340; // PRODUCTION-201611291003-338511768 + public final static int NewUserIdentityComposer = 3738; // PRODUCTION-201611291003-338511768 + public final static int NewNavigatorEventCategoriesComposer = 3244; // PRODUCTION-201611291003-338511768 + public final static int NewNavigatorCollapsedCategoriesComposer = 1543; // PRODUCTION-201611291003-338511768 + public final static int NewNavigatorLiftedRoomsComposer = 3104; // PRODUCTION-201611291003-338511768 + public final static int NewNavigatorSavedSearchesComposer = 3984; // PRODUCTION-201611291003-338511768 + public final static int PostItDataComposer = 2202; // PRODUCTION-201611291003-338511768 + public final static int ModToolReportReceivedAlertComposer = 3635; // PRODUCTION-201611291003-338511768 + public final static int ModToolIssueResponseAlertComposer = 3796; // PRODUCTION-201611291003-338511768 + public final static int AchievementListComposer = 305; // PRODUCTION-201611291003-338511768 + public final static int AchievementProgressComposer = 2107; // PRODUCTION-201611291003-338511768 + public final static int AchievementUnlockedComposer = 806; // PRODUCTION-201611291003-338511768 + public final static int ClubGiftsComposer = 619; // PRODUCTION-201611291003-338511768 + public final static int MachineIDComposer = 1488; // PRODUCTION-201611291003-338511768 + public final static int PongComposer = 10; // PRODUCTION-201611291003-338511768 + public final static int ModToolIssueHandlerDimensionsComposer = 1576; // PRODUCTION-201611291003-338511768 + + //Uknown but work + public final static int IsFirstLoginOfDayComposer = 793; // PRODUCTION-201611291003-338511768 //Quest Engine + public final static int MysteryBoxKeysComposer = 2833; // PRODUCTION-201611291003-338511768 //Mysterbox + public final static int IgnoredUsersComposer = 126; // PRODUCTION-201611291003-338511768 + public final static int NewNavigatorMetaDataComposer = 3052; // PRODUCTION-201611291003-338511768 + public final static int NewNavigatorSearchResultsComposer = 2690; // PRODUCTION-201611291003-338511768 + public final static int MysticBoxStartOpenComposer = 3201; // PRODUCTION-201611291003-338511768 + public final static int MysticBoxCloseComposer = 596; // PRODUCTION-201611291003-338511768 + public final static int MysticBoxPrizeComposer = 3712; // PRODUCTION-201611291003-338511768 + public final static int RentableSpaceInfoComposer = 3559; // PRODUCTION-201611291003-338511768 + public final static int RentableSpaceUnknownComposer = 2046; // PRODUCTION-201611291003-338511768 + public final static int RentableSpaceUnknown2Composer = 1868; // PRODUCTION-201611291003-338511768 + public final static int GuildConfirmRemoveMemberComposer = 1876; // PRODUCTION-201611291003-338511768 + + public final static int HotelViewBadgeButtonConfigComposer = 2998; // PRODUCTION-201611291003-338511768 + public final static int EpicPopupFrameComposer = 3945; // PRODUCTION-201611291003-338511768 + public final static int BaseJumpLoadGameURLComposer = 2624; // PRODUCTION-201611291003-338511768 + public final static int RoomUserTagsComposer = 1255; // PRODUCTION-201611291003-338511768 + public final static int RoomInviteErrorComposer = 462; // PRODUCTION-201611291003-338511768 + public final static int PostItStickyPoleOpenComposer = 2366; // PRODUCTION-201611291003-338511768 + public final static int NewYearResolutionProgressComposer = 3370; // PRODUCTION-201611291003-338511768 + public final static int ClubGiftReceivedComposer = 659; // PRODUCTION-201611291003-338511768 + public final static int ItemStateComposer = 2376; // PRODUCTION-201611291003-338511768 + public final static int ItemExtraDataComposer = 2547; // PRODUCTION-201611291003-338511768 + public final static int PostUpdateMessageComposer = 324; // PRODUCTION-201611291003-338511768 + //NotSure Needs Testing + public final static int QuestionInfoComposer = -1; // PRODUCTION-201611291003-338511768 + public final static int TalentTrackEmailVerifiedComposer = 612; // PRODUCTION-201611291003-338511768 + public final static int TalentTrackEmailFailedComposer = 1815; // PRODUCTION-201611291003-338511768 + public final static int UnknownAvatarEditorComposer = 3473; // PRODUCTION-201611291003-338511768 + + public final static int GuildMembershipRequestedComposer = 1180; // PRODUCTION-201611291003-338511768 + + public final static int GuildForumsUnreadMessagesCountComposer = 2379; // PRODUCTION-201611291003-338511768 + public final static int GuildForumThreadMessagesComposer = 1862; // PRODUCTION-201611291003-338511768 + public final static int GuildForumAddCommentComposer = 2049; // PRODUCTION-201611291003-338511768 + public final static int GuildForumDataComposer = 3011; // PRODUCTION-201611291003-338511768 + public final static int GuildForumCommentsComposer = 509; // PRODUCTION-201611291003-338511768 + public final static int UnknownGuildForumComposer6 = -1; // PRODUCTION-201611291003-338511768 + public final static int UnknownGuildForumComposer7 = -1; // PRODUCTION-201611291003-338511768 + public final static int GuildForumThreadsComposer = 1073; // PRODUCTION-201611291003-338511768 + public final static int GuildForumListComposer = 3001; // PRODUCTION-201611291003-338511768 + public final static int ThreadUpdateMessageComposer = 2528; + public final static int GuideSessionAttachedComposer = 1591; // PRODUCTION-201611291003-338511768 + public final static int GuideSessionDetachedComposer = 138; // PRODUCTION-201611291003-338511768 + public final static int GuideSessionStartedComposer = 3209; // PRODUCTION-201611291003-338511768 + public final static int GuideSessionEndedComposer = 1456; // PRODUCTION-201611291003-338511768 + public final static int GuideSessionErrorComposer = 673; // PRODUCTION-201611291003-338511768 + public final static int GuideSessionMessageComposer = 841; // PRODUCTION-201611291003-338511768 + public final static int GuideSessionRequesterRoomComposer = 1847; // PRODUCTION-201611291003-338511768 + public final static int GuideSessionInvitedToGuideRoomComposer = 219; // PRODUCTION-201611291003-338511768 + public final static int GuideSessionPartnerIsTypingComposer = 1016; // PRODUCTION-201611291003-338511768 + + public final static int GuideToolsComposer = 1548; // PRODUCTION-201611291003-338511768 + public final static int GuardianNewReportReceivedComposer = 735; // PRODUCTION-201611291003-338511768 + public final static int GuardianVotingRequestedComposer = 143; // PRODUCTION-201611291003-338511768 + public final static int GuardianVotingVotesComposer = 1829; // PRODUCTION-201611291003-338511768 + public final static int GuardianVotingResultComposer = 3276; // PRODUCTION-201611291003-338511768 + public final static int GuardianVotingTimeEnded = 30; // PRODUCTION-201611291003-338511768 + + public final static int RoomMutedComposer = 2533; // PRODUCTION-201611291003-338511768 + + public final static int HideDoorbellComposer = 3783; // PRODUCTION-201611291003-338511768 + public final static int RoomQueueStatusMessage = 2208; // PRODUCTION-201611291003-338511768 + public final static int RoomUnknown3Composer = 1033; // PRODUCTION-201611291003-338511768 + + public final static int EffectsListRemoveComposer = 2228; // PRODUCTION-201611291003-338511768 + + public final static int OldPublicRoomsComposer = 2726; // PRODUCTION-201611291003-338511768 + public final static int ItemStateComposer2 = 3431; // PRODUCTION-201611291003-338511768 + + public final static int HotelWillCloseInMinutesComposer = 1050; // PRODUCTION-201611291003-338511768 + public final static int HotelWillCloseInMinutesAndBackInComposer = 1350; // PRODUCTION-201611291003-338511768 + public final static int HotelClosesAndWillOpenAtComposer = 2771; // PRODUCTION-201611291003-338511768 + public final static int HotelClosedAndOpensComposer = 3728; // PRODUCTION-201611291003-338511768 + public final static int StaffAlertAndOpenHabboWayComposer = 1683; // PRODUCTION-201611291003-338511768 + public final static int StaffAlertWithLinkComposer = 2030; // PRODUCTION-201611291003-338511768 + public final static int StaffAlertWIthLinkAndOpenHabboWayComposer = 1890; // PRODUCTION-201611291003-338511768 + + public final static int RoomMessagesPostedCountComposer = 1634; // PRODUCTION-201611291003-338511768 + public final static int CantScratchPetNotOldEnoughComposer = 1130; // PRODUCTION-201611291003-338511768 + public final static int PetBoughtNotificationComposer = 1111; // PRODUCTION-201611291003-338511768 + public final static int MessagesForYouComposer = 2035; // PRODUCTION-201611291003-338511768 + public final static int UnknownStatusComposer = 1243; // PRODUCTION-201611291003-338511768 + public final static int CloseWebPageComposer = 426; // PRODUCTION-201611291003-338511768 + public final static int PickMonthlyClubGiftNotificationComposer = 2188; // PRODUCTION-201611291003-338511768 + public final static int RemoveGuildFromRoomComposer = 3129; // PRODUCTION-201611291003-338511768 + public final static int RoomBannedUsersComposer = 1869; // PRODUCTION-201611291003-338511768 + public final static int OpenRoomCreationWindowComposer = 2064; // PRODUCTION-201611291003-338511768 + public final static int ItemsDataUpdateComposer = 1453; // PRODUCTION-201611291003-338511768 + public final static int WelcomeGiftComposer = 2707; // PRODUCTION-201611291003-338511768 + public final static int SimplePollStartComposer = 2665; // PRODUCTION-201611291003-338511768 + public final static int RoomNoRightsComposer = 2392; // PRODUCTION-201611291003-338511768 + public final static int GuildEditFailComposer = 3988; // PRODUCTION-201611291003-338511768 + public final static int MinimailNewMessageComposer = 1911; // PRODUCTION-201611291003-338511768 + public final static int RoomFilterWordsComposer = 2937; // PRODUCTION-201611291003-338511768 + public final static int VerifyMobileNumberComposer = 3639; // PRODUCTION-201611291003-338511768 + public final static int NewUserGiftComposer = 3575; // PRODUCTION-201611291003-338511768 + public final static int UpdateUserLookComposer = 2429; // PRODUCTION-201611291003-338511768 + public final static int RoomUserIgnoredComposer = 207; // PRODUCTION-201611291003-338511768 + public final static int PetBreedingFailedComposer = 1625; // PRODUCTION-201611291003-338511768 + public final static int RoomUserNameChangedComposer = 2182; // PRODUCTION-201611291003-338511768 + public final static int LoveLockFurniStartComposer = 3753; // PRODUCTION-201611291003-338511768 + public final static int LoveLockFurniFriendConfirmedComposer = 382; // PRODUCTION-201611291003-338511768 + public final static int LoveLockFurniFinishedComposer = 770; // PRODUCTION-201611291003-338511768 + public final static int PetPackageNameValidationComposer = 546; // PRODUCTION-201611291003-338511768 + public final static int GameCenterFeaturedPlayersComposer = 3097; // PRODUCTION-201611291003-338511768 + public final static int HabboMallComposer = 1237; // PRODUCTION-201611291003-338511768 + public final static int TargetedOfferComposer = 119; // PRODUCTION-201611291003-338511768 + public final static int LeprechaunStarterBundleComposer = 2380; // PRODUCTION-201611291003-338511768 + public final static int VerifyMobilePhoneWindowComposer = 2890; // PRODUCTION-201611291003-338511768 + public final static int VerifyMobilePhoneCodeWindowComposer = 800; // PRODUCTION-201611291003-338511768 + public final static int VerifyMobilePhoneDoneComposer = 91; // PRODUCTION-201611291003-338511768 + public final static int RoomUserReceivedHandItemComposer = 354; // PRODUCTION-201611291003-338511768 + public final static int MutedWhisperComposer = 826; // PRODUCTION-201611291003-338511768 + public final static int UnknownHintComposer = 1787; // PRODUCTION-201611291003-338511768 + public final static int BullyReportClosedComposer = 2674; // PRODUCTION-201611291003-338511768 + public final static int PromoteOwnRoomsListComposer = 2468; // PRODUCTION-201611291003-338511768 + public final static int NotEnoughPointsTypeComposer = 3914; // PRODUCTION-201611291003-338511768 + public final static int WatchAndEarnRewardComposer = 2125; // PRODUCTION-201611291003-338511768 + public final static int NewYearResolutionComposer = 66; // PRODUCTION-201611291003-338511768 + public final static int WelcomeGiftErrorComposer = 2293; // PRODUCTION-201611291003-338511768 + public final static int RentableItemBuyOutPriceComposer = 35; // PRODUCTION-201611291003-338511768 + public final static int VipTutorialsStartComposer = 2278; // PRODUCTION-201611291003-338511768 + public final static int NewNavigatorCategoryUserCountComposer = 1455; // PRODUCTION-201611291003-338511768 + public final static int CameraRoomThumbnailSavedComposer = 3595; // PRODUCTION-201611291003-338511768 + public final static int RoomEditSettingsErrorComposer = 1555; // PRODUCTION-201611291003-338511768 + public final static int GuildAcceptMemberErrorComposer = 818; // PRODUCTION-201611291003-338511768 + public final static int MostUselessErrorAlertComposer = 662; // PRODUCTION-201611291003-338511768 + public final static int AchievementsConfigurationComposer = 1689; // PRODUCTION-201611291003-338511768 + public final static int PetBreedingResultComposer = 634; // PRODUCTION-201611291003-338511768 + public final static int RoomUserQuestionAnsweredComposer = -1; // PRODUCTION-201611291003-338511768 + public final static int PetBreedingStartComposer = 1746; // PRODUCTION-201611291003-338511768 + public final static int CustomNotificationComposer = 909; // PRODUCTION-201611291003-338511768 + public final static int UpdateStackHeightTileHeightComposer = 2816; // PRODUCTION-201611291003-338511768 + public final static int HotelViewCustomTimerComposer = -1; // PRODUCTION-201611291003-338511768 + public final static int MarketplaceItemPostedComposer = 1359; // PRODUCTION-201611291003-338511768 + public final static int HabboWayQuizComposer2 = 2927; // PRODUCTION-201611291003-338511768 + public final static int GuildFavoriteRoomUserUpdateComposer = 3403; // PRODUCTION-201611291003-338511768 + public final static int RoomAdErrorComposer = 1759; // PRODUCTION-201611291003-338511768 + public final static int NewNavigatorSettingsComposer = 518; // PRODUCTION-201611291003-338511768 + public final static int CameraPublishWaitMessageComposer = 2057; // PRODUCTION-201611291003-338511768 + public final static int RoomInviteComposer = 3870; // PRODUCTION-201611291003-338511768 + public final static int BullyReportRequestComposer = 3463; // PRODUCTION-201611291003-338511768 + public final static int UnknownHelperComposer = 77; // PRODUCTION-201611291003-338511768 + public final static int HelperRequestDisabledComposer = 1651; // PRODUCTION-201611291003-338511768 + public final static int RoomUnitIdleComposer = 1797; // PRODUCTION-201611291003-338511768 + public final static int QuestCompletedComposer = 949; // PRODUCTION-201611291003-338511768 + public final static int UnkownPetPackageComposer = 1723; // PRODUCTION-201611291003-338511768 + public final static int ForwardToRoomComposer = 160; // PRODUCTION-201611291003-338511768 + public final static int EffectsListEffectEnableComposer = 1959; // PRODUCTION-201611291003-338511768 + public final static int CompetitionEntrySubmitResultComposer = 1177; // PRODUCTION-201611291003-338511768 + public final static int ExtendClubMessageComposer = 3964; // PRODUCTION-201611291003-338511768 + public final static int HotelViewConcurrentUsersComposer = 2737; // PRODUCTION-201611291003-338511768 + public final static int InventoryAddEffectComposer = -1;//error 404 + public final static int TalentLevelUpdateComposer = 638; // PRODUCTION-201611291003-338511768 + public final static int BullyReportedMessageComposer = 3285; // PRODUCTION-201611291003-338511768 + public final static int UnknownQuestComposer3 = 1122; // PRODUCTION-201611291003-338511768 + public final static int FriendToolbarNotificationComposer = 3082; // PRODUCTION-201611291003-338511768 + public final static int MessengerErrorComposer = 896; // PRODUCTION-201611291003-338511768 + public final static int CameraPriceComposer = 3878; // PRODUCTION-201611291003-338511768 + public final static int PetBreedingCompleted = 2527; // PRODUCTION-201611291003-338511768 + public final static int RoomUserUnbannedComposer = 3429; // PRODUCTION-201611291003-338511768 + public final static int HotelViewCommunityGoalComposer = 2525; // PRODUCTION-201611291003-338511768 + public final static int UserClassificationComposer = 966; // PRODUCTION-201611291003-338511768 + public final static int CanCreateEventComposer = 2599; // PRODUCTION-201611291003-338511768 + public final static int UnknownGuild2Composer = 1459; // PRODUCTION-201611291003-338511768 + public final static int YoutubeDisplayListComposer = 1112; // PRODUCTION-201611291003-338511768 + public final static int YoutubeMessageComposer2 = 1411; // PRODUCTION-201611291003-338511768 + public final static int YoutubeMessageComposer3 = 1554; // PRODUCTION-201611291003-338511768 + public final static int RoomCategoryUpdateMessageComposer = 3896; // PRODUCTION-201611291003-338511768 + public final static int QuestsComposer = 3625; // PRODUCTION-201611291003-338511768 + public final static int GiftReceiverNotFoundComposer = 1517; // PRODUCTION-201611291003-338511768 + public final static int ConvertedForwardToRoomComposer = 1331; // PRODUCTION-201611291003-338511768 + public final static int FavoriteRoomChangedComposer = 2524; // PRODUCTION-201611291003-338511768 + public final static int AlertPurchaseUnavailableComposer = 3770; // PRODUCTION-201611291003-338511768 + public final static int PetBreedingStartFailedComposer = 2621; // PRODUCTION-201611291003-338511768 + public final static int DailyQuestComposer = 1878; // PRODUCTION-201611291003-338511768 + public final static int HotelViewHideCommunityVoteButtonComposer = 1435; // PRODUCTION-201611291003-338511768 + public final static int CatalogSearchResultComposer = 3388; // PRODUCTION-201611291003-338511768 + public final static int FriendFindingRoomComposer = 1210; // PRODUCTION-201611291003-338511768 + public final static int QuestComposer = 230; // PRODUCTION-201611291003-338511768 + public final static int ModToolSanctionDataComposer = 2782; // PRODUCTION-201611291003-338511768 + public final static int RoomEventMessageComposer = 1840; + + + public final static int JukeBoxMySongsComposer = 2602; // PRODUCTION-201611291003-338511768 + public final static int JukeBoxNowPlayingMessageComposer = 469; // PRODUCTION-201611291003-338511768 + public final static int JukeBoxPlaylistFullComposer = 105; // PRODUCTION-201611291003-338511768 + public final static int JukeBoxPlayListUpdatedComposer = 1748; // PRODUCTION-201611291003-338511768 + public final static int JukeBoxPlayListAddSongComposer = 1140; // PRODUCTION-201611291003-338511768 + public final static int JukeBoxPlayListComposer = 34; // PRODUCTION-201611291003-338511768 + public final static int JukeBoxTrackDataComposer = 3365; // PRODUCTION-201611291003-338511768 + public final static int JukeBoxTrackCodeComposer = 1381; // PRODUCTION-201611291003-338511768 + + + public final static int CraftableProductsComposer = 1000; // PRODUCTION-201611291003-338511768 + public final static int CraftingRecipeComposer = 2774; // PRODUCTION-201611291003-338511768 + public final static int CraftingResultComposer = 618; // PRODUCTION-201611291003-338511768 + public final static int CraftingComposerFour = 2124; // PRODUCTION-201611291003-338511768 + + public final static int UnknownComposer_100 = 1553; // PRODUCTION-201611291003-338511768 //PetBReedingResult + public final static int ConnectionErrorComposer = 1004; // PRODUCTION-201611291003-338511768 + public final static int BotForceOpenContextMenuComposer = 296; // PRODUCTION-201611291003-338511768 + public final static int UnknownComposer_1111 = 1551; // PRODUCTION-201611291003-338511768 + public final static int Game2WeeklyLeaderboardComposer = 2196; // PRODUCTION-201611291003-338511768 + public final static int UnknownComposer_1165 = 904; // PRODUCTION-201611291003-338511768 + public final static int EffectsListAddComposer = 2867; // PRODUCTION-201611291003-338511768 + public final static int UnknownComposer_1188 = 1437; // PRODUCTION-201611291003-338511768 + public final static int SubmitCompetitionRoomComposer = 3841; // PRODUCTION-201611291003-338511768 + public final static int GameAchievementsListComposer = 2265; // PRODUCTION-201611291003-338511768 + public final static int OtherTradingDisabledComposer = 1254; // PRODUCTION-201611291003-338511768 + public final static int BaseJumpUnloadGameComposer = 1715; // PRODUCTION-201611291003-338511768 + public final static int UnknownComposer_137 = 2897; // PRODUCTION-201611291003-338511768 + public final static int GameCenterAccountInfoComposer = 2893; // PRODUCTION-201611291003-338511768 + public final static int UnknowComposer_1390 = 2270; // PRODUCTION-201611291003-338511768 + public final static int BaseJumpLoadGameComposer = 3654; // PRODUCTION-201611291003-338511768 + public final static int UnknowComposer_1427 = 3319; // PRODUCTION-201611291003-338511768 + public final static int AdventCalendarDataComposer = 2531; // PRODUCTION-201611291003-338511768 + public final static int UnknownComposer_152 = 3954; // PRODUCTION-201611291003-338511768 + public final static int UnknownComposer_1577 = 2641; // PRODUCTION-201611291003-338511768 + public final static int NewYearResolutionCompletedComposer = 740; // PRODUCTION-201611291003-338511768 + public final static int UnknownComposer_1741 = 2246; // PRODUCTION-201611291003-338511768 + public final static int UnknownComposer_1744 = 2873; // PRODUCTION-201611291003-338511768 + public final static int AdventCalendarProductComposer = 2551; // PRODUCTION-201611291003-338511768 + public final static int ModToolSanctionInfoComposer = 2221; // PRODUCTION-201611291003-338511768 + public final static int UnknownComposer_1965 = 3292; // PRODUCTION-201611291003-338511768 + public final static int GuideSessionPartnerIsPlayingComposer = 448; // PRODUCTION-201611291003-338511768 + public final static int BaseJumpLeaveQueueComposer = 1477; // PRODUCTION-201611291003-338511768 + public final static int Game2WeeklySmallLeaderboardComposer = 3512; // PRODUCTION-201611291003-338511768 + public final static int GameCenterGameListComposer = 222; // PRODUCTION-201611291003-338511768 + public final static int RoomUsersGuildBadgesComposer = 2402; // PRODUCTION-201611291003-338511768 + public final static int UnknownComposer_2563 = 1774; // PRODUCTION-201611291003-338511768 + public final static int UnknownComposer_2601 = 1663; // PRODUCTION-201611291003-338511768 + public final static int UnknownComposer_2621 = 1927; // PRODUCTION-201611291003-338511768 + public final static int UnknownComposer_2698 = 563; // PRODUCTION-201611291003-338511768 + // 2699; +// 2748; +// 2773; +// 2964; +// 3020; +// 3024; +// 3046; +// 3124; +// 3179; +// 3189; +// 328; +// 3291; +// 3334; + public final static int HabboWayQuizComposer1 = 3379; + // 3391; +// 3427; +// 347; +// 3509; +// 3519; +// 3581; +// 3684; + public final static int YouTradingDisabledComposer = 3058; // PRODUCTION-201611291003-338511768 + // 3707; +// 3745; +// 3759; +// 3782; + public final static int RoomFloorThicknessUpdatedComposer = 3786; + // 3822; + public final static int CameraPurchaseSuccesfullComposer = 2783; // PRODUCTION-201611291003-338511768 + public final static int CameraCompetitionStatusComposer = 133; // PRODUCTION-201611291003-338511768 + // 3986; +// 467; +// 549; + public final static int CameraURLComposer = 3696; // PRODUCTION-201611291003-338511768 + // 608; +// 624; +// 675; + public final static int HotelViewCatalogPageExpiringComposer = 690; +// 749; +// 812; +// 843; +// 947; +// 982; + + + public final static int SimplePollAnswerComposer = 2589; + + public final static int PingComposer = 3928; + public final static int TradingWaitingConfirmComposer = 2720; + public final static int BaseJumpJoinQueueComposer = 2260; + public final static int ClubCenterDataComposer = 3277; + + public final static int SimplePollAnswersComposer = 1066; + public final static int UnknownFurniModelComposer = 1501; + public final static int UnknownAdManagerComposer = 1808; + public final static int WiredOpenComposer = 1830; + public final static int UnknownCatalogPageOfferComposer = 1889; + public final static int NuxAlertComposer = 2023; + public final static int HotelViewExpiringCatalogPageCommposer = 2515; + public final static int UnknownHabboWayQuizComposer = 2772; + public final static int PetLevelUpdatedComposer = 2824; + public final static int QuestExpiredComposer = 3027; + public final static int UnknownTradeComposer = 3128; + public final static int UnknownMessengerErrorComposer = 3359; + public final static int UnknownComposer8 = 3441; + public final static int RemoveRoomEventComposer = 3479; + public final static int UnknownCompetitionComposer = 3506; + public final static int UnknownRoomViewerComposer = 3523; + public final static int ErrorLoginComposer = 4000; + public final static int HotelViewNextLTDAvailableComposer = 44; + public final static int HotelViewSecondsUntilComposer = 3926; + public final static int UnknownRoomDesktopComposer = 69; + public final static int UnknownGuildComposer3 = 876; + + public final static int GameCenterGameComposer = 3805; + + + public static final int SnowStormGameStartedComposer = 5000; + public static final int SnowStormQuePositionComposer = 5001; + public static final int SnowStormStartBlockTickerComposer = 5002; + public static final int SnowStormStartLobbyCounterComposer = 5003; + public static final int SnowStormUnusedAlertGenericComposer = 5004; + public static final int SnowStormLongDataComposer = 5005; + public static final int SnowStormGameEndedComposer = 5006; + public static final int SnowStormQuePlayerAddedComposer = 5008; + public static final int SnowStormPlayAgainComposer = 5009; + public static final int SnowStormGamesLeftComposer = 5010; + public static final int SnowStormQuePlayerRemovedComposer = 5011; + public static final int SnowStormGamesInformationComposer = 5012; + public static final int SnowStormLongData2Composer = 5013; + public static final int UNUSED_SNOWSTORM_5014 = 5014; + public static final int SnowStormGameStatusComposer = 5015; + public static final int SnowStormFullGameStatusComposer = 5016; + public static final int SnowStormOnStageStartComposer = 5017; + public static final int SnowStormIntializeGameArenaViewComposer = 5018; + public static final int SnowStormRejoinPreviousRoomComposer = 5019; + public static final int UNKNOWN_SNOWSTORM_5020 = 5020; + public static final int SnowStormLevelDataComposer = 5021; + public static final int SnowStormOnGameEndingComposer = 5022; + public static final int SnowStormUserChatMessageComposer = 5023; + public static final int SnowStormOnStageRunningComposer = 5024; + public static final int SnowStormOnStageEndingComposer = 5025; + public static final int SnowStormIntializedPlayersComposer = 5026; + public static final int SnowStormOnPlayerExitedArenaComposer = 5027; + public static final int SnowStormGenericErrorComposer = 5028; + public static final int SnowStormUserRematchedComposer = 5029; + + +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/AchievementListComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/AchievementListComposer.java new file mode 100644 index 0000000..e68b4ce --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/AchievementListComposer.java @@ -0,0 +1,59 @@ +package com.eu.habbo.messages.outgoing.achievements; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.achievements.AchievementLevel; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +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.Outgoing; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AchievementListComposer extends MessageComposer { + private final Habbo habbo; + + public AchievementListComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.AchievementListComposer); + + try { + this.response.appendInt(Emulator.getGameEnvironment().getAchievementManager().getAchievements().size()); + + for (Achievement achievement : Emulator.getGameEnvironment().getAchievementManager().getAchievements().values()) { + int achievementProgress; + AchievementLevel currentLevel; + AchievementLevel nextLevel; + + achievementProgress = this.habbo.getHabboStats().getAchievementProgress(achievement); + currentLevel = achievement.getLevelForProgress(achievementProgress); + nextLevel = achievement.getNextLevel(currentLevel != null ? currentLevel.level : 0); + + this.response.appendInt(achievement.id); //ID + this.response.appendInt(nextLevel != null ? nextLevel.level : currentLevel != null ? currentLevel.level : 0); // + this.response.appendString("ACH_" + achievement.name + (nextLevel != null ? nextLevel.level : currentLevel != null ? currentLevel.level : 0)); //Target badge code + this.response.appendInt(currentLevel != null ? currentLevel.progress : 0); //Last level progress needed + this.response.appendInt(nextLevel != null ? nextLevel.progress : -1); //Progress needed + this.response.appendInt(nextLevel != null ? nextLevel.rewardAmount : -1); //Reward amount + this.response.appendInt(nextLevel != null ? nextLevel.rewardType : -1); //Reward currency ID + this.response.appendInt(achievementProgress <= 0 ? 0 : achievementProgress); //Current progress + this.response.appendBoolean(AchievementManager.hasAchieved(this.habbo, achievement)); //Achieved? (Current Progress == MaxLevel.Progress) + this.response.appendString(achievement.category.toString().toLowerCase()); //Category + this.response.appendString(""); //Empty, completly unused in client code + this.response.appendInt(achievement.levels.size()); //Count of total levels in this achievement + this.response.appendInt(AchievementManager.hasAchieved(this.habbo, achievement) ? 1 : 0); //1 = Progressbar visible if the achievement is completed + } + + this.response.appendString(""); + } catch (Exception e) { + log.error("Caught exception", e); + } + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/AchievementProgressComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/AchievementProgressComposer.java new file mode 100644 index 0000000..8cf649b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/AchievementProgressComposer.java @@ -0,0 +1,59 @@ +package com.eu.habbo.messages.outgoing.achievements; + +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.achievements.AchievementLevel; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +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.Outgoing; + +public class AchievementProgressComposer extends MessageComposer { + private final Habbo habbo; + private final Achievement achievement; + + public AchievementProgressComposer(Habbo habbo, Achievement achievement) { + this.habbo = habbo; + this.achievement = achievement; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.AchievementProgressComposer); + + int achievementProgress; + AchievementLevel currentLevel; + AchievementLevel nextLevel; + + achievementProgress = this.habbo.getHabboStats().getAchievementProgress(this.achievement); + currentLevel = this.achievement.getLevelForProgress(achievementProgress); + nextLevel = this.achievement.getNextLevel(currentLevel != null ? currentLevel.level : 0); + + if (currentLevel != null && currentLevel.level == this.achievement.levels.size()) + nextLevel = null; + + int targetLevel = 1; + + if (nextLevel != null) + targetLevel = nextLevel.level; + + if (currentLevel != null && currentLevel.level == this.achievement.levels.size()) + targetLevel = currentLevel.level; + + this.response.appendInt(this.achievement.id); //ID + this.response.appendInt(targetLevel); //Target level + this.response.appendString("ACH_" + this.achievement.name + targetLevel); //Target badge code + this.response.appendInt(currentLevel != null ? currentLevel.progress : 0); //Last level progress needed + this.response.appendInt(nextLevel != null ? nextLevel.progress : 0); //Progress needed + this.response.appendInt(nextLevel != null ? nextLevel.rewardAmount : 0); //Reward amount + this.response.appendInt(nextLevel != null ? nextLevel.rewardType : 0); //Reward currency ID + this.response.appendInt(achievementProgress == -1 ? 0 : achievementProgress); //Current progress + this.response.appendBoolean(AchievementManager.hasAchieved(this.habbo, this.achievement)); //Achieved? (Current Progress == MaxLevel.Progress) + this.response.appendString(this.achievement.category.toString().toLowerCase()); //Category + this.response.appendString(""); //Empty, completly unused in client code + this.response.appendInt(this.achievement.levels.size()); //Count of total levels in this achievement + this.response.appendInt(0); //1 = Progressbar visible if the achievement is completed + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/AchievementUnlockedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/AchievementUnlockedComposer.java new file mode 100644 index 0000000..ca2449f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/AchievementUnlockedComposer.java @@ -0,0 +1,38 @@ +package com.eu.habbo.messages.outgoing.achievements; + +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.achievements.AchievementLevel; +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.Outgoing; + +public class AchievementUnlockedComposer extends MessageComposer { + private final Achievement achievement; + private final Habbo habbo; + + public AchievementUnlockedComposer(Habbo habbo, Achievement achievement) { + this.achievement = achievement; + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.AchievementUnlockedComposer); + + AchievementLevel level = this.achievement.getLevelForProgress(this.habbo.getHabboStats().getAchievementProgress(this.achievement)); + this.response.appendInt(this.achievement.id); + this.response.appendInt(level.level); + this.response.appendInt(144); + this.response.appendString("ACH_" + this.achievement.name + level.level); + this.response.appendInt(level.rewardAmount); + this.response.appendInt(level.rewardType); + this.response.appendInt(0); + this.response.appendInt(10); + this.response.appendInt(21); + this.response.appendString(level.level > 1 ? "ACH_" + this.achievement.name + (level.level - 1) : ""); + this.response.appendString(this.achievement.category.name()); + this.response.appendBoolean(true); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/talenttrack/TalentLevelUpdateComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/talenttrack/TalentLevelUpdateComposer.java new file mode 100644 index 0000000..3a51535 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/talenttrack/TalentLevelUpdateComposer.java @@ -0,0 +1,41 @@ +package com.eu.habbo.messages.outgoing.achievements.talenttrack; + +import com.eu.habbo.habbohotel.achievements.TalentTrackLevel; +import com.eu.habbo.habbohotel.achievements.TalentTrackType; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class TalentLevelUpdateComposer extends MessageComposer { + private final TalentTrackType talentTrackType; + private final TalentTrackLevel talentTrackLevel; + + public TalentLevelUpdateComposer(TalentTrackType talentTrackType, TalentTrackLevel talentTrackLevel) { + this.talentTrackType = talentTrackType; + this.talentTrackLevel = talentTrackLevel; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.TalentLevelUpdateComposer); + this.response.appendString(this.talentTrackType.name()); + this.response.appendInt(this.talentTrackLevel.level); + + if (this.talentTrackLevel.perks != null) { + this.response.appendInt(this.talentTrackLevel.perks.length); + for (String s : this.talentTrackLevel.perks) { + this.response.appendString(s); + } + } else { + this.response.appendInt(0); + } + + this.response.appendInt(this.talentTrackLevel.items.size()); + for (Item item : this.talentTrackLevel.items) { + this.response.appendString(item.getName()); + this.response.appendInt(item.getSpriteId()); + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/talenttrack/TalentTrackComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/talenttrack/TalentTrackComposer.java new file mode 100644 index 0000000..87515a2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/achievements/talenttrack/TalentTrackComposer.java @@ -0,0 +1,130 @@ +package com.eu.habbo.messages.outgoing.achievements.talenttrack; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementLevel; +import com.eu.habbo.habbohotel.achievements.TalentTrackLevel; +import com.eu.habbo.habbohotel.achievements.TalentTrackType; +import com.eu.habbo.habbohotel.items.Item; +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.Outgoing; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.NoSuchElementException; + +public class TalentTrackComposer extends MessageComposer { + public final Habbo habbo; + public final TalentTrackType type; + public TalentTrackComposer(Habbo habbo, TalentTrackType type) { + this.habbo = habbo; + this.type = type; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.TalentTrackComposer); + this.response.appendString(this.type.name().toLowerCase()); + + LinkedHashMap talentTrackLevels = Emulator.getGameEnvironment().getAchievementManager().getTalenTrackLevels(this.type); + if (talentTrackLevels != null) { + this.response.appendInt(talentTrackLevels.size()); //Count + for (Map.Entry set : talentTrackLevels.entrySet()) { + try { + TalentTrackLevel level = set.getValue(); + + this.response.appendInt(level.level); + + TalentTrackState state = TalentTrackState.LOCKED; + + int currentLevel = this.habbo.getHabboStats().talentTrackLevel(this.type); + + if (currentLevel + 1 == level.level) { + state = TalentTrackState.IN_PROGRESS; + } else if (currentLevel >= level.level) { + state = TalentTrackState.COMPLETED; + } + + this.response.appendInt(state.id); + this.response.appendInt(level.achievements.size()); + + final TalentTrackState finalState = state; + level.achievements.forEachEntry((achievement, index) -> { + if (achievement != null) { + this.response.appendInt(achievement.id); + + //TODO Move this to TalenTrackLevel class + this.response.appendInt(index); //idk + this.response.appendString("ACH_" + achievement.name + index); + + int progress = Math.max(0, this.habbo.getHabboStats().getAchievementProgress(achievement)); + AchievementLevel achievementLevel = achievement.getLevelForProgress(progress); + + if (achievementLevel == null) { + achievementLevel = achievement.firstLevel(); + } + if (finalState != TalentTrackState.LOCKED) { + if (achievementLevel != null && achievementLevel.progress <= progress) { + this.response.appendInt(2); + } else { + this.response.appendInt(1); + } + } else { + this.response.appendInt(0); + } + this.response.appendInt(progress); + this.response.appendInt(achievementLevel != null ? achievementLevel.progress : 0); + } else { + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendString(""); + this.response.appendString(""); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + } + return true; + }); + + + if (level.perks != null && level.perks.length > 0) { + this.response.appendInt(level.perks.length); + for (String perk : level.perks) { + this.response.appendString(perk); + } + } else { + this.response.appendInt(-1); + } + + if (!level.items.isEmpty()) { + this.response.appendInt(level.items.size()); + for (Item item : level.items) { + this.response.appendString(item.getName()); + this.response.appendInt(0); + } + } else { + this.response.appendInt(-1); + } + } catch (NoSuchElementException e) { + return null; + } + } + } else { + this.response.appendInt(0); + } + return this.response; + } + + public enum TalentTrackState { + LOCKED(0), + IN_PROGRESS(1), + COMPLETED(2); + + public final int id; + + TalentTrackState(int id) { + this.id = id; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraCompetitionStatusComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraCompetitionStatusComposer.java new file mode 100644 index 0000000..31d4ef6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraCompetitionStatusComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.camera; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CameraCompetitionStatusComposer extends MessageComposer { + private final boolean unknownBoolean; + private final String unknownString; + + public CameraCompetitionStatusComposer(boolean unknownBoolean, String unknownString) { + this.unknownBoolean = unknownBoolean; + this.unknownString = unknownString; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CameraCompetitionStatusComposer); + this.response.appendBoolean(this.unknownBoolean); + this.response.appendString(this.unknownString); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraPriceComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraPriceComposer.java new file mode 100644 index 0000000..133352c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraPriceComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.camera; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CameraPriceComposer extends MessageComposer { + public final int credits; + public final int points; + public final int pointsType; + + public CameraPriceComposer(int credits, int points, int pointsType) { + this.credits = credits; + this.points = points; + this.pointsType = pointsType; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CameraPriceComposer); + this.response.appendInt(this.credits); + this.response.appendInt(this.points); + this.response.appendInt(this.pointsType); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraPublishWaitMessageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraPublishWaitMessageComposer.java new file mode 100644 index 0000000..9c01241 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraPublishWaitMessageComposer.java @@ -0,0 +1,31 @@ +package com.eu.habbo.messages.outgoing.camera; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CameraPublishWaitMessageComposer extends MessageComposer { + public final boolean isOk; + public final int cooldownSeconds; + public final String extraDataId; + + public CameraPublishWaitMessageComposer(boolean isOk, int cooldownSeconds, String extraDataId) { + this.isOk = isOk; + this.cooldownSeconds = cooldownSeconds; + this.extraDataId = extraDataId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CameraPublishWaitMessageComposer); + + this.response.appendBoolean(this.isOk); + this.response.appendInt(this.cooldownSeconds); + + if (!this.extraDataId.isEmpty()) { + this.response.appendString(this.extraDataId); + } + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraPurchaseSuccesfullComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraPurchaseSuccesfullComposer.java new file mode 100644 index 0000000..293f840 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraPurchaseSuccesfullComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.camera; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CameraPurchaseSuccesfullComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CameraPurchaseSuccesfullComposer); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraRoomThumbnailSavedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraRoomThumbnailSavedComposer.java new file mode 100644 index 0000000..3927984 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraRoomThumbnailSavedComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.camera; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CameraRoomThumbnailSavedComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CameraRoomThumbnailSavedComposer); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraURLComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraURLComposer.java new file mode 100644 index 0000000..414f6f5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/camera/CameraURLComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.camera; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CameraURLComposer extends MessageComposer { + private final String URL; + + public CameraURLComposer(String url) { + this.URL = url; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CameraURLComposer); + this.response.appendString(this.URL); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/AlertLimitedSoldOutComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/AlertLimitedSoldOutComposer.java new file mode 100644 index 0000000..d6688e4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/AlertLimitedSoldOutComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class AlertLimitedSoldOutComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.AlertLimitedSoldOutComposer); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/AlertPurchaseFailedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/AlertPurchaseFailedComposer.java new file mode 100644 index 0000000..4a8a456 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/AlertPurchaseFailedComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class AlertPurchaseFailedComposer extends MessageComposer { + public static final int SERVER_ERROR = 0; + public static final int ALREADY_HAVE_BADGE = 1; + + private final int error; + + public AlertPurchaseFailedComposer(int error) { + this.error = error; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.AlertPurchaseFailedComposer); + this.response.appendInt(this.error); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/AlertPurchaseUnavailableComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/AlertPurchaseUnavailableComposer.java new file mode 100644 index 0000000..fb4f809 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/AlertPurchaseUnavailableComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class AlertPurchaseUnavailableComposer extends MessageComposer { + public final static int ILLEGAL = 0; + public final static int REQUIRES_CLUB = 1; + + private final int code; + + public AlertPurchaseUnavailableComposer(int code) { + this.code = code; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.AlertPurchaseUnavailableComposer); + this.response.appendInt(this.code); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogModeComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogModeComposer.java new file mode 100644 index 0000000..4c45a1d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogModeComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CatalogModeComposer extends MessageComposer { + private final int mode; + + public CatalogModeComposer(int mode) { + this.mode = mode; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CatalogModeComposer); + this.response.appendInt(this.mode); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogPageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogPageComposer.java new file mode 100644 index 0000000..0f4d8bd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogPageComposer.java @@ -0,0 +1,71 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.CatalogFeaturedPage; +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.habbohotel.catalog.layouts.FrontPageFeaturedLayout; +import com.eu.habbo.habbohotel.catalog.layouts.FrontpageLayout; +import com.eu.habbo.habbohotel.catalog.layouts.RecentPurchasesLayout; +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.Outgoing; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class CatalogPageComposer extends MessageComposer { + private final CatalogPage page; + private final Habbo habbo; + private final int offerId; + private final String mode; + + public CatalogPageComposer(CatalogPage page, Habbo habbo, int offerId, String mode) { + this.page = page; + this.habbo = habbo; + this.offerId = offerId; + this.mode = mode; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CatalogPageComposer); + this.response.appendInt(this.page.getId()); + this.response.appendString(this.mode); + this.page.serialize(this.response); + + if (this.page instanceof RecentPurchasesLayout) { + this.response.appendInt(this.habbo.getHabboStats().getRecentPurchases().size()); + + for (Map.Entry item : this.habbo.getHabboStats().getRecentPurchases().entrySet()) { + item.getValue().serialize(this.response); + } + } else { + this.response.appendInt(this.page.getCatalogItems().size()); + List items = new ArrayList<>(this.page.getCatalogItems().valueCollection()); + Collections.sort(items); + for (CatalogItem item : items) { + item.serialize(this.response); + } + } + this.response.appendInt(this.offerId); + this.response.appendBoolean(false); //acceptSeasonCurrencyAsCredits + + if (this.page instanceof FrontPageFeaturedLayout || this.page instanceof FrontpageLayout) { + this.serializeExtra(this.response); + } + + return this.response; + } + + public void serializeExtra(ServerMessage message) { + message.appendInt(Emulator.getGameEnvironment().getCatalogManager().getCatalogFeaturedPages().size()); + + for (CatalogFeaturedPage page : Emulator.getGameEnvironment().getCatalogManager().getCatalogFeaturedPages().valueCollection()) { + page.serialize(message); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogPagesListComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogPagesListComposer.java new file mode 100644 index 0000000..a8f0dd9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogPagesListComposer.java @@ -0,0 +1,77 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.habbohotel.permissions.Permission; +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.Outgoing; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +@Slf4j +public class CatalogPagesListComposer extends MessageComposer { + + private final Habbo habbo; + private final String mode; + private final boolean hasPermission; + + public CatalogPagesListComposer(Habbo habbo, String mode) { + this.habbo = habbo; + this.mode = mode; + this.hasPermission = this.habbo.hasPermission(Permission.ACC_CATALOG_IDS); + } + + @Override + protected ServerMessage composeInternal() { + try { + List pages = Emulator.getGameEnvironment().getCatalogManager().getCatalogPages(-1, this.habbo); + + this.response.init(Outgoing.CatalogPagesListComposer); + + this.response.appendBoolean(true); + this.response.appendInt(0); + this.response.appendInt(-1); + this.response.appendString("root"); + this.response.appendString(""); + this.response.appendInt(0); + this.response.appendInt(pages.size()); + + for (CatalogPage category : pages) { + this.append(category); + } + + this.response.appendBoolean(false); + this.response.appendString(this.mode); + + return this.response; + } catch (Exception e) { + log.error("Caught exception", e); + } + + return null; + } + + private void append(CatalogPage category) { + List pagesList = Emulator.getGameEnvironment().getCatalogManager().getCatalogPages(category.getId(), this.habbo); + + this.response.appendBoolean(category.isVisible()); + this.response.appendInt(category.getIconImage()); + this.response.appendInt(category.isEnabled() ? category.getId() : -1); + this.response.appendString(category.getPageName()); + this.response.appendString(category.getCaption() + (this.hasPermission ? " (" + category.getId() + ")" : "")); + this.response.appendInt(category.getOfferIds().size()); + + for (int i : category.getOfferIds().toArray()) { + this.response.appendInt(i); + } + + this.response.appendInt(pagesList.size()); + + for (CatalogPage page : pagesList) { + this.append(page); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogSearchResultComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogSearchResultComposer.java new file mode 100644 index 0000000..640683d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogSearchResultComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CatalogSearchResultComposer extends MessageComposer { + private final CatalogItem item; + + public CatalogSearchResultComposer(CatalogItem item) { + this.item = item; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CatalogSearchResultComposer); + this.item.serialize(this.response); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogUpdatedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogUpdatedComposer.java new file mode 100644 index 0000000..8c82f2c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogUpdatedComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CatalogUpdatedComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CatalogUpdatedComposer); + this.response.appendBoolean(false); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/ClubCenterDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/ClubCenterDataComposer.java new file mode 100644 index 0000000..64e4a3f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/ClubCenterDataComposer.java @@ -0,0 +1,54 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.subscriptions.Subscription; +import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionHabboClub; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + +public class ClubCenterDataComposer extends MessageComposer { + public final int currentHcStreak; + public final String firstSubDate; + public final double kickbackPercentage; + public final int totalCreditsMissed; + public final int totalCreditsRewarded; + public final int totalCreditsSpent; + public final int creditRewardForStreakBonus; + public final int creditRewardForMonthlySpent; + public final int timeUntilPayday; + + public ClubCenterDataComposer(int currentHcStreak, String firstSubDate, double kickbackPercentage, int totalCreditsMissed, int totalCreditsRewarded, int totalCreditsSpent, int creditRewardForStreakBonus, int creditRewardForMonthlySpent, int timeUntilPayday) { + this.currentHcStreak = currentHcStreak; + this.firstSubDate = firstSubDate; + this.kickbackPercentage = kickbackPercentage; + this.totalCreditsMissed = totalCreditsMissed; + this.totalCreditsRewarded = totalCreditsRewarded; + this.totalCreditsSpent = totalCreditsSpent; + this.creditRewardForStreakBonus = creditRewardForStreakBonus; + this.creditRewardForMonthlySpent = creditRewardForMonthlySpent; + this.timeUntilPayday = timeUntilPayday; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ClubCenterDataComposer); + this.response.appendInt(this.currentHcStreak); // currentHcStreak (days) + this.response.appendString(this.firstSubDate); // firstSubscriptionDate (dd-mm-yyyy) + this.response.appendDouble(this.kickbackPercentage); // kickbackPercentage (e.g. 0.1 for 10%) + this.response.appendInt(this.totalCreditsMissed); // (not used) + this.response.appendInt(this.totalCreditsRewarded); // (not used) + this.response.appendInt(this.totalCreditsSpent); + this.response.appendInt(this.creditRewardForStreakBonus); + this.response.appendInt(this.creditRewardForMonthlySpent); + this.response.appendInt(this.timeUntilPayday); // timeUntilPayday (minutes) + return this.response; + } + + +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/ClubDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/ClubDataComposer.java new file mode 100644 index 0000000..96188ad --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/ClubDataComposer.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.ClubOffer; +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.Outgoing; + +import java.util.Calendar; +import java.util.List; + +public class ClubDataComposer extends MessageComposer { + private final int windowId; + private final Habbo habbo; + + public ClubDataComposer(Habbo habbo, int windowId) { + this.habbo = habbo; + this.windowId = windowId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ClubDataComposer); + + List offers = Emulator.getGameEnvironment().getCatalogManager().getClubOffers(); + this.response.appendInt(offers.size()); + + //TODO Change this to a seperate table. + for (ClubOffer offer : offers) { + offer.serialize(this.response, this.habbo.getHabboStats().getClubExpireTimestamp()); + } + + this.response.appendInt(this.windowId); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/ClubGiftsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/ClubGiftsComposer.java new file mode 100644 index 0000000..e45b482 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/ClubGiftsComposer.java @@ -0,0 +1,68 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.habbohotel.catalog.CatalogPageLayouts; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.iterator.TIntObjectIterator; +import gnu.trove.procedure.TObjectProcedure; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.NoSuchElementException; + +public class ClubGiftsComposer extends MessageComposer { + + private final int daysTillNextGift; + private final int availableGifts; + private final int daysAsHc; + + public ClubGiftsComposer(int daysTillNextGift, int availableGifts, int daysAsHc) { + this.daysTillNextGift = daysTillNextGift; + this.availableGifts = availableGifts; + this.daysAsHc = daysAsHc; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ClubGiftsComposer); + + this.response.appendInt(this.daysTillNextGift); //Days Until Next Gift + this.response.appendInt(this.availableGifts); //Gift Selectable + + CatalogPage page = Emulator.getGameEnvironment().getCatalogManager().getCatalogPageByLayout(CatalogPageLayouts.club_gift.name().toLowerCase()); + + if (page != null) { + final List items = new ArrayList<>(page.getCatalogItems().valueCollection()); + Collections.sort(items); + + this.response.appendInt(items.size()); + for(CatalogItem item : items) { + item.serialize(this.response); + } + + this.response.appendInt(items.size()); + for(CatalogItem item : items) { + int daysRequired = 0; + try { + daysRequired = Integer.parseInt(item.getExtradata()); + } + catch (NumberFormatException ignored) { } + + this.response.appendInt(item.getId()); + this.response.appendBoolean(item.isClubOnly()); + this.response.appendInt(daysRequired); + this.response.appendBoolean(daysRequired <= daysAsHc); + } + } else { + this.response.appendInt(0); + this.response.appendInt(0); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/DiscountComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/DiscountComposer.java new file mode 100644 index 0000000..387e2a2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/DiscountComposer.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class DiscountComposer extends MessageComposer { + public static int MAXIMUM_ALLOWED_ITEMS = 100; + public static int DISCOUNT_BATCH_SIZE = 6; + public static int DISCOUNT_AMOUNT_PER_BATCH = 1; + public static int MINIMUM_DISCOUNTS_FOR_BONUS = 1; + public static int[] ADDITIONAL_DISCOUNT_THRESHOLDS = new int[]{40, 99}; + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.DiscountComposer); + + this.response.appendInt(MAXIMUM_ALLOWED_ITEMS); + this.response.appendInt(DISCOUNT_BATCH_SIZE); + this.response.appendInt(DISCOUNT_AMOUNT_PER_BATCH); + this.response.appendInt(MINIMUM_DISCOUNTS_FOR_BONUS); + + this.response.appendInt(ADDITIONAL_DISCOUNT_THRESHOLDS.length); + for (int threshold : ADDITIONAL_DISCOUNT_THRESHOLDS) { + this.response.appendInt(threshold); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/GiftConfigurationComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/GiftConfigurationComposer.java new file mode 100644 index 0000000..7732810 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/GiftConfigurationComposer.java @@ -0,0 +1,45 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +public class GiftConfigurationComposer extends MessageComposer { + public static List BOX_TYPES = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 8); + public static List RIBBON_TYPES = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GiftConfigurationComposer); + this.response.appendBoolean(true); + this.response.appendInt(Emulator.getConfig().getInt("hotel.gifts.special.price", 2)); + + this.response.appendInt(Emulator.getGameEnvironment().getCatalogManager().giftWrappers.size()); + for (Integer i : Emulator.getGameEnvironment().getCatalogManager().giftWrappers.keySet()) { + this.response.appendInt(i); + } + + this.response.appendInt(BOX_TYPES.size()); + for (Integer type : BOX_TYPES) { + this.response.appendInt(type); + } + + this.response.appendInt(RIBBON_TYPES.size()); + for (Integer type : RIBBON_TYPES) { + this.response.appendInt(type); + } + + this.response.appendInt(Emulator.getGameEnvironment().getCatalogManager().giftFurnis.size()); + + for (Map.Entry set : Emulator.getGameEnvironment().getCatalogManager().giftFurnis.entrySet()) { + this.response.appendInt(set.getKey()); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/GiftReceiverNotFoundComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/GiftReceiverNotFoundComposer.java new file mode 100644 index 0000000..27ee4e3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/GiftReceiverNotFoundComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GiftReceiverNotFoundComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GiftReceiverNotFoundComposer); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/NotEnoughPointsTypeComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/NotEnoughPointsTypeComposer.java new file mode 100644 index 0000000..ec20a8a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/NotEnoughPointsTypeComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class NotEnoughPointsTypeComposer extends MessageComposer { + private final boolean isCredits; + private final boolean isPixels; + private final int pointsType; + + public NotEnoughPointsTypeComposer(boolean isCredits, boolean isPixels, int pointsType) { + this.isCredits = isCredits; + this.isPixels = isPixels; + this.pointsType = pointsType; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.NotEnoughPointsTypeComposer); + this.response.appendBoolean(this.isCredits); + this.response.appendBoolean(this.isPixels); + this.response.appendInt(this.pointsType); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/PetBoughtNotificationComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/PetBoughtNotificationComposer.java new file mode 100644 index 0000000..f2ed562 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/PetBoughtNotificationComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PetBoughtNotificationComposer extends MessageComposer { + private final Pet pet; + private final boolean gift; + + public PetBoughtNotificationComposer(Pet pet, boolean gift) { + this.pet = pet; + this.gift = gift; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PetBoughtNotificationComposer); + this.response.appendBoolean(this.gift); + this.pet.serialize(this.response); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/PetBreedsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/PetBreedsComposer.java new file mode 100644 index 0000000..a469dfa --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/PetBreedsComposer.java @@ -0,0 +1,34 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.habbohotel.pets.PetRace; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.set.hash.THashSet; + +public class PetBreedsComposer extends MessageComposer { + private final String petName; + private final THashSet petRaces; + + public PetBreedsComposer(String petName, THashSet petRaces) { + this.petName = petName; + this.petRaces = petRaces; + } + + @Override + protected ServerMessage composeInternal() { + if (this.petRaces == null) + return null; + this.response.init(Outgoing.PetBreedsComposer); + this.response.appendString(this.petName); + this.response.appendInt(this.petRaces.size()); + for (PetRace race : this.petRaces) { + this.response.appendInt(race.race); + this.response.appendInt(race.colorOne); + this.response.appendInt(race.colorTwo); + this.response.appendBoolean(race.hasColorOne); + this.response.appendBoolean(race.hasColorTwo); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/PetNameErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/PetNameErrorComposer.java new file mode 100644 index 0000000..c392c97 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/PetNameErrorComposer.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PetNameErrorComposer extends MessageComposer { + public static final int NAME_OK = 0; + public static final int NAME_TO_LONG = 1; + public static final int NAME_TO_SHORT = 2; + public static final int FORBIDDEN_CHAR = 3; + public static final int FORBIDDEN_WORDS = 4; + + private final int type; + private final String value; + + public PetNameErrorComposer(int type, String value) { + this.type = type; + this.value = value; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PetNameErrorComposer); + this.response.appendInt(this.type); + this.response.appendString(this.value); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/PurchaseOKComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/PurchaseOKComposer.java new file mode 100644 index 0000000..1750480 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/PurchaseOKComposer.java @@ -0,0 +1,43 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PurchaseOKComposer extends MessageComposer { + private final CatalogItem catalogItem; + + public PurchaseOKComposer(CatalogItem catalogItem) { + this.catalogItem = catalogItem; + } + + public PurchaseOKComposer() { + this.catalogItem = null; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PurchaseOKComposer); + if (this.catalogItem != null) { + this.catalogItem.serialize(this.response); + } else { + this.response.appendInt(0); + this.response.appendString(""); + this.response.appendBoolean(false); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendBoolean(true); + this.response.appendInt(1); + this.response.appendString("s"); + this.response.appendInt(0); + this.response.appendString(""); + this.response.appendInt(1); + this.response.appendInt(0); + this.response.appendString(""); + this.response.appendInt(1); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/RecyclerCompleteComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/RecyclerCompleteComposer.java new file mode 100644 index 0000000..54cfc60 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/RecyclerCompleteComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RecyclerCompleteComposer extends MessageComposer { + public static final int RECYCLING_COMPLETE = 1; + public static final int RECYCLING_CLOSED = 2; + + private final int code; + + public RecyclerCompleteComposer(int code) { + this.code = code; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RecyclerCompleteComposer); + this.response.appendInt(this.code); + this.response.appendInt(0); //prize ID. + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/RecyclerLogicComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/RecyclerLogicComposer.java new file mode 100644 index 0000000..8d1890a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/RecyclerLogicComposer.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.set.hash.THashSet; + +import java.util.Map; + +public class RecyclerLogicComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RecyclerLogicComposer); + this.response.appendInt(Emulator.getGameEnvironment().getCatalogManager().prizes.size()); + for (Map.Entry> map : Emulator.getGameEnvironment().getCatalogManager().prizes.entrySet()) { + this.response.appendInt(map.getKey()); + this.response.appendInt(Integer.valueOf(Emulator.getConfig().getValue("hotel.ecotron.rarity.chance." + map.getKey()))); + this.response.appendInt(map.getValue().size()); + for (Item item : map.getValue()) { + this.response.appendString(item.getName()); + this.response.appendInt(1); + this.response.appendString(item.getType().code.toLowerCase()); + this.response.appendInt(item.getSpriteId()); + } + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/RedeemVoucherErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/RedeemVoucherErrorComposer.java new file mode 100644 index 0000000..1632021 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/RedeemVoucherErrorComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RedeemVoucherErrorComposer extends MessageComposer { + public static final int INVALID_CODE = 0; + public static final int TECHNICAL_ERROR = 1; + + private final int code; + + public RedeemVoucherErrorComposer(int code) { + this.code = code; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RedeemVoucherErrorComposer); + this.response.appendString(this.code + ""); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/RedeemVoucherOKComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/RedeemVoucherOKComposer.java new file mode 100644 index 0000000..b198877 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/RedeemVoucherOKComposer.java @@ -0,0 +1,15 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RedeemVoucherOKComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RedeemVoucherOKComposer); + this.response.appendString(""); + this.response.appendString(""); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/ReloadRecyclerComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/ReloadRecyclerComposer.java new file mode 100644 index 0000000..a6432ee --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/ReloadRecyclerComposer.java @@ -0,0 +1,15 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ReloadRecyclerComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ReloadRecyclerComposer); + this.response.appendInt(1); + this.response.appendInt(0); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/TargetedOfferComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/TargetedOfferComposer.java new file mode 100644 index 0000000..ee8cbb6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/TargetedOfferComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.catalog; + +import com.eu.habbo.habbohotel.catalog.TargetOffer; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.cache.HabboOfferPurchase; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class TargetedOfferComposer extends MessageComposer { + private final Habbo habbo; + private final TargetOffer offer; + + public TargetedOfferComposer(Habbo habbo, TargetOffer offer) { + this.habbo = habbo; + this.offer = offer; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.TargetedOfferComposer); + HabboOfferPurchase purchase = HabboOfferPurchase.getOrCreate(this.habbo, this.offer.getId()); + this.offer.serialize(this.response, purchase); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceBuyErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceBuyErrorComposer.java new file mode 100644 index 0000000..800bd4c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceBuyErrorComposer.java @@ -0,0 +1,34 @@ +package com.eu.habbo.messages.outgoing.catalog.marketplace; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class MarketplaceBuyErrorComposer extends MessageComposer { + public static final int REFRESH = 1; + public static final int SOLD_OUT = 2; + public static final int UPDATES = 3; + public static final int NOT_ENOUGH_CREDITS = 4; + + private final int errorCode; + private final int unknown; + private final int offerId; + private final int price; + + public MarketplaceBuyErrorComposer(int errorCode, int unknown, int offerId, int price) { + this.errorCode = errorCode; + this.unknown = unknown; + this.offerId = offerId; + this.price = price; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MarketplaceBuyErrorComposer); + this.response.appendInt(this.errorCode); //result + this.response.appendInt(this.unknown); //newOfferId + this.response.appendInt(this.offerId); //newPrice + this.response.appendInt(this.price); //requestedOfferId + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceCancelSaleComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceCancelSaleComposer.java new file mode 100644 index 0000000..97d2462 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceCancelSaleComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.catalog.marketplace; + +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlaceOffer; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class MarketplaceCancelSaleComposer extends MessageComposer { + private final MarketPlaceOffer offer; + private final boolean success; + + public MarketplaceCancelSaleComposer(MarketPlaceOffer offer, Boolean success) { + this.offer = offer; + this.success = success; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MarketplaceCancelSaleComposer); + this.response.appendInt(this.offer.getOfferId()); + this.response.appendBoolean(this.success); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceConfigComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceConfigComposer.java new file mode 100644 index 0000000..1ee4ac1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceConfigComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.catalog.marketplace; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class MarketplaceConfigComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MarketplaceConfigComposer); + this.response.appendBoolean(true); + this.response.appendInt(1); //Commision Percentage. + this.response.appendInt(10); //Credits + this.response.appendInt(5); //Advertisements + this.response.appendInt(1); //Min price + this.response.appendInt(1000000); //Max price + this.response.appendInt(48); //Hours in marketplace + this.response.appendInt(7); //Days to display + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceItemInfoComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceItemInfoComposer.java new file mode 100644 index 0000000..f9f5f6e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceItemInfoComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.catalog.marketplace; + +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlace; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class MarketplaceItemInfoComposer extends MessageComposer { + private final int itemId; + + public MarketplaceItemInfoComposer(int itemId) { + this.itemId = itemId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MarketplaceItemInfoComposer); + MarketPlace.serializeItemInfo(this.itemId, this.response); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceItemPostedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceItemPostedComposer.java new file mode 100644 index 0000000..2489af8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceItemPostedComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.catalog.marketplace; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class MarketplaceItemPostedComposer extends MessageComposer { + public static final int POST_SUCCESS = 1; + public static final int FAILED_TECHNICAL_ERROR = 2; + public static final int MARKETPLACE_DISABLED = 3; + public static final int ITEM_JUST_ADDED_TO_SHOP = 4; + + private final int code; + + public MarketplaceItemPostedComposer(int code) { + this.code = code; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MarketplaceItemPostedComposer); + this.response.appendInt(this.code); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceOffersComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceOffersComposer.java new file mode 100644 index 0000000..e2e28d3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceOffersComposer.java @@ -0,0 +1,48 @@ +package com.eu.habbo.messages.outgoing.catalog.marketplace; + +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlace; +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlaceOffer; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.List; + +public class MarketplaceOffersComposer extends MessageComposer { + private final List offers; + + public MarketplaceOffersComposer(List offers) { + this.offers = offers; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MarketplaceOffersComposer); + int total = 0; + this.response.appendInt(this.offers.size()); + + for (MarketPlaceOffer offer : this.offers) { + this.response.appendInt(offer.getOfferId()); + this.response.appendInt(1); + this.response.appendInt(offer.getType()); + this.response.appendInt(offer.getItemId()); + if (offer.getType() == 3) { + this.response.appendInt(offer.getLimitedNumber()); + this.response.appendInt(offer.getLimitedStack()); + } else if (offer.getType() == 2) { + this.response.appendString(""); + } else { + this.response.appendInt(0); + this.response.appendString(""); + } + this.response.appendInt(MarketPlace.calculateCommision(offer.getPrice())); + this.response.appendInt(0); + this.response.appendInt(MarketPlace.calculateCommision(offer.avarage)); + this.response.appendInt(offer.count); + + total += offer.count; + } + this.response.appendInt(this.offers.size()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceOwnItemsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceOwnItemsComposer.java new file mode 100644 index 0000000..7e04d75 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceOwnItemsComposer.java @@ -0,0 +1,65 @@ +package com.eu.habbo.messages.outgoing.catalog.marketplace; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlaceOffer; +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlaceState; +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.Outgoing; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MarketplaceOwnItemsComposer extends MessageComposer { + private final Habbo habbo; + + public MarketplaceOwnItemsComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MarketplaceOwnItemsComposer); + this.response.appendInt(this.habbo.getInventory().getSoldPriceTotal()); + this.response.appendInt(this.habbo.getInventory().getMarketplaceItems().size()); + + for (MarketPlaceOffer offer : this.habbo.getInventory().getMarketplaceItems()) { + try { + if (offer.getState() == MarketPlaceState.OPEN) { + if ((offer.getTimestamp() + 172800) - Emulator.getIntUnixTimestamp() <= 0) { + offer.setState(MarketPlaceState.CLOSED); + Emulator.getThreading().run(offer); + } + } + + this.response.appendInt(offer.getOfferId()); + this.response.appendInt(offer.getState().getState()); + this.response.appendInt(offer.getType()); + this.response.appendInt(offer.getItemId()); + + if (offer.getType() == 3) { + this.response.appendInt(offer.getLimitedNumber()); + this.response.appendInt(offer.getLimitedStack()); + } else if (offer.getType() == 2) { + this.response.appendString(""); + } else { + this.response.appendInt(0); + this.response.appendString(""); + } + + this.response.appendInt(offer.getPrice()); + + if (offer.getState() == MarketPlaceState.OPEN) + this.response.appendInt((((offer.getTimestamp() + 172800) - Emulator.getIntUnixTimestamp()) / 60)); + else + this.response.appendInt(0); + + this.response.appendInt(0); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceSellItemComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceSellItemComposer.java new file mode 100644 index 0000000..0834ed4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/catalog/marketplace/MarketplaceSellItemComposer.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.outgoing.catalog.marketplace; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class MarketplaceSellItemComposer extends MessageComposer { + public static final int NOT_ALLOWED = 2; + public static final int NO_TRADE_PASS = 3; + public static final int NO_ADS_LEFT = 4; + + private final int errorCode; + private final int valueA; + private final int valueB; + + public MarketplaceSellItemComposer(int errorCode, int valueA, int valueB) { + this.errorCode = errorCode; + this.valueA = valueA; + this.valueB = valueB; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MarketplaceSellItemComposer); + this.response.appendInt(this.errorCode); + this.response.appendInt(this.valueA); + this.response.appendInt(this.valueB); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/crafting/CraftableProductsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/crafting/CraftableProductsComposer.java new file mode 100644 index 0000000..0c2254e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/crafting/CraftableProductsComposer.java @@ -0,0 +1,38 @@ +package com.eu.habbo.messages.outgoing.crafting; + +import com.eu.habbo.habbohotel.crafting.CraftingRecipe; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.Collection; +import java.util.List; + +public class CraftableProductsComposer extends MessageComposer { + private final List recipes; + private final Collection ingredients; + + public CraftableProductsComposer(List recipes, Collection ingredients) { + this.recipes = recipes; + this.ingredients = ingredients; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CraftableProductsComposer); + + this.response.appendInt(this.recipes.size()); + for (CraftingRecipe recipe : this.recipes) { + this.response.appendString(recipe.getName()); + this.response.appendString(recipe.getReward().getName()); + } + + this.response.appendInt(this.ingredients.size()); + for (Item item : this.ingredients) { + this.response.appendString(item.getName()); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/crafting/CraftingRecipeComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/crafting/CraftingRecipeComposer.java new file mode 100644 index 0000000..a8db678 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/crafting/CraftingRecipeComposer.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.outgoing.crafting; + +import com.eu.habbo.habbohotel.crafting.CraftingRecipe; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.Map; + +public class CraftingRecipeComposer extends MessageComposer { + private final CraftingRecipe recipe; + + public CraftingRecipeComposer(CraftingRecipe recipe) { + this.recipe = recipe; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CraftingRecipeComposer); + this.response.appendInt(this.recipe.getIngredients().size()); + + for (Map.Entry ingredient : this.recipe.getIngredients().entrySet()) { + this.response.appendInt(ingredient.getValue()); + this.response.appendString(ingredient.getKey().getName()); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/crafting/CraftingRecipesAvailableComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/crafting/CraftingRecipesAvailableComposer.java new file mode 100644 index 0000000..5f0c773 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/crafting/CraftingRecipesAvailableComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.crafting; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CraftingRecipesAvailableComposer extends MessageComposer { + private final int count; + private final boolean found; + + public CraftingRecipesAvailableComposer(int count, boolean found) { + this.count = count; + this.found = found; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CraftingComposerFour); + this.response.appendInt((this.found ? -1 : 0) + this.count); + this.response.appendBoolean(this.found); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/crafting/CraftingResultComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/crafting/CraftingResultComposer.java new file mode 100644 index 0000000..d7967e8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/crafting/CraftingResultComposer.java @@ -0,0 +1,35 @@ +package com.eu.habbo.messages.outgoing.crafting; + +import com.eu.habbo.habbohotel.crafting.CraftingRecipe; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CraftingResultComposer extends MessageComposer { + private final CraftingRecipe recipe; + private final boolean succes; + + public CraftingResultComposer(CraftingRecipe recipe) { + this.recipe = recipe; + this.succes = this.recipe != null; + } + + public CraftingResultComposer(CraftingRecipe recipe, boolean success) { + this.recipe = recipe; + this.succes = success; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CraftingResultComposer); + + this.response.appendBoolean(this.succes); //succes + + if (this.recipe != null) { + this.response.appendString(this.recipe.getName()); + this.response.appendString(this.recipe.getReward().getName()); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarDataComposer.java new file mode 100644 index 0000000..abf20a7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarDataComposer.java @@ -0,0 +1,64 @@ +package com.eu.habbo.messages.outgoing.events.calendar; + +import com.eu.habbo.habbohotel.campaign.calendar.CalendarRewardClaimed; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.list.array.TIntArrayList; + +import java.util.ArrayList; + +public class AdventCalendarDataComposer extends MessageComposer { + private final String eventName; + private final String campaignImage; + private final int totalDays; + private final int currentDay; + private final ArrayList unlocked; + private final boolean lockExpired; + + public AdventCalendarDataComposer(String eventName, String campaignImage, int totalDays, int currentDay, ArrayList unlocked, boolean lockExpired) { + this.eventName = eventName; + this.campaignImage = campaignImage; + this.totalDays = totalDays; + this.currentDay = currentDay; + this.unlocked = unlocked; + this.lockExpired = lockExpired; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.AdventCalendarDataComposer); + this.response.appendString(this.eventName); + this.response.appendString(this.campaignImage); + this.response.appendInt(this.currentDay); + this.response.appendInt(this.totalDays); + this.response.appendInt(this.unlocked.size()); + + TIntArrayList expired = new TIntArrayList(); + if (this.lockExpired) { for (int i = 0; i < this.totalDays; i++) { + expired.add(i); + } + } + expired.remove(this.currentDay); + if(this.currentDay > 1) expired.remove(this.currentDay - 2); + if(this.currentDay > 0) expired.remove(this.currentDay - 1); + + this.unlocked.forEach(claimed -> { + AdventCalendarDataComposer.this.response.appendInt(claimed.getDay()); + expired.remove(claimed.getDay()); + }); + + + if (this.lockExpired) { + this.response.appendInt(expired.size()); + expired.forEach(value -> { + AdventCalendarDataComposer.this.response.appendInt(value); + return true; + }); + } else { + this.response.appendInt(0); + } + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarProductComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarProductComposer.java new file mode 100644 index 0000000..fb23b31 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarProductComposer.java @@ -0,0 +1,49 @@ +package com.eu.habbo.messages.outgoing.events.calendar; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarManager; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarRewardObject; +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.Outgoing; + +public class AdventCalendarProductComposer extends MessageComposer { + public final boolean visible; + public final CalendarRewardObject rewardObject; + public final Habbo habbo; + + public AdventCalendarProductComposer(boolean visible, CalendarRewardObject rewardObject, Habbo habbo) { + this.visible = visible; + this.rewardObject = rewardObject; + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.AdventCalendarProductComposer); + this.response.appendBoolean(this.visible); + + String className = ""; + String productName = this.rewardObject.getProductName() + .replace("%credits%", String.valueOf(this.rewardObject.getCredits())) + .replace("%pixels%", String.valueOf((int) (this.rewardObject.getPixels() * (habbo.getHabboStats().hasActiveClub() ? CalendarManager.HC_MODIFIER : 1.0)))) + .replace("%points%", String.valueOf(this.rewardObject.getPoints())) + .replace("%points_type%", String.valueOf(this.rewardObject.getPointsType())) + .replace("%badge%", this.rewardObject.getBadge()); + if(this.rewardObject.getSubscriptionType() != null){ + productName = productName.replace("%subscription_type%", this.rewardObject.getSubscriptionType()).replace("%subscription_days%", String.valueOf(this.rewardObject.getSubscriptionDays())); + } + + if(this.rewardObject.getItem() != null){ + productName = productName.replace("%item%", this.rewardObject.getItem().getName()); + className = this.rewardObject.getItem().getName(); + } + + this.response.appendString(productName); + this.response.appendString(this.rewardObject.getCustomImage()); + this.response.appendString(className); + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/mysticbox/MysticBoxCloseComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/mysticbox/MysticBoxCloseComposer.java new file mode 100644 index 0000000..c1593ce --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/mysticbox/MysticBoxCloseComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.events.mysticbox; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class MysticBoxCloseComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MysticBoxCloseComposer); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/mysticbox/MysticBoxPrizeComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/mysticbox/MysticBoxPrizeComposer.java new file mode 100644 index 0000000..f5e95b3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/mysticbox/MysticBoxPrizeComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.events.mysticbox; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class MysticBoxPrizeComposer extends MessageComposer { + private final String type; + private final int itemId; + + public MysticBoxPrizeComposer(String type, int itemId) { + this.type = type; + this.itemId = itemId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MysticBoxPrizeComposer); + this.response.appendString(this.type); + this.response.appendInt(this.itemId); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/mysticbox/MysticBoxStartOpenComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/mysticbox/MysticBoxStartOpenComposer.java new file mode 100644 index 0000000..b88c73c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/mysticbox/MysticBoxStartOpenComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.events.mysticbox; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class MysticBoxStartOpenComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MysticBoxStartOpenComposer); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/resolution/NewYearResolutionCompletedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/resolution/NewYearResolutionCompletedComposer.java new file mode 100644 index 0000000..741b944 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/resolution/NewYearResolutionCompletedComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.events.resolution; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class NewYearResolutionCompletedComposer extends MessageComposer { + public final String badge; + + public NewYearResolutionCompletedComposer(String badge) { + this.badge = badge; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.NewYearResolutionCompletedComposer); + this.response.appendString(this.badge); + this.response.appendString(this.badge); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/resolution/NewYearResolutionComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/resolution/NewYearResolutionComposer.java new file mode 100644 index 0000000..7b2a425 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/resolution/NewYearResolutionComposer.java @@ -0,0 +1,32 @@ +package com.eu.habbo.messages.outgoing.events.resolution; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class NewYearResolutionComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + //:test 817 i:230 i:1 i:1 i:1 s:NY2013RES i:3 i:0 i:60000000 + this.response.init(Outgoing.NewYearResolutionComposer); + + this.response.appendInt(230); //reward ID or item id? (stuffId) + this.response.appendInt(2); //count + + this.response.appendInt(1); //achievementId + this.response.appendInt(1); //achievementLevel + this.response.appendString("NY2013RES"); + this.response.appendInt(3); //type ? + this.response.appendInt(0); //Finished/ enabled + + this.response.appendInt(2); //achievementId + this.response.appendInt(1); //achievementLevel + this.response.appendString("ADM"); + this.response.appendInt(2); //type ? + this.response.appendInt(0); //Finished/ enabled + + this.response.appendInt(1000); //Time in secs left. + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/resolution/NewYearResolutionProgressComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/resolution/NewYearResolutionProgressComposer.java new file mode 100644 index 0000000..c478f2e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/events/resolution/NewYearResolutionProgressComposer.java @@ -0,0 +1,35 @@ +package com.eu.habbo.messages.outgoing.events.resolution; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class NewYearResolutionProgressComposer extends MessageComposer { + private final int stuffId; + private final int achievementId; + private final String achievementName; + private final int currentProgress; + private final int progressNeeded; + private final int timeLeft; + + public NewYearResolutionProgressComposer(int stuffId, int achievementId, String achievementName, int currentProgress, int progressNeeded, int timeLeft) { + this.stuffId = stuffId; + this.achievementId = achievementId; + this.achievementName = achievementName; + this.currentProgress = currentProgress; + this.progressNeeded = progressNeeded; + this.timeLeft = timeLeft; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.NewYearResolutionProgressComposer); + this.response.appendInt(this.stuffId); + this.response.appendInt(this.achievementId); + this.response.appendString(this.achievementName); + this.response.appendInt(this.currentProgress); + this.response.appendInt(this.progressNeeded); + this.response.appendInt(this.timeLeft); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/floorplaneditor/FloorPlanEditorBlockedTilesComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/floorplaneditor/FloorPlanEditorBlockedTilesComposer.java new file mode 100644 index 0000000..3cccbe1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/floorplaneditor/FloorPlanEditorBlockedTilesComposer.java @@ -0,0 +1,31 @@ +package com.eu.habbo.messages.outgoing.floorplaneditor; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.set.hash.THashSet; + +public class FloorPlanEditorBlockedTilesComposer extends MessageComposer { + private final Room room; + + public FloorPlanEditorBlockedTilesComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.FloorPlanEditorBlockedTilesComposer); + + THashSet tileList = this.room.getLockedTiles(); + + this.response.appendInt(tileList.size()); + for (RoomTile node : tileList) { + this.response.appendInt((int) node.x); + this.response.appendInt((int) node.y); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/floorplaneditor/FloorPlanEditorDoorSettingsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/floorplaneditor/FloorPlanEditorDoorSettingsComposer.java new file mode 100644 index 0000000..21874ea --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/floorplaneditor/FloorPlanEditorDoorSettingsComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.floorplaneditor; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class FloorPlanEditorDoorSettingsComposer extends MessageComposer { + private final Room room; + + public FloorPlanEditorDoorSettingsComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.FloorPlanEditorDoorSettingsComposer); + this.response.appendInt(this.room.getLayout().getDoorX()); + this.response.appendInt(this.room.getLayout().getDoorY()); + this.response.appendInt(this.room.getLayout().getDoorDirection()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendChatMessageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendChatMessageComposer.java new file mode 100644 index 0000000..4806b43 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendChatMessageComposer.java @@ -0,0 +1,53 @@ +package com.eu.habbo.messages.outgoing.friends; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.messenger.Message; +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.Outgoing; + +public class FriendChatMessageComposer extends MessageComposer { + private final Message message; + private final int toId; + private final int fromId; + + public FriendChatMessageComposer(Message message) { + this.message = message; + this.toId = message.getFromId(); + this.fromId = message.getFromId(); + } + + public FriendChatMessageComposer(Message message, int toId, int fromId) { + this.message = message; + this.toId = toId; + this.fromId = fromId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.FriendChatMessageComposer); + this.response.appendInt(this.toId); + this.response.appendString(this.message.getMessage()); + this.response.appendInt(Emulator.getIntUnixTimestamp() - this.message.getTimestamp()); + + if (this.toId < 0) // group chat + { + String name = "AUTO_MODERATOR"; + String look = "lg-5635282-1193.hd-3091-1.sh-3089-73.cc-156282-64.hr-831-34.ha-1012-1186.ch-3050-62-62"; + if (this.fromId > 0) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.fromId); + + if (habbo != null) { + name = habbo.getHabboInfo().getUsername(); + look = habbo.getHabboInfo().getLook(); + } else { + name = "UNKNOWN"; + } + } + this.response.appendString(name + "/" + look + "/" + this.fromId); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendFindingRoomComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendFindingRoomComposer.java new file mode 100644 index 0000000..8c100a6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendFindingRoomComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.friends; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class FriendFindingRoomComposer extends MessageComposer { + public static final int NO_ROOM_FOUND = 0; + public static final int ROOM_FOUND = 1; + + private final int errorCode; + + public FriendFindingRoomComposer(int errorCode) { + this.errorCode = errorCode; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.FriendFindingRoomComposer); + this.response.appendInt(this.errorCode); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendNotificationComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendNotificationComposer.java new file mode 100644 index 0000000..9e9ed2f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendNotificationComposer.java @@ -0,0 +1,34 @@ +package com.eu.habbo.messages.outgoing.friends; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class FriendNotificationComposer extends MessageComposer { + public final static int INSTANT_MESSAGE = -1; + public final static int ROOM_EVENT = 0; + public final static int ACHIEVEMENT_COMPLETED = 1; + public final static int QUEST_COMPLETED = 2; + public final static int IS_PLAYING_GAME = 3; + public final static int FINISHED_GAME = 4; + public final static int INVITE_TO_PLAY_GAME = 5; + + private final int userId; + private final int type; + private final String data; + + public FriendNotificationComposer(int userId, int type, String data) { + this.userId = userId; + this.type = type; + this.data = data; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.FriendToolbarNotificationComposer); + this.response.appendString(this.userId + ""); + this.response.appendInt(this.type); + this.response.appendString(this.data); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendRequestComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendRequestComposer.java new file mode 100644 index 0000000..005ac3d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendRequestComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.friends; + +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.Outgoing; + +public class FriendRequestComposer extends MessageComposer { + private final Habbo habbo; + + public FriendRequestComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.FriendRequestComposer); + + this.response.appendInt(this.habbo.getHabboInfo().getId()); + this.response.appendString(this.habbo.getHabboInfo().getUsername()); + this.response.appendString(this.habbo.getHabboInfo().getLook()); + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendRequestErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendRequestErrorComposer.java new file mode 100644 index 0000000..84ebe13 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendRequestErrorComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.friends; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class FriendRequestErrorComposer extends MessageComposer { + public static final int FRIEND_LIST_OWN_FULL = 1; + public static final int FRIEND_LIST_TARGET_FULL = 2; + public static final int TARGET_NOT_ACCEPTING_REQUESTS = 3; + public static final int TARGET_NOT_FOUND = 4; + + private final int errorCode; + + public FriendRequestErrorComposer(int errorCode) { + this.errorCode = errorCode; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.FriendRequestErrorComposer); + this.response.appendInt(0); + this.response.appendInt(this.errorCode); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendsComposer.java new file mode 100644 index 0000000..47e77c3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendsComposer.java @@ -0,0 +1,80 @@ +package com.eu.habbo.messages.outgoing.friends; + +import com.eu.habbo.habbohotel.messenger.MessengerBuddy; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; +import java.util.Collection; + +@Slf4j +public class FriendsComposer extends MessageComposer { + private final int totalPages; + private final int pageIndex; + private final Collection friends; + + public FriendsComposer(int totalPages, int pageIndex, Collection friends) { + this.totalPages = totalPages; + this.pageIndex = pageIndex; + this.friends = friends; + } + + @Override + protected ServerMessage composeInternal() { + try { + this.response.init(Outgoing.FriendsComposer); + + this.response.appendInt(this.totalPages); + this.response.appendInt(this.pageIndex); + this.response.appendInt(this.friends.size()); + + for (MessengerBuddy row : this.friends) { + this.response.appendInt(row.getId()); + this.response.appendString(row.getUsername()); + this.response.appendInt(row.getGender().equals(HabboGender.M) ? 0 : 1); + this.response.appendBoolean(row.getOnline() == 1); + this.response.appendBoolean(row.inRoom()); //IN ROOM + this.response.appendString(row.getOnline() == 1 ? row.getLook() : ""); + this.response.appendInt(row.getCategoryId()); //Friends category + this.response.appendString(row.getMotto()); + this.response.appendString(""); //Last seen as DATETIMESTRING + this.response.appendString(""); //Realname or Facebookame as String + this.response.appendBoolean(false); //Offline messaging. + this.response.appendBoolean(false); + this.response.appendBoolean(false); + this.response.appendShort(row.getRelation()); + } + return this.response; + } catch (Exception e) { + log.error("Caught exception", e); + } + return null; + } + + public static ArrayList getMessagesForBuddyList(Collection buddies) { + ArrayList messages = new ArrayList(); + THashSet friends = new THashSet(); + + int totalPages = (int)Math.ceil(buddies.size() / 750.0); + int page = 0; + + for(MessengerBuddy buddy : buddies) { + friends.add(buddy); + + if(friends.size() == 750) { + messages.add(new FriendsComposer(totalPages, page, friends).compose()); + friends.clear(); + page++; + } + } + + if(page == 0 || friends.size() > 0) { + messages.add(new FriendsComposer(totalPages, page, friends).compose()); + } + + return messages; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/LoadFriendRequestsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/LoadFriendRequestsComposer.java new file mode 100644 index 0000000..fb3314b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/LoadFriendRequestsComposer.java @@ -0,0 +1,33 @@ +package com.eu.habbo.messages.outgoing.friends; + +import com.eu.habbo.habbohotel.messenger.FriendRequest; +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.Outgoing; + +public class LoadFriendRequestsComposer extends MessageComposer { + private final Habbo habbo; + + public LoadFriendRequestsComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.LoadFriendRequestsComposer); + + synchronized (this.habbo.getMessenger().getFriendRequests()) { + this.response.appendInt(this.habbo.getMessenger().getFriendRequests().size()); + this.response.appendInt(this.habbo.getMessenger().getFriendRequests().size()); + + for (FriendRequest friendRequest : this.habbo.getMessenger().getFriendRequests()) { + this.response.appendInt(friendRequest.getId()); + this.response.appendString(friendRequest.getUsername()); + this.response.appendString(friendRequest.getLook()); + } + } + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/MessengerInitComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/MessengerInitComposer.java new file mode 100644 index 0000000..de3b920 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/MessengerInitComposer.java @@ -0,0 +1,48 @@ +package com.eu.habbo.messages.outgoing.friends; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.messenger.Messenger; +import com.eu.habbo.habbohotel.messenger.MessengerCategory; +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.Outgoing; + +import java.util.List; + +public class MessengerInitComposer extends MessageComposer { + private final Habbo habbo; + + public MessengerInitComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + + this.response.init(Outgoing.MessengerInitComposer); + if (this.habbo.hasPermission("acc_infinite_friends")) { + this.response.appendInt(Integer.MAX_VALUE); + this.response.appendInt(1337); + this.response.appendInt(Integer.MAX_VALUE); + } else { + this.response.appendInt(Messenger.MAXIMUM_FRIENDS); + this.response.appendInt(1337); + this.response.appendInt(Messenger.MAXIMUM_FRIENDS_HC); + } + if (!this.habbo.getHabboInfo().getMessengerCategories().isEmpty()) { + + List messengerCategories = this.habbo.getHabboInfo().getMessengerCategories(); + this.response.appendInt(messengerCategories.size()); + + for (MessengerCategory mc : messengerCategories) { + this.response.appendInt(mc.getId()); + this.response.appendString(mc.getName()); + } + } else { + this.response.appendInt(0); + } + return this.response; + } +} + diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/RemoveFriendComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/RemoveFriendComposer.java new file mode 100644 index 0000000..34cbe1b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/RemoveFriendComposer.java @@ -0,0 +1,33 @@ +package com.eu.habbo.messages.outgoing.friends; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.list.array.TIntArrayList; + +public class RemoveFriendComposer extends MessageComposer { + private final TIntArrayList unfriendIds; + + public RemoveFriendComposer(TIntArrayList unfriendIds) { + this.unfriendIds = unfriendIds; + } + + public RemoveFriendComposer(int i) { + this.unfriendIds = new TIntArrayList(); + this.unfriendIds.add(i); + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UpdateFriendComposer); + + this.response.appendInt(0); + this.response.appendInt(this.unfriendIds.size()); + for (int i = 0; i < this.unfriendIds.size(); i++) { + this.response.appendInt(-1); + this.response.appendInt(this.unfriendIds.get(i)); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/RoomInviteComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/RoomInviteComposer.java new file mode 100644 index 0000000..1b761a5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/RoomInviteComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.friends; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomInviteComposer extends MessageComposer { + private final int userId; + private final String message; + + public RoomInviteComposer(int userId, String message) { + this.userId = userId; + this.message = message; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomInviteComposer); + this.response.appendInt(this.userId); + this.response.appendString(this.message); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/RoomInviteErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/RoomInviteErrorComposer.java new file mode 100644 index 0000000..b2d3c54 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/RoomInviteErrorComposer.java @@ -0,0 +1,33 @@ +package com.eu.habbo.messages.outgoing.friends; + +import com.eu.habbo.habbohotel.messenger.MessengerBuddy; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; + +public class RoomInviteErrorComposer extends MessageComposer { + private final int errorCode; + private final THashSet buddies; + + public RoomInviteErrorComposer(int errorCode, THashSet buddies) { + this.errorCode = errorCode; + this.buddies = buddies; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomInviteErrorComposer); + this.response.appendInt(this.errorCode); + this.response.appendInt(this.buddies.size()); + this.buddies.forEach(new TObjectProcedure() { + @Override + public boolean execute(MessengerBuddy object) { + RoomInviteErrorComposer.this.response.appendInt(object.getId()); + return true; + } + }); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/StalkErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/StalkErrorComposer.java new file mode 100644 index 0000000..7eac0a9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/StalkErrorComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.friends; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class StalkErrorComposer extends MessageComposer { + public static final int NOT_IN_FRIEND_LIST = 0; + public static final int FRIEND_OFFLINE = 1; + public static final int FRIEND_NOT_IN_ROOM = 2; + public static final int FRIEND_BLOCKED_STALKING = 3; + + private final int errorCode; + + public StalkErrorComposer(int errorCode) { + this.errorCode = errorCode; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.StalkErrorComposer); + this.response.appendInt(this.errorCode); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/UpdateFriendComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/UpdateFriendComposer.java new file mode 100644 index 0000000..1be0b1a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/UpdateFriendComposer.java @@ -0,0 +1,77 @@ +package com.eu.habbo.messages.outgoing.friends; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import com.eu.habbo.habbohotel.messenger.MessengerBuddy; +import com.eu.habbo.habbohotel.messenger.MessengerCategory; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UpdateFriendComposer extends MessageComposer { + private Collection buddies; + + private Habbo habbo; + private int action; + + public UpdateFriendComposer(Habbo habbo, MessengerBuddy buddy, Integer action) { + this.habbo = habbo; + this.buddies = Collections.singletonList(buddy); + this.action = action; + } + + public UpdateFriendComposer(Habbo habbo, Collection buddies, Integer action) { + this.habbo = habbo; + this.buddies = buddies; + this.action = action; + } + + @Override + protected ServerMessage composeInternal() { + + this.response.init(Outgoing.UpdateFriendComposer); + if (this.habbo != null && !this.habbo.getHabboInfo().getMessengerCategories().isEmpty()) { + + List messengerCategories = this.habbo.getHabboInfo().getMessengerCategories(); + this.response.appendInt(messengerCategories.size()); + + for (MessengerCategory mc : messengerCategories) { + this.response.appendInt(mc.getId()); + this.response.appendString(mc.getName()); + } + } else { + this.response.appendInt(0); + } + + this.response.appendInt(buddies.size()); // totalbuddies + + for(MessengerBuddy buddy : buddies){ + + if (buddy != null) { + this.response.appendInt(this.action); // -1 = removed friendId / 0 = updated friend / 1 = added friend + this.response.appendInt(buddy.getId()); + if (this.action == -1) { + continue; + } + this.response.appendString(buddy.getUsername()); + this.response.appendInt(buddy.getGender().equals(HabboGender.M) ? 0 : 1); + this.response.appendBoolean(buddy.getOnline() == 1); + this.response.appendBoolean(buddy.inRoom()); //In room + this.response.appendString(buddy.getLook()); + this.response.appendInt(buddy.getCategoryId()); + this.response.appendString(buddy.getMotto()); + this.response.appendString(""); //Last seen as DATETIMESTRING + this.response.appendString(""); //Realname or Facebookame as String + this.response.appendBoolean(false); //Offline messaging. + this.response.appendBoolean(false); + this.response.appendBoolean(false); + this.response.appendShort(buddy.getRelation()); + } + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/UserSearchResultComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/UserSearchResultComposer.java new file mode 100644 index 0000000..7c66c3d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/friends/UserSearchResultComposer.java @@ -0,0 +1,80 @@ +package com.eu.habbo.messages.outgoing.friends; + +import com.eu.habbo.habbohotel.messenger.MessengerBuddy; +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.Outgoing; +import gnu.trove.set.hash.THashSet; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +public class UserSearchResultComposer extends MessageComposer { + private final THashSet users; + private final THashSet friends; + private final Habbo habbo; + + private static Comparator COMPARATOR = Comparator.comparing((MessengerBuddy b) -> b.getUsername().length()).thenComparing((MessengerBuddy b, MessengerBuddy b2) -> b.getUsername().compareToIgnoreCase(b2.getUsername())); + + public UserSearchResultComposer(THashSet users, THashSet friends, Habbo habbo) { + this.users = users; + this.friends = friends; + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserSearchResultComposer); + List u = new ArrayList<>(); + + for (MessengerBuddy buddy : this.users) { + if (!this.inFriendList(buddy)) { + u.add(buddy); + } + } + + List friends = new ArrayList<>(this.friends); + + u.sort(UserSearchResultComposer.COMPARATOR); + friends.sort(UserSearchResultComposer.COMPARATOR); + + this.response.appendInt(this.friends.size()); + for (MessengerBuddy buddy : this.friends) { + this.response.appendInt(buddy.getId()); + this.response.appendString(buddy.getUsername()); + this.response.appendString(buddy.getMotto()); + this.response.appendBoolean(false); + this.response.appendBoolean(false); + this.response.appendString(""); + this.response.appendInt(1); + this.response.appendString(buddy.getLook()); + this.response.appendString(""); + } + + this.response.appendInt(u.size()); + for (MessengerBuddy buddy : u) { + this.response.appendInt(buddy.getId()); + this.response.appendString(buddy.getUsername()); + this.response.appendString(buddy.getMotto()); + this.response.appendBoolean(false); + this.response.appendBoolean(false); + this.response.appendString(""); + this.response.appendInt(1); + this.response.appendString(buddy.getOnline() == 1 ? buddy.getLook() : ""); + this.response.appendString(""); + } + + return this.response; + } + + private boolean inFriendList(MessengerBuddy buddy) { + for (MessengerBuddy friend : this.friends) { + if (friend.getUsername().equals(buddy.getUsername())) + return true; + } + + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/GameCenterAccountInfoComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/GameCenterAccountInfoComposer.java new file mode 100644 index 0000000..fd8760f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/GameCenterAccountInfoComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.gamecenter; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GameCenterAccountInfoComposer extends MessageComposer { + private final int gameId; + private final int gamesLeft; + + public GameCenterAccountInfoComposer(int gameId, int gamesLeft) { + this.gameId = gameId; + this.gamesLeft = gamesLeft; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GameCenterAccountInfoComposer); + this.response.appendInt(this.gameId); + this.response.appendInt(this.gamesLeft); + this.response.appendInt(1); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/GameCenterAchievementsConfigurationComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/GameCenterAchievementsConfigurationComposer.java new file mode 100644 index 0000000..6a78ec9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/GameCenterAchievementsConfigurationComposer.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.outgoing.gamecenter; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class GameCenterAchievementsConfigurationComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(2265); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(3); + this.response.appendInt(1); + this.response.appendInt(1); + this.response.appendString("BaseJumpBigParachute"); + this.response.appendInt(1); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/GameCenterGameComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/GameCenterGameComposer.java new file mode 100644 index 0000000..2d28e93 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/GameCenterGameComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.gamecenter; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GameCenterGameComposer extends MessageComposer { + public final static int OK = 0; + public final static int ERROR = 1; + + public final int gameId; + public final int status; + + public GameCenterGameComposer(int gameId, int status) { + this.gameId = gameId; + this.status = status; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GameCenterGameComposer); + this.response.appendInt(this.gameId); + this.response.appendInt(this.status); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/GameCenterGameListComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/GameCenterGameListComposer.java new file mode 100644 index 0000000..f8f1e25 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/GameCenterGameListComposer.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.outgoing.gamecenter; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GameCenterGameListComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GameCenterGameListComposer); + this.response.appendInt(2);//Count + + this.response.appendInt(0); + this.response.appendString("snowwar"); + this.response.appendString("93d4f3"); + this.response.appendString(""); + this.response.appendString(Emulator.getConfig().getValue("images.gamecenter.snowwar")); + this.response.appendString(""); + + this.response.appendInt(3); + this.response.appendString("basejump"); + this.response.appendString("68bbd2"); //Background Color + this.response.appendString(""); //Text color + this.response.appendString(Emulator.getConfig().getValue("images.gamecenter.basejump")); + this.response.appendString(""); + + this.response.appendInt(4); + this.response.appendString("slotcar"); + this.response.appendString("4a95df"); + this.response.appendString(""); + this.response.appendString("http://habboo-a.akamaihd.net/gamecenter/Sulake/slotcar/20130214010101/"); + this.response.appendString(""); + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpJoinQueueComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpJoinQueueComposer.java new file mode 100644 index 0000000..6df404f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpJoinQueueComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.gamecenter.basejump; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class BaseJumpJoinQueueComposer extends MessageComposer { + private final int gameId; + + public BaseJumpJoinQueueComposer(int gameId) { + this.gameId = gameId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.BaseJumpJoinQueueComposer); + this.response.appendInt(this.gameId); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpLeaveQueueComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpLeaveQueueComposer.java new file mode 100644 index 0000000..11a5ea1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpLeaveQueueComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.gamecenter.basejump; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class BaseJumpLeaveQueueComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.BaseJumpLeaveQueueComposer); + this.response.appendInt(3); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpLoadGameComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpLoadGameComposer.java new file mode 100644 index 0000000..99d4c66 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpLoadGameComposer.java @@ -0,0 +1,51 @@ +package com.eu.habbo.messages.outgoing.gamecenter.basejump; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class BaseJumpLoadGameComposer extends MessageComposer { + public static String FASTFOOD_KEY = ""; + + private final GameClient client; + private final int game; + + public BaseJumpLoadGameComposer(GameClient client, int game) { + this.client = client; + this.game = game; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.BaseJumpLoadGameComposer); + + if (this.game == 3) { + this.response.appendInt(3); + this.response.appendString("basejump"); + this.response.appendString(Emulator.getConfig().getValue("basejump.url")); + this.response.appendString("best"); + this.response.appendString("showAll"); + this.response.appendInt(60); + this.response.appendInt(10); + this.response.appendInt(0); + this.response.appendInt(6); + this.response.appendString("assetUrl"); + this.response.appendString(Emulator.getConfig().getValue("basejump.assets.url")); + this.response.appendString("habboHost"); + this.response.appendString(Emulator.getConfig().getValue("hotel.url")); + this.response.appendString("accessToken"); + this.response.appendString(Emulator.getConfig().getValue("username") + "\t" + Emulator.version + "\t" + this.client.getHabbo().getHabboInfo().getId() + "\t" + this.client.getHabbo().getHabboInfo().getUsername() + "\t" + this.client.getHabbo().getHabboInfo().getLook() + "\t" + this.client.getHabbo().getHabboInfo().getCredits() + "\t" + FASTFOOD_KEY); + this.response.appendString("gameServerHost"); + this.response.appendString("google.com"); + this.response.appendString("gameServerPort"); + this.response.appendString("3002"); + this.response.appendString("socketPolicyPort"); + this.response.appendString("3002"); + + + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpLoadGameURLComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpLoadGameURLComposer.java new file mode 100644 index 0000000..906ee30 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpLoadGameURLComposer.java @@ -0,0 +1,16 @@ +package com.eu.habbo.messages.outgoing.gamecenter.basejump; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class BaseJumpLoadGameURLComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.BaseJumpLoadGameURLComposer); + this.response.appendInt(4); + this.response.appendString("1351418858673"); + this.response.appendString("http://images.habbo.com/speedway/200912/index.html?accessToken=ff5d09d1-ef22-4ee5-8b1b-8260d13d0d6f&gameServerHost=localhost&gameServerPort=30000&socketPolicyPort=30000"); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpUnloadGameComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpUnloadGameComposer.java new file mode 100644 index 0000000..1e2df09 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/gamecenter/basejump/BaseJumpUnloadGameComposer.java @@ -0,0 +1,15 @@ +package com.eu.habbo.messages.outgoing.gamecenter.basejump; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class BaseJumpUnloadGameComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.BaseJumpUnloadGameComposer); + this.response.appendInt(3); + this.response.appendString("basejump"); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/MinimailCountComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/MinimailCountComposer.java new file mode 100644 index 0000000..34edf5a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/MinimailCountComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.generic; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class MinimailCountComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MinimailCountComposer); + this.response.appendInt(0); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/PickMonthlyClubGiftNotificationComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/PickMonthlyClubGiftNotificationComposer.java new file mode 100644 index 0000000..bae14e7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/PickMonthlyClubGiftNotificationComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.generic; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PickMonthlyClubGiftNotificationComposer extends MessageComposer { + private final int count; + + public PickMonthlyClubGiftNotificationComposer(int count) { + this.count = count; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PickMonthlyClubGiftNotificationComposer); + this.response.appendInt(this.count); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/BotErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/BotErrorComposer.java new file mode 100644 index 0000000..8773d9c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/BotErrorComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.generic.alerts; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class BotErrorComposer extends MessageComposer { + public static final int ROOM_ERROR_BOTS_FORBIDDEN_IN_HOTEL = 0; + public static final int ROOM_ERROR_BOTS_FORBIDDEN_IN_FLAT = 1; + public static final int ROOM_ERROR_MAX_BOTS = 2; + public static final int ROOM_ERROR_BOTS_SELECTED_TILE_NOT_FREE = 3; + public static final int ROOM_ERROR_BOTS_NAME_NOT_ACCEPT = 4; + + private final int errorCode; + + public BotErrorComposer(int errorCode) { + this.errorCode = errorCode; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.BotErrorComposer); + this.response.appendInt(this.errorCode); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/BubbleAlertComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/BubbleAlertComposer.java new file mode 100644 index 0000000..391cd6e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/BubbleAlertComposer.java @@ -0,0 +1,41 @@ +package com.eu.habbo.messages.outgoing.generic.alerts; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.map.hash.THashMap; + +import java.util.Map; + +public class BubbleAlertComposer extends MessageComposer { + private final String errorKey; + private final THashMap keys; + + public BubbleAlertComposer(String errorKey, THashMap keys) { + this.errorKey = errorKey; + this.keys = keys; + } + + public BubbleAlertComposer(String errorKey, String message) { + this.errorKey = errorKey; + this.keys = new THashMap<>(); + this.keys.put("message", message); + } + + public BubbleAlertComposer(String errorKey) { + this.errorKey = errorKey; + this.keys = new THashMap<>(); + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.BubbleAlertComposer); + this.response.appendString(this.errorKey); + this.response.appendInt(this.keys.size()); + for (Map.Entry set : this.keys.entrySet()) { + this.response.appendString(set.getKey()); + this.response.appendString(set.getValue()); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/BubbleAlertKeys.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/BubbleAlertKeys.java new file mode 100644 index 0000000..36ed044 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/BubbleAlertKeys.java @@ -0,0 +1,43 @@ +package com.eu.habbo.messages.outgoing.generic.alerts; + +public enum BubbleAlertKeys { + ADMIN_PERSISTENT("admin.persistent"), + ADMIN_TRANSIENT("admin.transient"), + BUILDERS_CLUB_MEMBERSHIP_EXPIRED("builders_club.membership_expired"), + BUILDERS_CLUB_MEMBERSHIP_EXPIRES("builders_club.membership_expires"), + BUILDERS_CLUB_MEMBERSHIP_EXTENDED("builders_club.membership_extended"), + BUILDERS_CLUB_MEMBERSHIP_MADE("builders_club.membership_made"), + BUILDERS_CLUB_MEMBERSHIP_RENEWED("builders_club.membership_renewed"), + BUILDERS_CLUB_ROOM_LOCKED("builders_club.room_locked"), + BUILDERS_CLUB_ROOM_UNLOCKED("builders_club.room_unlocked"), + BUILDERS_CLUB_VISIT_DENIED_OWNER("builders_club.visit_denied_for_owner"), + BUILDERS_CLUB_VISIT_DENIED_GUEST("builders_club.visit_denied_for_visitor"), + CASINO_TOO_MANY_DICE_PLACEMENT("casino.too_many_dice.placement"), + CASINO_TOO_MANY_DICE("casino.too_many_dice"), + FLOORPLAN_EDITOR_ERROR("floorplan_editor.error"), + FORUMS_DELIVERED("forums.delivered"), + FORUMS_FORUM_SETTINGS_UPDATED("forums.forum_settings_updated"), + FORUMS_MESSAGE_HIDDEN("forums.message.hidden"), + FORUMS_MESSAGE_RESTORED("forums.message.restored"), + FORUMS_THREAD_HIDDEN("forums.thread.hidden"), + FORUMS_ACCESS_DENIED("forums.error.access_denied"), + FORUMS_THREAD_LOCKED("forums.thread.locked"), + FORUMS_THREAD_PINNED("forums.thread.pinned"), + FORUMS_THREAD_RESTORED("forums.thread.restored"), + FORUMS_THREAD_UNLOCKED("forums.thread.unlocked"), + FORUMS_THREAD_UNPINNED("forums.thread.unpinned"), + FURNITURE_PLACEMENT_ERROR("furni_placement_error"), + GIFTING_VALENTINE("gifting.valentine"), + NUX_POPUP("nux.popup"), + PURCHASING_ROOM("purchasing.room"), + RECEIVED_GIFT("received.gift"), + RECEIVED_BADGE("received.badge"), + FIGURESET_REDEEMED("figureset.redeemed.success"), + FIGURESET_OWNED_ALREADY("figureset.already.redeemed"); + + public final String key; + + BubbleAlertKeys(String key) { + this.key = key; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/CustomNotificationComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/CustomNotificationComposer.java new file mode 100644 index 0000000..2e1a52d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/CustomNotificationComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.generic.alerts; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CustomNotificationComposer extends MessageComposer { + public static final int HOPPER_NO_COSTUME = 1; + public static final int HOPPER_NO_HC = 2; + public static final int GATE_NO_HC = 3; + public static final int STARS_NOT_CANDIDATE = 4; + public static final int STARS_NOT_ENOUGH_USERS = 5; + + private final int type; + + public CustomNotificationComposer(int type) { + this.type = type; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CustomNotificationComposer); + this.response.appendInt(this.type); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/GenericAlertComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/GenericAlertComposer.java new file mode 100644 index 0000000..2b4d597 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/GenericAlertComposer.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.outgoing.generic.alerts; + +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.Outgoing; + +public class GenericAlertComposer extends MessageComposer { + private final String message; + + public GenericAlertComposer(String message) { + this.message = message; + } + + public GenericAlertComposer(String message, Habbo habbo) { + this.message = message.replace("%username%", habbo.getHabboInfo().getUsername()); + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GenericAlertComposer); + + this.response.appendString(this.message); + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/GenericErrorMessagesComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/GenericErrorMessagesComposer.java new file mode 100644 index 0000000..7757cdd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/GenericErrorMessagesComposer.java @@ -0,0 +1,28 @@ +package com.eu.habbo.messages.outgoing.generic.alerts; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GenericErrorMessagesComposer extends MessageComposer { + public static final int AUTHENTICATION_FAILED = -3; + public static final int CONNECTING_TO_THE_SERVER_FAILED = -400; + public static final int KICKED_OUT_OF_THE_ROOM = 4008; + public static final int NEED_TO_BE_VIP = 4009; + public static final int ROOM_NAME_UNACCEPTABLE = 4010; + public static final int CANNOT_BAN_GROUP_MEMBER = 4011; + public static final int WRONG_PASSWORD_USED = -100002; + + private final int errorCode; + + public GenericErrorMessagesComposer(int errorCode) { + this.errorCode = errorCode; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GenericErrorMessages); + this.response.appendInt(this.errorCode); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/HotelClosedAndOpensComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/HotelClosedAndOpensComposer.java new file mode 100644 index 0000000..fc7cc92 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/HotelClosedAndOpensComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.generic.alerts; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HotelClosedAndOpensComposer extends MessageComposer { + private final int hour; + private final int minute; + + public HotelClosedAndOpensComposer(int hour, int minute) { + this.hour = hour; + this.minute = minute; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HotelClosedAndOpensComposer); + this.response.appendInt(this.hour); + this.response.appendInt(this.minute); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/HotelClosesAndWillOpenAtComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/HotelClosesAndWillOpenAtComposer.java new file mode 100644 index 0000000..d92497f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/HotelClosesAndWillOpenAtComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.generic.alerts; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HotelClosesAndWillOpenAtComposer extends MessageComposer { + private final int hour; + private final int minute; + private final boolean disconnected; + + public HotelClosesAndWillOpenAtComposer(int hour, int minute, boolean disconnected) { + this.hour = hour; + this.minute = minute; + this.disconnected = disconnected; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HotelClosesAndWillOpenAtComposer); + this.response.appendInt(this.hour); + this.response.appendInt(this.minute); + this.response.appendBoolean(this.disconnected); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/HotelWillCloseInMinutesAndBackInComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/HotelWillCloseInMinutesAndBackInComposer.java new file mode 100644 index 0000000..3e9d3ad --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/HotelWillCloseInMinutesAndBackInComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.generic.alerts; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HotelWillCloseInMinutesAndBackInComposer extends MessageComposer { + private final int closeInMinutes; + private final int reopenInMinutes; + + public HotelWillCloseInMinutesAndBackInComposer(int closeInMinutes, int reopenInMinutes) { + this.closeInMinutes = closeInMinutes; + this.reopenInMinutes = reopenInMinutes; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HotelWillCloseInMinutesAndBackInComposer); + this.response.appendBoolean(true); + this.response.appendInt(this.closeInMinutes); + this.response.appendInt(this.reopenInMinutes); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/HotelWillCloseInMinutesComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/HotelWillCloseInMinutesComposer.java new file mode 100644 index 0000000..0a4f1a9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/HotelWillCloseInMinutesComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.generic.alerts; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HotelWillCloseInMinutesComposer extends MessageComposer { + private final int minutes; + + public HotelWillCloseInMinutesComposer(int minutes) { + this.minutes = minutes; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HotelWillCloseInMinutesComposer); + this.response.appendInt(this.minutes); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/MessagesForYouComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/MessagesForYouComposer.java new file mode 100644 index 0000000..0003c63 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/MessagesForYouComposer.java @@ -0,0 +1,39 @@ +package com.eu.habbo.messages.outgoing.generic.alerts; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.ArrayList; +import java.util.List; + +public class MessagesForYouComposer extends MessageComposer { + private final String[] messages; + private final List newMessages; + + public MessagesForYouComposer(String[] messages) { + this.messages = messages; + this.newMessages = new ArrayList<>(); + } + + public MessagesForYouComposer(List newMessages) { + this.newMessages = newMessages; + this.messages = new String[]{}; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MessagesForYouComposer); + this.response.appendInt(this.messages.length + this.newMessages.size()); + + for (String s : this.messages) { + this.response.appendString(s); + } + + for (String s : this.newMessages) { + this.response.appendString(s); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/PetErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/PetErrorComposer.java new file mode 100644 index 0000000..7318ff2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/PetErrorComposer.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.outgoing.generic.alerts; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PetErrorComposer extends MessageComposer { + public static final int ROOM_ERROR_PETS_FORBIDDEN_IN_HOTEL = 0; + public static final int ROOM_ERROR_PETS_FORBIDDEN_IN_FLAT = 1; + public static final int ROOM_ERROR_MAX_PETS = 2; + public static final int ROOM_ERROR_PETS_SELECTED_TILE_NOT_FREE = 3; + public static final int ROOM_ERROR_PETS_NO_FREE_TILES = 4; + public static final int ROOM_ERROR_MAX_OWN_PETS = 5; + + private final int errorCode; + + public PetErrorComposer(int errorCode) { + this.errorCode = errorCode; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PetErrorComposer); + this.response.appendInt(this.errorCode); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/StaffAlertAndOpenHabboWayComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/StaffAlertAndOpenHabboWayComposer.java new file mode 100644 index 0000000..687b43e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/StaffAlertAndOpenHabboWayComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.generic.alerts; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class StaffAlertAndOpenHabboWayComposer extends MessageComposer { + private final String message; + + public StaffAlertAndOpenHabboWayComposer(String message) { + this.message = message; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.StaffAlertAndOpenHabboWayComposer); + this.response.appendString(this.message); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/StaffAlertWIthLinkAndOpenHabboWayComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/StaffAlertWIthLinkAndOpenHabboWayComposer.java new file mode 100644 index 0000000..7a7686c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/StaffAlertWIthLinkAndOpenHabboWayComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.generic.alerts; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class StaffAlertWIthLinkAndOpenHabboWayComposer extends MessageComposer { + private final String message; + private final String link; + + public StaffAlertWIthLinkAndOpenHabboWayComposer(String message, String link) { + this.message = message; + this.link = link; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.StaffAlertWIthLinkAndOpenHabboWayComposer); + this.response.appendString(this.message); + this.response.appendString(this.link); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/StaffAlertWithLinkComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/StaffAlertWithLinkComposer.java new file mode 100644 index 0000000..8244798 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/StaffAlertWithLinkComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.generic.alerts; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class StaffAlertWithLinkComposer extends MessageComposer { + private final String message; + private final String link; + + public StaffAlertWithLinkComposer(String message, String link) { + this.message = message; + this.link = link; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.StaffAlertWithLinkComposer); + this.response.appendString(this.message); + this.response.appendString(this.link); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/UpdateFailedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/UpdateFailedComposer.java new file mode 100644 index 0000000..5a0e70a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/UpdateFailedComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.generic.alerts; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UpdateFailedComposer extends MessageComposer { + private final String message; + + public UpdateFailedComposer(String message) { + this.message = message; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UpdateFailedComposer); + this.response.appendString(this.message); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/testcomposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/testcomposer.java new file mode 100644 index 0000000..74f1301 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/generic/testcomposer.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.outgoing.generic; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class testcomposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(3019); + this.response.appendInt(3); + + this.response.appendInt(1); + this.response.appendInt(2); + this.response.appendString("Key"); + + this.response.appendInt(1); + this.response.appendInt(2); + this.response.appendString("Key"); + + this.response.appendInt(1); + this.response.appendInt(2); + this.response.appendString("Key"); + this.response.appendBoolean(true); + this.response.appendInt(1); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianNewReportReceivedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianNewReportReceivedComposer.java new file mode 100644 index 0000000..02d2387 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianNewReportReceivedComposer.java @@ -0,0 +1,15 @@ +package com.eu.habbo.messages.outgoing.guardians; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuardianNewReportReceivedComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuardianNewReportReceivedComposer); + this.response.appendInt(Emulator.getConfig().getInt("guardians.accept.timer")); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianVotingRequestedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianVotingRequestedComposer.java new file mode 100644 index 0000000..e420971 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianVotingRequestedComposer.java @@ -0,0 +1,50 @@ +package com.eu.habbo.messages.outgoing.guardians; + +import com.eu.habbo.habbohotel.guides.GuardianTicket; +import com.eu.habbo.habbohotel.modtool.ModToolChatLog; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.map.hash.TIntIntHashMap; + +import java.util.Calendar; + +public class GuardianVotingRequestedComposer extends MessageComposer { + private final GuardianTicket ticket; + + public GuardianVotingRequestedComposer(GuardianTicket ticket) { + this.ticket = ticket; + } + + @Override + protected ServerMessage composeInternal() { + TIntIntHashMap mappedUsers = new TIntIntHashMap(); + mappedUsers.put(this.ticket.getReported().getHabboInfo().getId(), 0); + + Calendar c = Calendar.getInstance(); + c.setTime(this.ticket.getDate()); + + StringBuilder fullMessage = new StringBuilder(c.get(Calendar.YEAR) + " "); + fullMessage.append(c.get(Calendar.MONTH)).append(" "); + fullMessage.append(c.get(Calendar.DAY_OF_MONTH)).append(" "); + fullMessage.append(c.get(Calendar.MINUTE)).append(" "); + fullMessage.append(c.get(Calendar.SECOND)).append(";"); + + fullMessage.append("\r"); + + for (ModToolChatLog chatLog : this.ticket.getChatLogs()) { + if (!mappedUsers.containsKey(chatLog.habboId)) { + mappedUsers.put(chatLog.habboId, mappedUsers.size()); + } + + fullMessage.append("unused;").append(mappedUsers.get(chatLog.habboId)).append(";").append(chatLog.message).append("\r"); + } + + this.response.init(Outgoing.GuardianVotingRequestedComposer); + this.response.appendInt(this.ticket.getTimeLeft()); + this.response.appendString(fullMessage.toString()); + + //2015 10 17 14 24 30 + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianVotingResultComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianVotingResultComposer.java new file mode 100644 index 0000000..a0f50fc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianVotingResultComposer.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.outgoing.guardians; + +import com.eu.habbo.habbohotel.guides.GuardianTicket; +import com.eu.habbo.habbohotel.guides.GuardianVote; +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.Outgoing; + +import java.util.Map; + +public class GuardianVotingResultComposer extends MessageComposer { + private final GuardianTicket ticket; + private final GuardianVote vote; + + public GuardianVotingResultComposer(GuardianTicket ticket, GuardianVote vote) { + this.ticket = ticket; + this.vote = vote; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuardianVotingResultComposer); + this.response.appendInt(this.ticket.getVerdict().getType()); //Final Verdict + this.response.appendInt(this.vote.type.getType()); //Your vote + + this.response.appendInt(this.ticket.getVotes().size() - 1); //Other votes count. + + for (Map.Entry set : this.ticket.getVotes().entrySet()) { + if (set.getValue().equals(this.vote)) + continue; + + this.response.appendInt(set.getValue().type.getType()); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianVotingTimeEnded.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianVotingTimeEnded.java new file mode 100644 index 0000000..d210c04 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianVotingTimeEnded.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.guardians; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuardianVotingTimeEnded extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuardianVotingTimeEnded); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianVotingVotesComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianVotingVotesComposer.java new file mode 100644 index 0000000..82138a8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guardians/GuardianVotingVotesComposer.java @@ -0,0 +1,35 @@ +package com.eu.habbo.messages.outgoing.guardians; + +import com.eu.habbo.habbohotel.guides.GuardianTicket; +import com.eu.habbo.habbohotel.guides.GuardianVote; +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.Outgoing; + +import java.util.ArrayList; + +public class GuardianVotingVotesComposer extends MessageComposer { + private final GuardianTicket ticket; + private final Habbo guardian; + + public GuardianVotingVotesComposer(GuardianTicket ticket, Habbo guardian) { + this.ticket = ticket; + this.guardian = guardian; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuardianVotingVotesComposer); + + ArrayList votes = this.ticket.getSortedVotes(this.guardian); + + this.response.appendInt(votes.size()); + + for (GuardianVote vote : votes) { + this.response.appendInt(vote.type.getType()); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/BullyReportClosedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/BullyReportClosedComposer.java new file mode 100644 index 0000000..f89afe9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/BullyReportClosedComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.guides; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class BullyReportClosedComposer extends MessageComposer { + public final static int CLOSED = 1; + public final static int MISUSE = 2; + + public final int code; + + public BullyReportClosedComposer(int code) { + this.code = code; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.BullyReportClosedComposer); + this.response.appendInt(this.code); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionAttachedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionAttachedComposer.java new file mode 100644 index 0000000..999ccc7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionAttachedComposer.java @@ -0,0 +1,28 @@ +package com.eu.habbo.messages.outgoing.guides; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuideTour; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuideSessionAttachedComposer extends MessageComposer { + private final GuideTour tour; + private final boolean isHelper; + + public GuideSessionAttachedComposer(GuideTour tour, boolean isHelper) { + this.tour = tour; + this.isHelper = isHelper; + } + + @Override + protected ServerMessage composeInternal() { + //:test 3549 b:1 i:1 s:abcd i:100 + this.response.init(Outgoing.GuideSessionAttachedComposer); + this.response.appendBoolean(this.isHelper); //? //isHelper + this.response.appendInt(1); //? Tour type + this.response.appendString(this.tour.getHelpRequest()); //? Instruction (Help message) + this.response.appendInt(this.isHelper ? 60 : Emulator.getGameEnvironment().getGuideManager().getAverageWaitingTime()); //? Avarage Waiting Time (for noob) | Time left to pickup (For helper) + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionDetachedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionDetachedComposer.java new file mode 100644 index 0000000..d68aa2a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionDetachedComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.guides; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuideSessionDetachedComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuideSessionDetachedComposer); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionEndedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionEndedComposer.java new file mode 100644 index 0000000..a08c395 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionEndedComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.guides; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuideSessionEndedComposer extends MessageComposer { + public static final int SOMETHING_WRONG = 0; + public static final int HELP_CASE_CLOSED = 1; + + private final int errorCode; + + public GuideSessionEndedComposer(int errorCode) { + this.errorCode = errorCode; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuideSessionEndedComposer); + this.response.appendInt(this.errorCode); //? + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionErrorComposer.java new file mode 100644 index 0000000..1776a3e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionErrorComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.guides; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuideSessionErrorComposer extends MessageComposer { + public static final int SOMETHING_WRONG_REQUEST = 0; + public static final int NO_HELPERS_AVAILABLE = 1; + public static final int NO_GUARDIANS_AVAILABLE = 2; + + private final int errorCode; + + public GuideSessionErrorComposer(int errorCode) { + this.errorCode = errorCode; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuideSessionErrorComposer); + this.response.appendInt(this.errorCode); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionInvitedToGuideRoomComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionInvitedToGuideRoomComposer.java new file mode 100644 index 0000000..15a7fd3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionInvitedToGuideRoomComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.guides; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuideSessionInvitedToGuideRoomComposer extends MessageComposer { + private final Room room; + + public GuideSessionInvitedToGuideRoomComposer(Room room) { + this.room = room; + } + + //Helper invites noob + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuideSessionInvitedToGuideRoomComposer); + this.response.appendInt(this.room != null ? this.room.getId() : 0); + this.response.appendString(this.room != null ? this.room.getName() : ""); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionMessageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionMessageComposer.java new file mode 100644 index 0000000..fdf74f7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionMessageComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.guides; + +import com.eu.habbo.habbohotel.guides.GuideChatMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuideSessionMessageComposer extends MessageComposer { + private final GuideChatMessage message; + + public GuideSessionMessageComposer(GuideChatMessage message) { + this.message = message; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuideSessionMessageComposer); + this.response.appendString(this.message.message); //Message + this.response.appendInt(this.message.userId); //Sender ID + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionPartnerIsPlayingComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionPartnerIsPlayingComposer.java new file mode 100644 index 0000000..496368a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionPartnerIsPlayingComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.guides; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuideSessionPartnerIsPlayingComposer extends MessageComposer { + public final boolean isPlaying; + + public GuideSessionPartnerIsPlayingComposer(boolean isPlaying) { + this.isPlaying = isPlaying; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuideSessionPartnerIsPlayingComposer); + this.response.appendBoolean(this.isPlaying); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionPartnerIsTypingComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionPartnerIsTypingComposer.java new file mode 100644 index 0000000..3781c45 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionPartnerIsTypingComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.guides; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuideSessionPartnerIsTypingComposer extends MessageComposer { + private final boolean typing; + + public GuideSessionPartnerIsTypingComposer(boolean typing) { + this.typing = typing; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuideSessionPartnerIsTypingComposer); + this.response.appendBoolean(this.typing); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionRequesterRoomComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionRequesterRoomComposer.java new file mode 100644 index 0000000..cd6e5b8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionRequesterRoomComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.guides; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuideSessionRequesterRoomComposer extends MessageComposer { + private final Room room; + + public GuideSessionRequesterRoomComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuideSessionRequesterRoomComposer); + this.response.appendInt(this.room != null ? this.room.getId() : 0); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionStartedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionStartedComposer.java new file mode 100644 index 0000000..dd1ce31 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideSessionStartedComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.guides; + +import com.eu.habbo.habbohotel.guides.GuideTour; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuideSessionStartedComposer extends MessageComposer { + private final GuideTour tour; + + public GuideSessionStartedComposer(GuideTour tour) { + this.tour = tour; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuideSessionStartedComposer); + this.response.appendInt(this.tour.getNoob().getHabboInfo().getId()); + this.response.appendString(this.tour.getNoob().getHabboInfo().getUsername()); + this.response.appendString(this.tour.getNoob().getHabboInfo().getLook()); + this.response.appendInt(this.tour.getHelper().getHabboInfo().getId()); + this.response.appendString(this.tour.getHelper().getHabboInfo().getUsername()); + this.response.appendString(this.tour.getHelper().getHabboInfo().getLook()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideToolsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideToolsComposer.java new file mode 100644 index 0000000..dbcc32e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guides/GuideToolsComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.guides; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuideToolsComposer extends MessageComposer { + private final boolean onDuty; + + public GuideToolsComposer(boolean onDuty) { + this.onDuty = onDuty; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuideToolsComposer); + this.response.appendBoolean(this.onDuty); //OnDuty + this.response.appendInt(0); //Guides On Duty + this.response.appendInt(Emulator.getGameEnvironment().getGuideManager().getGuidesCount()); //Helpers On Duty + this.response.appendInt(Emulator.getGameEnvironment().getGuideManager().getGuardiansCount()); //Guardians On Duty + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildAcceptMemberErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildAcceptMemberErrorComposer.java new file mode 100644 index 0000000..460e6da --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildAcceptMemberErrorComposer.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.outgoing.guilds; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuildAcceptMemberErrorComposer extends MessageComposer { + public final static int NO_LONGER_MEMBER = 0; + public final static int ALREADY_REJECTED = 1; + public final static int ALREADY_ACCEPTED = 2; + + private final int guildId; + private final int errorCode; + + public GuildAcceptMemberErrorComposer(int guildId, int errorCode) { + this.guildId = guildId; + this.errorCode = errorCode; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildAcceptMemberErrorComposer); + this.response.appendInt(this.guildId); + this.response.appendInt(this.errorCode); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildBoughtComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildBoughtComposer.java new file mode 100644 index 0000000..8c5f1ac --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildBoughtComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuildBoughtComposer extends MessageComposer { + private final Guild guild; + + public GuildBoughtComposer(Guild guild) { + this.guild = guild; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildBoughtComposer); + this.response.appendInt(this.guild.getRoomId()); + this.response.appendInt(this.guild.getId()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildBuyRoomsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildBuyRoomsComposer.java new file mode 100644 index 0000000..e55f913 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildBuyRoomsComposer.java @@ -0,0 +1,52 @@ +package com.eu.habbo.messages.outgoing.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.set.hash.THashSet; + +public class GuildBuyRoomsComposer extends MessageComposer { + private final THashSet rooms; + + public GuildBuyRoomsComposer(THashSet rooms) { + this.rooms = rooms; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildBuyRoomsComposer); + this.response.appendInt(Emulator.getConfig().getInt("catalog.guild.price")); + this.response.appendInt(this.rooms.size()); + + for (Room room : this.rooms) { + this.response.appendInt(room.getId()); + this.response.appendString(room.getName()); + this.response.appendBoolean(false); + } + + this.response.appendInt(5); + + this.response.appendInt(10); + this.response.appendInt(3); + this.response.appendInt(4); + + this.response.appendInt(25); + this.response.appendInt(17); + this.response.appendInt(5); + + this.response.appendInt(25); + this.response.appendInt(17); + this.response.appendInt(3); + + this.response.appendInt(29); + this.response.appendInt(11); + this.response.appendInt(4); + + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildConfirmRemoveMemberComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildConfirmRemoveMemberComposer.java new file mode 100644 index 0000000..798fcf3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildConfirmRemoveMemberComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.guilds; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuildConfirmRemoveMemberComposer extends MessageComposer { + private int userId; + private int furniCount; + + public GuildConfirmRemoveMemberComposer(int userId, int furniCount) { + this.userId = userId; + this.furniCount = furniCount; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildConfirmRemoveMemberComposer); + this.response.appendInt(this.userId); + this.response.appendInt(this.furniCount); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildEditFailComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildEditFailComposer.java new file mode 100644 index 0000000..17780d8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildEditFailComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.guilds; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuildEditFailComposer extends MessageComposer { + public static final int ROOM_ALREADY_IN_USE = 0; + public static final int INVALID_GUILD_NAME = 1; + public static final int HC_REQUIRED = 2; + public static final int MAX_GUILDS_JOINED = 3; + + private int errorCode; + + public GuildEditFailComposer(int errorCode) { + this.errorCode = errorCode; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildEditFailComposer); + this.response.appendInt(this.errorCode); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildFavoriteRoomUserUpdateComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildFavoriteRoomUserUpdateComposer.java new file mode 100644 index 0000000..37df211 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildFavoriteRoomUserUpdateComposer.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.outgoing.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuildFavoriteRoomUserUpdateComposer extends MessageComposer { + private RoomUnit roomUnit; + private Guild guild; + + public GuildFavoriteRoomUserUpdateComposer(RoomUnit roomUnit, Guild guild) { + this.roomUnit = roomUnit; + this.guild = guild; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildFavoriteRoomUserUpdateComposer); + this.response.appendInt(this.roomUnit.getId()); + this.response.appendInt(this.guild != null ? this.guild.getId() : 0); + this.response.appendInt(this.guild != null ? this.guild.getState().state : 3); + this.response.appendString(this.guild != null ? this.guild.getName() : ""); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildFurniWidgetComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildFurniWidgetComposer.java new file mode 100644 index 0000000..e437320 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildFurniWidgetComposer.java @@ -0,0 +1,33 @@ +package com.eu.habbo.messages.outgoing.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuildFurniWidgetComposer extends MessageComposer { + private final HabboItem item; + private final Guild guild; + private final Habbo habbo; + + public GuildFurniWidgetComposer(Habbo habbo, Guild guild, HabboItem item) { + this.habbo = habbo; + this.item = item; + this.guild = guild; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildFurniWidgetComposer); + this.response.appendInt(item.getId()); + this.response.appendInt(this.guild.getId()); + this.response.appendString(this.guild.getName()); + this.response.appendInt(this.guild.getRoomId()); + this.response.appendBoolean(Emulator.getGameEnvironment().getGuildManager().getGuildMember(this.guild, this.habbo) != null); //User Joined. + this.response.appendBoolean(this.guild.hasForum()); //Has Forum. + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildInfoComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildInfoComposer.java new file mode 100644 index 0000000..dab0c0e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildInfoComposer.java @@ -0,0 +1,56 @@ +package com.eu.habbo.messages.outgoing.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.habbohotel.guilds.GuildMembershipStatus; +import com.eu.habbo.habbohotel.guilds.GuildRank; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.text.SimpleDateFormat; +import java.util.Date; + +public class GuildInfoComposer extends MessageComposer { + private final Guild guild; + private final GameClient client; + private final boolean newWindow; + private final GuildMember member; + + public GuildInfoComposer(Guild guild, GameClient client, boolean newWindow, GuildMember member) { + this.guild = guild; + this.client = client; + this.newWindow = newWindow; + this.member = member; + } + + @Override + protected ServerMessage composeInternal() { + boolean adminPermissions = this.client.getHabbo().getHabboStats().hasGuild(this.guild.getId()) && this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN) || Emulator.getGameEnvironment().getGuildManager().getOnlyAdmins(guild).get(this.client.getHabbo().getHabboInfo().getId()) != null; + this.response.init(Outgoing.GuildInfoComposer); + this.response.appendInt(this.guild.getId()); + this.response.appendBoolean(true); + this.response.appendInt(this.guild.getState().state); + this.response.appendString(this.guild.getName()); + this.response.appendString(this.guild.getDescription()); + this.response.appendString(this.guild.getBadge()); + this.response.appendInt(this.guild.getRoomId()); + this.response.appendString(this.guild.getRoomName()); + this.response.appendInt((this.member == null ? GuildMembershipStatus.NOT_MEMBER : this.member.getMembershipStatus()).getStatus()); + this.response.appendInt(this.guild.getMemberCount()); + this.response.appendBoolean(this.client.getHabbo().getHabboStats().guild == this.guild.getId()); // favorite group + this.response.appendString(new SimpleDateFormat("dd-MM-yyyy").format(new Date(this.guild.getDateCreated() * 1000L))); + this.response.appendBoolean(adminPermissions || (this.guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId())); + this.response.appendBoolean(adminPermissions || (this.member != null && (this.member.getRank().equals(GuildRank.ADMIN)))); + + this.response.appendString(this.guild.getOwnerName()); + this.response.appendBoolean(this.newWindow); + this.response.appendBoolean(this.guild.getRights()); + this.response.appendInt((adminPermissions || this.guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId()) ? this.guild.getRequestCount() : 0); //Guild invites count. + this.response.appendBoolean(this.guild.hasForum()); + return this.response; + } + } diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildJoinErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildJoinErrorComposer.java new file mode 100644 index 0000000..00716bf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildJoinErrorComposer.java @@ -0,0 +1,28 @@ +package com.eu.habbo.messages.outgoing.guilds; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuildJoinErrorComposer extends MessageComposer { + public static final int GROUP_FULL = 0; + public static final int GROUP_LIMIT_EXCEED = 1; + public static final int GROUP_CLOSED = 2; + public static final int GROUP_NOT_ACCEPT_REQUESTS = 3; + public static final int NON_HC_LIMIT_REACHED = 4; + public static final int MEMBER_FAIL_JOIN_LIMIT_EXCEED_NON_HC = 5; + public static final int MEMBER_FAIL_JOIN_LIMIT_EXCEED_HC = 6; + + private final int code; + + public GuildJoinErrorComposer(int code) { + this.code = code; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildJoinErrorComposer); + this.response.appendInt(this.code); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildListComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildListComposer.java new file mode 100644 index 0000000..82965f0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildListComposer.java @@ -0,0 +1,36 @@ +package com.eu.habbo.messages.outgoing.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +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.Outgoing; +import gnu.trove.set.hash.THashSet; + +public class GuildListComposer extends MessageComposer { + private final THashSet guilds; + private final Habbo habbo; + + public GuildListComposer(THashSet guilds, Habbo habbo) { + this.guilds = guilds; + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildListComposer); + this.response.appendInt(this.guilds.size()); + for (Guild guild : this.guilds) { + this.response.appendInt(guild.getId()); + this.response.appendString(guild.getName()); + this.response.appendString(guild.getBadge()); + this.response.appendString(Emulator.getGameEnvironment().getGuildManager().getSymbolColor(guild.getColorOne()).valueA); + this.response.appendString(Emulator.getGameEnvironment().getGuildManager().getBackgroundColor(guild.getColorTwo()).valueA); + this.response.appendBoolean(this.habbo.getHabboStats().guild == guild.getId()); + this.response.appendInt(guild.getOwnerId()); + this.response.appendBoolean(guild.hasForum()); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildManageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildManageComposer.java new file mode 100644 index 0000000..7983974 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildManageComposer.java @@ -0,0 +1,62 @@ +package com.eu.habbo.messages.outgoing.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuildManageComposer extends MessageComposer { + private final Guild guild; + + public GuildManageComposer(Guild guild) { + this.guild = guild; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildManageComposer); + this.response.appendInt(1); + this.response.appendInt(guild.getRoomId()); + this.response.appendString(guild.getRoomName()); + this.response.appendBoolean(false); + this.response.appendBoolean(true); + this.response.appendInt(this.guild.getId()); + this.response.appendString(this.guild.getName()); + this.response.appendString(this.guild.getDescription()); + this.response.appendInt(this.guild.getRoomId()); + this.response.appendInt(this.guild.getColorOne()); + this.response.appendInt(this.guild.getColorTwo()); + this.response.appendInt(this.guild.getState().state); + this.response.appendInt(this.guild.getRights() ? 0 : 1); + this.response.appendBoolean(false); + this.response.appendString(""); + this.response.appendInt(5); + String badge = this.guild.getBadge(); + badge = badge.replace("b", ""); + String[] data = badge.split("s"); + int req = 5 - data.length; + int i = 0; + + for (String s : data) { + this.response.appendInt((s.length() >= 6 ? Integer.parseInt(s.substring(0, 3)) : Integer.parseInt(s.substring(0, 2)))); + this.response.appendInt((s.length() >= 6 ? Integer.parseInt(s.substring(3, 5)) : Integer.parseInt(s.substring(2, 4)))); + + if (s.length() < 5) + this.response.appendInt(0); + else if (s.length() >= 6) + this.response.appendInt(Integer.parseInt(s.substring(5, 6))); + else + this.response.appendInt(Integer.parseInt(s.substring(4, 5))); + } + + while (i != req) { + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + i++; + } + this.response.appendString(this.guild.getBadge()); + this.response.appendInt(this.guild.getMemberCount()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildMemberUpdateComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildMemberUpdateComposer.java new file mode 100644 index 0000000..e5a1290 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildMemberUpdateComposer.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.outgoing.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuildMemberUpdateComposer extends MessageComposer { + private final Guild guild; + private final GuildMember guildMember; + + public GuildMemberUpdateComposer(Guild guild, GuildMember guildMember) { + this.guildMember = guildMember; + this.guild = guild; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildMemberUpdateComposer); + this.response.appendInt(this.guild.getId()); + this.response.appendInt(this.guildMember.getRank().type); + this.response.appendInt(this.guildMember.getUserId()); + this.response.appendString(this.guildMember.getUsername()); + this.response.appendString(this.guildMember.getLook()); + this.response.appendString(this.guildMember.getRank().type != 0 ? this.guildMember.getJoinDate() + "" : ""); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildMembersComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildMembersComposer.java new file mode 100644 index 0000000..8bacc76 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildMembersComposer.java @@ -0,0 +1,62 @@ +package com.eu.habbo.messages.outgoing.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +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.Outgoing; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.TimeZone; + +public class GuildMembersComposer extends MessageComposer { + private final ArrayList members; + private final Guild guild; + private final Habbo session; + private final int pageId; + private final int level; + private final String searchValue; + private final boolean isAdmin; + private final int totalCount; + + public GuildMembersComposer(Guild guild, ArrayList members, Habbo session, int pageId, int level, String searchValue, boolean isAdmin, int totalCount) { + this.guild = guild; + this.members = members; + this.session = session; + this.pageId = pageId; + this.level = level; + this.searchValue = searchValue; + this.isAdmin = isAdmin; + this.totalCount = totalCount; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildMembersComposer); + this.response.appendInt(this.guild.getId()); + this.response.appendString(this.guild.getName()); + this.response.appendInt(this.guild.getRoomId()); + this.response.appendString(this.guild.getBadge()); + this.response.appendInt(this.totalCount); + this.response.appendInt(this.members.size()); + + Calendar cal = Calendar.getInstance(TimeZone.getDefault()); + for (GuildMember member : this.members) { + cal.setTimeInMillis(member.getJoinDate() * 1000L); + this.response.appendInt(member.getRank().type); + this.response.appendInt(member.getUserId()); + this.response.appendString(member.getUsername()); + this.response.appendString(member.getLook()); + this.response.appendString(member.getRank().type < 3 ? cal.get(Calendar.DAY_OF_MONTH) + "/" + (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.YEAR) : ""); + } + + this.response.appendBoolean(this.isAdmin); + this.response.appendInt(14); + this.response.appendInt(this.pageId); + this.response.appendInt(this.level); + this.response.appendString(this.searchValue); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildPartsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildPartsComposer.java new file mode 100644 index 0000000..01cf5cf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildPartsComposer.java @@ -0,0 +1,47 @@ +package com.eu.habbo.messages.outgoing.guilds; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.GuildPart; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuildPartsComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GroupPartsComposer); + this.response.appendInt(Emulator.getGameEnvironment().getGuildManager().getBases().size()); + for (GuildPart part : Emulator.getGameEnvironment().getGuildManager().getBases()) { + this.response.appendInt(part.id); + this.response.appendString(part.valueA); + this.response.appendString(part.valueB); + } + + this.response.appendInt(Emulator.getGameEnvironment().getGuildManager().getSymbols().size()); + for (GuildPart part : Emulator.getGameEnvironment().getGuildManager().getSymbols()) { + this.response.appendInt(part.id); + this.response.appendString(part.valueA); + this.response.appendString(part.valueB); + } + + this.response.appendInt(Emulator.getGameEnvironment().getGuildManager().getBaseColors().size()); + for (GuildPart part : Emulator.getGameEnvironment().getGuildManager().getBaseColors()) { + this.response.appendInt(part.id); + this.response.appendString(part.valueA); + } + + this.response.appendInt(Emulator.getGameEnvironment().getGuildManager().getSymbolColors().size()); + for (GuildPart part : Emulator.getGameEnvironment().getGuildManager().getSymbolColors()) { + this.response.appendInt(part.id); + this.response.appendString(part.valueA); + } + + this.response.appendInt(Emulator.getGameEnvironment().getGuildManager().getBackgroundColors().size()); + for (GuildPart part : Emulator.getGameEnvironment().getGuildManager().getBackgroundColors()) { + this.response.appendInt(part.id); + this.response.appendString(part.valueA); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildRefreshMembersListComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildRefreshMembersListComposer.java new file mode 100644 index 0000000..4a0f124 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildRefreshMembersListComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuildRefreshMembersListComposer extends MessageComposer { + private final Guild guild; + + public GuildRefreshMembersListComposer(Guild guild) { + this.guild = guild; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildRefreshMembersListComposer); + this.response.appendInt(this.guild.getId()); + this.response.appendInt(0); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/RemoveGuildFromRoomComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/RemoveGuildFromRoomComposer.java new file mode 100644 index 0000000..47a86da --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/RemoveGuildFromRoomComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.guilds; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RemoveGuildFromRoomComposer extends MessageComposer { + private int guildId; + + public RemoveGuildFromRoomComposer(int guildId) { + this.guildId = guildId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RemoveGuildFromRoomComposer); + this.response.appendInt(this.guildId); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumAddCommentComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumAddCommentComposer.java new file mode 100644 index 0000000..3570f86 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumAddCommentComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.guilds.forums; + +import com.eu.habbo.habbohotel.guilds.forums.ForumThreadComment; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuildForumAddCommentComposer extends MessageComposer { + private final ForumThreadComment comment; + + public GuildForumAddCommentComposer(ForumThreadComment comment) { + this.comment = comment; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildForumAddCommentComposer); + this.response.appendInt(this.comment.getThread().getGuildId()); //guild_id + this.response.appendInt(this.comment.getThreadId()); //thread_id + this.comment.serialize(this.response); //Comment + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumCommentsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumCommentsComposer.java new file mode 100644 index 0000000..ecafc48 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumCommentsComposer.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.outgoing.guilds.forums; + +import com.eu.habbo.habbohotel.guilds.forums.ForumThreadComment; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.Collection; + +public class GuildForumCommentsComposer extends MessageComposer { + private final int guildId; + private final int threadId; + private final int index; + private final Collection guildForumCommentList; + + public GuildForumCommentsComposer(int guildId, int threadId, int index, Collection guildForumCommentList) { + this.guildId = guildId; + this.threadId = threadId; + this.index = index; + this.guildForumCommentList = guildForumCommentList; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildForumCommentsComposer); + + this.response.appendInt(this.guildId); //guild_id + this.response.appendInt(this.threadId); //thread_id + this.response.appendInt(this.index); //start_index + this.response.appendInt(this.guildForumCommentList.size()); + + for (ForumThreadComment comment : this.guildForumCommentList) { + comment.serialize(this.response); + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumDataComposer.java new file mode 100644 index 0000000..6acd20d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumDataComposer.java @@ -0,0 +1,162 @@ +package com.eu.habbo.messages.outgoing.guilds.forums; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildMember; +import com.eu.habbo.habbohotel.guilds.GuildRank; +import com.eu.habbo.habbohotel.guilds.forums.ForumThread; +import com.eu.habbo.habbohotel.guilds.forums.ForumThreadComment; +import com.eu.habbo.habbohotel.permissions.Permission; +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.Outgoing; +import com.eu.habbo.messages.outgoing.handshake.ConnectionErrorComposer; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + + +@Slf4j +public class GuildForumDataComposer extends MessageComposer { + public final Guild guild; + public Habbo habbo; + + public GuildForumDataComposer(Guild guild, Habbo habbo) { + this.guild = guild; + this.habbo = habbo; + } + + public static void serializeForumData(ServerMessage response, Guild guild, Habbo habbo) { + + final THashSet forumThreads = ForumThread.getByGuildId(guild.getId()); + int lastSeenAt = 0; + + int totalComments = 0; + int newComments = 0; + int totalThreads = 0; + ForumThreadComment lastComment = null; + + synchronized (forumThreads) { + for (ForumThread thread : forumThreads) { + totalThreads++; + totalComments += thread.getPostsCount(); + + ForumThreadComment comment = thread.getLastComment(); + if (comment != null && (lastComment == null || lastComment.getCreatedAt() < comment.getCreatedAt())) { + lastComment = comment; + } + } + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement( + "SELECT COUNT(*) " + + "FROM guilds_forums_threads A " + + "JOIN ( " + + "SELECT * " + + "FROM `guilds_forums_comments` " + + "WHERE `id` IN ( " + + "SELECT id " + + "FROM `guilds_forums_comments` B " + + "ORDER BY B.`id` ASC " + + ") " + + "ORDER BY `id` DESC " + + ") B ON A.`id` = B.`thread_id` " + + "WHERE A.`guild_id` = ? AND B.`created_at` > ?" + )) { + statement.setInt(1, guild.getId()); + statement.setInt(2, lastSeenAt); + + ResultSet set = statement.executeQuery(); + while (set.next()) { + newComments = set.getInt(1); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + response.appendInt(guild.getId()); + response.appendString(guild.getName()); + response.appendString(guild.getDescription()); + response.appendString(guild.getBadge()); + response.appendInt(totalThreads); + response.appendInt(0); //Rating + response.appendInt(totalComments); //Total comments + response.appendInt(newComments); //Unread comments + response.appendInt(lastComment != null ? lastComment.getThreadId() : -1); + response.appendInt(lastComment != null ? lastComment.getUserId() : -1); + response.appendString(lastComment != null && lastComment.getHabbo() != null ? lastComment.getHabbo().getHabboInfo().getUsername() : ""); + response.appendInt(lastComment != null ? Emulator.getIntUnixTimestamp() - lastComment.getCreatedAt() : 0); + } + + @Override + protected ServerMessage composeInternal() { + + try { + this.response.init(Outgoing.GuildForumDataComposer); + serializeForumData(this.response, guild, habbo); + + GuildMember member = Emulator.getGameEnvironment().getGuildManager().getGuildMember(guild, habbo); + boolean isAdmin = member != null && (member.getRank().type < GuildRank.MEMBER.type || guild.getOwnerId() == this.habbo.getHabboInfo().getId()); + boolean isStaff = this.habbo.hasPermission(Permission.ACC_MODTOOL_TICKET_Q); + + String errorRead = ""; + String errorPost = ""; + String errorStartThread = ""; + String errorModerate = ""; + + if (guild.canReadForum().state == 1 && member == null && !isStaff) { + errorRead = "not_member"; + } else if (guild.canReadForum().state == 2 && !isAdmin && !isStaff) { + errorRead = "not_admin"; + } + + if (guild.canPostMessages().state == 1 && member == null && !isStaff) { + errorPost = "not_member"; + } else if (guild.canPostMessages().state == 2 && !isAdmin && !isStaff) { + errorPost = "not_admin"; + } else if (guild.canPostMessages().state == 3 && guild.getOwnerId() != this.habbo.getHabboInfo().getId() && !isStaff) { + errorPost = "not_owner"; + } + + if (guild.canPostThreads().state == 1 && member == null && !isStaff) { + errorStartThread = "not_member"; + } else if (guild.canPostThreads().state == 2 && !isAdmin && !isStaff) { + errorStartThread = "not_admin"; + } else if (guild.canPostThreads().state == 3 && guild.getOwnerId() != this.habbo.getHabboInfo().getId() && !isStaff) { + errorStartThread = "not_owner"; + } + + if (guild.canModForum().state == 3 && guild.getOwnerId() != this.habbo.getHabboInfo().getId() && !isStaff) { + errorModerate = "not_owner"; + } else if (!isAdmin && !isStaff) { + errorModerate = "not_admin"; + } + + this.response.appendInt(guild.canReadForum().state); + this.response.appendInt(guild.canPostMessages().state); + this.response.appendInt(guild.canPostThreads().state); + this.response.appendInt(guild.canModForum().state); + this.response.appendString(errorRead); + this.response.appendString(errorPost); + this.response.appendString(errorStartThread); + this.response.appendString(errorModerate); + this.response.appendString(""); //citizen + this.response.appendBoolean(guild.getOwnerId() == this.habbo.getHabboInfo().getId()); //Forum Settings + if (guild.canModForum().state == 3) { + this.response.appendBoolean(guild.getOwnerId() == this.habbo.getHabboInfo().getId() || isStaff); + } + else { + this.response.appendBoolean(guild.getOwnerId() == this.habbo.getHabboInfo().getId() || isStaff || isAdmin); //Can Mod (staff) + } + } catch (Exception e) { + e.printStackTrace(); + return new ConnectionErrorComposer(500).compose(); + } + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumListComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumListComposer.java new file mode 100644 index 0000000..ebe1d96 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumListComposer.java @@ -0,0 +1,55 @@ +package com.eu.habbo.messages.outgoing.guilds.forums; + +import com.eu.habbo.habbohotel.guilds.Guild; +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.Outgoing; +import gnu.trove.set.hash.THashSet; + +import java.util.Iterator; +import java.util.Set; + +public class GuildForumListComposer extends MessageComposer { + private final Set guilds; + private final Habbo habbo; + private final int mode; + private final int index; + + public GuildForumListComposer(Set guilds, Habbo habbo, int mode, int index) { + this.guilds = guilds; + this.habbo = habbo; + this.mode = mode; + this.index = index; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildForumListComposer); + this.response.appendInt(this.mode); + this.response.appendInt(this.guilds.size()); + + this.response.appendInt(this.index); + + Iterator it = guilds.iterator(); + int count = guilds.size() > 20 ? 20 : guilds.size(); + + this.response.appendInt(count); + + for (int i = 0; i < index; i++) { + if (!it.hasNext()) + break; + + it.next(); + } + + for (int i = 0; i < count; i++) { + if (!it.hasNext()) + break; + + GuildForumDataComposer.serializeForumData(this.response, it.next(), habbo); + } + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumThreadMessagesComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumThreadMessagesComposer.java new file mode 100644 index 0000000..c1d77bb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumThreadMessagesComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.guilds.forums; + +import com.eu.habbo.habbohotel.guilds.forums.ForumThread; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuildForumThreadMessagesComposer extends MessageComposer { + public final ForumThread thread; + + public GuildForumThreadMessagesComposer(ForumThread thread) { + this.thread = thread; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildForumThreadMessagesComposer); + this.response.appendInt(this.thread.getGuildId()); + this.thread.serialize(this.response); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumThreadsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumThreadsComposer.java new file mode 100644 index 0000000..e5750b8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumThreadsComposer.java @@ -0,0 +1,61 @@ +package com.eu.habbo.messages.outgoing.guilds.forums; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.forums.ForumThread; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import com.eu.habbo.messages.outgoing.handshake.ConnectionErrorComposer; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; + +public class GuildForumThreadsComposer extends MessageComposer { + public final Guild guild; + public final int index; + + public GuildForumThreadsComposer(Guild guild, int index) { + this.guild = guild; + this.index = index; + } + + @Override + protected ServerMessage composeInternal() { + ArrayList threads; + + try { + threads = new ArrayList<>(ForumThread.getByGuildId(guild.getId())); + } catch (Exception e) { + return new ConnectionErrorComposer(500).compose(); + } + + threads.sort(Comparator.comparingInt(o -> o.isPinned() ? Integer.MAX_VALUE : o.getUpdatedAt())); + Collections.reverse(threads); + + Iterator it = threads.iterator(); + int count = threads.size() > 20 ? 20 : threads.size(); + + this.response.init(Outgoing.GuildForumThreadsComposer); + this.response.appendInt(this.guild.getId()); + this.response.appendInt(this.index); + this.response.appendInt(count); + + for (int i = 0; i < index; i++) { + if (!it.hasNext()) + break; + + it.next(); + } + + for (int i = 0; i < count; i++) { + if (!it.hasNext()) + break; + + it.next().serialize(this.response); + } + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumsUnreadMessagesCountComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumsUnreadMessagesCountComposer.java new file mode 100644 index 0000000..e989747 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumsUnreadMessagesCountComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.guilds.forums; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class GuildForumsUnreadMessagesCountComposer extends MessageComposer { + public final int count; + + public GuildForumsUnreadMessagesCountComposer(int count) { + this.count = count; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.GuildForumsUnreadMessagesCountComposer); + this.response.appendInt(this.count); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/PostUpdateMessageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/PostUpdateMessageComposer.java new file mode 100644 index 0000000..bdf20b7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/PostUpdateMessageComposer.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.outgoing.guilds.forums; + +import com.eu.habbo.habbohotel.guilds.forums.ForumThreadComment; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PostUpdateMessageComposer extends MessageComposer { + public final int guildId; + public final int threadId; + public final ForumThreadComment comment; + + public PostUpdateMessageComposer(int guildId, int threadId, ForumThreadComment comment) { + this.guildId = guildId; + this.threadId = threadId; + this.comment = comment; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PostUpdateMessageComposer); + + this.response.appendInt(this.guildId); //guild_id + this.response.appendInt(this.threadId); //thread_id + this.comment.serialize(this.response); //Comment + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/ThreadUpdatedMessageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/ThreadUpdatedMessageComposer.java new file mode 100644 index 0000000..96ab2ea --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/ThreadUpdatedMessageComposer.java @@ -0,0 +1,38 @@ +package com.eu.habbo.messages.outgoing.guilds.forums; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.forums.ForumThread; +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.Outgoing; + +public class ThreadUpdatedMessageComposer extends MessageComposer { + + public final Guild guild; + + public final ForumThread thread; + + private final Habbo habbo; + + private final boolean isPinned; + + private final boolean isLocked; + + public ThreadUpdatedMessageComposer(Guild guild, ForumThread thread, Habbo habbo, boolean isPinned, boolean isLocked) { + this.guild = guild; + this.habbo = habbo; + this.thread = thread; + this.isPinned = isPinned; + this.isLocked = isLocked; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ThreadUpdateMessageComposer); + this.response.appendInt(this.thread.getGuildId()); + this.thread.serialize(this.response); + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/HabboWayQuizComposer1.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/HabboWayQuizComposer1.java new file mode 100644 index 0000000..d2f73e4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/HabboWayQuizComposer1.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.habboway; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HabboWayQuizComposer1 extends MessageComposer { + public final String name; + public final int[] items; + + public HabboWayQuizComposer1(String name, int[] items) { + this.name = name; + this.items = items; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HabboWayQuizComposer1); + this.response.appendString(this.name); + this.response.appendInt(this.items.length); + for (int item : this.items) { + this.response.appendInt(item); + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/HabboWayQuizComposer2.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/HabboWayQuizComposer2.java new file mode 100644 index 0000000..dd3086e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/HabboWayQuizComposer2.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.habboway; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HabboWayQuizComposer2 extends MessageComposer { + public final String name; + public final int[] items; + + public HabboWayQuizComposer2(String name, int[] items) { + this.name = name; + this.items = items; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HabboWayQuizComposer2); + this.response.appendString(this.name); + this.response.appendInt(this.items.length); + for (int item : this.items) { + this.response.appendInt(item); + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/nux/NewUserGiftComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/nux/NewUserGiftComposer.java new file mode 100644 index 0000000..ec2a8b4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/nux/NewUserGiftComposer.java @@ -0,0 +1,31 @@ +package com.eu.habbo.messages.outgoing.habboway.nux; + +import com.eu.habbo.habbohotel.items.NewUserGift; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.List; + +public class NewUserGiftComposer extends MessageComposer { + private final List> options; + + public NewUserGiftComposer(List> options) { + this.options = options; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.NewUserGiftComposer); + this.response.appendInt(this.options.size()); + for (List option : this.options) { + this.response.appendInt(1); + this.response.appendInt(3); + this.response.appendInt(option.size()); + for (NewUserGift gift : option) { + gift.serialize(this.response); + } + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/nux/NewUserIdentityComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/nux/NewUserIdentityComposer.java new file mode 100644 index 0000000..13c03ac --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/nux/NewUserIdentityComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.habboway.nux; + +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.Outgoing; + +public class NewUserIdentityComposer extends MessageComposer { + private final Habbo habbo; + + public NewUserIdentityComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.NewUserIdentityComposer); + this.response.appendInt(this.habbo.noobStatus()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/nux/NuxAlertComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/nux/NuxAlertComposer.java new file mode 100644 index 0000000..02188a0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/habboway/nux/NuxAlertComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.habboway.nux; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class NuxAlertComposer extends MessageComposer { + private final String link; + + public NuxAlertComposer(String link) { + this.link = link; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.NuxAlertComposer); + this.response.appendString(this.link); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/AvailabilityStatusMessageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/AvailabilityStatusMessageComposer.java new file mode 100644 index 0000000..d65cc78 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/AvailabilityStatusMessageComposer.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.outgoing.handshake; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class AvailabilityStatusMessageComposer extends MessageComposer { + private final boolean isOpen; + private final boolean isShuttingDown; + private final boolean isAuthenticHabbo; + + public AvailabilityStatusMessageComposer(boolean isOpen, boolean isShuttingDown, boolean isAuthenticHabbo) { + this.isOpen = isOpen; + this.isShuttingDown = isShuttingDown; + this.isAuthenticHabbo = isAuthenticHabbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.AvailabilityStatusMessageComposer); + + this.response.appendBoolean(isOpen);//isOpen + this.response.appendBoolean(isShuttingDown);//onShutdown + this.response.appendBoolean(isAuthenticHabbo);//isAuthenticHabbo + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/CompleteDiffieHandshakeComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/CompleteDiffieHandshakeComposer.java new file mode 100644 index 0000000..dc2c5fb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/CompleteDiffieHandshakeComposer.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.outgoing.handshake; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CompleteDiffieHandshakeComposer extends MessageComposer { + + private final String publicKey; + private final boolean clientEncryption; + + public CompleteDiffieHandshakeComposer(String publicKey) { + this(publicKey, true); + } + + public CompleteDiffieHandshakeComposer(String publicKey, boolean clientEncryption) { + this.publicKey = publicKey; + this.clientEncryption = clientEncryption; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CompleteDiffieHandshakeComposer); + this.response.appendString(this.publicKey); + this.response.appendBoolean(this.clientEncryption); + return this.response; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/ConnectionErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/ConnectionErrorComposer.java new file mode 100644 index 0000000..fb01eff --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/ConnectionErrorComposer.java @@ -0,0 +1,33 @@ +package com.eu.habbo.messages.outgoing.handshake; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ConnectionErrorComposer extends MessageComposer { + private final int messageId; + private final int errorCode; + private final String timestamp; + + public ConnectionErrorComposer(int errorCode) { + this.messageId = 0; + this.errorCode = errorCode; + this.timestamp = ""; + } + + public ConnectionErrorComposer(int messageId, int errorCode, String timestamp) { + this.messageId = messageId; + this.errorCode = errorCode; + this.timestamp = timestamp; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ConnectionErrorComposer); + this.response.appendInt(this.messageId); + this.response.appendInt(this.errorCode); + this.response.appendString(this.timestamp); + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/EnableNotificationsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/EnableNotificationsComposer.java new file mode 100644 index 0000000..575cd17 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/EnableNotificationsComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.handshake; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class EnableNotificationsComposer extends MessageComposer { + private final boolean enabled; + + public EnableNotificationsComposer(boolean enabled) { + this.enabled = enabled; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.EnableNotificationsComposer); + this.response.appendBoolean(this.enabled); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/InitDiffieHandshakeComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/InitDiffieHandshakeComposer.java new file mode 100644 index 0000000..72ffdb0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/InitDiffieHandshakeComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.handshake; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class InitDiffieHandshakeComposer extends MessageComposer { + + private final String signedPrime; + private final String signedGenerator; + + public InitDiffieHandshakeComposer(String signedPrime, String signedGenerator) { + this.signedPrime = signedPrime; + this.signedGenerator = signedGenerator; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.InitDiffieHandshakeComposer); + this.response.appendString(this.signedPrime); + this.response.appendString(this.signedGenerator); + return this.response; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/MachineIDComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/MachineIDComposer.java new file mode 100644 index 0000000..f96abff --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/MachineIDComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.handshake; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class MachineIDComposer extends MessageComposer { + + private final String machineId; + + public MachineIDComposer(String machineId) { + this.machineId = machineId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MachineIDComposer); + this.response.appendString(this.machineId); + return this.response; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/PingComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/PingComposer.java new file mode 100644 index 0000000..a830068 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/PingComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.handshake; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PingComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PingComposer); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/PongComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/PongComposer.java new file mode 100644 index 0000000..c30c6af --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/PongComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.handshake; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PongComposer extends MessageComposer { + private final int id; + + public PongComposer(int id) { + this.id = id; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PongComposer); + this.response.appendInt(this.id); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/SecureLoginOKComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/SecureLoginOKComposer.java new file mode 100644 index 0000000..03ec75f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/handshake/SecureLoginOKComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.handshake; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class SecureLoginOKComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.SecureLoginOKComposer); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/BonusRareComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/BonusRareComposer.java new file mode 100644 index 0000000..1c38778 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/BonusRareComposer.java @@ -0,0 +1,28 @@ +package com.eu.habbo.messages.outgoing.hotelview; + +import com.eu.habbo.Emulator; +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.Outgoing; + +public class BonusRareComposer extends MessageComposer { + private final Habbo habbo; + + public BonusRareComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.BonusRareComposer); + this.response.appendString(Emulator.getConfig().getValue("hotelview.promotional.reward.name", "prizetrophy_breed_gold")); //Furniture Name. Note: Image is in external_variables.txt + this.response.appendInt(Emulator.getConfig().getInt("hotelview.promotional.reward.id", 0)); //Furniture ID + this.response.appendInt(Emulator.getConfig().getInt("hotelview.promotional.points", 120)); //Total Required + //this.response.appendInt(this.habbo.getHabboInfo().getBonusRarePoints() >= Emulator.getConfig().getInt("hotelview.promotinal.points", 120) ? Emulator.getConfig().getInt("hotelview.promotinal.points", 120) : this.habbo.getHabboInfo().getBonusRarePoints() ); //Total To Gain + int points = Emulator.getConfig().getInt("hotelview.promotional.points", 120) - this.habbo.getHabboInfo().getBonusRarePoints(); + this.response.appendInt(points < 0 ? 0 : points); + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HallOfFameComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HallOfFameComposer.java new file mode 100644 index 0000000..ef796db --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HallOfFameComposer.java @@ -0,0 +1,40 @@ +package com.eu.habbo.messages.outgoing.hotelview; + +import com.eu.habbo.habbohotel.hotelview.HallOfFame; +import com.eu.habbo.habbohotel.hotelview.HallOfFameWinner; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class HallOfFameComposer extends MessageComposer { + private final HallOfFame hallOfFame; + + public HallOfFameComposer(HallOfFame hallOfFame) { + this.hallOfFame = hallOfFame; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HallOfFameComposer); + this.response.appendString(this.hallOfFame.getCompetitionName()); + this.response.appendInt(this.hallOfFame.getWinners().size()); + + int count = 1; + + List winners = new ArrayList<>(this.hallOfFame.getWinners().values()); + Collections.sort(winners); + for (HallOfFameWinner winner : winners) { + this.response.appendInt(winner.getId()); + this.response.appendString(winner.getUsername()); + this.response.appendString(winner.getLook()); + this.response.appendInt(count); + this.response.appendInt(winner.getPoints()); + count++; + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewBadgeButtonConfigComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewBadgeButtonConfigComposer.java new file mode 100644 index 0000000..501103d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewBadgeButtonConfigComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.hotelview; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HotelViewBadgeButtonConfigComposer extends MessageComposer { + private final String badge; + private final boolean enabled; + + public HotelViewBadgeButtonConfigComposer(String badge, boolean enabled) { + this.badge = badge; + this.enabled = enabled; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HotelViewBadgeButtonConfigComposer); + this.response.appendString(this.badge); + this.response.appendBoolean(this.enabled); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewCatalogPageExpiringComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewCatalogPageExpiringComposer.java new file mode 100644 index 0000000..bc98a0c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewCatalogPageExpiringComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.hotelview; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HotelViewCatalogPageExpiringComposer extends MessageComposer { + private final String name; + private final int time; + private final String image; + + public HotelViewCatalogPageExpiringComposer(String name, int time, String image) { + this.name = name; + this.time = time; + this.image = image; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HotelViewCatalogPageExpiringComposer); + this.response.appendString(this.name); + this.response.appendInt(this.time); + this.response.appendString(this.image); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewCommunityGoalComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewCommunityGoalComposer.java new file mode 100644 index 0000000..f1614f5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewCommunityGoalComposer.java @@ -0,0 +1,60 @@ +package com.eu.habbo.messages.outgoing.hotelview; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HotelViewCommunityGoalComposer extends MessageComposer { + private final boolean achieved; + private final int personalContributionScore; + private final int personalRank; + private final int totalAmount; + private final int communityHighestAchievedLevel; + private final int scoreRemainingUntilNextLevel; + private final int percentCompletionTowardsNextLevel; + private final String competitionName; + private final int timeLeft; + private final int[] rankData; + + public HotelViewCommunityGoalComposer(boolean achieved, + int personalContributionScore, + int personalRank, + int totalAmount, + int communityHighestAchievedLevel, + int scoreRemainingUntilNextLevel, + int percentCompletionTowardsNextLevel, + String competitionName, + int timeLeft, + int[] rankData) { + this.achieved = achieved; + this.personalContributionScore = personalContributionScore; + this.personalRank = personalRank; + this.totalAmount = totalAmount; + this.communityHighestAchievedLevel = communityHighestAchievedLevel; + this.scoreRemainingUntilNextLevel = scoreRemainingUntilNextLevel; + this.percentCompletionTowardsNextLevel = percentCompletionTowardsNextLevel; + this.competitionName = competitionName; + this.timeLeft = timeLeft; + this.rankData = rankData; + } + + //:test 1579 b:1 i:0 i:1 i:2 i:3 i:4 i:5 s:a i:6 i:1 i:1 + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HotelViewCommunityGoalComposer); + this.response.appendBoolean(this.achieved); //Achieved? + this.response.appendInt(this.personalContributionScore); //User Amount + this.response.appendInt(this.personalRank); //User Rank + this.response.appendInt(this.personalRank); //Total Amount + this.response.appendInt(this.totalAmount); //Community Highest Achieved + this.response.appendInt(this.communityHighestAchievedLevel); //Community Score Untill Next Level + this.response.appendInt(this.scoreRemainingUntilNextLevel); //Percent Completed Till Next Level + this.response.appendString(this.competitionName); + this.response.appendInt(this.timeLeft); //Timer + this.response.appendInt(this.rankData.length); //Rank Count + for (int i : this.rankData) { + this.response.appendInt(i); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewComposer.java new file mode 100644 index 0000000..26dd8cb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.hotelview; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HotelViewComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HotelViewComposer); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewConcurrentUsersComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewConcurrentUsersComposer.java new file mode 100644 index 0000000..87a90fc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewConcurrentUsersComposer.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.outgoing.hotelview; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HotelViewConcurrentUsersComposer extends MessageComposer { + public static final int ACTIVE = 0; + public static final int HIDDEN = 2; + public static final int ACHIEVED = 3; + + private final int state; + private final int userCount; + private final int goal; + + public HotelViewConcurrentUsersComposer(int state, int userCount, int goal) { + this.state = state; + this.userCount = userCount; + this.goal = goal; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HotelViewConcurrentUsersComposer); + this.response.appendInt(this.state); + this.response.appendInt(this.userCount); + this.response.appendInt(this.goal); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewCustomTimerComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewCustomTimerComposer.java new file mode 100644 index 0000000..f31e320 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewCustomTimerComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.hotelview; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HotelViewCustomTimerComposer extends MessageComposer { + private final String name; + private final int seconds; + + public HotelViewCustomTimerComposer(String name, int seconds) { + this.name = name; + this.seconds = seconds; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HotelViewCustomTimerComposer); + this.response.appendString(this.name); //Send by the client. + this.response.appendInt(this.seconds); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewDataComposer.java new file mode 100644 index 0000000..1271d5f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewDataComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.hotelview; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HotelViewDataComposer extends MessageComposer { + private final String data; + private final String key; + + public HotelViewDataComposer(String data, String key) { + this.data = data; + this.key = key; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HotelViewDataComposer); + + this.response.appendString(this.data); + this.response.appendString(this.key); + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewExpiringCatalogPageCommposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewExpiringCatalogPageCommposer.java new file mode 100644 index 0000000..bc0b082 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewExpiringCatalogPageCommposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.hotelview; + +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HotelViewExpiringCatalogPageCommposer extends MessageComposer { + private final CatalogPage page; + private final String image; + + public HotelViewExpiringCatalogPageCommposer(CatalogPage page, String image) { + this.page = page; + this.image = image; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HotelViewExpiringCatalogPageCommposer); + this.response.appendString(this.page.getCaption()); + this.response.appendInt(this.page.getId()); + this.response.appendString(this.image); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewHideCommunityVoteButtonComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewHideCommunityVoteButtonComposer.java new file mode 100644 index 0000000..6a32b5d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewHideCommunityVoteButtonComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.hotelview; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HotelViewHideCommunityVoteButtonComposer extends MessageComposer { + private final boolean unknownBoolean; + + public HotelViewHideCommunityVoteButtonComposer(boolean unknownBoolean) { + this.unknownBoolean = unknownBoolean; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HotelViewHideCommunityVoteButtonComposer); + this.response.appendBoolean(this.unknownBoolean); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewNextLTDAvailableComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewNextLTDAvailableComposer.java new file mode 100644 index 0000000..d922ceb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewNextLTDAvailableComposer.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.outgoing.hotelview; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HotelViewNextLTDAvailableComposer extends MessageComposer { + private final int time; + private final int pageId; + private final int itemId; + private final String itemName; + + public HotelViewNextLTDAvailableComposer(int time, int pageId, int itemId, String itemName) { + this.time = time; + this.pageId = pageId; + this.itemId = itemId; + this.itemName = itemName; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HotelViewNextLTDAvailableComposer); + this.response.appendInt(this.time); + this.response.appendInt(this.pageId); + this.response.appendInt(this.itemId); + this.response.appendString(this.itemName); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewSecondsUntilComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewSecondsUntilComposer.java new file mode 100644 index 0000000..91538dc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/HotelViewSecondsUntilComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.hotelview; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HotelViewSecondsUntilComposer extends MessageComposer { + private final String dateString; + private final int seconds; + + public HotelViewSecondsUntilComposer(String dateString, int seconds) { + this.dateString = dateString; + this.seconds = seconds; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HotelViewSecondsUntilComposer); + this.response.appendString(this.dateString); + this.response.appendInt(this.seconds); + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/NewsListComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/NewsListComposer.java new file mode 100644 index 0000000..bdb6e59 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/hotelview/NewsListComposer.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.outgoing.hotelview; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.hotelview.NewsList; +import com.eu.habbo.habbohotel.hotelview.NewsWidget; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class NewsListComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.NewsWidgetsComposer); + NewsList newsList = Emulator.getGameEnvironment().getHotelViewManager().getNewsList(); + + this.response.appendInt(newsList.getNewsWidgets().size()); + + for (NewsWidget widget : newsList.getNewsWidgets()) { + this.response.appendInt(widget.getId()); + this.response.appendString(widget.getTitle()); + this.response.appendString(widget.getMessage()); + this.response.appendString(widget.getButtonMessage()); + this.response.appendInt(widget.getType()); + this.response.appendString(widget.getLink()); + this.response.appendString(widget.getImage()); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/AddBotComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/AddBotComposer.java new file mode 100644 index 0000000..fc64df0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/AddBotComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class AddBotComposer extends MessageComposer { + private final Bot bot; + + public AddBotComposer(Bot bot) { + this.bot = bot; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.AddBotComposer); + this.response.appendInt(this.bot.getId()); + this.response.appendString(this.bot.getName()); + this.response.appendString(this.bot.getMotto()); + this.response.appendString(this.bot.getGender().toString().toLowerCase().charAt(0) + ""); + this.response.appendString(this.bot.getFigure()); + this.response.appendBoolean(true); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/AddHabboItemComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/AddHabboItemComposer.java new file mode 100644 index 0000000..266d413 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/AddHabboItemComposer.java @@ -0,0 +1,97 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.set.hash.THashSet; + +import java.util.List; +import java.util.Map; + +public class AddHabboItemComposer extends MessageComposer { + private THashSet itemsList; + private HabboItem item; + private int[] ids; + private AddHabboItemCategory category; + private Map> entries; + + public AddHabboItemComposer(THashSet itemsList) { + this.itemsList = itemsList; + this.category = AddHabboItemCategory.OWNED_FURNI; + } + + public AddHabboItemComposer(HabboItem item) { + this.item = item; + this.category = AddHabboItemCategory.OWNED_FURNI; + } + + public AddHabboItemComposer(int[] ids, AddHabboItemCategory category) { + this.ids = ids; + this.category = category; + } + + public AddHabboItemComposer(int id, AddHabboItemCategory category) { + this.ids = new int[]{id}; + this.category = category; + } + + public AddHabboItemComposer(Map> entries) { + this.entries = entries; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.AddHabboItemComposer); + + if (this.ids != null) { + this.response.appendInt(1); + + this.response.appendInt(this.category.number); + this.response.appendInt(this.ids.length); + for (int id : this.ids) { + this.response.appendInt(id); + } + } else if (this.entries != null) { + this.response.appendInt(this.entries.size()); + + for (Map.Entry> item : this.entries.entrySet()) { + this.response.appendInt(item.getKey().number); + + this.response.appendInt(item.getValue().size()); + for (int id : item.getValue()) { + this.response.appendInt(id); + } + } + } else if (this.item == null) { + this.response.appendInt(1); + this.response.appendInt(1); + this.response.appendInt(this.itemsList.size()); + for (HabboItem habboItem : this.itemsList) { + this.response.appendInt(habboItem.getId()); + } + } else { + this.response.appendInt(1); + this.response.appendInt(1); + this.response.appendInt(1); + this.response.appendInt(this.item.getId()); + } + + return this.response; + } + + public enum AddHabboItemCategory { + OWNED_FURNI(1), + RENTED_FURNI(2), + PET(3), + BADGE(4), + BOT(5), + GAME(6); + + public final int number; + + AddHabboItemCategory(int number) { + this.number = number; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/AddPetComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/AddPetComposer.java new file mode 100644 index 0000000..150d678 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/AddPetComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class AddPetComposer extends MessageComposer { + private final Pet pet; + + public AddPetComposer(Pet pet) { + this.pet = pet; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.AddPetComposer); + this.pet.serialize(this.response); + this.response.appendBoolean(false); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/EffectsListAddComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/EffectsListAddComposer.java new file mode 100644 index 0000000..f518760 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/EffectsListAddComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.habbohotel.users.inventory.EffectsComponent; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class EffectsListAddComposer extends MessageComposer { + public final EffectsComponent.HabboEffect effect; + + public + EffectsListAddComposer(EffectsComponent.HabboEffect effect) { + this.effect = effect; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.EffectsListAddComposer); + this.response.appendInt(this.effect.effect); //Type + this.response.appendInt(0); //Unknown Costume? + this.response.appendInt(effect.duration > 0 ? effect.duration : Integer.MAX_VALUE); //Duration + this.response.appendBoolean(effect.duration <= 0); //Is active + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/EffectsListEffectEnableComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/EffectsListEffectEnableComposer.java new file mode 100644 index 0000000..8b107b5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/EffectsListEffectEnableComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.habbohotel.users.inventory.EffectsComponent; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class EffectsListEffectEnableComposer extends MessageComposer { + public final EffectsComponent.HabboEffect effect; + + public EffectsListEffectEnableComposer(EffectsComponent.HabboEffect effect) { + this.effect = effect; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.EffectsListEffectEnableComposer); + this.response.appendInt(this.effect.effect); //Type + this.response.appendInt(this.effect.duration); //Duration + this.response.appendBoolean(this.effect.enabled); //activated + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/EffectsListRemoveComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/EffectsListRemoveComposer.java new file mode 100644 index 0000000..f9d8020 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/EffectsListRemoveComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.habbohotel.users.inventory.EffectsComponent; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class EffectsListRemoveComposer extends MessageComposer { + public final EffectsComponent.HabboEffect effect; + + public EffectsListRemoveComposer(EffectsComponent.HabboEffect effect) { + this.effect = effect; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.EffectsListRemoveComposer); + this.response.appendInt(this.effect.effect); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryAchievementsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryAchievementsComposer.java new file mode 100644 index 0000000..40c66bb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryAchievementsComposer.java @@ -0,0 +1,38 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.achievements.AchievementLevel; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectProcedure; + +public class InventoryAchievementsComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.InventoryAchievementsComposer); + + synchronized (Emulator.getGameEnvironment().getAchievementManager().getAchievements()) { + THashMap achievements = Emulator.getGameEnvironment().getAchievementManager().getAchievements(); + + this.response.appendInt(achievements.size()); + achievements.forEachValue(new TObjectProcedure() { + @Override + public boolean execute(Achievement achievement) { + InventoryAchievementsComposer.this.response.appendString((achievement.name.startsWith("ACH_") ? achievement.name.replace("ACH_", "") : achievement.name)); + InventoryAchievementsComposer.this.response.appendInt(achievement.levels.size()); + + for (AchievementLevel level : achievement.levels.values()) { + InventoryAchievementsComposer.this.response.appendInt(level.level); + InventoryAchievementsComposer.this.response.appendInt(level.progress); + } + + return true; + } + }); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryBadgesComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryBadgesComposer.java new file mode 100644 index 0000000..e9dd505 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryBadgesComposer.java @@ -0,0 +1,44 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.set.hash.THashSet; + +public class InventoryBadgesComposer extends MessageComposer { + private final Habbo habbo; + + public InventoryBadgesComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + if (this.habbo == null) + return null; + + THashSet equippedBadges = new THashSet<>(); + + this.response.init(Outgoing.InventoryBadgesComposer); + + this.response.appendInt(this.habbo.getInventory().getBadgesComponent().getBadges().size()); + for (HabboBadge badge : this.habbo.getInventory().getBadgesComponent().getBadges()) { + this.response.appendInt(badge.getId()); + this.response.appendString(badge.getCode()); + + if (badge.getSlot() > 0) + equippedBadges.add(badge); + } + + this.response.appendInt(equippedBadges.size()); + + for (HabboBadge badge : equippedBadges) { + this.response.appendInt(badge.getSlot()); + this.response.appendString(badge.getCode()); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryBotsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryBotsComposer.java new file mode 100644 index 0000000..fe3b04e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryBotsComposer.java @@ -0,0 +1,33 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.habbohotel.bots.Bot; +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.Outgoing; +import gnu.trove.map.hash.THashMap; + +public class InventoryBotsComposer extends MessageComposer { + private final Habbo habbo; + + public InventoryBotsComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.InventoryBotsComposer); + + THashMap userBots = this.habbo.getInventory().getBotsComponent().getBots(); + this.response.appendInt(userBots.size()); + for (Bot bot : userBots.values()) { + this.response.appendInt(bot.getId()); + this.response.appendString(bot.getName()); + this.response.appendString(bot.getMotto()); + this.response.appendString(bot.getGender().toString().toLowerCase().charAt(0) + ""); + this.response.appendString(bot.getFigure()); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryItemsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryItemsComposer.java new file mode 100644 index 0000000..284d611 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryItemsComposer.java @@ -0,0 +1,107 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.habbohotel.items.FurnitureType; +import com.eu.habbo.habbohotel.items.interactions.InteractionGift; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.procedure.TIntObjectProcedure; +import lombok.extern.slf4j.Slf4j; +import java.util.Arrays; +import java.util.List; + +@Slf4j +public class InventoryItemsComposer extends MessageComposer implements TIntObjectProcedure { + private final int fragmentNumber; + private final int totalFragments; + private final TIntObjectMap items; + + public InventoryItemsComposer(int fragmentNumber, int totalFragments, TIntObjectMap items) { + this.fragmentNumber = fragmentNumber; + this.totalFragments = totalFragments; + this.items = items; + } + + @Override + protected ServerMessage composeInternal() { + try { + this.response.init(Outgoing.InventoryItemsComposer); + this.response.appendInt(this.totalFragments); + this.response.appendInt(this.fragmentNumber - 1); + this.response.appendInt(this.items.size()); + + this.items.forEachEntry(this); + return this.response; + } catch (Exception e) { + log.error("Caught exception", e); + } + + return null; + } + + @Override + public boolean execute(int a, HabboItem habboItem) { + this.response.appendInt(habboItem.getGiftAdjustedId()); + this.response.appendString(habboItem.getBaseItem().getType().code); + this.response.appendInt(habboItem.getId()); + this.response.appendInt(habboItem.getBaseItem().getSpriteId()); + + if (habboItem.getBaseItem().getName().equals("floor") || habboItem.getBaseItem().getName().equals("landscape") || habboItem.getBaseItem().getName().equals("song_disk") || habboItem.getBaseItem().getName().equals("wallpaper") || habboItem.getBaseItem().getName().equals("poster")) { + switch (habboItem.getBaseItem().getName()) { + case "landscape": + this.response.appendInt(4); + break; + case "floor": + this.response.appendInt(3); + break; + case "wallpaper": + this.response.appendInt(2); + break; + case "poster": + this.response.appendInt(6); + break; + case "song_disk": + this.response.appendInt(8); + break; + } + this.addExtraDataToResponse(habboItem); + } else { + if (habboItem.getBaseItem().getName().equals("gnome_box")) + this.response.appendInt(13); + else + this.response.appendInt(habboItem instanceof InteractionGift ? ((((InteractionGift) habboItem).getColorId() * 1000) + ((InteractionGift) habboItem).getRibbonId()) : 1); + + habboItem.serializeExtradata(this.response); + } + this.response.appendBoolean(habboItem.getBaseItem().allowRecyle()); + this.response.appendBoolean(habboItem.getBaseItem().allowTrade()); + this.response.appendBoolean(!habboItem.isLimited() && habboItem.getBaseItem().allowInventoryStack()); + this.response.appendBoolean(habboItem.getBaseItem().allowMarketplace()); + this.response.appendInt(-1); + this.response.appendBoolean(true); + this.response.appendInt(-1); + + + if (habboItem.getBaseItem().getType() == FurnitureType.FLOOR) { + this.response.appendString(""); + if(habboItem.getBaseItem().getName().equals("song_disk")) { + List extraDataAsList = Arrays.asList(habboItem.getExtradata().split("\n")); + this.response.appendInt(Integer.valueOf(extraDataAsList.get(extraDataAsList.size() - 1))); + return true; + } + this.response.appendInt(habboItem instanceof InteractionGift ? ((((InteractionGift) habboItem).getColorId() * 1000) + ((InteractionGift) habboItem).getRibbonId()) : 1); + } + + + + return true; + } + + public void addExtraDataToResponse(HabboItem habboItem) { + this.response.appendInt(0); + this.response.appendString(habboItem.getExtradata()); + } + +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryPetsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryPetsComposer.java new file mode 100644 index 0000000..a0f9740 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryPetsComposer.java @@ -0,0 +1,40 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.habbohotel.pets.Pet; +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.Outgoing; +import gnu.trove.iterator.TIntObjectIterator; + +import java.util.NoSuchElementException; + +public class InventoryPetsComposer extends MessageComposer { + private final Habbo habbo; + + public InventoryPetsComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.InventoryPetsComposer); + + this.response.appendInt(1); + this.response.appendInt(1); + this.response.appendInt(this.habbo.getInventory().getPetsComponent().getPetsCount()); + + TIntObjectIterator petIterator = this.habbo.getInventory().getPetsComponent().getPets().iterator(); + + for (int i = this.habbo.getInventory().getPetsComponent().getPets().size(); i-- > 0; ) { + try { + petIterator.advance(); + } catch (NoSuchElementException e) { + break; + } + petIterator.value().serialize(this.response); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryRefreshComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryRefreshComposer.java new file mode 100644 index 0000000..9bafa3d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryRefreshComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class InventoryRefreshComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.InventoryRefreshComposer); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryUpdateItemComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryUpdateItemComposer.java new file mode 100644 index 0000000..c558f98 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryUpdateItemComposer.java @@ -0,0 +1,65 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.habbohotel.items.FurnitureType; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class InventoryUpdateItemComposer extends MessageComposer { + private final HabboItem habboItem; + + public InventoryUpdateItemComposer(HabboItem item) { + this.habboItem = item; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.InventoryItemUpdateComposer); + this.response.appendInt(this.habboItem.getGiftAdjustedId()); + this.response.appendString(this.habboItem.getBaseItem().getType().code); + this.response.appendInt(this.habboItem.getId()); + this.response.appendInt(this.habboItem.getBaseItem().getSpriteId()); + + switch (this.habboItem.getBaseItem().getName()) { + case "landscape": + this.response.appendInt(4); + break; + case "floor": + this.response.appendInt(3); + break; + case "wallpaper": + this.response.appendInt(2); + break; + case "poster": + this.response.appendInt(6); + break; + } + + if (this.habboItem.isLimited()) { + this.response.appendInt(1); + this.response.appendInt(256); + this.response.appendString(this.habboItem.getExtradata()); + this.response.appendInt(this.habboItem.getLimitedSells()); + this.response.appendInt(this.habboItem.getLimitedStack()); + } else { + this.response.appendInt(1); + this.response.appendInt(0); + this.response.appendString(this.habboItem.getExtradata()); + } + this.response.appendBoolean(this.habboItem.getBaseItem().allowRecyle()); + this.response.appendBoolean(this.habboItem.getBaseItem().allowTrade()); + this.response.appendBoolean(!this.habboItem.isLimited() && this.habboItem.getBaseItem().allowInventoryStack()); + this.response.appendBoolean(this.habboItem.getBaseItem().allowMarketplace()); + this.response.appendInt(-1); + this.response.appendBoolean(false); + this.response.appendInt(-1); + + if (this.habboItem.getBaseItem().getType() == FurnitureType.FLOOR) { + this.response.appendString(""); //slotId + this.response.appendInt(0); + } + this.response.appendInt(100); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/RemoveBotComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/RemoveBotComposer.java new file mode 100644 index 0000000..cda6dc6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/RemoveBotComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RemoveBotComposer extends MessageComposer { + private final Bot bot; + + public RemoveBotComposer(Bot bot) { + this.bot = bot; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RemoveBotComposer); + this.response.appendInt(this.bot.getId()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/RemoveHabboItemComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/RemoveHabboItemComposer.java new file mode 100644 index 0000000..c9855e9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/RemoveHabboItemComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RemoveHabboItemComposer extends MessageComposer { + private final int itemId; + + public RemoveHabboItemComposer(final int itemId) { + this.itemId = itemId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RemoveHabboItemComposer); + this.response.appendInt(this.itemId); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/RemovePetComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/RemovePetComposer.java new file mode 100644 index 0000000..af495d2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/RemovePetComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RemovePetComposer extends MessageComposer { + private final int petId; + + public RemovePetComposer(Pet pet) { + this.petId = pet.getId(); + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RemovePetComposer); + this.response.appendInt(this.petId); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/UserEffectsListComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/UserEffectsListComposer.java new file mode 100644 index 0000000..13e42b5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/inventory/UserEffectsListComposer.java @@ -0,0 +1,51 @@ +package com.eu.habbo.messages.outgoing.inventory; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.inventory.EffectsComponent; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.Collection; + + +public class UserEffectsListComposer extends MessageComposer { + public final Habbo habbo; + public final Collection effects; + + public UserEffectsListComposer(Habbo habbo, Collection effects) { + this.habbo = habbo; + this.effects = effects; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserEffectsListComposer); + + + if (this.habbo == null || this.habbo.getInventory() == null || this.habbo.getInventory().getEffectsComponent() == null || this.habbo.getInventory().getEffectsComponent().effects == null) { + this.response.appendInt(0); + } else { + synchronized (this.habbo.getInventory().getEffectsComponent().effects) { + this.response.appendInt(this.effects.size()); + + for (EffectsComponent.HabboEffect effect : effects) { + UserEffectsListComposer.this.response.appendInt(effect.effect); + UserEffectsListComposer.this.response.appendInt(0); + UserEffectsListComposer.this.response.appendInt(effect.duration > 0 ? effect.duration : Integer.MAX_VALUE); + UserEffectsListComposer.this.response.appendInt((effect.duration > 0 ? (effect.total - (effect.isActivated() ? 1 : 0)) : 0)); + + if(!effect.isActivated() && effect.duration > 0) { + UserEffectsListComposer.this.response.appendInt(0); + } + else { + UserEffectsListComposer.this.response.appendInt(effect.duration > 0 ? (Emulator.getIntUnixTimestamp() - effect.activationTimestamp) + effect.duration : 0); + } + UserEffectsListComposer.this.response.appendBoolean(effect.duration <= 0); // is perm + } + } + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/BullyReportRequestComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/BullyReportRequestComposer.java new file mode 100644 index 0000000..9d64854 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/BullyReportRequestComposer.java @@ -0,0 +1,44 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class BullyReportRequestComposer extends MessageComposer { + public static final int START_REPORT = 0; + public static final int ONGOING_HELPER_CASE = 1; + public static final int INVALID_REQUESTS = 2; + public static final int TOO_RECENT = 3; + + private final int errorCode; + private final int errorCodeType; + + public BullyReportRequestComposer(int errorCode, int errorCodeType) { + this.errorCode = errorCode; + this.errorCodeType = errorCodeType; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.BullyReportRequestComposer); + this.response.appendInt(this.errorCode); + + if (this.errorCode == ONGOING_HELPER_CASE) { + this.response.appendInt(this.errorCodeType); + this.response.appendInt(1); //Timestamp + this.response.appendBoolean(true); //Pending guide session. + + this.response.appendString("admin"); + this.response.appendString("ca-1807-64.lg-3365-78.hr-3370-42-31.hd-3093-1359.ch-3372-65"); + switch (this.errorCodeType) { + case 3: + this.response.appendString("room Name"); + break; + case 1: + this.response.appendString("description"); + } + } + //:test 1917 i:1 i:3 i:1 b:0 s:1 s:1 s:1 + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/BullyReportedMessageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/BullyReportedMessageComposer.java new file mode 100644 index 0000000..bca14d5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/BullyReportedMessageComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class BullyReportedMessageComposer extends MessageComposer { + public static final int RECEIVED = 0; + public static final int IGNORED = 1; + public static final int NO_CHAT = 2; + public static final int ALREADY_REPORTED = 3; + public static final int NO_MISSUSE = 4; + + private final int code; + + public BullyReportedMessageComposer(int code) { + this.code = code; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.BullyReportedMessageComposer); + this.response.appendInt(this.code); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/CfhTopicsMessageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/CfhTopicsMessageComposer.java new file mode 100644 index 0000000..5a7f3ee --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/CfhTopicsMessageComposer.java @@ -0,0 +1,38 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.CfhCategory; +import com.eu.habbo.habbohotel.modtool.CfhTopic; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.procedure.TObjectProcedure; + +public class CfhTopicsMessageComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CfhTopicsMessageComposer); + + this.response.appendInt(Emulator.getGameEnvironment().getModToolManager().getCfhCategories().valueCollection().size()); + + Emulator.getGameEnvironment().getModToolManager().getCfhCategories().forEachValue(new TObjectProcedure() { + @Override + public boolean execute(CfhCategory category) { + CfhTopicsMessageComposer.this.response.appendString(category.getName()); + CfhTopicsMessageComposer.this.response.appendInt(category.getTopics().valueCollection().size()); + category.getTopics().forEachValue(new TObjectProcedure() { + @Override + public boolean execute(CfhTopic topic) { + CfhTopicsMessageComposer.this.response.appendString(topic.name); + CfhTopicsMessageComposer.this.response.appendInt(topic.id); + CfhTopicsMessageComposer.this.response.appendString(topic.action.toString()); + return true; + } + }); + return true; + } + }); + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/HelperRequestDisabledComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/HelperRequestDisabledComposer.java new file mode 100644 index 0000000..8c8a1d2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/HelperRequestDisabledComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HelperRequestDisabledComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HelperRequestDisabledComposer); + this.response.appendString(""); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolComposer.java new file mode 100644 index 0000000..aacc82a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolComposer.java @@ -0,0 +1,97 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolCategory; +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.habbohotel.modtool.ModToolTicketState; +import com.eu.habbo.habbohotel.permissions.Permission; +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.Outgoing; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectProcedure; +import gnu.trove.set.hash.THashSet; + +import java.util.Iterator; + +public class ModToolComposer extends MessageComposer implements TObjectProcedure { + private final Habbo habbo; + + public ModToolComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ModToolComposer); + + if (this.habbo.hasPermission(Permission.ACC_MODTOOL_TICKET_Q)) { + THashSet openTickets = new THashSet<>(); + + THashMap tickets = Emulator.getGameEnvironment().getModToolManager().getTickets(); + + for (ModToolIssue t : tickets.values()) { + if (t.state != ModToolTicketState.CLOSED) + openTickets.add(t); + } + + int ticketsCount = openTickets.size(); + + if (ticketsCount > 100) { + ticketsCount = 100; + } + + this.response.appendInt(ticketsCount); //tickets + + Iterator it = openTickets.iterator(); + + for (int i = 0; i < ticketsCount; i++) { + it.next().serialize(this.response); + } + } else { + this.response.appendInt(0); + } + + synchronized (Emulator.getGameEnvironment().getModToolManager().getPresets()) { + this.response.appendInt(Emulator.getGameEnvironment().getModToolManager().getPresets().get("user").size()); + for (String s : Emulator.getGameEnvironment().getModToolManager().getPresets().get("user")) { + this.response.appendString(s); + } + } + + this.response.appendInt(Emulator.getGameEnvironment().getModToolManager().getCategory().size()); + + Emulator.getGameEnvironment().getModToolManager().getCategory().forEachValue(this); + + this.response.appendBoolean(this.habbo.hasPermission(Permission.ACC_MODTOOL_TICKET_Q)); //ticketQueueueuhuehuehuehue + this.response.appendBoolean(this.habbo.hasPermission(Permission.ACC_MODTOOL_USER_LOGS)); //user chatlogs + this.response.appendBoolean(this.habbo.hasPermission(Permission.ACC_MODTOOL_USER_ALERT)); //can send caution + this.response.appendBoolean(this.habbo.hasPermission(Permission.ACC_MODTOOL_USER_KICK)); //can send kick + this.response.appendBoolean(this.habbo.hasPermission(Permission.ACC_MODTOOL_USER_BAN)); //can send ban + this.response.appendBoolean(this.habbo.hasPermission(Permission.ACC_MODTOOL_ROOM_INFO)); //room info ??Not sure + this.response.appendBoolean(this.habbo.hasPermission(Permission.ACC_MODTOOL_ROOM_LOGS)); //room chatlogs ??Not sure + + synchronized (Emulator.getGameEnvironment().getModToolManager().getPresets()) { + this.response.appendInt(Emulator.getGameEnvironment().getModToolManager().getPresets().get("room").size()); + for (String s : Emulator.getGameEnvironment().getModToolManager().getPresets().get("room")) { + this.response.appendString(s); + } + } + + return this.response; + } + + @Override + public boolean execute(ModToolCategory category) { + this.response.appendString(category.getName()); + + +// + +// + + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueChatlogComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueChatlogComposer.java new file mode 100644 index 0000000..fbbc23a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueChatlogComposer.java @@ -0,0 +1,101 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.*; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.List; + +public class ModToolIssueChatlogComposer extends MessageComposer { + public static SimpleDateFormat format = new SimpleDateFormat("HH:mm"); + private final ModToolIssue issue; + private final List chatlog; + private final String roomName; + private ModToolIssueChatlogType type = ModToolIssueChatlogType.CHAT; + + public ModToolIssueChatlogComposer(ModToolIssue issue, List chatlog, String roomName) { + this.issue = issue; + this.chatlog = chatlog; + this.roomName = roomName; + } + + public ModToolIssueChatlogComposer(ModToolIssue issue, List chatlog, String roomName, ModToolIssueChatlogType type) { + this.issue = issue; + this.chatlog = chatlog; + this.roomName = roomName; + this.type = type; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ModToolIssueChatlogComposer); + this.response.appendInt(this.issue.id); + this.response.appendInt(this.issue.senderId); + this.response.appendInt(this.issue.reportedId); + this.response.appendInt(this.issue.roomId); + + Collections.sort(this.chatlog); + + if (this.chatlog.isEmpty()) + return null; + + this.response.appendByte(this.type.getType()); //Report Type + + if (this.issue.type == ModToolTicketType.IM) { + this.response.appendShort(1); + + ModToolChatRecordDataContext.MESSAGE_ID.append(this.response); + this.response.appendInt(this.issue.senderId); + } else if (this.issue.type == ModToolTicketType.DISCUSSION) { + this.response.appendShort(this.type == ModToolIssueChatlogType.FORUM_COMMENT ? 3 : 2); + + ModToolChatRecordDataContext.GROUP_ID.append(this.response); + this.response.appendInt(this.issue.groupId); + + ModToolChatRecordDataContext.THREAD_ID.append(this.response); + this.response.appendInt(this.issue.threadId); + + if (this.type == ModToolIssueChatlogType.FORUM_COMMENT) { + ModToolChatRecordDataContext.MESSAGE_ID.append(this.response); + this.response.appendInt(this.issue.commentId); + } + } else if (this.issue.type == ModToolTicketType.PHOTO) { + this.response.appendShort(2); + + ModToolChatRecordDataContext.ROOM_NAME.append(this.response); + this.response.appendString(this.roomName); + + ModToolChatRecordDataContext.PHOTO_ID.append(this.response); + this.response.appendString(this.issue.photoItem.getId() + ""); + } else { + this.response.appendShort(3); //Context Count + + ModToolChatRecordDataContext.ROOM_NAME.append(this.response); + this.response.appendString(this.roomName); + + ModToolChatRecordDataContext.ROOM_ID.append(this.response); + this.response.appendInt(this.issue.roomId); + + ModToolChatRecordDataContext.GROUP_ID.append(this.response); + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.issue.roomId); + this.response.appendInt(room == null ? 0 : room.getGuildId()); + } + + this.response.appendShort(this.chatlog.size()); + for (ModToolChatLog chatLog : this.chatlog) { + this.response.appendString(format.format(chatLog.timestamp * 1000L)); + this.response.appendInt(chatLog.habboId); + this.response.appendString(chatLog.username); + this.response.appendString(chatLog.message); + this.response.appendBoolean(chatLog.highlighted); + } + //} + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueHandledComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueHandledComposer.java new file mode 100644 index 0000000..0cdc7ee --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueHandledComposer.java @@ -0,0 +1,32 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ModToolIssueHandledComposer extends MessageComposer { + public static final int HANDLED = 0; + public static final int USELESS = 1; + public static final int ABUSIVE = 2; + + private final int code; + private final String message; + + public ModToolIssueHandledComposer(int code) { + this.code = code; + this.message = ""; + } + + public ModToolIssueHandledComposer(String message) { + this.code = 0; + this.message = message; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ModToolIssueHandledComposer); + this.response.appendInt(this.code); + this.response.appendString(this.message); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueHandlerDimensionsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueHandlerDimensionsComposer.java new file mode 100644 index 0000000..225c212 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueHandlerDimensionsComposer.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ModToolIssueHandlerDimensionsComposer extends MessageComposer { + private final int x; + private final int y; + private final int width; + private final int height; + + public ModToolIssueHandlerDimensionsComposer(int x, int y, int width, int height) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ModToolIssueHandlerDimensionsComposer); + this.response.appendInt(this.x); + this.response.appendInt(this.y); + this.response.appendInt(this.width); + this.response.appendInt(this.height); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueInfoComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueInfoComposer.java new file mode 100644 index 0000000..6abe7b2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueInfoComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ModToolIssueInfoComposer extends MessageComposer { + private final ModToolIssue issue; + + public ModToolIssueInfoComposer(ModToolIssue issue) { + this.issue = issue; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ModToolIssueInfoComposer); + this.issue.serialize(this.response); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueResponseAlertComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueResponseAlertComposer.java new file mode 100644 index 0000000..3be7663 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueResponseAlertComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ModToolIssueResponseAlertComposer extends MessageComposer { + private final String message; + + public ModToolIssueResponseAlertComposer(String message) { + this.message = message; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ModToolIssueResponseAlertComposer); + this.response.appendString(this.message); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueUpdateComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueUpdateComposer.java new file mode 100644 index 0000000..e3756e7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolIssueUpdateComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ModToolIssueUpdateComposer extends MessageComposer { + private final ModToolIssue issue; + + public ModToolIssueUpdateComposer(ModToolIssue issue) { + this.issue = issue; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ModToolIssueUpdateComposer); + this.issue.serialize(this.response); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolReportReceivedAlertComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolReportReceivedAlertComposer.java new file mode 100644 index 0000000..6f6315e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolReportReceivedAlertComposer.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ModToolReportReceivedAlertComposer extends MessageComposer { + public static final int REPORT_RECEIVED = 0; + public static final int REPORT_WINDOW = 1; + public static final int REPORT_ABUSIVE = 2; + + private final int errorCode; + private final String message; + + public ModToolReportReceivedAlertComposer(int errorCode, String message) { + this.errorCode = errorCode; + this.message = message; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ModToolReportReceivedAlertComposer); + this.response.appendInt(this.errorCode); + this.response.appendString(this.message); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolRoomChatlogComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolRoomChatlogComposer.java new file mode 100644 index 0000000..50ec979 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolRoomChatlogComposer.java @@ -0,0 +1,46 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.habbohotel.modtool.ModToolChatLog; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; + +public class ModToolRoomChatlogComposer extends MessageComposer { + private final Room room; + private final ArrayList chatlog; + + public ModToolRoomChatlogComposer(Room room, ArrayList chatlog) { + this.room = room; + this.chatlog = chatlog; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ModToolRoomChatlogComposer); + this.response.appendByte(1); + this.response.appendShort(2); + this.response.appendString("roomName"); + this.response.appendByte(2); + this.response.appendString(this.room.getName()); + this.response.appendString("roomId"); + this.response.appendByte(1); + this.response.appendInt(this.room.getId()); + + SimpleDateFormat formatDate = new SimpleDateFormat("HH:mm"); + + this.response.appendShort(this.chatlog.size()); + for (ModToolChatLog line : this.chatlog) { + this.response.appendString(formatDate.format(new Date((line.timestamp * 1000L)))); + this.response.appendInt(line.habboId); + this.response.appendString(line.username); + this.response.appendString(line.message); + this.response.appendBoolean(false); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolRoomInfoComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolRoomInfoComposer.java new file mode 100644 index 0000000..c62423f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolRoomInfoComposer.java @@ -0,0 +1,32 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ModToolRoomInfoComposer extends MessageComposer { + private final Room room; + + public ModToolRoomInfoComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ModToolRoomInfoComposer); + this.response.appendInt(this.room.getId()); + this.response.appendInt(this.room.getCurrentHabbos().size()); + this.response.appendBoolean(this.room.getHabbo(this.room.getOwnerId()) != null); + this.response.appendInt(this.room.getOwnerId()); + this.response.appendString(this.room.getOwnerName()); + this.response.appendBoolean(true); + this.response.appendString(this.room.getName()); + this.response.appendString(this.room.getDescription()); + this.response.appendInt(this.room.getTags().split(";").length); + for (int i = 0; i < this.room.getTags().split(";").length; i++) { + this.response.appendString(this.room.getTags().split(";")[i]); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolSanctionInfoComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolSanctionInfoComposer.java new file mode 100644 index 0000000..e343f67 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolSanctionInfoComposer.java @@ -0,0 +1,105 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolSanctionItem; +import com.eu.habbo.habbohotel.modtool.ModToolSanctionLevelItem; +import com.eu.habbo.habbohotel.modtool.ModToolSanctions; +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.Outgoing; +import gnu.trove.map.hash.THashMap; +import org.joda.time.DateTime; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; + +public class ModToolSanctionInfoComposer extends MessageComposer { + + private final Habbo habbo; + + public ModToolSanctionInfoComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + ModToolSanctions modToolSanctions = Emulator.getGameEnvironment().getModToolSanctions(); + + Date probationEndTime; + Date probationStartTime; + + if (Emulator.getConfig().getBoolean("hotel.sanctions.enabled")) { + THashMap> modToolSanctionItemsHashMap = Emulator.getGameEnvironment().getModToolSanctions().getSanctions(habbo.getHabboInfo().getId()); + ArrayList modToolSanctionItems = modToolSanctionItemsHashMap.get(habbo.getHabboInfo().getId()); + + if (modToolSanctionItems != null && modToolSanctionItems.size() > 0) { + ModToolSanctionItem item = modToolSanctionItems.get(modToolSanctionItems.size() - 1); + + ModToolSanctionItem prevItem = null; + if (modToolSanctionItems.size() > 1 && modToolSanctionItems.get(modToolSanctionItems.size() - 2) != null) { + prevItem = modToolSanctionItems.get(modToolSanctionItems.size() - 2); + } + + ModToolSanctionLevelItem modToolSanctionLevelItem = modToolSanctions.getSanctionLevelItem(item.sanctionLevel); + ModToolSanctionLevelItem nextModToolSanctionLevelItem = modToolSanctions.getSanctionLevelItem(item.sanctionLevel + 1); + + if (item.probationTimestamp > 0) { + probationEndTime = new Date((long) item.probationTimestamp * 1000); + + probationStartTime = new DateTime(probationEndTime).minusDays(modToolSanctions.getProbationDays(modToolSanctionLevelItem)).toDate(); + + Date tradeLockedUntil = null; + + if (item.tradeLockedUntil > 0) { + tradeLockedUntil = new Date((long) item.tradeLockedUntil * 1000); + } + + this.response.init(Outgoing.ModToolSanctionInfoComposer); + + this.response.appendBoolean(prevItem != null && prevItem.probationTimestamp > 0); // has prev sanction + this.response.appendBoolean(item.probationTimestamp >= Emulator.getIntUnixTimestamp()); // is on probation + this.response.appendString(modToolSanctions.getSanctionType(modToolSanctionLevelItem)); // current sanction type + this.response.appendInt(modToolSanctions.getTimeOfSanction(modToolSanctionLevelItem)); // time of current sanction + this.response.appendInt(30); // TODO: unused? + this.response.appendString(item.reason.equals("") ? "cfh.reason.EMPTY" : item.reason); // reason + this.response.appendString(probationStartTime == null ? Emulator.getDate().toString() : probationStartTime.toString()); // probation start time + this.response.appendInt(0); // TODO: unused? + this.response.appendString(modToolSanctions.getSanctionType(nextModToolSanctionLevelItem)); // next sanction type + this.response.appendInt(modToolSanctions.getTimeOfSanction(nextModToolSanctionLevelItem)); // time to be applied in next sanction (in hours) + this.response.appendInt(30); // TODO: unused? + this.response.appendBoolean(item.isMuted); // muted + this.response.appendString(tradeLockedUntil == null ? "" : tradeLockedUntil.toString()); // trade locked until + } else { + return cleanResponse(); + } + + } else { + return cleanResponse(); + } + } + + return this.response; + } + + private ServerMessage cleanResponse() { + this.response.init(Outgoing.ModToolSanctionInfoComposer); + + this.response.appendBoolean(false); // has prev sanction + this.response.appendBoolean(false); // is on probation + this.response.appendString("ALERT"); // last sanction type + this.response.appendInt(0); // time of current sanction + this.response.appendInt(30); // TODO: unused? + this.response.appendString("cfh.reason.EMPTY"); // reason + this.response.appendString(Emulator.getDate().toString()); // probation start time + this.response.appendInt(0); // TODO: unused? + this.response.appendString("ALERT"); // next sanction type + this.response.appendInt(0); // time to be applied in next sanction (in hours) + this.response.appendInt(30); // TODO: unused? + this.response.appendBoolean(false); // muted + this.response.appendString(""); // trade locked until + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolUserChatlogComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolUserChatlogComposer.java new file mode 100644 index 0000000..19ed914 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolUserChatlogComposer.java @@ -0,0 +1,52 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.habbohotel.modtool.ModToolChatLog; +import com.eu.habbo.habbohotel.modtool.ModToolRoomVisit; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; + +public class ModToolUserChatlogComposer extends MessageComposer { + public static SimpleDateFormat format = new SimpleDateFormat("HH:mm"); + private final ArrayList set; + private final int userId; + private final String username; + + public ModToolUserChatlogComposer(ArrayList set, int userId, String username) { + this.set = set; + this.userId = userId; + this.username = username; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ModToolUserChatlogComposer); + this.response.appendInt(this.userId); + this.response.appendString(this.username); + this.response.appendInt(this.set.size()); + + for (ModToolRoomVisit visit : this.set) { + this.response.appendByte(1); + this.response.appendShort(2); + this.response.appendString("roomName"); + this.response.appendByte(2); + this.response.appendString(visit.roomName); + this.response.appendString("roomId"); + this.response.appendByte(1); + this.response.appendInt(visit.roomId); + + this.response.appendShort(visit.chat.size()); + for (ModToolChatLog chatLog : visit.chat) { + this.response.appendString(format.format(chatLog.timestamp * 1000L)); + this.response.appendInt(chatLog.habboId); + this.response.appendString(chatLog.username); + this.response.appendString(chatLog.message); + this.response.appendBoolean(false); + } + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolUserInfoComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolUserInfoComposer.java new file mode 100644 index 0000000..c009b24 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolUserInfoComposer.java @@ -0,0 +1,84 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolSanctionItem; +import com.eu.habbo.habbohotel.modtool.ModToolSanctionLevelItem; +import com.eu.habbo.habbohotel.modtool.ModToolSanctions; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; +import java.sql.*; +import java.util.ArrayList; + +@Slf4j +public class ModToolUserInfoComposer extends MessageComposer { + private final ResultSet set; + + public ModToolUserInfoComposer(ResultSet set) { + this.set = set; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ModToolUserInfoComposer); + try { + int totalBans = 0; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("SELECT COUNT(*) AS amount FROM bans WHERE user_id = ?")) { + statement.setInt(1, this.set.getInt("user_id")); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + totalBans = set.getInt("amount"); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.response.appendInt(this.set.getInt("user_id")); + this.response.appendString(this.set.getString("username")); + this.response.appendString(this.set.getString("look")); + this.response.appendInt((Emulator.getIntUnixTimestamp() - this.set.getInt("account_created")) / 60); + this.response.appendInt((this.set.getInt("online") == 1 ? 0 : Emulator.getIntUnixTimestamp() - this.set.getInt("last_online")) / 60); + this.response.appendBoolean(this.set.getInt("online") == 1); + this.response.appendInt(this.set.getInt("cfh_send")); + this.response.appendInt(this.set.getInt("cfh_abusive")); + this.response.appendInt(this.set.getInt("cfh_warnings")); + this.response.appendInt(totalBans); // Number of bans + this.response.appendInt(this.set.getInt("tradelock_amount")); + this.response.appendString(""); //Trading lock expiry timestamp + this.response.appendString(""); //Last Purchase Timestamp + this.response.appendInt(this.set.getInt("user_id")); //Personal Identification # + this.response.appendInt(0); // Number of account bans + this.response.appendString(this.set.getBoolean("hide_mail") ? "" : this.set.getString("mail")); + this.response.appendString("Rank (" + this.set.getInt("rank_id") + "): " + this.set.getString("rank_name")); //user_class_txt + + ModToolSanctions modToolSanctions = Emulator.getGameEnvironment().getModToolSanctions(); + + if (Emulator.getConfig().getBoolean("hotel.sanctions.enabled")) { + THashMap> modToolSanctionItemsHashMap = Emulator.getGameEnvironment().getModToolSanctions().getSanctions(this.set.getInt("user_id")); + ArrayList modToolSanctionItems = modToolSanctionItemsHashMap.get(this.set.getInt("user_id")); + + if (modToolSanctionItems != null && modToolSanctionItems.size() > 0) //has sanction + { + ModToolSanctionItem item = modToolSanctionItems.get(modToolSanctionItems.size() - 1); + ModToolSanctionLevelItem modToolSanctionLevelItem = modToolSanctions.getSanctionLevelItem(item.sanctionLevel); + + this.response.appendString(modToolSanctions.getSanctionType(modToolSanctionLevelItem)); + this.response.appendInt(31); + } + + } + + return this.response; + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + return null; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolUserRoomVisitsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolUserRoomVisitsComposer.java new file mode 100644 index 0000000..91e4b47 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ModToolUserRoomVisitsComposer.java @@ -0,0 +1,39 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.habbohotel.modtool.ModToolRoomVisit; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.set.hash.THashSet; + +import java.util.Calendar; +import java.util.TimeZone; + +public class ModToolUserRoomVisitsComposer extends MessageComposer { + private final HabboInfo habboInfo; + private final THashSet roomVisits; + + public ModToolUserRoomVisitsComposer(HabboInfo habboInfo, THashSet roomVisits) { + this.habboInfo = habboInfo; + this.roomVisits = roomVisits; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ModToolUserRoomVisitsComposer); + this.response.appendInt(this.habboInfo.getId()); + this.response.appendString(this.habboInfo.getUsername()); + this.response.appendInt(this.roomVisits.size()); + + Calendar cal = Calendar.getInstance(TimeZone.getDefault()); + for (ModToolRoomVisit visit : this.roomVisits) { + cal.setTimeInMillis(visit.timestamp * 1000); + this.response.appendInt(visit.roomId); + this.response.appendString(visit.roomName); + this.response.appendInt(cal.get(Calendar.HOUR)); + this.response.appendInt(cal.get(Calendar.MINUTE)); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ReportRoomFormComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ReportRoomFormComposer.java new file mode 100644 index 0000000..5498e45 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/modtool/ReportRoomFormComposer.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.outgoing.modtool; + +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.List; + +public class ReportRoomFormComposer extends MessageComposer { + private final List pendingIssues; + + public ReportRoomFormComposer(List issues) { + this.pendingIssues = issues; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ReportRoomFormComposer); + this.response.appendInt(this.pendingIssues.size()); //Current standing help request(s) amount: + + for (ModToolIssue issue : this.pendingIssues) { + this.response.appendString(issue.id + ""); + this.response.appendString(issue.timestamp + ""); + this.response.appendString(issue.message); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/mysterybox/MysteryBoxKeysComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/mysterybox/MysteryBoxKeysComposer.java new file mode 100644 index 0000000..8aa8d34 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/mysterybox/MysteryBoxKeysComposer.java @@ -0,0 +1,15 @@ +package com.eu.habbo.messages.outgoing.mysterybox; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class MysteryBoxKeysComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MysteryBoxKeysComposer); + this.response.appendString(""); //Box color + this.response.appendString(""); //Key color + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/CanCreateEventComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/CanCreateEventComposer.java new file mode 100644 index 0000000..61b268c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/CanCreateEventComposer.java @@ -0,0 +1,15 @@ +package com.eu.habbo.messages.outgoing.navigator; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CanCreateEventComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CanCreateEventComposer); + this.response.appendBoolean(true); + this.response.appendInt(0); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/CanCreateRoomComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/CanCreateRoomComposer.java new file mode 100644 index 0000000..051d651 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/CanCreateRoomComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.navigator; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CanCreateRoomComposer extends MessageComposer { + private final int count; + private final int max; + + public CanCreateRoomComposer(int count, int max) { + this.count = count; + this.max = max; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CanCreateRoomComposer); + + this.response.appendInt(this.count >= this.max ? 1 : 0); + this.response.appendInt(this.max); + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorCategoryUserCountComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorCategoryUserCountComposer.java new file mode 100644 index 0000000..119d15f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorCategoryUserCountComposer.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.outgoing.navigator; + +import com.eu.habbo.habbohotel.rooms.RoomCategory; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.List; + +public class NewNavigatorCategoryUserCountComposer extends MessageComposer { + public final List roomCategories; + + public NewNavigatorCategoryUserCountComposer(List roomCategories) { + this.roomCategories = roomCategories; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.NewNavigatorCategoryUserCountComposer); + this.response.appendInt(this.roomCategories.size()); + + for (RoomCategory category : this.roomCategories) { + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(200); + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorCollapsedCategoriesComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorCollapsedCategoriesComposer.java new file mode 100644 index 0000000..129cf75 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorCollapsedCategoriesComposer.java @@ -0,0 +1,60 @@ +package com.eu.habbo.messages.outgoing.navigator; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class NewNavigatorCollapsedCategoriesComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.NewNavigatorCollapsedCategoriesComposer); + this.response.appendInt(46); + this.response.appendString("new_ads"); + this.response.appendString("friend_finding"); + this.response.appendString("staffpicks"); + this.response.appendString("with_friends"); + this.response.appendString("with_rights"); + this.response.appendString("query"); + this.response.appendString("recommended"); + this.response.appendString("my_groups"); + this.response.appendString("favorites"); + this.response.appendString("history"); + this.response.appendString("top_promotions"); + this.response.appendString("campaign_target"); + this.response.appendString("friends_rooms"); + this.response.appendString("groups"); + this.response.appendString("metadata"); + this.response.appendString("history_freq"); + this.response.appendString("highest_score"); + this.response.appendString("competition"); + this.response.appendString("category__Agencies"); + this.response.appendString("category__Role Playing"); + this.response.appendString("category__Global Chat & Discussi"); + this.response.appendString("category__GLOBAL BUILDING AND DE"); + this.response.appendString("category__global party"); + this.response.appendString("category__global games"); + this.response.appendString("category__global fansite"); + this.response.appendString("category__global help"); + this.response.appendString("category__Trading"); + this.response.appendString("category__global personal space"); + this.response.appendString("category__Habbo Life"); + this.response.appendString("category__TRADING"); + this.response.appendString("category__global official"); + this.response.appendString("category__global trade"); + this.response.appendString("category__global reviews"); + this.response.appendString("category__global bc"); + this.response.appendString("category__global personal space"); + this.response.appendString("eventcategory__Hottest Events"); + this.response.appendString("eventcategory__Parties & Music"); + this.response.appendString("eventcategory__Role Play"); + this.response.appendString("eventcategory__Help Desk"); + this.response.appendString("eventcategory__Trading"); + this.response.appendString("eventcategory__Games"); + this.response.appendString("eventcategory__Debates & Discuss"); + this.response.appendString("eventcategory__Grand Openings"); + this.response.appendString("eventcategory__Friending"); + this.response.appendString("eventcategory__Jobs"); + this.response.appendString("eventcategory__Group Events"); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorEventCategoriesComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorEventCategoriesComposer.java new file mode 100644 index 0000000..8537682 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorEventCategoriesComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.navigator; + +import com.eu.habbo.habbohotel.navigation.EventCategory; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.ArrayList; +import java.util.List; + +public class NewNavigatorEventCategoriesComposer extends MessageComposer { + public static List CATEGORIES = new ArrayList<>(); + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.NewNavigatorEventCategoriesComposer); + + this.response.appendInt(NewNavigatorEventCategoriesComposer.CATEGORIES.size()); + + for (EventCategory category : NewNavigatorEventCategoriesComposer.CATEGORIES) { + category.serialize(this.response); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorLiftedRoomsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorLiftedRoomsComposer.java new file mode 100644 index 0000000..6a7dc06 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorLiftedRoomsComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.navigator; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class NewNavigatorLiftedRoomsComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.NewNavigatorLiftedRoomsComposer); + this.response.appendInt(0); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorMetaDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorMetaDataComposer.java new file mode 100644 index 0000000..2f8eaba --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorMetaDataComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.navigator; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class NewNavigatorMetaDataComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.NewNavigatorMetaDataComposer); + this.response.appendInt(4); + this.response.appendString("official_view"); + this.response.appendInt(0); + this.response.appendString("hotel_view"); + this.response.appendInt(0); + this.response.appendString("roomads_view"); + this.response.appendInt(0); + this.response.appendString("myworld_view"); + this.response.appendInt(0); + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorSavedSearchesComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorSavedSearchesComposer.java new file mode 100644 index 0000000..2f613c6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorSavedSearchesComposer.java @@ -0,0 +1,32 @@ +package com.eu.habbo.messages.outgoing.navigator; + +import com.eu.habbo.habbohotel.navigation.NavigatorSavedSearch; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.HashSet; +import java.util.List; + +public class NewNavigatorSavedSearchesComposer extends MessageComposer { + private final List searches; + + public NewNavigatorSavedSearchesComposer(List searches) { + this.searches = searches; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.NewNavigatorSavedSearchesComposer); + this.response.appendInt(this.searches.size()); + + for (NavigatorSavedSearch search : this.searches) { + this.response.appendInt(search.getId()); + this.response.appendString(search.getSearchCode()); + this.response.appendString(search.getFilter() == null ? "" : search.getFilter()); + this.response.appendString(""); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorSearchResultsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorSearchResultsComposer.java new file mode 100644 index 0000000..0db1126 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorSearchResultsComposer.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.outgoing.navigator; + +import com.eu.habbo.habbohotel.navigation.SearchResultList; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.List; + +public class NewNavigatorSearchResultsComposer extends MessageComposer { + private final String searchCode; + private final String searchQuery; + private final List resultList; + + public NewNavigatorSearchResultsComposer(String searchCode, String searchQuery, List resultList) { + this.searchCode = searchCode; + this.searchQuery = searchQuery; + this.resultList = resultList; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.NewNavigatorSearchResultsComposer); + this.response.appendString(this.searchCode); + this.response.appendString(this.searchQuery); + + this.response.appendInt(this.resultList.size()); //Count + + for (SearchResultList item : this.resultList) { + item.serialize(this.response); + } + + return this.response; + } + + +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorSettingsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorSettingsComposer.java new file mode 100644 index 0000000..da4025a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/NewNavigatorSettingsComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.navigator; + +import com.eu.habbo.habbohotel.users.HabboNavigatorWindowSettings; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class NewNavigatorSettingsComposer extends MessageComposer { + private final HabboNavigatorWindowSettings windowSettings; + + public NewNavigatorSettingsComposer(HabboNavigatorWindowSettings windowSettings) { + this.windowSettings = windowSettings; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.NewNavigatorSettingsComposer); + this.response.appendInt(this.windowSettings.x); + this.response.appendInt(this.windowSettings.y); + this.response.appendInt(this.windowSettings.width); + this.response.appendInt(this.windowSettings.height); + this.response.appendBoolean(this.windowSettings.openSearches); + this.response.appendInt(0); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/OpenRoomCreationWindowComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/OpenRoomCreationWindowComposer.java new file mode 100644 index 0000000..1b84ba1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/OpenRoomCreationWindowComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.navigator; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class OpenRoomCreationWindowComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.OpenRoomCreationWindowComposer); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/PrivateRoomsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/PrivateRoomsComposer.java new file mode 100644 index 0000000..beda9e0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/PrivateRoomsComposer.java @@ -0,0 +1,49 @@ +package com.eu.habbo.messages.outgoing.navigator; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import lombok.extern.slf4j.Slf4j; +import java.util.List; + +@Slf4j +public class PrivateRoomsComposer extends MessageComposer { + private final List rooms; + + public PrivateRoomsComposer(List rooms) { + this.rooms = rooms; + } + + @Override + protected ServerMessage composeInternal() { + try { + this.response.init(Outgoing.PrivateRoomsComposer); + + this.response.appendInt(2); + this.response.appendString(""); + + this.response.appendInt(this.rooms.size()); + + for (Room room : this.rooms) { + room.serialize(this.response); + } + this.response.appendBoolean(true); + + this.response.appendInt(0); + this.response.appendString("A"); + this.response.appendString("B"); + this.response.appendInt(1); + this.response.appendString("C"); + this.response.appendString("D"); + this.response.appendInt(1); + this.response.appendInt(1); + this.response.appendInt(1); + this.response.appendString("E"); + return this.response; + } catch (Exception e) { + log.error("Caught exception", e); + } + return null; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/RoomCategoriesComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/RoomCategoriesComposer.java new file mode 100644 index 0000000..9313791 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/RoomCategoriesComposer.java @@ -0,0 +1,40 @@ +package com.eu.habbo.messages.outgoing.navigator; + +import com.eu.habbo.habbohotel.rooms.RoomCategory; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.List; + +public class RoomCategoriesComposer extends MessageComposer { + private final List categories; + + public RoomCategoriesComposer(List categories) { + this.categories = categories; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomCategoriesComposer); + + this.response.appendInt(this.categories.size()); + for (RoomCategory category : this.categories) { + this.response.appendInt(category.getId()); + this.response.appendString(category.getCaption()); + this.response.appendBoolean(true); //Visible + this.response.appendBoolean(false); //True = Disconnect? + this.response.appendString(category.getCaption()); + + if (category.getCaption().startsWith("${")) { + this.response.appendString(""); + } else { + this.response.appendString(category.getCaption()); + } + + this.response.appendBoolean(false); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/RoomCreatedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/RoomCreatedComposer.java new file mode 100644 index 0000000..266b5fc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/RoomCreatedComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.navigator; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomCreatedComposer extends MessageComposer { + private final Room room; + + public RoomCreatedComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomCreatedComposer); + this.response.appendInt(this.room.getId()); + this.response.appendString(this.room.getName()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/TagsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/TagsComposer.java new file mode 100644 index 0000000..cc96671 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/navigator/TagsComposer.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.outgoing.navigator; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.Set; + +public class TagsComposer extends MessageComposer { + private final Set tags; + + public TagsComposer(Set tags) { + this.tags = tags; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.TagsComposer); + this.response.appendInt(this.tags.size()); + + int i = 1; + for (String s : this.tags) { + this.response.appendString(s); + this.response.appendInt(i); + i++; + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/PollQuestionsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/PollQuestionsComposer.java new file mode 100644 index 0000000..02ff958 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/PollQuestionsComposer.java @@ -0,0 +1,31 @@ +package com.eu.habbo.messages.outgoing.polls; + +import com.eu.habbo.habbohotel.polls.Poll; +import com.eu.habbo.habbohotel.polls.PollQuestion; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PollQuestionsComposer extends MessageComposer { + private final Poll poll; + + public PollQuestionsComposer(Poll poll) { + this.poll = poll; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PollQuestionsComposer); + + this.response.appendInt(this.poll.id); + this.response.appendString(this.poll.title); + this.response.appendString(this.poll.thanksMessage); + this.response.appendInt(this.poll.getQuestions().size()); + for (PollQuestion question : this.poll.getQuestions()) { + question.serialize(this.response); + } + + this.response.appendBoolean(true); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/PollStartComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/PollStartComposer.java new file mode 100644 index 0000000..3486d2f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/PollStartComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.polls; + +import com.eu.habbo.habbohotel.polls.Poll; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PollStartComposer extends MessageComposer { + private final Poll poll; + + public PollStartComposer(Poll poll) { + this.poll = poll; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PollStartComposer); + this.response.appendInt(this.poll.id); + this.response.appendString(this.poll.title); + this.response.appendString(this.poll.thanksMessage); + this.response.appendString(this.poll.title); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/infobus/SimplePollAnswerComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/infobus/SimplePollAnswerComposer.java new file mode 100644 index 0000000..faee66d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/infobus/SimplePollAnswerComposer.java @@ -0,0 +1,32 @@ +package com.eu.habbo.messages.outgoing.polls.infobus; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class SimplePollAnswerComposer extends MessageComposer { + private final int userId; + private final String choice; + private final int no; + private final int yes; + + public SimplePollAnswerComposer(int userId, String choice, int no, int yes) { + this.userId = userId; + this.choice = choice; + this.no = no; + this.yes = yes; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.SimplePollAnswerComposer); + this.response.appendInt(this.userId); + this.response.appendString(this.choice); + this.response.appendInt(2); + this.response.appendString("0"); + this.response.appendInt(this.no); + this.response.appendString("1"); + this.response.appendInt(this.yes); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/infobus/SimplePollAnswersComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/infobus/SimplePollAnswersComposer.java new file mode 100644 index 0000000..18ab468 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/infobus/SimplePollAnswersComposer.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.outgoing.polls.infobus; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class SimplePollAnswersComposer extends MessageComposer { + private final int no; + private final int yes; + + public SimplePollAnswersComposer(int no, int yes) { + this.no = no; + this.yes = yes; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.SimplePollAnswersComposer); + this.response.appendInt(-1); + this.response.appendInt(2); + this.response.appendString("0"); + this.response.appendInt(this.no); + this.response.appendString("1"); + this.response.appendInt(this.yes); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/infobus/SimplePollStartComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/infobus/SimplePollStartComposer.java new file mode 100644 index 0000000..efa720b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/polls/infobus/SimplePollStartComposer.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.outgoing.polls.infobus; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class SimplePollStartComposer extends MessageComposer { + public final int duration; + public final String question; + + public SimplePollStartComposer(int duration, String question) { + this.duration = duration; + this.question = question; + } + //:test 3047 s:a i:10 i:20 i:10000 i:1 i:1 i:3 s:abcdefghijklmnopqrstuvwxyz12345678901234? i:1 s:a s:b + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.SimplePollStartComposer); + this.response.appendString(this.question); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(this.duration); //duration + this.response.appendInt(-1); //Id + this.response.appendInt(0); //Number + this.response.appendInt(3); //Type + this.response.appendString(this.question); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestCompletedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestCompletedComposer.java new file mode 100644 index 0000000..dddf6a8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestCompletedComposer.java @@ -0,0 +1,62 @@ +package com.eu.habbo.messages.outgoing.quests; + +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class QuestCompletedComposer extends MessageComposer { + private final UnknownClass unknownClass; + private final boolean unknowbOolean; + + public QuestCompletedComposer(UnknownClass unknownClass, boolean unknowbOolean) { + this.unknownClass = unknownClass; + this.unknowbOolean = unknowbOolean; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.QuestCompletedComposer); + + return this.response; + } + + public static class UnknownClass implements ISerialize { + private final int activityPointsType; + private final boolean accepted; + private final int id; + private final String type; + private final int sortOrder; + private final boolean easy; + + public UnknownClass(int activityPointsType, boolean accepted, int id, String type, int sortOrder, boolean easy) { + this.activityPointsType = activityPointsType; + this.accepted = accepted; + this.id = id; + this.type = type; + this.sortOrder = sortOrder; + this.easy = easy; + } + + @Override + public void serialize(ServerMessage message) { + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.activityPointsType); + message.appendInt(this.id); + message.appendBoolean(this.accepted); + message.appendString(this.type); + message.appendString(""); + message.appendInt(0); + message.appendString(""); + message.appendInt(0); + message.appendInt(0); + message.appendInt(this.sortOrder); + message.appendString(""); + message.appendString(""); + message.appendBoolean(this.easy); + } + + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestComposer.java new file mode 100644 index 0000000..f95a405 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.quests; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class QuestComposer extends MessageComposer { + private final QuestsComposer.Quest quest; + + public QuestComposer(QuestsComposer.Quest quest) { + this.quest = quest; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.QuestComposer); + this.response.append(this.quest); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestExpiredComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestExpiredComposer.java new file mode 100644 index 0000000..479e150 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestExpiredComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.quests; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class QuestExpiredComposer extends MessageComposer { + private final boolean expired; + + public QuestExpiredComposer(boolean expired) { + this.expired = expired; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.QuestExpiredComposer); + this.response.appendBoolean(this.expired); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestionInfoComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestionInfoComposer.java new file mode 100644 index 0000000..1aa0574 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestionInfoComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.quests; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class QuestionInfoComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.QuestionInfoComposer); + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestsComposer.java new file mode 100644 index 0000000..60d877e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/quests/QuestsComposer.java @@ -0,0 +1,87 @@ +package com.eu.habbo.messages.outgoing.quests; + +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.List; + +public class QuestsComposer extends MessageComposer { + private final List quests; + private final boolean unknownBoolean; + + public QuestsComposer(List quests, boolean unknownBoolean) { + this.quests = quests; + this.unknownBoolean = unknownBoolean; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.QuestsComposer); + this.response.appendInt(this.quests.size()); + for (Quest quest : this.quests) { + this.response.append(quest); + } + this.response.appendBoolean(this.unknownBoolean); + return this.response; + } + + public static class Quest implements ISerialize { + private final String campaignCode; + private final int completedQuestsInCampaign; + private final int questCountInCampaign; + private final int activityPointType; + private final int id; + private final boolean accepted; + private final String type; + private final String imageVersion; + private final int rewardCurrencyAmount; + private final String localizationCode; + private final int completedSteps; + private final int totalSteps; + private final int sortOrder; + private final String catalogPageName; + private final String chainCode; + private final boolean easy; + + public Quest(String campaignCode, int completedQuestsInCampaign, int questCountInCampaign, int activityPointType, int id, boolean accepted, String type, String imageVersion, int rewardCurrencyAmount, String localizationCode, int completedSteps, int totalSteps, int sortOrder, String catalogPageName, String chainCode, boolean easy) { + this.campaignCode = campaignCode; + this.completedQuestsInCampaign = completedQuestsInCampaign; + this.questCountInCampaign = questCountInCampaign; + this.activityPointType = activityPointType; + this.id = id; + this.accepted = accepted; + this.type = type; + this.imageVersion = imageVersion; + this.rewardCurrencyAmount = rewardCurrencyAmount; + this.localizationCode = localizationCode; + this.completedSteps = completedSteps; + this.totalSteps = totalSteps; + this.sortOrder = sortOrder; + this.catalogPageName = catalogPageName; + this.chainCode = chainCode; + this.easy = easy; + } + + @Override + public void serialize(ServerMessage message) { + message.appendString(this.campaignCode); + message.appendInt(this.completedQuestsInCampaign); + message.appendInt(this.questCountInCampaign); + message.appendInt(this.activityPointType); + message.appendInt(this.id); + message.appendBoolean(this.accepted); + message.appendString(this.type); + message.appendString(this.imageVersion); + message.appendInt(this.rewardCurrencyAmount); + message.appendString(this.localizationCode); + message.appendInt(this.completedSteps); + message.appendInt(this.totalSteps); + message.appendInt(this.sortOrder); + message.appendString(this.catalogPageName); + message.appendString(this.chainCode); + message.appendBoolean(this.easy); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/BotForceOpenContextMenuComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/BotForceOpenContextMenuComposer.java new file mode 100644 index 0000000..3e7a7bf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/BotForceOpenContextMenuComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class BotForceOpenContextMenuComposer extends MessageComposer { + private final int botId; + + public BotForceOpenContextMenuComposer(int botId) { + this.botId = botId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.BotForceOpenContextMenuComposer); + this.response.appendInt(this.botId); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/BotSettingsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/BotSettingsComposer.java new file mode 100644 index 0000000..655e5a1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/BotSettingsComposer.java @@ -0,0 +1,62 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class BotSettingsComposer extends MessageComposer { + private final Bot bot; + private final int settingId; + + public BotSettingsComposer(Bot bot, int settingId) { + this.bot = bot; + this.settingId = settingId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.BotSettingsComposer); + this.response.appendInt(-this.bot.getId()); + this.response.appendInt(this.settingId); + + switch (this.settingId) { + case 1: + this.response.appendString(""); + break; + case 2: + StringBuilder data = new StringBuilder(); + + if (this.bot.hasChat()) { + for (String s : this.bot.getChatLines()) { + data.append(s).append("\r"); + } + } else { + data.append(Bot.NO_CHAT_SET); + } + + + data.append(";#;").append(this.bot.isChatAuto() ? "true" : "false"); + data.append(";#;").append(this.bot.getChatDelay()); + data.append(";#;").append(this.bot.isChatRandom() ? "true" : "false"); + this.response.appendString(data.toString()); + break; + case 3: + this.response.appendString(""); + break; + case 4: + this.response.appendString(""); + break; + case 5: + this.response.appendString(this.bot.getName()); + break; + case 6: + this.response.appendString(""); + break; + case 9: + this.response.appendString(this.bot.getMotto()); + break; + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/DoorbellAddUserComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/DoorbellAddUserComposer.java new file mode 100644 index 0000000..0f67890 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/DoorbellAddUserComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class DoorbellAddUserComposer extends MessageComposer { + private final String habbo; + + public DoorbellAddUserComposer(String habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.DoorbellAddUserComposer); + this.response.appendString(this.habbo); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/FavoriteRoomChangedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/FavoriteRoomChangedComposer.java new file mode 100644 index 0000000..af2ce19 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/FavoriteRoomChangedComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class FavoriteRoomChangedComposer extends MessageComposer { + private final int roomId; + private final boolean favorite; + + public FavoriteRoomChangedComposer(int roomId, boolean favorite) { + this.roomId = roomId; + this.favorite = favorite; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.FavoriteRoomChangedComposer); + this.response.appendInt(this.roomId); + this.response.appendBoolean(this.favorite); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/FloodCounterComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/FloodCounterComposer.java new file mode 100644 index 0000000..90f747b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/FloodCounterComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class FloodCounterComposer extends MessageComposer { + private final int time; + + public FloodCounterComposer(int time) { + this.time = time; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.FloodCounterComposer); + this.response.appendInt(this.time); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/ForwardToRoomComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/ForwardToRoomComposer.java new file mode 100644 index 0000000..7d758d2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/ForwardToRoomComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ForwardToRoomComposer extends MessageComposer { + private final int roomId; + + public ForwardToRoomComposer(int roomId) { + this.roomId = roomId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ForwardToRoomComposer); + this.response.appendInt(this.roomId); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/FreezeLivesComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/FreezeLivesComposer.java new file mode 100644 index 0000000..c4bf6d9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/FreezeLivesComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.games.freeze.FreezeGamePlayer; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class FreezeLivesComposer extends MessageComposer { + private final FreezeGamePlayer gamePlayer; + + public FreezeLivesComposer(FreezeGamePlayer gamePlayer) { + this.gamePlayer = gamePlayer; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.FreezeLivesComposer); + this.response.appendInt(this.gamePlayer.getHabbo().getRoomUnit().getId()); + this.response.appendInt(this.gamePlayer.getLives()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/HideDoorbellComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/HideDoorbellComposer.java new file mode 100644 index 0000000..e9a49ee --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/HideDoorbellComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HideDoorbellComposer extends MessageComposer { + private final String username; + + public HideDoorbellComposer(String username) { + this.username = username; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HideDoorbellComposer); + this.response.appendString(this.username); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/KnockKnockUnknownComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/KnockKnockUnknownComposer.java new file mode 100644 index 0000000..6751805 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/KnockKnockUnknownComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class KnockKnockUnknownComposer extends MessageComposer { + private final Habbo habbo; + + public KnockKnockUnknownComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(478); //TODO Hardcoded header + this.response.appendString(this.habbo.getHabboInfo().getUsername()); + this.response.appendInt(this.habbo.getHabboInfo().getId()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomAccessDeniedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomAccessDeniedComposer.java new file mode 100644 index 0000000..728a23b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomAccessDeniedComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomAccessDeniedComposer extends MessageComposer { + private final String habbo; + + public RoomAccessDeniedComposer(String habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomAccessDeniedComposer); + this.response.appendString(this.habbo); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomAddRightsListComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomAddRightsListComposer.java new file mode 100644 index 0000000..6829f5f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomAddRightsListComposer.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomAddRightsListComposer extends MessageComposer { + private final Room room; + private final int userId; + private final String userName; + + public RoomAddRightsListComposer(Room room, int userId, String username) { + this.room = room; + this.userId = userId; + this.userName = username; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomAddRightsListComposer); + this.response.appendInt(this.room.getId()); + this.response.appendInt(this.userId); + this.response.appendString(this.userName); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomBannedUsersComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomBannedUsersComposer.java new file mode 100644 index 0000000..763e5a7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomBannedUsersComposer.java @@ -0,0 +1,54 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomBan; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.iterator.TIntObjectIterator; +import gnu.trove.set.hash.THashSet; + +import java.util.NoSuchElementException; + +public class RoomBannedUsersComposer extends MessageComposer { + private final Room room; + + public RoomBannedUsersComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + int timeStamp = Emulator.getIntUnixTimestamp(); + + THashSet roomBans = new THashSet<>(); + + TIntObjectIterator iterator = this.room.getBannedHabbos().iterator(); + + for (int i = this.room.getBannedHabbos().size(); i-- > 0; ) { + try { + iterator.advance(); + + if (iterator.value().endTimestamp > timeStamp) + roomBans.add(iterator.value()); + } catch (NoSuchElementException e) { + break; + } + } + + if (roomBans.isEmpty()) + return null; + + this.response.init(Outgoing.RoomBannedUsersComposer); + this.response.appendInt(this.room.getId()); + this.response.appendInt(roomBans.size()); + + for (RoomBan ban : roomBans) { + this.response.appendInt(ban.userId); + this.response.appendString(ban.username); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomChatSettingsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomChatSettingsComposer.java new file mode 100644 index 0000000..43a971a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomChatSettingsComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomChatSettingsComposer extends MessageComposer { + private final Room room; + + public RoomChatSettingsComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomChatSettingsComposer); + this.response.appendInt(this.room.getChatMode()); + this.response.appendInt(this.room.getChatWeight()); + this.response.appendInt(this.room.getChatSpeed()); + this.response.appendInt(this.room.getChatDistance()); + this.response.appendInt(this.room.getChatProtection()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomDataComposer.java new file mode 100644 index 0000000..895cacc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomDataComposer.java @@ -0,0 +1,115 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.rooms.Room; +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.Outgoing; + +public class RoomDataComposer extends MessageComposer { + private final Room room; + private final Habbo habbo; + private final boolean roomForward; + private final boolean enterRoom; + + public RoomDataComposer(Room room, Habbo habbo, boolean roomForward, boolean enterRoom) { + this.room = room; + this.habbo = habbo; + this.roomForward = roomForward; + this.enterRoom = enterRoom; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomDataComposer); + this.response.appendBoolean(this.enterRoom); + this.response.appendInt(this.room.getId()); + this.response.appendString(this.room.getName()); + if (this.room.isPublicRoom()) { + this.response.appendInt(0); + this.response.appendString(""); + } else { + this.response.appendInt(this.room.getOwnerId()); + this.response.appendString(this.room.getOwnerName()); + } + this.response.appendInt(this.room.getState().getState()); + this.response.appendInt(this.room.getUserCount()); + this.response.appendInt(this.room.getUsersMax()); + this.response.appendString(this.room.getDescription()); + this.response.appendInt(this.room.getTradeMode()); + this.response.appendInt(this.room.getScore()); + this.response.appendInt(2);//Top rated room rank + this.response.appendInt(this.room.getCategory()); + + if (!this.room.getTags().isEmpty()) { + String[] tags = this.room.getTags().split(";"); + this.response.appendInt(tags.length); + for (String s : tags) { + this.response.appendString(s); + } + } else { + this.response.appendInt(0); + } + + int base = 0; + + if (this.room.getGuildId() > 0) { + base = base | 2; + } + + if (!this.room.isPublicRoom()) { + base = base | 8; + } + + if (this.room.isPromoted()) { + base = base | 4; + } + + if (this.room.isAllowPets()) { + base = base | 16; + } + + this.response.appendInt(base); + + if (this.room.getGuildId() > 0) { + Guild g = Emulator.getGameEnvironment().getGuildManager().getGuild(this.room.getGuildId()); + if (g != null) { + this.response.appendInt(g.getId()); + this.response.appendString(g.getName()); + this.response.appendString(g.getBadge()); + } else { + this.response.appendInt(0); + this.response.appendString(""); + this.response.appendString(""); + } + } + + if (this.room.isPromoted()) { + this.response.appendString(this.room.getPromotion().getTitle()); + this.response.appendString(this.room.getPromotion().getDescription()); + this.response.appendInt((this.room.getPromotion().getEndTimestamp() - Emulator.getIntUnixTimestamp()) / 60); + } + + this.response.appendBoolean(this.roomForward); + this.response.appendBoolean(this.room.isStaffPromotedRoom()); // staffpicked + this.response.appendBoolean(this.room.hasGuild() && Emulator.getGameEnvironment().getGuildManager().getGuildMember(this.room.getGuildId(), this.habbo.getHabboInfo().getId()) != null); // is group member + this.response.appendBoolean(this.room.isMuted()); // isroommuted + + this.response.appendInt(this.room.getMuteOption()); + this.response.appendInt(this.room.getKickOption()); + this.response.appendInt(this.room.getBanOption()); + + this.response.appendBoolean(this.room.hasRights(this.habbo)); //mute all button + + this.response.appendInt(this.room.getChatMode()); + this.response.appendInt(this.room.getChatWeight()); + this.response.appendInt(this.room.getChatSpeed()); + this.response.appendInt(this.room.getChatDistance()); + this.response.appendInt(this.room.getChatProtection()); + + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomEditSettingsErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomEditSettingsErrorComposer.java new file mode 100644 index 0000000..f53bef2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomEditSettingsErrorComposer.java @@ -0,0 +1,34 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomEditSettingsErrorComposer extends MessageComposer { + public final static int PASSWORD_REQUIRED = 5; + public final static int ROOM_NAME_MISSING = 7; + public final static int ROOM_NAME_BADWORDS = 8; + public final static int ROOM_DESCRIPTION_BADWORDS = 10; + public final static int ROOM_TAGS_BADWWORDS = 11; + public final static int RESTRICTED_TAGS = 12; + public final static int TAGS_TOO_LONG = 13; + + private final int roomId; + private final int errorCode; + private final String info; + + public RoomEditSettingsErrorComposer(int roomId, int errorCode, String info) { + this.roomId = roomId; + this.errorCode = errorCode; + this.info = info; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomEditSettingsErrorComposer); + this.response.appendInt(this.roomId); + this.response.appendInt(this.errorCode); + this.response.appendString(this.info); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomEnterErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomEnterErrorComposer.java new file mode 100644 index 0000000..a2ec60e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomEnterErrorComposer.java @@ -0,0 +1,38 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomEnterErrorComposer extends MessageComposer { + public static final int ROOM_ERROR_GUESTROOM_FULL = 1; + public static final int ROOM_ERROR_CANT_ENTER = 2; + public static final int ROOM_ERROR_QUE = 3; + public static final int ROOM_ERROR_BANNED = 4; + + public static final String ROOM_NEEDS_VIP = "c"; + public static final String EVENT_USERS_ONLY = "e1"; + public static final String ROOM_LOCKED = "na"; + public static final String TO_MANY_SPECTATORS = "spectator_mode_full"; + + private final int errorCode; + private final String queError; + + public RoomEnterErrorComposer(int errorCode) { + this.errorCode = errorCode; + this.queError = ""; + } + + public RoomEnterErrorComposer(int errorCode, String queError) { + this.errorCode = errorCode; + this.queError = queError; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomEnterErrorComposer); + this.response.appendInt(this.errorCode); + this.response.appendString(this.queError); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomEntryInfoComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomEntryInfoComposer.java new file mode 100644 index 0000000..be3d118 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomEntryInfoComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomEntryInfoComposer extends MessageComposer { + private final Room room; + + public RoomEntryInfoComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomEntryInfoComposer); + this.response.appendInt(this.room.getId()); + this.response.appendString(this.room.getOwnerName()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomFilterWordsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomFilterWordsComposer.java new file mode 100644 index 0000000..85b379d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomFilterWordsComposer.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomFilterWordsComposer extends MessageComposer { + private final Room room; + + public RoomFilterWordsComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomFilterWordsComposer); + + this.response.appendInt(this.room.getWordFilterWords().size()); + + for (String string : this.room.getWordFilterWords()) { + this.response.appendString(string); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomFloorThicknessUpdatedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomFloorThicknessUpdatedComposer.java new file mode 100644 index 0000000..9d8c46c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomFloorThicknessUpdatedComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomFloorThicknessUpdatedComposer extends MessageComposer { + private final Room room; + + public RoomFloorThicknessUpdatedComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomFloorThicknessUpdatedComposer); + this.response.appendBoolean(this.room.isHideWall()); //Hide walls? + this.response.appendInt(this.room.getFloorSize()); //Floor Thickness + this.response.appendInt(this.room.getWallSize()); //Wall Thickness + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomHeightMapComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomHeightMapComposer.java new file mode 100644 index 0000000..bfe4220 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomHeightMapComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomHeightMapComposer extends MessageComposer { + private final Room room; + + public RoomHeightMapComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomHeightMapComposer); + this.response.appendBoolean(true); + this.response.appendInt(this.room.getWallHeight()); //FixedWallsHeight + this.response.appendString(this.room.getLayout().getRelativeMap()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomModelComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomModelComposer.java new file mode 100644 index 0000000..d845f54 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomModelComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomModelComposer extends MessageComposer { + private final Room room; + + public RoomModelComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomModelComposer); + this.response.appendString(this.room.getLayout().getName()); + this.response.appendInt(this.room.getId()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomMutedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomMutedComposer.java new file mode 100644 index 0000000..7e038cc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomMutedComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomMutedComposer extends MessageComposer { + private final Room room; + + public RoomMutedComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomMutedComposer); + this.response.appendBoolean(this.room.isMuted()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomNoRightsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomNoRightsComposer.java new file mode 100644 index 0000000..6f4fc61 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomNoRightsComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomNoRightsComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomNoRightsComposer); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomOpenComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomOpenComposer.java new file mode 100644 index 0000000..b695c74 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomOpenComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomOpenComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomOpenComposer); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomOwnerComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomOwnerComposer.java new file mode 100644 index 0000000..ccdc631 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomOwnerComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomOwnerComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomOwnerComposer); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomPaintComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomPaintComposer.java new file mode 100644 index 0000000..6961fa6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomPaintComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomPaintComposer extends MessageComposer { + private final String type; + private final String value; + + public RoomPaintComposer(String type, String value) { + this.type = type; + this.value = value; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomPaintComposer); + this.response.appendString(this.type); + this.response.appendString(this.value); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomPaneComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomPaneComposer.java new file mode 100644 index 0000000..db8e392 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomPaneComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomPaneComposer extends MessageComposer { + private final Room room; + private final boolean roomOwner; + + public RoomPaneComposer(Room room, boolean roomOwner) { + this.room = room; + this.roomOwner = roomOwner; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomPaneComposer); + this.response.appendInt(this.room.getId()); + this.response.appendBoolean(this.roomOwner); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomQueueStatusMessage.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomQueueStatusMessage.java new file mode 100644 index 0000000..4425c29 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomQueueStatusMessage.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomQueueStatusMessage extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomQueueStatusMessage); + this.response.appendInt(1); //Count + { + this.response.appendString("TEST"); //Name + this.response.appendInt(94); //Target + + this.response.appendInt(1); //Count + this.response.appendString("d"); + this.response.appendInt(1); + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRelativeMapComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRelativeMapComposer.java new file mode 100644 index 0000000..8236b45 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRelativeMapComposer.java @@ -0,0 +1,42 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomRelativeMapComposer extends MessageComposer { + private final Room room; + + public RoomRelativeMapComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomRelativeMapComposer); + this.response.appendInt(this.room.getLayout().getMapSize() / this.room.getLayout().getMapSizeY()); + this.response.appendInt(this.room.getLayout().getMapSize()); + for (short y = 0; y < this.room.getLayout().getMapSizeY(); y++) { + for (short x = 0; x < this.room.getLayout().getMapSizeX(); x++) { + RoomTile t = this.room.getLayout().getTile(x, y); + + if (t != null) { + if(Emulator.getConfig().getBoolean("custom.stacking.enabled")) { + this.response.appendShort((short) (t.z * 256.0)); + } + else { + this.response.appendShort(t.relativeHeight()); + } + } + else { + this.response.appendShort(Short.MAX_VALUE); + } + + } + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRemoveRightsListComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRemoveRightsListComposer.java new file mode 100644 index 0000000..cf12bde --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRemoveRightsListComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomRemoveRightsListComposer extends MessageComposer { + private final Room room; + private final int userId; + + public RoomRemoveRightsListComposer(Room room, int userId) { + this.room = room; + this.userId = userId; + } + + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomRemoveRightsListComposer); + this.response.appendInt(this.room.getId()); + this.response.appendInt(this.userId); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRightsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRightsComposer.java new file mode 100644 index 0000000..23e5e4c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRightsComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.rooms.RoomRightLevels; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomRightsComposer extends MessageComposer { + private final RoomRightLevels type; + + public RoomRightsComposer(RoomRightLevels type) { + this.type = type; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomRightsComposer); + this.response.appendInt(this.type.level); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRightsListComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRightsListComposer.java new file mode 100644 index 0000000..7a08a9d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRightsListComposer.java @@ -0,0 +1,34 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.map.hash.THashMap; + +import java.util.Map; + +public class RoomRightsListComposer extends MessageComposer { + private final Room room; + + public RoomRightsListComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomRightsListComposer); + this.response.appendInt(this.room.getId()); + + THashMap rightsMap = this.room.getUsersWithRights(); + + this.response.appendInt(rightsMap.size()); + + for (Map.Entry set : rightsMap.entrySet()) { + this.response.appendInt(set.getKey()); + this.response.appendString(set.getValue()); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomScoreComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomScoreComposer.java new file mode 100644 index 0000000..e3e7eb7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomScoreComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomScoreComposer extends MessageComposer { + private final int score; + private final boolean canVote; + + public RoomScoreComposer(int score, boolean canVote) { + this.score = score; + this.canVote = canVote; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomScoreComposer); + this.response.appendInt(this.score); + this.response.appendBoolean(this.canVote); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomSettingsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomSettingsComposer.java new file mode 100644 index 0000000..f37dce6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomSettingsComposer.java @@ -0,0 +1,57 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomSettingsComposer extends MessageComposer { + private final Room room; + + public RoomSettingsComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomSettingsComposer); + this.response.appendInt(this.room.getId()); + this.response.appendString(this.room.getName()); + this.response.appendString(this.room.getDescription()); + this.response.appendInt(this.room.getState().getState()); + this.response.appendInt(this.room.getCategory()); + this.response.appendInt(this.room.getUsersMax()); + this.response.appendInt(this.room.getUsersMax()); + + if (!this.room.getTags().isEmpty()) { + this.response.appendInt(this.room.getTags().split(";").length); + for (String tag : this.room.getTags().split(";")) { + this.response.appendString(tag); + } + } else { + this.response.appendInt(0); + } + + //this.response.appendInt(this.room.getRights().size()); + this.response.appendInt(this.room.getTradeMode()); //Trade Mode + this.response.appendInt(this.room.isAllowPets() ? 1 : 0); + this.response.appendInt(this.room.isAllowPetsEat() ? 1 : 0); + this.response.appendInt(this.room.isAllowWalkthrough() ? 1 : 0); + this.response.appendInt(this.room.isHideWall() ? 1 : 0); + this.response.appendInt(this.room.getWallSize()); + this.response.appendInt(this.room.getFloorSize()); + + this.response.appendInt(this.room.getChatMode()); + this.response.appendInt(this.room.getChatWeight()); + this.response.appendInt(this.room.getChatSpeed()); + this.response.appendInt(this.room.getChatDistance()); + this.response.appendInt(this.room.getChatProtection()); + + this.response.appendBoolean(false); //IDK? + + this.response.appendInt(this.room.getMuteOption()); + this.response.appendInt(this.room.getKickOption()); + this.response.appendInt(this.room.getBanOption()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomSettingsSavedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomSettingsSavedComposer.java new file mode 100644 index 0000000..b6c6ac4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomSettingsSavedComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomSettingsSavedComposer extends MessageComposer { + private final Room room; + + public RoomSettingsSavedComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomSettingsSavedComposer); + this.response.appendInt(this.room.getId()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomSettingsUpdatedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomSettingsUpdatedComposer.java new file mode 100644 index 0000000..7e1041b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomSettingsUpdatedComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomSettingsUpdatedComposer extends MessageComposer { + private final Room room; + + public RoomSettingsUpdatedComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomSettingsUpdatedComposer); + this.response.appendInt(this.room.getId()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomThicknessComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomThicknessComposer.java new file mode 100644 index 0000000..9a1c9ea --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomThicknessComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomThicknessComposer extends MessageComposer { + private final Room room; + + public RoomThicknessComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomThicknessComposer); + this.response.appendBoolean(this.room.isHideWall()); + this.response.appendInt(this.room.getWallSize()); + this.response.appendInt(this.room.getFloorSize()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/UpdateStackHeightComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/UpdateStackHeightComposer.java new file mode 100644 index 0000000..a6d5d64 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/UpdateStackHeightComposer.java @@ -0,0 +1,82 @@ +package com.eu.habbo.messages.outgoing.rooms; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.set.hash.THashSet; + +public class UpdateStackHeightComposer extends MessageComposer { + private int x; + private int y; + private short z; + private double height; + + private THashSet updateTiles; + private Room room; + + public UpdateStackHeightComposer(int x, int y, short z, double height) { + this.x = x; + this.y = y; + this.z = z; + this.height = height; + } + + public UpdateStackHeightComposer(Room room, THashSet updateTiles) { + this.updateTiles = updateTiles; + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + //TODO: maybe do this another way? doesn't seem to be very clean but gets the job done + this.response.init(Outgoing.UpdateStackHeightComposer); + if (this.updateTiles != null) { + // prevent overflow. Byte max value is 127 + if(this.updateTiles.size() > 127) { + RoomTile[] tiles = this.updateTiles.toArray(new RoomTile[updateTiles.size()]); + this.response.appendByte(127); + for(int i = 0; i < 127; i++) { + RoomTile t = tiles[i]; + updateTiles.remove(t); // remove it from the set + this.response.appendByte((int) t.x); + this.response.appendByte((int) t.y); + if(Emulator.getConfig().getBoolean("custom.stacking.enabled")) { + this.response.appendShort((short) (t.z * 256.0)); + } + else { + this.response.appendShort(t.relativeHeight()); + } + } + //send the remaining tiles in a new message + this.room.sendComposer(new UpdateStackHeightComposer(this.room, updateTiles).compose()); + return this.response; + } + + this.response.appendByte(this.updateTiles.size()); + for (RoomTile t : this.updateTiles) { + this.response.appendByte((int) t.x); + this.response.appendByte((int) t.y); + if(Emulator.getConfig().getBoolean("custom.stacking.enabled")) { + this.response.appendShort((short) (t.z * 256.0)); + } + else { + this.response.appendShort(t.relativeHeight()); + } + } + } else { + this.response.appendByte(1); + this.response.appendByte(this.x); + this.response.appendByte(this.y); + if(Emulator.getConfig().getBoolean("custom.stacking.enabled")) { + this.response.appendShort((short) (this.z * 256.0)); + } + else { + this.response.appendShort((int) (this.height)); + } + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/AddFloorItemComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/AddFloorItemComposer.java new file mode 100644 index 0000000..b27e75d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/AddFloorItemComposer.java @@ -0,0 +1,31 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.items.interactions.InteractionGift; +import com.eu.habbo.habbohotel.items.interactions.InteractionMusicDisc; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class AddFloorItemComposer extends MessageComposer { + private final HabboItem item; + private final String itemOwnerName; + + public AddFloorItemComposer(HabboItem item, String itemOwnerName) { + this.item = item; + this.itemOwnerName = itemOwnerName == null ? "" : itemOwnerName; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.AddFloorItemComposer); + this.item.serializeFloorData(this.response); + this.response.appendInt(this.item instanceof InteractionGift ? ((((InteractionGift) this.item).getColorId() * 1000) + ((InteractionGift) this.item).getRibbonId()) : (this.item instanceof InteractionMusicDisc ? ((InteractionMusicDisc) this.item).getSongId() : 1)); + this.item.serializeExtradata(this.response); + this.response.appendInt(-1); + this.response.appendInt(this.item.isUsable()); + this.response.appendInt(this.item.getUserId()); + this.response.appendString(this.itemOwnerName); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/AddWallItemComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/AddWallItemComposer.java new file mode 100644 index 0000000..300eec1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/AddWallItemComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class AddWallItemComposer extends MessageComposer { + private final HabboItem item; + private final String itemOwnerName; + + public AddWallItemComposer(HabboItem item, String itemOwnerName) { + this.item = item; + this.itemOwnerName = itemOwnerName; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.AddWallItemComposer); + this.item.serializeWallData(this.response); + this.response.appendString(this.itemOwnerName); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/FloorItemOnRollerComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/FloorItemOnRollerComposer.java new file mode 100644 index 0000000..878b949 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/FloorItemOnRollerComposer.java @@ -0,0 +1,80 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import com.eu.habbo.messages.outgoing.rooms.UpdateStackHeightComposer; +import gnu.trove.set.hash.THashSet; +import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; + +public class FloorItemOnRollerComposer extends MessageComposer { + private final HabboItem item; + private final HabboItem roller; + private final RoomTile oldLocation; + private final RoomTile newLocation; + private final double heightOffset; + private final double oldZ; + private final double newZ; + private final Room room; + + public FloorItemOnRollerComposer(HabboItem item, HabboItem roller, RoomTile newLocation, double heightOffset, Room room) { + this.item = item; + this.roller = roller; + this.newLocation = newLocation; + this.heightOffset = heightOffset; + this.room = room; + this.oldLocation = null; + this.oldZ = -1; + this.newZ = -1; + } + + public FloorItemOnRollerComposer(HabboItem item, HabboItem roller, RoomTile oldLocation, double oldZ, RoomTile newLocation, double newZ, double heightOffset, Room room) { + this.item = item; + this.roller = roller; + this.oldLocation = oldLocation; + this.oldZ = oldZ; + this.newLocation = newLocation; + this.newZ = newZ; + this.heightOffset = heightOffset; + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + short oldX = this.item.getX(); + short oldY = this.item.getY(); + + this.response.init(Outgoing.ObjectOnRollerComposer); + this.response.appendInt(this.oldLocation != null ? this.oldLocation.x : this.item.getX()); + this.response.appendInt(this.oldLocation != null ? this.oldLocation.y : this.item.getY()); + this.response.appendInt(this.newLocation.x); + this.response.appendInt(this.newLocation.y); + this.response.appendInt(1); + this.response.appendInt(this.item.getId()); + this.response.appendString(Double.toString(this.oldLocation != null ? this.oldZ : this.item.getZ())); + this.response.appendString(Double.toString(this.oldLocation != null ? this.newZ : (this.item.getZ() + this.heightOffset))); + this.response.appendInt(this.roller != null ? this.roller.getId() : -1); + + if(this.oldLocation == null) { + this.item.onMove(this.room, this.room.getLayout().getTile(this.item.getX(), this.item.getY()), this.newLocation); + this.item.setX(this.newLocation.x); + this.item.setY(this.newLocation.y); + this.item.setZ(this.item.getZ() + this.heightOffset); + this.item.needsUpdate(true); + + //TODO This is bad + // + THashSet tiles = this.room.getLayout().getTilesAt(this.room.getLayout().getTile(oldX, oldY), this.item.getBaseItem().getWidth(), this.item.getBaseItem().getLength(), this.item.getRotation()); + tiles.addAll(this.room.getLayout().getTilesAt(this.room.getLayout().getTile(this.item.getX(), this.item.getY()), this.item.getBaseItem().getWidth(), this.item.getBaseItem().getLength(), this.item.getRotation())); + this.room.updateTiles(tiles); + //this.room.sendComposer(new UpdateStackHeightComposer(oldX, oldY, this.room.getStackHeight(oldX, oldY, true)).compose()); + // + //this.room.updateHabbosAt(RoomLayout.getRectangle(this.item.getX(), this.item.getY(), this.item.getBaseItem().getWidth(), this.item.getBaseItem().getLength(), this.item.getRotation())); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/FloorItemUpdateComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/FloorItemUpdateComposer.java new file mode 100644 index 0000000..df9cf6f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/FloorItemUpdateComposer.java @@ -0,0 +1,28 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.items.interactions.InteractionGift; +import com.eu.habbo.habbohotel.items.interactions.InteractionMusicDisc; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class FloorItemUpdateComposer extends MessageComposer { + private final HabboItem item; + + public FloorItemUpdateComposer(HabboItem item) { + this.item = item; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.FloorItemUpdateComposer); + this.item.serializeFloorData(this.response); + this.response.appendInt(this.item instanceof InteractionGift ? ((((InteractionGift) this.item).getColorId() * 1000) + ((InteractionGift) this.item).getRibbonId()) : (this.item instanceof InteractionMusicDisc ? ((InteractionMusicDisc) this.item).getSongId() : item.isUsable() ? 0 : 0)); + this.item.serializeExtradata(this.response); + this.response.appendInt(-1); + this.response.appendInt(0); + this.response.appendInt(this.item.getUserId()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/ItemExtraDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/ItemExtraDataComposer.java new file mode 100644 index 0000000..1fe1ebf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/ItemExtraDataComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ItemExtraDataComposer extends MessageComposer { + private final HabboItem item; + + public ItemExtraDataComposer(HabboItem item) { + this.item = item; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ItemExtraDataComposer); + this.response.appendString(this.item.getId() + ""); + this.item.serializeExtradata(this.response); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/ItemIntStateComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/ItemIntStateComposer.java new file mode 100644 index 0000000..af739f2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/ItemIntStateComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ItemIntStateComposer extends MessageComposer { + private final int id; + private final int value; + + public ItemIntStateComposer(int id, int value) { + this.id = id; + this.value = value; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ItemStateComposer2); + this.response.appendInt(this.id); + this.response.appendInt(this.value); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/ItemStateComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/ItemStateComposer.java new file mode 100644 index 0000000..792b96a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/ItemStateComposer.java @@ -0,0 +1,28 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ItemStateComposer extends MessageComposer { + private final HabboItem item; + + public ItemStateComposer(HabboItem item) { + this.item = item; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ItemStateComposer); + this.response.appendInt(this.item.getId()); + try { + int state = Integer.valueOf(this.item.getExtradata()); + this.response.appendInt(state); + } catch (Exception e) { + this.response.appendInt(0); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/ItemsDataUpdateComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/ItemsDataUpdateComposer.java new file mode 100644 index 0000000..3e5fb51 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/ItemsDataUpdateComposer.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.List; +import java.util.Set; + +public class ItemsDataUpdateComposer extends MessageComposer { + private final Set items; + + public ItemsDataUpdateComposer(Set items) { + this.items = items; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ItemsDataUpdateComposer); + this.response.appendInt(this.items.size()); + + for (HabboItem item : this.items) { + this.response.appendInt(item.getId()); + item.serializeExtradata(this.response); + } + + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/MoodLightDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/MoodLightDataComposer.java new file mode 100644 index 0000000..45c934c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/MoodLightDataComposer.java @@ -0,0 +1,55 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.rooms.RoomMoodlightData; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.map.TIntObjectMap; + +public class MoodLightDataComposer extends MessageComposer { + private final TIntObjectMap moodLightData; + + public MoodLightDataComposer(TIntObjectMap moodLightData) { + this.moodLightData = moodLightData; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MoodLightDataComposer); + this.response.appendInt(3); //PresetCount + + int index = 1; + for (RoomMoodlightData data : this.moodLightData.valueCollection()) { + if (data.isEnabled()) { + this.response.appendInt(data.getId()); + index = -1; + break; + } + index++; + } + + if (index != -1) { + this.response.appendInt(1); + } + + int i = 1; + for (RoomMoodlightData data : this.moodLightData.valueCollection()) { + this.response.appendInt(data.getId()); //Preset ID + this.response.appendInt(data.isBackgroundOnly() ? 2 : 1); //Background only ? 2 : 1 + this.response.appendString(data.getColor()); //Color + this.response.appendInt(data.getIntensity()); //Intensity + i++; + } + + for (; i <= 3; i++) { + this.response.appendInt(i); + this.response.appendInt(1); + this.response.appendString("#000000"); + this.response.appendInt(255); + } + + + //:test 2780 i:1 i:1 i:1 i:2 s:#FF00FF i:255 + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/PostItDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/PostItDataComposer.java new file mode 100644 index 0000000..497317a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/PostItDataComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.items.interactions.InteractionPostIt; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PostItDataComposer extends MessageComposer { + private final InteractionPostIt postIt; + + public PostItDataComposer(InteractionPostIt postIt) { + this.postIt = postIt; + } + + @Override + protected ServerMessage composeInternal() { + if (this.postIt.getExtradata().isEmpty() || this.postIt.getExtradata().length() < 6) { + this.postIt.setExtradata("FFFF33"); + } + + this.response.init(Outgoing.PostItDataComposer); + this.response.appendString(this.postIt.getId() + ""); + this.response.appendString(this.postIt.getExtradata()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/PostItStickyPoleOpenComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/PostItStickyPoleOpenComposer.java new file mode 100644 index 0000000..e415174 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/PostItStickyPoleOpenComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PostItStickyPoleOpenComposer extends MessageComposer { + private final HabboItem item; + + public PostItStickyPoleOpenComposer(HabboItem item) { + this.item = item; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PostItStickyPoleOpenComposer); + this.response.appendInt(this.item == null ? -1234 : this.item.getId()); + this.response.appendString(""); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/PresentItemOpenedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/PresentItemOpenedComposer.java new file mode 100644 index 0000000..fea440e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/PresentItemOpenedComposer.java @@ -0,0 +1,31 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PresentItemOpenedComposer extends MessageComposer { + private final HabboItem item; + private final String text; + private final boolean unknown; + + public PresentItemOpenedComposer(HabboItem item, String text, boolean unknown) { + this.item = item; + this.text = text; + this.unknown = unknown; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PresentItemOpenedComposer); + this.response.appendString(this.item.getBaseItem().getType().code.toLowerCase()); + this.response.appendInt(this.item.getBaseItem().getSpriteId()); + this.response.appendString(this.item.getBaseItem().getName()); + this.response.appendInt(this.item.getId()); + this.response.appendString(this.item.getBaseItem().getType().code.toLowerCase()); + this.response.appendBoolean(this.unknown); + this.response.appendString(this.text); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RemoveFloorItemComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RemoveFloorItemComposer.java new file mode 100644 index 0000000..9050674 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RemoveFloorItemComposer.java @@ -0,0 +1,33 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RemoveFloorItemComposer extends MessageComposer { + private final HabboItem item; + private final boolean noUser; + + public RemoveFloorItemComposer(HabboItem item) { + this.item = item; + this.noUser = false; + } + + public RemoveFloorItemComposer(HabboItem item, boolean noUser) { + this.item = item; + this.noUser = noUser; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RemoveFloorItemComposer); + + this.response.appendString(this.item.getId() + ""); + this.response.appendBoolean(false); + this.response.appendInt(this.noUser ? 0 : this.item.getUserId()); + this.response.appendInt(0); + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RemoveWallItemComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RemoveWallItemComposer.java new file mode 100644 index 0000000..eb92680 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RemoveWallItemComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RemoveWallItemComposer extends MessageComposer { + private final HabboItem item; + + public RemoveWallItemComposer(HabboItem item) { + this.item = item; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RemoveWallItemComposer); + this.response.appendString(this.item.getId() + ""); + this.response.appendInt(this.item.getUserId()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RoomFloorItemsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RoomFloorItemsComposer.java new file mode 100644 index 0000000..35210fa --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RoomFloorItemsComposer.java @@ -0,0 +1,53 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.items.interactions.InteractionGift; +import com.eu.habbo.habbohotel.items.interactions.InteractionMusicDisc; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.iterator.TIntObjectIterator; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.set.hash.THashSet; + +import java.util.NoSuchElementException; + +public class RoomFloorItemsComposer extends MessageComposer { + private final TIntObjectMap furniOwnerNames; + private final THashSet items; + + public RoomFloorItemsComposer(TIntObjectMap furniOwnerNames, THashSet items) { + this.furniOwnerNames = furniOwnerNames; + this.items = items; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomFloorItemsComposer); + + TIntObjectIterator iterator = this.furniOwnerNames.iterator(); + + this.response.appendInt(this.furniOwnerNames.size()); + for (int i = this.furniOwnerNames.size(); i-- > 0; ) { + try { + iterator.advance(); + this.response.appendInt(iterator.key()); + this.response.appendString(iterator.value()); + } catch (NoSuchElementException e) { + break; + } + } + + this.response.appendInt(this.items.size()); + + for (HabboItem item : this.items) { + item.serializeFloorData(this.response); + this.response.appendInt(item instanceof InteractionGift ? ((((InteractionGift) item).getColorId() * 1000) + ((InteractionGift) item).getRibbonId()) : (item instanceof InteractionMusicDisc ? ((InteractionMusicDisc) item).getSongId() : 1)); + item.serializeExtradata(this.response); + this.response.appendInt(-1); + this.response.appendInt(item.isUsable() ? 1 : 0); + this.response.appendInt(item.getUserId()); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RoomWallItemsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RoomWallItemsComposer.java new file mode 100644 index 0000000..0f8a669 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/RoomWallItemsComposer.java @@ -0,0 +1,54 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.iterator.TIntObjectIterator; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + +import java.util.Map; +import java.util.NoSuchElementException; + +public class RoomWallItemsComposer extends MessageComposer { + private final Room room; + + public RoomWallItemsComposer(Room room) { + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomWallItemsComposer); + THashMap userNames = new THashMap<>(); + TIntObjectMap furniOwnerNames = this.room.getFurniOwnerNames(); + TIntObjectIterator iterator = furniOwnerNames.iterator(); + + for (int i = furniOwnerNames.size(); i-- > 0; ) { + try { + iterator.advance(); + + userNames.put(iterator.key(), iterator.value()); + } catch (NoSuchElementException e) { + break; + } + } + + this.response.appendInt(userNames.size()); + for (Map.Entry set : userNames.entrySet()) { + this.response.appendInt(set.getKey()); + this.response.appendString(set.getValue()); + } + + THashSet items = this.room.getWallItems(); + + this.response.appendInt(items.size()); + for (HabboItem item : items) { + item.serializeWallData(this.response); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/UpdateStackHeightTileHeightComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/UpdateStackHeightTileHeightComposer.java new file mode 100644 index 0000000..2b378c9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/UpdateStackHeightTileHeightComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UpdateStackHeightTileHeightComposer extends MessageComposer { + private final HabboItem item; + private final int height; + + public UpdateStackHeightTileHeightComposer(HabboItem item, int height) { + this.item = item; + this.height = height; + + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UpdateStackHeightTileHeightComposer); + this.response.appendInt(this.item.getId()); + this.response.appendInt(this.height); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/WallItemUpdateComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/WallItemUpdateComposer.java new file mode 100644 index 0000000..2a00959 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/WallItemUpdateComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.rooms.items; + +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class WallItemUpdateComposer extends MessageComposer { + private final HabboItem item; + + public WallItemUpdateComposer(HabboItem item) { + this.item = item; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.WallItemUpdateComposer); + this.item.serializeWallData(this.response); + this.response.appendString(this.item.getUserId() + ""); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxMySongsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxMySongsComposer.java new file mode 100644 index 0000000..e9a6157 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxMySongsComposer.java @@ -0,0 +1,31 @@ +package com.eu.habbo.messages.outgoing.rooms.items.jukebox; + +import com.eu.habbo.habbohotel.items.interactions.InteractionMusicDisc; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.List; + +public class JukeBoxMySongsComposer extends MessageComposer { + private final List items; + + public JukeBoxMySongsComposer(List items) { + this.items = items; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.JukeBoxMySongsComposer); + + this.response.appendInt(this.items.size()); + + for (HabboItem item : this.items) { + this.response.appendInt(item.getId()); + this.response.appendInt(((InteractionMusicDisc) item).getSongId()); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxNowPlayingMessageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxNowPlayingMessageComposer.java new file mode 100644 index 0000000..9e8f0c6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxNowPlayingMessageComposer.java @@ -0,0 +1,38 @@ +package com.eu.habbo.messages.outgoing.rooms.items.jukebox; + +import com.eu.habbo.habbohotel.items.SoundTrack; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class JukeBoxNowPlayingMessageComposer extends MessageComposer { + private final SoundTrack track; + private final int playListId; + private final int msPlayed; + + public JukeBoxNowPlayingMessageComposer(SoundTrack track, int playListId, int msPlayed) { + this.track = track; + this.playListId = playListId; + this.msPlayed = msPlayed; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.JukeBoxNowPlayingMessageComposer); + + if (this.track != null) { + this.response.appendInt(this.track.getId()); + this.response.appendInt(this.playListId); + this.response.appendInt(this.track.getId()); + this.response.appendInt(this.track.getLength()); + this.response.appendInt(this.msPlayed); + } else { + this.response.appendInt(-1); + this.response.appendInt(-1); + this.response.appendInt(-1); + this.response.appendInt(-1); + this.response.appendInt(-1); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxPlayListAddSongComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxPlayListAddSongComposer.java new file mode 100644 index 0000000..ec65f39 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxPlayListAddSongComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.rooms.items.jukebox; + +import com.eu.habbo.habbohotel.items.SoundTrack; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class JukeBoxPlayListAddSongComposer extends MessageComposer { + private final SoundTrack track; + + public JukeBoxPlayListAddSongComposer(SoundTrack track) { + this.track = track; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.JukeBoxPlayListAddSongComposer); + this.response.appendInt(this.track.getId()); + this.response.appendInt(this.track.getLength() * 1000); + this.response.appendString(this.track.getCode()); + this.response.appendString(this.track.getAuthor()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxPlayListComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxPlayListComposer.java new file mode 100644 index 0000000..29c82b7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxPlayListComposer.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.outgoing.rooms.items.jukebox; + +import com.eu.habbo.habbohotel.items.interactions.InteractionMusicDisc; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.List; + +public class JukeBoxPlayListComposer extends MessageComposer { + private final List songs; + private final int totalLength; + + public JukeBoxPlayListComposer(List songs, int totalLength) { + this.songs = songs; + this.totalLength = totalLength; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.JukeBoxPlayListComposer); + this.response.appendInt(this.totalLength); //Dunno //TODO Total play length? + this.response.appendInt(this.songs.size()); + for (InteractionMusicDisc soundTrack : this.songs) { + this.response.appendInt(soundTrack.getId()); + this.response.appendInt(soundTrack.getSongId()); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxPlayListUpdatedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxPlayListUpdatedComposer.java new file mode 100644 index 0000000..c4a0ceb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxPlayListUpdatedComposer.java @@ -0,0 +1,38 @@ +package com.eu.habbo.messages.outgoing.rooms.items.jukebox; + +import com.eu.habbo.habbohotel.items.SoundTrack; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.set.hash.THashSet; + +public class JukeBoxPlayListUpdatedComposer extends MessageComposer { + private final THashSet tracks; + + public JukeBoxPlayListUpdatedComposer(THashSet tracks) { + this.tracks = tracks; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.JukeBoxPlayListUpdatedComposer); + + int length = 0; + + for (SoundTrack track : this.tracks) { + length += track.getLength(); + } + + this.response.appendInt(length * 1000); + this.response.appendInt(this.tracks.size()); + + for (SoundTrack track : this.tracks) { + this.response.appendInt(track.getId()); + this.response.appendInt(track.getLength() * 1000); + this.response.appendString(track.getCode()); + this.response.appendString(track.getAuthor()); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxPlaylistFullComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxPlaylistFullComposer.java new file mode 100644 index 0000000..1851110 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxPlaylistFullComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.rooms.items.jukebox; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class JukeBoxPlaylistFullComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.JukeBoxPlaylistFullComposer); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxTrackCodeComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxTrackCodeComposer.java new file mode 100644 index 0000000..3759c33 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxTrackCodeComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.rooms.items.jukebox; + +import com.eu.habbo.habbohotel.items.SoundTrack; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class JukeBoxTrackCodeComposer extends MessageComposer { + private final SoundTrack track; + + public JukeBoxTrackCodeComposer(SoundTrack track) { + this.track = track; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.JukeBoxTrackCodeComposer); + this.response.appendString(this.track.getCode()); + this.response.appendInt(this.track.getId()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxTrackDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxTrackDataComposer.java new file mode 100644 index 0000000..77fbb08 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/jukebox/JukeBoxTrackDataComposer.java @@ -0,0 +1,33 @@ +package com.eu.habbo.messages.outgoing.rooms.items.jukebox; + +import com.eu.habbo.habbohotel.items.SoundTrack; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.List; + +public class JukeBoxTrackDataComposer extends MessageComposer { + private final List tracks; + + public JukeBoxTrackDataComposer(List tracks) { + this.tracks = tracks; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.JukeBoxTrackDataComposer); + this.response.appendInt(this.tracks.size()); + + for (SoundTrack track : this.tracks) { + this.response.appendInt(track.getId()); + this.response.appendString(track.getCode()); + this.response.appendString(track.getName()); + this.response.appendString(track.getData()); + this.response.appendInt(track.getLength() * 1000); + this.response.appendString(track.getAuthor()); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/lovelock/LoveLockFurniFinishedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/lovelock/LoveLockFurniFinishedComposer.java new file mode 100644 index 0000000..ddeb2ff --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/lovelock/LoveLockFurniFinishedComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.rooms.items.lovelock; + +import com.eu.habbo.habbohotel.items.interactions.InteractionLoveLock; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class LoveLockFurniFinishedComposer extends MessageComposer { + private final InteractionLoveLock loveLock; + + public LoveLockFurniFinishedComposer(InteractionLoveLock loveLock) { + this.loveLock = loveLock; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.LoveLockFurniFinishedComposer); + this.response.appendInt(this.loveLock.getId()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/lovelock/LoveLockFurniFriendConfirmedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/lovelock/LoveLockFurniFriendConfirmedComposer.java new file mode 100644 index 0000000..660fbe9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/lovelock/LoveLockFurniFriendConfirmedComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.rooms.items.lovelock; + +import com.eu.habbo.habbohotel.items.interactions.InteractionLoveLock; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class LoveLockFurniFriendConfirmedComposer extends MessageComposer { + private final InteractionLoveLock loveLock; + + public LoveLockFurniFriendConfirmedComposer(InteractionLoveLock loveLock) { + this.loveLock = loveLock; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.LoveLockFurniFriendConfirmedComposer); + this.response.appendInt(this.loveLock.getId()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/lovelock/LoveLockFurniStartComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/lovelock/LoveLockFurniStartComposer.java new file mode 100644 index 0000000..20cb7c9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/lovelock/LoveLockFurniStartComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.rooms.items.lovelock; + +import com.eu.habbo.habbohotel.items.interactions.InteractionLoveLock; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class LoveLockFurniStartComposer extends MessageComposer { + private final InteractionLoveLock loveLock; + + public LoveLockFurniStartComposer(InteractionLoveLock loveLock) { + this.loveLock = loveLock; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.LoveLockFurniStartComposer); + this.response.appendInt(this.loveLock.getId()); + this.response.appendBoolean(true); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/rentablespaces/RentableSpaceInfoComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/rentablespaces/RentableSpaceInfoComposer.java new file mode 100644 index 0000000..cbefc15 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/rentablespaces/RentableSpaceInfoComposer.java @@ -0,0 +1,54 @@ +package com.eu.habbo.messages.outgoing.rooms.items.rentablespaces; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionRentableSpace; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RentableSpaceInfoComposer extends MessageComposer { + public static final int SPACE_ALREADY_RENTED = 100; + public static final int SPACE_EXTEND_NOT_RENTED = 101; + public static final int SPACE_EXTEND_NOT_RENTED_BY_YOU = 102; + public static final int CAN_RENT_ONLY_ONE_SPACE = 103; + public static final int NOT_ENOUGH_CREDITS = 200; + public static final int NOT_ENOUGH_PIXELS = 201; + public static final int CANT_RENT_NO_PERMISSION = 202; + public static final int CANT_RENT_NO_HABBO_CLUB = 203; + public static final int CANT_RENT = 300; + public static final int CANT_RENT_GENERIC = 400; + //:test 194 b:1 i:101 i:1 s:Admin i:10 i:10 + + private final Habbo habbo; + private final HabboItem item; + private final int errorCode; + + public RentableSpaceInfoComposer(Habbo habbo, HabboItem item) { + this.habbo = habbo; + this.item = item; + this.errorCode = 0; + } + + public RentableSpaceInfoComposer(Habbo habbo, HabboItem item, int errorCode) { + this.habbo = habbo; + this.item = item; + this.errorCode = errorCode; + } + + @Override + protected ServerMessage composeInternal() { + if (!(this.item instanceof InteractionRentableSpace)) + return null; + + this.response.init(Outgoing.RentableSpaceInfoComposer); + this.response.appendBoolean(((InteractionRentableSpace) this.item).isRented()); //In Use + this.response.appendInt(this.errorCode); //Error code. + this.response.appendInt(((InteractionRentableSpace) this.item).getRenterId()); //User ID + this.response.appendString(((InteractionRentableSpace) this.item).getRenterName()); //Current Owner + this.response.appendInt(((InteractionRentableSpace) this.item).getEndTimestamp() - Emulator.getIntUnixTimestamp()); //Seconds Remaining + this.response.appendInt(((InteractionRentableSpace) this.item).rentCost()); //Price + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/rentablespaces/RentableSpaceUnknown2Composer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/rentablespaces/RentableSpaceUnknown2Composer.java new file mode 100644 index 0000000..81ce6b2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/rentablespaces/RentableSpaceUnknown2Composer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.rooms.items.rentablespaces; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RentableSpaceUnknown2Composer extends MessageComposer { + private final int itemId; + + public RentableSpaceUnknown2Composer(int itemId) { + this.itemId = itemId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RentableSpaceUnknown2Composer); + this.response.appendInt(this.itemId); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/rentablespaces/RentableSpaceUnknownComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/rentablespaces/RentableSpaceUnknownComposer.java new file mode 100644 index 0000000..af042c1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/rentablespaces/RentableSpaceUnknownComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.rooms.items.rentablespaces; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RentableSpaceUnknownComposer extends MessageComposer { + private final int itemId; + + public RentableSpaceUnknownComposer(int itemId) { + this.itemId = itemId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RentableSpaceUnknownComposer); + this.response.appendInt(this.itemId); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/youtube/YoutubeDisplayListComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/youtube/YoutubeDisplayListComposer.java new file mode 100644 index 0000000..11c6773 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/youtube/YoutubeDisplayListComposer.java @@ -0,0 +1,36 @@ +package com.eu.habbo.messages.outgoing.rooms.items.youtube; + +import com.eu.habbo.habbohotel.items.YoutubeManager; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.ArrayList; + +public class YoutubeDisplayListComposer extends MessageComposer { + private final int itemId; + private final ArrayList playlists; + private final YoutubeManager.YoutubePlaylist currentPlaylist; + + public YoutubeDisplayListComposer(int itemId, ArrayList playlists, YoutubeManager.YoutubePlaylist currentPlaylist) { + this.itemId = itemId; + this.playlists = playlists; + this.currentPlaylist = currentPlaylist; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.YoutubeDisplayListComposer); + this.response.appendInt(this.itemId); + this.response.appendInt(this.playlists.size()); + + for (YoutubeManager.YoutubePlaylist item : this.playlists) { + this.response.appendString(item.getId()); // playlist ID + this.response.appendString(item.getName()); // playlist title + this.response.appendString(item.getDescription()); // playlist description + } + + this.response.appendString(this.currentPlaylist == null ? "" : this.currentPlaylist.getId()); // current playlist ID + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/youtube/YoutubeStateChangeComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/youtube/YoutubeStateChangeComposer.java new file mode 100644 index 0000000..762a502 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/youtube/YoutubeStateChangeComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.rooms.items.youtube; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class YoutubeStateChangeComposer extends MessageComposer { + private final int furniId; + private final int state; + + public YoutubeStateChangeComposer(int furniId, int state) { + this.furniId = furniId; + this.state = state; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.YoutubeMessageComposer3); + this.response.appendInt(this.furniId); + this.response.appendInt(this.state); + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/youtube/YoutubeVideoComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/youtube/YoutubeVideoComposer.java new file mode 100644 index 0000000..225220e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/items/youtube/YoutubeVideoComposer.java @@ -0,0 +1,31 @@ +package com.eu.habbo.messages.outgoing.rooms.items.youtube; + +import com.eu.habbo.habbohotel.items.YoutubeManager; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class YoutubeVideoComposer extends MessageComposer { + private final int itemId; + private final YoutubeManager.YoutubeVideo video; + private final boolean playing; + private final int startTime; + + public YoutubeVideoComposer(int itemId, YoutubeManager.YoutubeVideo video, boolean playing, int startTime) { + this.itemId = itemId; + this.video = video; + this.playing = playing; + this.startTime = startTime; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.YoutubeMessageComposer2); + this.response.appendInt(this.itemId); + this.response.appendString(this.video.getId()); + this.response.appendInt(this.startTime); + this.response.appendInt(this.video.getDuration()); + this.response.appendInt(this.playing ? 1 : 2); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/CantScratchPetNotOldEnoughComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/CantScratchPetNotOldEnoughComposer.java new file mode 100644 index 0000000..b3e33e3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/CantScratchPetNotOldEnoughComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.rooms.pets; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CantScratchPetNotOldEnoughComposer extends MessageComposer { + private final int currentAge; + private final int requiredAge; + + public CantScratchPetNotOldEnoughComposer(int currentAge, int requiredAge) { + this.currentAge = currentAge; + this.requiredAge = requiredAge; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CantScratchPetNotOldEnoughComposer); + this.response.appendInt(this.currentAge); + this.response.appendInt(this.requiredAge); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetInformationComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetInformationComposer.java new file mode 100644 index 0000000..06a05b4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetInformationComposer.java @@ -0,0 +1,70 @@ +package com.eu.habbo.messages.outgoing.rooms.pets; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.MonsterplantPet; +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.Room; +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.Outgoing; + +public class PetInformationComposer extends MessageComposer { + private final Pet pet; + private final Room room; + private final Habbo requestingHabbo; + + public PetInformationComposer(Pet pet, Room room, Habbo requestingHabbo) { + this.pet = pet; + this.room = room; + this.requestingHabbo = requestingHabbo; + } + + @Override + protected ServerMessage composeInternal() { + double days = Math.floor((Emulator.getIntUnixTimestamp() - this.pet.getCreated()) / (3600 * 24)); + this.response.init(Outgoing.PetInformationComposer); + this.response.appendInt(this.pet.getId()); + this.response.appendString(this.pet.getName()); + if (this.pet instanceof MonsterplantPet) { + this.response.appendInt(((MonsterplantPet) this.pet).getGrowthStage()); //This equal + this.response.appendInt(7); //... to this means breedable + } else { + this.response.appendInt(this.pet.getLevel()); //level + this.response.appendInt(20); //max level + } + this.response.appendInt(this.pet.getExperience()); + if (this.pet.getLevel() < PetManager.experiences.length + 1) { + this.response.appendInt(PetManager.experiences[this.pet.getLevel() - 1]); //XP Goal + } else { + this.response.appendInt(this.pet.getExperience()); + } + this.response.appendInt(this.pet.getEnergy()); + this.response.appendInt(this.pet.getMaxEnergy()); //Max energy + this.response.appendInt(this.pet.getHappyness()); //this.pet.getHappyness() + this.response.appendInt(100); + this.response.appendInt(this.pet.getRespect()); + this.response.appendInt(this.pet.getUserId()); + this.response.appendInt((int) days + 1); + this.response.appendString(this.room.getFurniOwnerName(this.pet.getUserId())); //Owner name + + this.response.appendInt(this.pet instanceof MonsterplantPet ? ((MonsterplantPet) this.pet).getRarity() : 0); + this.response.appendBoolean(this.pet instanceof RideablePet && this.requestingHabbo != null && (((RideablePet) this.pet).getRider() == null || this.pet.getUserId() == this.requestingHabbo.getHabboInfo().getId()) && ((RideablePet) this.pet).hasSaddle()); // can ride + this.response.appendBoolean(this.pet instanceof RideablePet && ((RideablePet) this.pet).getRider() != null && this.requestingHabbo != null && ((RideablePet) this.pet).getRider().getHabboInfo().getId() == this.requestingHabbo.getHabboInfo().getId()); // is current user riding + this.response.appendInt(0); + this.response.appendInt(this.pet instanceof RideablePet && ((RideablePet) this.pet).anyoneCanRide() ? 1 : 0); // anyone can ride + this.response.appendBoolean(this.pet instanceof MonsterplantPet && ((MonsterplantPet) this.pet).canBreed()); //State Grown + this.response.appendBoolean(!(this.pet instanceof MonsterplantPet && ((MonsterplantPet) this.pet).isFullyGrown())); //unknown 1 + this.response.appendBoolean(this.pet instanceof MonsterplantPet && ((MonsterplantPet) this.pet).isDead()); //Dead + this.response.appendInt(this.pet instanceof MonsterplantPet ? ((MonsterplantPet) this.pet).getRarity() : 0); + this.response.appendInt(MonsterplantPet.timeToLive); //Maximum wellbeing + this.response.appendInt(this.pet instanceof MonsterplantPet ? ((MonsterplantPet) this.pet).remainingTimeToLive() : 0); //Remaining Wellbeing + this.response.appendInt(this.pet instanceof MonsterplantPet ? ((MonsterplantPet) this.pet).remainingGrowTime() : 0); + this.response.appendBoolean(this.pet instanceof MonsterplantPet && ((MonsterplantPet) this.pet).isPubliclyBreedable()); //Breedable checkbox + + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetLevelUpComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetLevelUpComposer.java new file mode 100644 index 0000000..f3bf2bf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetLevelUpComposer.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.outgoing.rooms.pets; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PetLevelUpComposer extends MessageComposer { + private final Pet pet; + + public PetLevelUpComposer(Pet pet) { + this.pet = pet; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PetLevelUpComposer); + this.response.appendInt(this.pet.getId()); + this.response.appendString(this.pet.getName()); + this.response.appendInt(this.pet.getLevel()); + this.response.appendInt(this.pet.getPetData().getType()); + this.response.appendInt(this.pet.getRace()); + this.response.appendString(this.pet.getColor()); + this.response.appendInt(0); + this.response.appendInt(0); + + //:test 2329 i:0 s:a i:3 i:1 i:1 s:FF00FF i:0 i:0 + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetLevelUpdatedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetLevelUpdatedComposer.java new file mode 100644 index 0000000..46f76ae --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetLevelUpdatedComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.rooms.pets; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PetLevelUpdatedComposer extends MessageComposer { + private final Pet pet; + + public PetLevelUpdatedComposer(Pet pet) { + this.pet = pet; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PetLevelUpdatedComposer); + this.response.appendInt(this.pet.getRoomUnit().getId()); + this.response.appendInt(this.pet.getId()); + this.response.appendInt(this.pet.getLevel()); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetPackageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetPackageComposer.java new file mode 100644 index 0000000..70f8d91 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetPackageComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.rooms.pets; + +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PetPackageComposer extends MessageComposer { + private final HabboItem item; + + public PetPackageComposer(HabboItem item) { + this.item = item; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.LeprechaunStarterBundleComposer); + this.response.appendInt(this.item.getId()); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetPackageNameValidationComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetPackageNameValidationComposer.java new file mode 100644 index 0000000..9d99ade --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetPackageNameValidationComposer.java @@ -0,0 +1,32 @@ +package com.eu.habbo.messages.outgoing.rooms.pets; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PetPackageNameValidationComposer extends MessageComposer { + public static final int CLOSE_WIDGET = 0; + public static final int NAME_TOO_SHORT = 1; + public static final int NAME_TOO_LONG = 2; + public static final int CONTAINS_INVALID_CHARS = 3; + public static final int FORBIDDEN_WORDS = 4; + + private final int itemId; + private final int errorCode; + private final String errorString; + + public PetPackageNameValidationComposer(int itemId, int errorCode, String errorString) { + this.itemId = itemId; + this.errorCode = errorCode; + this.errorString = errorString; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PetPackageNameValidationComposer); + this.response.appendInt(this.itemId); + this.response.appendInt(this.errorCode); + this.response.appendString(this.errorString); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetStatusUpdateComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetStatusUpdateComposer.java new file mode 100644 index 0000000..37549fe --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetStatusUpdateComposer.java @@ -0,0 +1,28 @@ +package com.eu.habbo.messages.outgoing.rooms.pets; + +import com.eu.habbo.habbohotel.pets.MonsterplantPet; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.RideablePet; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PetStatusUpdateComposer extends MessageComposer { + private final Pet pet; + + public PetStatusUpdateComposer(Pet pet) { + this.pet = pet; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PetStatusUpdateComposer); + this.response.appendInt(this.pet.getRoomUnit().getId()); + this.response.appendInt(this.pet instanceof RideablePet && ((RideablePet) this.pet).anyoneCanRide() ? 1 : 0); + this.response.appendBoolean((this.pet instanceof MonsterplantPet && ((MonsterplantPet) this.pet).canBreed())); //unknown 1 + this.response.appendBoolean((this.pet instanceof MonsterplantPet && !((MonsterplantPet) this.pet).isFullyGrown())); + this.response.appendBoolean(this.pet instanceof MonsterplantPet && ((MonsterplantPet) this.pet).isDead()); //State Grown + this.response.appendBoolean(this.pet instanceof MonsterplantPet && ((MonsterplantPet) this.pet).isPubliclyBreedable()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetTrainingPanelComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetTrainingPanelComposer.java new file mode 100644 index 0000000..f925426 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/PetTrainingPanelComposer.java @@ -0,0 +1,49 @@ +package com.eu.habbo.messages.outgoing.rooms.pets; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetCommand; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class PetTrainingPanelComposer extends MessageComposer { + private final Pet pet; + + public PetTrainingPanelComposer(Pet pet) { + this.pet = pet; + } + + @Override + protected ServerMessage composeInternal() { + List enabled = new ArrayList<>(); + Collections.sort(this.pet.getPetData().getPetCommands()); + + this.response.init(Outgoing.PetTrainingPanelComposer); + this.response.appendInt(this.pet.getId()); + this.response.appendInt(this.pet.getPetData().getPetCommands().size()); + + for (PetCommand petCommand : this.pet.getPetData().getPetCommands()) { + this.response.appendInt(petCommand.id); + + if (this.pet.getLevel() >= petCommand.level) { + enabled.add(petCommand); + } + } + + if (!enabled.isEmpty()) { + Collections.sort(enabled); + } + + this.response.appendInt(enabled.size()); + + for (PetCommand petCommand : enabled) { + this.response.appendInt(petCommand.id); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetComposer.java new file mode 100644 index 0000000..c515a69 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetComposer.java @@ -0,0 +1,62 @@ +package com.eu.habbo.messages.outgoing.rooms.pets; + +import com.eu.habbo.habbohotel.pets.*; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.procedure.TIntObjectProcedure; + +public class RoomPetComposer extends MessageComposer implements TIntObjectProcedure { + private final TIntObjectMap pets; + + public RoomPetComposer(Pet pet) { + this.pets = new TIntObjectHashMap<>(); + this.pets.put(pet.getId(), pet); + } + + public RoomPetComposer(TIntObjectMap pets) { + this.pets = pets; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUsersComposer); + this.response.appendInt(this.pets.size()); + this.pets.forEachEntry(this); + return this.response; + } + + @Override + public boolean execute(int a, Pet pet) { + this.response.appendInt(pet.getId()); + this.response.appendString(pet.getName()); + this.response.appendString(""); + if (pet instanceof IPetLook) { + this.response.appendString(((IPetLook) pet).getLook()); + } else { + this.response.appendString(pet.getPetData().getType() + " " + pet.getRace() + " " + pet.getColor() + " " + ((pet instanceof HorsePet ? (((HorsePet) pet).hasSaddle() ? "3" : "2") + " 2 " + ((HorsePet) pet).getHairStyle() + " " + ((HorsePet) pet).getHairColor() + " 3 " + ((HorsePet) pet).getHairStyle() + " " + ((HorsePet) pet).getHairColor() + (((HorsePet) pet).hasSaddle() ? " 4 9 0" : "") : pet instanceof MonsterplantPet ? (((MonsterplantPet) pet).look.isEmpty() ? "2 1 8 6 0 -1 -1" : ((MonsterplantPet) pet).look) : "2 2 -1 0 3 -1 0"))); + } + this.response.appendInt(pet.getRoomUnit().getId()); + this.response.appendInt(pet.getRoomUnit().getX()); + this.response.appendInt(pet.getRoomUnit().getY()); + this.response.appendString(pet.getRoomUnit().getZ() + ""); + this.response.appendInt(0); + this.response.appendInt(2); + this.response.appendInt(pet.getPetData().getType()); + this.response.appendInt(pet.getUserId()); + this.response.appendString(pet.getRoom().getFurniOwnerNames().get(pet.getUserId())); + this.response.appendInt(pet instanceof MonsterplantPet ? ((MonsterplantPet) pet).getRarity() : 1); + this.response.appendBoolean(pet instanceof RideablePet && ((RideablePet) pet).hasSaddle()); + this.response.appendBoolean(false); + this.response.appendBoolean((pet instanceof MonsterplantPet && ((MonsterplantPet) pet).canBreed())); //Has breeasasd// + this.response.appendBoolean(!(pet instanceof MonsterplantPet && ((MonsterplantPet) pet).isFullyGrown())); //unknown 1 + this.response.appendBoolean(pet instanceof MonsterplantPet && ((MonsterplantPet) pet).isDead()); //Can revive + this.response.appendBoolean(pet instanceof MonsterplantPet && ((MonsterplantPet) pet).isPubliclyBreedable()); //Breedable checkbox //Toggle breeding permission + this.response.appendInt(pet instanceof MonsterplantPet ? ((MonsterplantPet) pet).getGrowthStage() : pet.getLevel()); + this.response.appendString(""); + + return true; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetExperienceComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetExperienceComposer.java new file mode 100644 index 0000000..6098302 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetExperienceComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.rooms.pets; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomPetExperienceComposer extends MessageComposer { + private final Pet pet; + private final int amount; + + public RoomPetExperienceComposer(Pet pet, int amount) { + this.pet = pet; + this.amount = amount; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomPetExperienceComposer); + this.response.appendInt(this.pet.getId()); + this.response.appendInt(this.pet.getRoomUnit().getId()); + this.response.appendInt(this.amount); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetHorseFigureComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetHorseFigureComposer.java new file mode 100644 index 0000000..e8f066f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetHorseFigureComposer.java @@ -0,0 +1,51 @@ +package com.eu.habbo.messages.outgoing.rooms.pets; + +import com.eu.habbo.habbohotel.pets.HorsePet; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomPetHorseFigureComposer extends MessageComposer { + private final HorsePet pet; + + public RoomPetHorseFigureComposer(HorsePet pet) { + this.pet = pet; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomPetHorseFigureComposer); + this.response.appendInt(this.pet.getRoomUnit().getId()); + this.response.appendInt(this.pet.getId()); + this.response.appendInt(this.pet.getPetData().getType()); + this.response.appendInt(this.pet.getRace()); + this.response.appendString(this.pet.getColor().toLowerCase()); + + if (this.pet.hasSaddle()) { + this.response.appendInt(2); + this.response.appendInt(3); + this.response.appendInt(4); + this.response.appendInt(9); + this.response.appendInt(0); + this.response.appendInt(3); + + this.response.appendInt(this.pet.getHairStyle()); + this.response.appendInt(this.pet.getHairColor()); + this.response.appendInt(3); //Saddle type? + this.response.appendInt(this.pet.getHairStyle()); + this.response.appendInt(this.pet.getHairColor()); + } else { + this.response.appendInt(1); + this.response.appendInt(2); + this.response.appendInt(2); + this.response.appendInt(this.pet.getHairStyle()); + this.response.appendInt(this.pet.getHairColor()); + this.response.appendInt(3); + this.response.appendInt(this.pet.getHairStyle()); + this.response.appendInt(this.pet.getHairColor()); + } + this.response.appendBoolean(this.pet.hasSaddle()); + this.response.appendBoolean(false); // this.pet.anyoneCanRide() + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetRespectComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetRespectComposer.java new file mode 100644 index 0000000..59f939e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/RoomPetRespectComposer.java @@ -0,0 +1,33 @@ +package com.eu.habbo.messages.outgoing.rooms.pets; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomPetRespectComposer extends MessageComposer { + public final static int PET_RESPECTED = 1; + public final static int PET_TREATED = 2; + + private final Pet pet; + private final int type; + + public RoomPetRespectComposer(Pet pet) { + this.pet = pet; + this.type = 1; + } + + public RoomPetRespectComposer(Pet pet, int type) { + this.pet = pet; + this.type = type; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomPetRespectComposer); + this.response.appendInt(this.type); + this.response.appendInt(100); + this.pet.serialize(this.response); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingCompleted.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingCompleted.java new file mode 100644 index 0000000..2cd37d0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingCompleted.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.rooms.pets.breeding; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PetBreedingCompleted extends MessageComposer { + private final int type; + private final int race; + + public PetBreedingCompleted(int type, int race) { + this.type = type; + this.race = race; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PetBreedingCompleted); + this.response.appendInt(this.type); + this.response.appendInt(this.race); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingFailedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingFailedComposer.java new file mode 100644 index 0000000..b39a16a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingFailedComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.rooms.pets.breeding; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PetBreedingFailedComposer extends MessageComposer { + private final int anInt1; + private final int anInt2; + + public PetBreedingFailedComposer(int anInt1, int anInt2) { + this.anInt1 = anInt1; + this.anInt2 = anInt2; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PetBreedingFailedComposer); + this.response.appendInt(this.anInt1); + this.response.appendInt(this.anInt2); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingResultComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingResultComposer.java new file mode 100644 index 0000000..035e83c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingResultComposer.java @@ -0,0 +1,112 @@ +package com.eu.habbo.messages.outgoing.rooms.pets.breeding; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetBreedingReward; +import com.eu.habbo.habbohotel.pets.PetManager; +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.map.hash.TIntObjectHashMap; +import org.apache.commons.math3.distribution.NormalDistribution; + +import java.util.ArrayList; + +public class PetBreedingResultComposer extends MessageComposer { + private final int boxId; + private final int petType; + private final PetBreedingPet petOne; + private final PetBreedingPet petTwo; + + public PetBreedingResultComposer(int boxId, int petType, Pet petOne, String ownerPetOne, Pet petTwo, String ownerPetTwo) { + this.boxId = boxId; + this.petType = petType; + this.petOne = new PetBreedingPet(petOne, ownerPetOne); + this.petTwo = new PetBreedingPet(petTwo, ownerPetTwo); + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PetBreedingResultComposer); + this.response.appendInt(this.boxId); + this.petOne.serialize(this.response); + this.petTwo.serialize(this.response); + + double avgLevel = ((float) this.petOne.pet.getLevel() + this.petTwo.pet.getLevel()) / 2; + NormalDistribution normalDistribution = PetManager.getNormalDistributionForBreeding(avgLevel); + + + TIntObjectHashMap> rewardBreeds = Emulator.getGameEnvironment().getPetManager().getBreedingRewards(this.petType); + + this.response.appendInt(4); //Levels + { + int percentage1 = (int) (normalDistribution.cumulativeProbability(10) * 100); + int percentage2 = (int) (normalDistribution.cumulativeProbability(15) * 100) - percentage1; + int percentage3 = (int) (normalDistribution.cumulativeProbability(18) * 100) - percentage1 - percentage2; + int percentage4 = (int) (normalDistribution.cumulativeProbability(20) * 100) - percentage1 - percentage2 - percentage3; + + int dPercentage = 100 - (percentage1 + percentage2 + percentage3 + percentage4); + if (dPercentage > 0) { + percentage1 += dPercentage; + } else { + percentage4 -= dPercentage; + } + + this.response.appendInt(percentage4); //Percentage + this.response.appendInt(rewardBreeds.get(4).size()); //Count + { + for (PetBreedingReward reward : rewardBreeds.get(4)) { + this.response.appendInt(reward.breed); + } + } + + this.response.appendInt(percentage3); //Percentage + this.response.appendInt(rewardBreeds.get(3).size()); //Count + { + for (PetBreedingReward reward : rewardBreeds.get(3)) { + this.response.appendInt(reward.breed); + } + } + + this.response.appendInt(percentage2); //Percentage + this.response.appendInt(rewardBreeds.get(2).size()); //Count + { + for (PetBreedingReward reward : rewardBreeds.get(2)) { + this.response.appendInt(reward.breed); + } + } + + this.response.appendInt(percentage1); //Percentage + this.response.appendInt(rewardBreeds.get(1).size()); //Count + { + for (PetBreedingReward reward : rewardBreeds.get(1)) { + this.response.appendInt(reward.breed); + } + } + + } + + this.response.appendInt(this.petType); //Race type + return this.response; + } + + public class PetBreedingPet implements ISerialize { + public final Pet pet; + public final String ownerName; + + public PetBreedingPet(Pet pet, String ownerName) { + this.pet = pet; + this.ownerName = ownerName; + } + + @Override + public void serialize(ServerMessage message) { + message.appendInt(this.pet.getId()); + message.appendString(this.pet.getName()); + message.appendInt(this.pet.getLevel()); + message.appendString(this.pet.getColor()); + message.appendString(this.ownerName); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingStartComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingStartComposer.java new file mode 100644 index 0000000..5564711 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingStartComposer.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.outgoing.rooms.pets.breeding; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PetBreedingStartComposer extends MessageComposer { + private final int state; + private final int anInt1; + private final int anInt2; + + + public PetBreedingStartComposer(int state, int anInt1, int anInt2) { + this.state = state; + this.anInt1 = anInt1; + this.anInt2 = anInt2; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PetBreedingStartComposer); + this.response.appendInt(this.state); + this.response.appendInt(this.anInt1); + this.response.appendInt(this.anInt2); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingStartFailedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingStartFailedComposer.java new file mode 100644 index 0000000..6f1e51c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/pets/breeding/PetBreedingStartFailedComposer.java @@ -0,0 +1,28 @@ +package com.eu.habbo.messages.outgoing.rooms.pets.breeding; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class PetBreedingStartFailedComposer extends MessageComposer { + public final static int NO_NESTS = 0; + public final static int NO_SUITABLE_NESTS = 1; + public final static int NEST_FULL = 2; + public final static int NOT_OWNER = 3; + public final static int ALREADY_IN_NEST = 4; + public final static int NO_PATH_TO_NEST = 5; + public final static int TOO_TIRED = 6; + + private final int reason; + + public PetBreedingStartFailedComposer(int reason) { + this.reason = reason; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PetBreedingStartFailedComposer); + this.response.appendInt(this.reason); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/promotions/PromoteOwnRoomsListComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/promotions/PromoteOwnRoomsListComposer.java new file mode 100644 index 0000000..f791a26 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/promotions/PromoteOwnRoomsListComposer.java @@ -0,0 +1,33 @@ +package com.eu.habbo.messages.outgoing.rooms.promotions; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.ArrayList; +import java.util.List; + +public class PromoteOwnRoomsListComposer extends MessageComposer { + private final List rooms = new ArrayList<>(); + + public PromoteOwnRoomsListComposer(List rooms) { + for (Room room : rooms) { + if (!room.isPromoted()) + this.rooms.add(room); + } + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.PromoteOwnRoomsListComposer); + this.response.appendBoolean(true); + this.response.appendInt(this.rooms.size()); + for (Room room : this.rooms) { + this.response.appendInt(room.getId()); + this.response.appendString(room.getName()); + this.response.appendBoolean(true); //IDK what the fuck this is. + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/promotions/RoomPromotionMessageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/promotions/RoomPromotionMessageComposer.java new file mode 100644 index 0000000..6167e61 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/promotions/RoomPromotionMessageComposer.java @@ -0,0 +1,53 @@ +package com.eu.habbo.messages.outgoing.rooms.promotions; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomPromotion; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomPromotionMessageComposer extends MessageComposer { + private final Room room; + private final RoomPromotion roomPromotion; + + public RoomPromotionMessageComposer(Room room, RoomPromotion roomPromotion) { + this.room = room; + this.roomPromotion = roomPromotion; + } + + @Override + protected ServerMessage composeInternal() { + + this.response.init(Outgoing.RoomEventMessageComposer); + + if (this.room == null || this.roomPromotion == null) { + this.response.appendInt(-1); + this.response.appendInt(-1); + this.response.appendString(""); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendString(""); + this.response.appendString(""); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + } else { + this.response.appendInt(this.room.getId()); // promotion id + this.response.appendInt(this.room.getOwnerId()); + this.response.appendString(this.room.getOwnerName()); + + this.response.appendInt(this.room.getId()); // room id + this.response.appendInt(1); // "type" + + this.response.appendString(this.roomPromotion.getTitle()); + this.response.appendString(this.roomPromotion.getDescription()); + this.response.appendInt((Emulator.getIntUnixTimestamp() - this.roomPromotion.getStartTimestamp()) / 60); // minutes since starting + this.response.appendInt((this.roomPromotion.getEndTimestamp() - Emulator.getIntUnixTimestamp()) / 60); // minutes until end + this.response.appendInt(this.roomPromotion.getCategory()); // category + } + + return this.response; + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/ChangeNameUpdatedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/ChangeNameUpdatedComposer.java new file mode 100644 index 0000000..cb72a29 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/ChangeNameUpdatedComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +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.Outgoing; + +public class ChangeNameUpdatedComposer extends MessageComposer { + private final Habbo habbo; + + public ChangeNameUpdatedComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ChangeNameUpdateComposer); + this.response.appendInt(0); + this.response.appendString(this.habbo.getHabboInfo().getUsername()); + this.response.appendInt(0); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUnitIdleComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUnitIdleComposer.java new file mode 100644 index 0000000..9a01826 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUnitIdleComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomUnitIdleComposer extends MessageComposer { + private final RoomUnit roomUnit; + + public RoomUnitIdleComposer(RoomUnit roomUnit) { + this.roomUnit = roomUnit; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUnitIdleComposer); + this.response.appendInt(this.roomUnit.getId()); + this.response.appendBoolean(this.roomUnit.isIdle()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUnitOnRollerComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUnitOnRollerComposer.java new file mode 100644 index 0000000..70df0b1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUnitOnRollerComposer.java @@ -0,0 +1,124 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionRoller; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.set.hash.THashSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RoomUnitOnRollerComposer extends MessageComposer { + private static final Logger LOGGER = LoggerFactory.getLogger(RoomUnitOnRollerComposer.class); + private final RoomUnit roomUnit; + private final HabboItem roller; + private final RoomTile oldLocation; + private final double oldZ; + private final RoomTile newLocation; + private final double newZ; + private final Room room; + private int x; + private int y; + private HabboItem oldTopItem; + + public RoomUnitOnRollerComposer(RoomUnit roomUnit, HabboItem roller, RoomTile oldLocation, double oldZ, RoomTile newLocation, double newZ, Room room) { + this.roomUnit = roomUnit; + this.roller = roller; + this.oldLocation = oldLocation; + this.oldZ = oldZ; + this.newLocation = newLocation; + this.newZ = newZ; + this.room = room; + oldTopItem = this.room.getTopItemAt(oldLocation.x, oldLocation.y); + } + + public RoomUnitOnRollerComposer(RoomUnit roomUnit, RoomTile newLocation, Room room) { + this.roomUnit = roomUnit; + this.roller = null; + this.oldLocation = this.roomUnit.getCurrentLocation(); + this.oldZ = this.roomUnit.getZ(); + this.newLocation = newLocation; + this.newZ = this.newLocation.getStackHeight(); + this.room = room; + this.oldTopItem = null; + } + + @Override + protected ServerMessage composeInternal() { + if (!this.room.isLoaded()) + return null; + + this.response.init(Outgoing.ObjectOnRollerComposer); + this.response.appendInt(this.oldLocation.x); + this.response.appendInt(this.oldLocation.y); + this.response.appendInt(this.newLocation.x); + this.response.appendInt(this.newLocation.y); + this.response.appendInt(0); + this.response.appendInt(this.roller == null ? 0 : this.roller.getId()); + this.response.appendInt(2); + this.response.appendInt(this.roomUnit.getId()); + this.response.appendString(this.oldZ + ""); + this.response.appendString(this.newZ + ""); + + if (this.roller != null && room.getLayout() != null) { + Emulator.getThreading().run(() -> { + if(!this.roomUnit.isWalking() && this.roomUnit.getCurrentLocation() == this.oldLocation) { + HabboItem topItem = this.room.getTopItemAt(this.oldLocation.x, this.oldLocation.y); + HabboItem topItemNewLocation = this.room.getTopItemAt(this.newLocation.x, this.newLocation.y); + + if (topItem != null && (oldTopItem == null || oldTopItem != topItemNewLocation)) { + try { + topItem.onWalkOff(this.roomUnit, this.room, new Object[]{this}); + } catch (Exception e) { + LOGGER.error("Caught exception", e); + } + } + + this.roomUnit.setLocation(this.newLocation); + this.roomUnit.setZ(this.newLocation.getStackHeight()); + this.roomUnit.setPreviousLocationZ(this.newLocation.getStackHeight()); + + if (topItemNewLocation != null && topItemNewLocation != roller && oldTopItem != topItemNewLocation) { + try { + topItemNewLocation.onWalkOn(this.roomUnit, this.room, new Object[]{this}); + } catch (Exception e) { + LOGGER.error("Caught exception", e); + } + } + } + }, this.room.getRollerSpeed() == 0 ? 250 : InteractionRoller.DELAY); + /* + RoomTile rollerTile = room.getLayout().getTile(this.roller.getX(), this.roller.getY()); + Emulator.getThreading().run(() -> { + if (this.oldLocation == rollerTile && this.roomUnit.getGoal() == rollerTile) { + this.roomUnit.setLocation(newLocation); + this.roomUnit.setGoalLocation(newLocation); + this.roomUnit.setPreviousLocationZ(newLocation.getStackHeight()); + this.roomUnit.setZ(newLocation.getStackHeight()); + this.roomUnit.sitUpdate = true; + + HabboItem topItem = this.room.getTopItemAt(this.roomUnit.getCurrentLocation().x, this.roomUnit.getCurrentLocation().y); + if (topItem != null && topItem != roller && oldTopItem != topItem) { + try { + topItem.onWalkOff(this.roomUnit, this.room, new Object[]{this}); + } catch (Exception e) { + LOGGER.error("Caught exception", e); + } + } + } + }, this.room.getRollerSpeed() == 0 ? 250 : InteractionRoller.DELAY); + */ + } else { + this.roomUnit.setLocation(this.newLocation); + this.roomUnit.setZ(this.newZ); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserActionComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserActionComposer.java new file mode 100644 index 0000000..ec54fda --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserActionComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUserAction; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomUserActionComposer extends MessageComposer { + private RoomUserAction action; + private RoomUnit roomUnit; + + public RoomUserActionComposer(RoomUnit roomUnit, RoomUserAction action) { + this.roomUnit = roomUnit; + this.action = action; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserActionComposer); + this.response.appendInt(this.roomUnit.getId()); + this.response.appendInt(this.action.getAction()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserDanceComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserDanceComposer.java new file mode 100644 index 0000000..f0900df --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserDanceComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomUserDanceComposer extends MessageComposer { + private final RoomUnit roomUnit; + + public RoomUserDanceComposer(RoomUnit roomUnit) { + this.roomUnit = roomUnit; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserDanceComposer); + this.response.appendInt(this.roomUnit.getId()); + this.response.appendInt(this.roomUnit.getDanceType().getType()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserDataComposer.java new file mode 100644 index 0000000..322a7ac --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserDataComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +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.Outgoing; + +public class RoomUserDataComposer extends MessageComposer { + private final Habbo habbo; + + public RoomUserDataComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserDataComposer); + this.response.appendInt(this.habbo.getRoomUnit() == null ? -1 : this.habbo.getRoomUnit().getId()); + this.response.appendString(this.habbo.getHabboInfo().getLook()); + this.response.appendString(this.habbo.getHabboInfo().getGender().name() + ""); + this.response.appendString(this.habbo.getHabboInfo().getMotto()); + this.response.appendInt(this.habbo.getHabboStats().getAchievementScore()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserEffectComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserEffectComposer.java new file mode 100644 index 0000000..8053b35 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserEffectComposer.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomUserEffectComposer extends MessageComposer { + private final RoomUnit roomUnit; + private final int effectId; + + public RoomUserEffectComposer(RoomUnit roomUnit) { + this.roomUnit = roomUnit; + this.effectId = -1; + } + + public RoomUserEffectComposer(RoomUnit roomUnit, int effectId) { + this.roomUnit = roomUnit; + this.effectId = effectId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserEffectComposer); + this.response.appendInt(this.roomUnit.getId()); + this.response.appendInt(this.effectId == -1 ? this.roomUnit.getEffectId() : this.effectId); + this.response.appendInt(0); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserHandItemComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserHandItemComposer.java new file mode 100644 index 0000000..2c74c8f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserHandItemComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomUserHandItemComposer extends MessageComposer { + private final RoomUnit roomUnit; + + public RoomUserHandItemComposer(RoomUnit roomUnit) { + this.roomUnit = roomUnit; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserHandItemComposer); + this.response.appendInt(this.roomUnit.getId()); + this.response.appendInt(this.roomUnit.getHandItem()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserIgnoredComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserIgnoredComposer.java new file mode 100644 index 0000000..51f7482 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserIgnoredComposer.java @@ -0,0 +1,28 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +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.Outgoing; + +public class RoomUserIgnoredComposer extends MessageComposer { + public final static int IGNORED = 1; + public final static int MUTED = 2; + public final static int UNIGNORED = 3; + + private final Habbo habbo; + private final int state; + + public RoomUserIgnoredComposer(Habbo habbo, int state) { + this.habbo = habbo; + this.state = state; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserIgnoredComposer); + this.response.appendInt(this.state); + this.response.appendString(this.habbo.getHabboInfo().getUsername()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserNameChangedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserNameChangedComposer.java new file mode 100644 index 0000000..3e43c47 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserNameChangedComposer.java @@ -0,0 +1,39 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.habbohotel.rooms.Room; +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.Outgoing; + +public class RoomUserNameChangedComposer extends MessageComposer { + + private final int userId; + private final int roomId; + private final String name; + + public RoomUserNameChangedComposer(Habbo habbo) { + this(habbo, false); + } + + public RoomUserNameChangedComposer(Habbo habbo, boolean includePrefix) { + this.userId = habbo.getHabboInfo().getId(); + this.roomId = habbo.getRoomUnit().getId(); + this.name = (includePrefix ? Room.PREFIX_FORMAT.replace("%color%", habbo.getHabboInfo().getRank().getPrefixColor()).replace("%prefix%", habbo.getHabboInfo().getRank().getPrefix()) : "") + habbo.getHabboInfo().getUsername(); + } + + public RoomUserNameChangedComposer(int userId, int roomId, String name) { + this.userId = userId; + this.roomId = roomId; + this.name = name; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserNameChangedComposer); + this.response.appendInt(this.userId); + this.response.appendInt(this.roomId); + this.response.appendString(this.name); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserReceivedHandItemComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserReceivedHandItemComposer.java new file mode 100644 index 0000000..121ca4e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserReceivedHandItemComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomUserReceivedHandItemComposer extends MessageComposer { + private RoomUnit from; + private int handItem; + + public RoomUserReceivedHandItemComposer(RoomUnit from, int handItem) { + this.from = from; + this.handItem = handItem; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserReceivedHandItemComposer); + this.response.appendInt(this.from.getId()); + this.response.appendInt(this.handItem); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserRemoveComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserRemoveComposer.java new file mode 100644 index 0000000..9981b5b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserRemoveComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomUserRemoveComposer extends MessageComposer { + private final RoomUnit roomUnit; + + public RoomUserRemoveComposer(RoomUnit roomUnit) { + this.roomUnit = roomUnit; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserRemoveComposer); + this.response.appendString(this.roomUnit.getId() + ""); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserRemoveRightsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserRemoveRightsComposer.java new file mode 100644 index 0000000..ccf5626 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserRemoveRightsComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomUserRemoveRightsComposer extends MessageComposer { + private final Room room; + private final int habboId; + + public RoomUserRemoveRightsComposer(Room room, int habboId) { + this.room = room; + this.habboId = habboId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserRemoveRightsComposer); + this.response.appendInt(this.room.getId()); + this.response.appendInt(this.habboId); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserRespectComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserRespectComposer.java new file mode 100644 index 0000000..4e807ee --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserRespectComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +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.Outgoing; + +public class RoomUserRespectComposer extends MessageComposer { + private final Habbo habbo; + + public RoomUserRespectComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserRespectComposer); + this.response.appendInt(this.habbo.getHabboInfo().getId()); + this.response.appendInt(this.habbo.getHabboStats().respectPointsReceived); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserShoutComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserShoutComposer.java new file mode 100644 index 0000000..6c8945b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserShoutComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomUserShoutComposer extends MessageComposer { + private RoomChatMessage roomChatMessage; + + public RoomUserShoutComposer(RoomChatMessage roomChatMessage) { + this.roomChatMessage = roomChatMessage; + } + + @Override + protected ServerMessage composeInternal() { + if (this.roomChatMessage.getMessage().isEmpty()) + return null; + + this.response.init(Outgoing.RoomUserShoutComposer); + this.roomChatMessage.serialize(this.response); + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserStatusComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserStatusComposer.java new file mode 100644 index 0000000..4aedd6b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserStatusComposer.java @@ -0,0 +1,85 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +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.Outgoing; +import gnu.trove.set.hash.THashSet; + +import java.util.Collection; +import java.util.Map; + +public class RoomUserStatusComposer extends MessageComposer { + private Collection habbos; + private THashSet roomUnits; + private double overrideZ = -1; + + public RoomUserStatusComposer(RoomUnit roomUnit) { + this.roomUnits = new THashSet<>(); + this.roomUnits.add(roomUnit); + } + + public RoomUserStatusComposer(RoomUnit roomUnit, double overrideZ) { + this(roomUnit); + this.overrideZ = overrideZ; + } + + public RoomUserStatusComposer(THashSet roomUnits, boolean value) { + this.roomUnits = roomUnits; + } + + public RoomUserStatusComposer(Collection habbos) { + this.habbos = habbos; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserStatusComposer); + if (this.roomUnits != null) { + this.response.appendInt(this.roomUnits.size()); + for (RoomUnit roomUnit : this.roomUnits) { + this.response.appendInt(roomUnit.getId()); + this.response.appendInt(roomUnit.getPreviousLocation().x); + this.response.appendInt(roomUnit.getPreviousLocation().y); + this.response.appendString((this.overrideZ != -1 ? this.overrideZ : roomUnit.getPreviousLocationZ()) + ""); + + + this.response.appendInt(roomUnit.getHeadRotation().getValue()); + this.response.appendInt(roomUnit.getBodyRotation().getValue()); + + StringBuilder status = new StringBuilder("/"); + for (Map.Entry entry : roomUnit.getStatusMap().entrySet()) { + status.append(entry.getKey()).append(" ").append(entry.getValue()).append("/"); + } + + this.response.appendString(status.toString()); + roomUnit.setPreviousLocation(roomUnit.getCurrentLocation()); + } + } else { + synchronized (this.habbos) { + this.response.appendInt(this.habbos.size()); + for (Habbo habbo : this.habbos) { + this.response.appendInt(habbo.getRoomUnit().getId()); + this.response.appendInt(habbo.getRoomUnit().getPreviousLocation().x); + this.response.appendInt(habbo.getRoomUnit().getPreviousLocation().y); + this.response.appendString(habbo.getRoomUnit().getPreviousLocationZ() + ""); + + + this.response.appendInt(habbo.getRoomUnit().getHeadRotation().getValue()); + this.response.appendInt(habbo.getRoomUnit().getBodyRotation().getValue()); + + StringBuilder status = new StringBuilder("/"); + + for (Map.Entry entry : habbo.getRoomUnit().getStatusMap().entrySet()) { + status.append(entry.getKey()).append(" ").append(entry.getValue()).append("/"); + } + this.response.appendString(status.toString()); + habbo.getRoomUnit().setPreviousLocation(habbo.getRoomUnit().getCurrentLocation()); + } + } + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserTagsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserTagsComposer.java new file mode 100644 index 0000000..a612e9e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserTagsComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +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.Outgoing; + +public class RoomUserTagsComposer extends MessageComposer { + private final Habbo habbo; + + public RoomUserTagsComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserTagsComposer); + this.response.appendInt(this.habbo.getRoomUnit().getId()); + this.response.appendInt(this.habbo.getHabboStats().tags.length); + + for (String tag : this.habbo.getHabboStats().tags) { + this.response.appendString(tag); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserTalkComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserTalkComposer.java new file mode 100644 index 0000000..6af2fdb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserTalkComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomUserTalkComposer extends MessageComposer { + private final RoomChatMessage roomChatMessage; + + public RoomUserTalkComposer(RoomChatMessage roomChatMessage) { + this.roomChatMessage = roomChatMessage; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserTalkComposer); + + if (this.roomChatMessage.getMessage().isEmpty()) + return null; + + this.roomChatMessage.serialize(this.response); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserTypingComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserTypingComposer.java new file mode 100644 index 0000000..b412683 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserTypingComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomUserTypingComposer extends MessageComposer { + private final RoomUnit roomUnit; + private final boolean typing; + + public RoomUserTypingComposer(RoomUnit roomUnit, boolean typing) { + this.roomUnit = roomUnit; + this.typing = typing; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserTypingComposer); + this.response.appendInt(this.roomUnit.getId()); + this.response.appendInt(this.typing ? 1 : 0); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserUnbannedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserUnbannedComposer.java new file mode 100644 index 0000000..8390e13 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserUnbannedComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomUserUnbannedComposer extends MessageComposer { + private final Room room; + private final int userId; + + public RoomUserUnbannedComposer(Room room, int userId) { + this.room = room; + this.userId = userId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserUnbannedComposer); + this.response.appendInt(this.room.getId()); + this.response.appendInt(this.userId); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserWhisperComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserWhisperComposer.java new file mode 100644 index 0000000..10f8800 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUserWhisperComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomUserWhisperComposer extends MessageComposer { + private final RoomChatMessage roomChatMessage; + + public RoomUserWhisperComposer(RoomChatMessage roomChatMessage) { + this.roomChatMessage = roomChatMessage; + } + + @Override + protected ServerMessage composeInternal() { + if (this.roomChatMessage.getMessage().isEmpty()) + return null; + + this.response.init(Outgoing.RoomUserWhisperComposer); + this.roomChatMessage.serialize(this.response); + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUsersAddGuildBadgeComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUsersAddGuildBadgeComposer.java new file mode 100644 index 0000000..b834039 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUsersAddGuildBadgeComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomUsersAddGuildBadgeComposer extends MessageComposer { + private final Guild guild; + + public RoomUsersAddGuildBadgeComposer(Guild guild) { + this.guild = guild; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUsersGuildBadgesComposer); + this.response.appendInt(1); + this.response.appendInt(this.guild.getId()); + this.response.appendString(this.guild.getBadge()); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUsersComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUsersComposer.java new file mode 100644 index 0000000..4b53f9c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUsersComposer.java @@ -0,0 +1,153 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.guilds.Guild; +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.Outgoing; + +import java.util.Collection; + +public class RoomUsersComposer extends MessageComposer { + private Habbo habbo; + private Collection habbos; + private Bot bot; + private Collection bots; + + public RoomUsersComposer(Habbo habbo) { + this.habbo = habbo; + } + + public RoomUsersComposer(Collection habbos) { + this.habbos = habbos; + } + + public RoomUsersComposer(Bot bot) { + this.bot = bot; + } + + public RoomUsersComposer(Collection bots, boolean isBot) { + this.bots = bots; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUsersComposer); + if (this.habbo != null) { + this.response.appendInt(1); + this.response.appendInt(this.habbo.getHabboInfo().getId()); + this.response.appendString(this.habbo.getHabboInfo().getUsername()); + this.response.appendString(this.habbo.getHabboInfo().getMotto()); + this.response.appendString(this.habbo.getHabboInfo().getLook()); + this.response.appendInt(this.habbo.getRoomUnit().getId()); //Room Unit ID + this.response.appendInt(this.habbo.getRoomUnit().getX()); + this.response.appendInt(this.habbo.getRoomUnit().getY()); + this.response.appendString(this.habbo.getRoomUnit().getZ() + ""); + this.response.appendInt(this.habbo.getRoomUnit().getBodyRotation().getValue()); + this.response.appendInt(1); + this.response.appendString(this.habbo.getHabboInfo().getGender().name().toUpperCase()); + this.response.appendInt(this.habbo.getHabboStats().guild != 0 ? this.habbo.getHabboStats().guild : -1); + this.response.appendInt(this.habbo.getHabboStats().guild != 0 ? 1 : -1); + + String name = ""; + if (this.habbo.getHabboStats().guild != 0) { + Guild g = Emulator.getGameEnvironment().getGuildManager().getGuild(this.habbo.getHabboStats().guild); + + if (g != null) + name = g.getName(); + } + this.response.appendString(name); + + this.response.appendString(""); + this.response.appendInt(this.habbo.getHabboStats().getAchievementScore()); + this.response.appendBoolean(true); + } else if (this.habbos != null) { + this.response.appendInt(this.habbos.size()); + for (Habbo habbo : this.habbos) { + if (habbo != null) { + this.response.appendInt(habbo.getHabboInfo().getId()); + this.response.appendString(habbo.getHabboInfo().getUsername()); + this.response.appendString(habbo.getHabboInfo().getMotto()); + this.response.appendString(habbo.getHabboInfo().getLook()); + this.response.appendInt(habbo.getRoomUnit().getId()); //Room Unit ID + this.response.appendInt(habbo.getRoomUnit().getX()); + this.response.appendInt(habbo.getRoomUnit().getY()); + this.response.appendString(habbo.getRoomUnit().getZ() + ""); + this.response.appendInt(habbo.getRoomUnit().getBodyRotation().getValue()); + this.response.appendInt(1); + this.response.appendString(habbo.getHabboInfo().getGender().name().toUpperCase()); + this.response.appendInt(habbo.getHabboStats().guild != 0 ? habbo.getHabboStats().guild : -1); + this.response.appendInt(habbo.getHabboStats().guild != 0 ? habbo.getHabboStats().guild : -1); + String name = ""; + if (habbo.getHabboStats().guild != 0) { + Guild g = Emulator.getGameEnvironment().getGuildManager().getGuild(habbo.getHabboStats().guild); + + if (g != null) + name = g.getName(); + } + this.response.appendString(name); + this.response.appendString(""); + this.response.appendInt(habbo.getHabboStats().getAchievementScore()); + this.response.appendBoolean(true); + } + } + } else if (this.bot != null) { + this.response.appendInt(1); + this.response.appendInt(0 - this.bot.getId()); + this.response.appendString(this.bot.getName()); + this.response.appendString(this.bot.getMotto()); + this.response.appendString(this.bot.getFigure()); + this.response.appendInt(this.bot.getRoomUnit().getId()); + this.response.appendInt(this.bot.getRoomUnit().getX()); + this.response.appendInt(this.bot.getRoomUnit().getY()); + this.response.appendString(this.bot.getRoomUnit().getZ() + ""); + this.response.appendInt(this.bot.getRoomUnit().getBodyRotation().getValue()); + this.response.appendInt(4); + this.response.appendString(this.bot.getGender().name().toUpperCase()); + this.response.appendInt(this.bot.getOwnerId()); + this.response.appendString(this.bot.getOwnerName()); + this.response.appendInt(10); + this.response.appendShort(0); + this.response.appendShort(1); + this.response.appendShort(2); + this.response.appendShort(3); + this.response.appendShort(4); + this.response.appendShort(5); + this.response.appendShort(6); + this.response.appendShort(7); + this.response.appendShort(8); + this.response.appendShort(9); + } else if (this.bots != null) { + this.response.appendInt(this.bots.size()); + for (Bot bot : this.bots) { + this.response.appendInt(0 - bot.getId()); + this.response.appendString(bot.getName()); + this.response.appendString(bot.getMotto()); + this.response.appendString(bot.getFigure()); + this.response.appendInt(bot.getRoomUnit().getId()); + this.response.appendInt(bot.getRoomUnit().getX()); + this.response.appendInt(bot.getRoomUnit().getY()); + this.response.appendString(bot.getRoomUnit().getZ() + ""); + this.response.appendInt(bot.getRoomUnit().getBodyRotation().getValue()); + this.response.appendInt(4); + this.response.appendString(bot.getGender().name().toUpperCase()); + this.response.appendInt(bot.getOwnerId()); + this.response.appendString(bot.getOwnerName()); + this.response.appendInt(10); + this.response.appendShort(0); + this.response.appendShort(1); + this.response.appendShort(2); + this.response.appendShort(3); + this.response.appendShort(4); + this.response.appendShort(5); + this.response.appendShort(6); + this.response.appendShort(7); + this.response.appendShort(8); + this.response.appendShort(9); + } + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUsersGuildBadgesComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUsersGuildBadgesComposer.java new file mode 100644 index 0000000..babb298 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/users/RoomUsersGuildBadgesComposer.java @@ -0,0 +1,31 @@ +package com.eu.habbo.messages.outgoing.rooms.users; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectObjectProcedure; + +public class RoomUsersGuildBadgesComposer extends MessageComposer { + private final THashMap guildBadges; + + public RoomUsersGuildBadgesComposer(THashMap guildBadges) { + this.guildBadges = guildBadges; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUsersGuildBadgesComposer); + this.response.appendInt(this.guildBadges.size()); + + this.guildBadges.forEachEntry(new TObjectObjectProcedure() { + @Override + public boolean execute(Integer guildId, String badge) { + RoomUsersGuildBadgesComposer.this.response.appendInt(guildId); + RoomUsersGuildBadgesComposer.this.response.appendString(badge); + return true; + } + }); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/OtherTradingDisabledComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/OtherTradingDisabledComposer.java new file mode 100644 index 0000000..90c2315 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/OtherTradingDisabledComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.trading; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class OtherTradingDisabledComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.OtherTradingDisabledComposer); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeAcceptedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeAcceptedComposer.java new file mode 100644 index 0000000..e6f10f6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeAcceptedComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.trading; + +import com.eu.habbo.habbohotel.rooms.RoomTradeUser; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class TradeAcceptedComposer extends MessageComposer { + private final RoomTradeUser tradeUser; + + public TradeAcceptedComposer(RoomTradeUser tradeUser) { + this.tradeUser = tradeUser; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.TradeAcceptedComposer); + this.response.appendInt(this.tradeUser.getUserId()); + this.response.appendInt(this.tradeUser.getAccepted()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeCloseWindowComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeCloseWindowComposer.java new file mode 100644 index 0000000..225abef --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeCloseWindowComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.trading; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class TradeCloseWindowComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.TradeCloseWindowComposer); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeClosedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeClosedComposer.java new file mode 100644 index 0000000..db24787 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeClosedComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.trading; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class TradeClosedComposer extends MessageComposer { + public static final int USER_CANCEL_TRADE = 0; + public static final int ITEMS_NOT_FOUND = 1; + + private final int userId; + private final int errorCode; + + public TradeClosedComposer(int userId, int errorCode) { + this.userId = userId; + this.errorCode = errorCode; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.TradeStoppedComposer); + this.response.appendInt(this.userId); + this.response.appendInt(this.errorCode); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeCompleteComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeCompleteComposer.java new file mode 100644 index 0000000..2f21441 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeCompleteComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.trading; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class TradeCompleteComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownTradeComposer); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeStartComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeStartComposer.java new file mode 100644 index 0000000..57d9118 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeStartComposer.java @@ -0,0 +1,32 @@ +package com.eu.habbo.messages.outgoing.trading; + +import com.eu.habbo.habbohotel.rooms.RoomTrade; +import com.eu.habbo.habbohotel.rooms.RoomTradeUser; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class TradeStartComposer extends MessageComposer { + private final RoomTrade roomTrade; + private final int state; + + public TradeStartComposer(RoomTrade roomTrade) { + this.roomTrade = roomTrade; + this.state = 1; + } + + public TradeStartComposer(RoomTrade roomTrade, int state) { + this.roomTrade = roomTrade; + this.state = state; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.TradeStartComposer); + for (RoomTradeUser tradeUser : this.roomTrade.getRoomTradeUsers()) { + this.response.appendInt(tradeUser.getHabbo().getHabboInfo().getId()); + this.response.appendInt(this.state); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeStartFailComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeStartFailComposer.java new file mode 100644 index 0000000..1012e68 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeStartFailComposer.java @@ -0,0 +1,34 @@ +package com.eu.habbo.messages.outgoing.trading; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class TradeStartFailComposer extends MessageComposer { + public static final int HOTEL_TRADING_NOT_ALLOWED = 1; + public static final int YOU_TRADING_OFF = 2; + public static final int TARGET_TRADING_NOT_ALLOWED = 4; + public static final int ROOM_TRADING_NOT_ALLOWED = 6; + public static final int YOU_ALREADY_TRADING = 7; + public static final int TARGET_ALREADY_TRADING = 8; + + private final String username; + private final int code; + + public TradeStartFailComposer(int code) { + this.code = code; + this.username = ""; + } + + public TradeStartFailComposer(int code, String username) { + this.code = code; + this.username = username; + } + + protected ServerMessage composeInternal() { + this.response.init(Outgoing.TradeStartFailComposer); + this.response.appendInt(this.code); + this.response.appendString(this.username); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeUpdateComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeUpdateComposer.java new file mode 100644 index 0000000..14464cf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradeUpdateComposer.java @@ -0,0 +1,46 @@ +package com.eu.habbo.messages.outgoing.trading; + +import com.eu.habbo.habbohotel.items.FurnitureType; +import com.eu.habbo.habbohotel.rooms.RoomTrade; +import com.eu.habbo.habbohotel.rooms.RoomTradeUser; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class TradeUpdateComposer extends MessageComposer { + private final RoomTrade roomTrade; + + public TradeUpdateComposer(RoomTrade roomTrade) { + this.roomTrade = roomTrade; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.TradeUpdateComposer); + for (RoomTradeUser roomTradeUser : this.roomTrade.getRoomTradeUsers()) { + this.response.appendInt(roomTradeUser.getUserId()); + + this.response.appendInt(roomTradeUser.getItems().size()); + for (HabboItem item : roomTradeUser.getItems()) { + this.response.appendInt(item.getId()); + this.response.appendString(item.getBaseItem().getType().code); + this.response.appendInt(item.getId()); + this.response.appendInt(item.getBaseItem().getSpriteId()); + this.response.appendInt(0); + this.response.appendBoolean(item.getBaseItem().allowInventoryStack() && !item.isLimited()); + item.serializeExtradata(this.response); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + + if (item.getBaseItem().getType() == FurnitureType.FLOOR) + this.response.appendInt(0); + } + + this.response.appendInt(roomTradeUser.getItems().size()); + this.response.appendInt(roomTradeUser.getItems().stream().mapToInt(RoomTrade::getCreditsByItem).sum()); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradingWaitingConfirmComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradingWaitingConfirmComposer.java new file mode 100644 index 0000000..40efd6c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/TradingWaitingConfirmComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.trading; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class TradingWaitingConfirmComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.TradingWaitingConfirmComposer); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/YouTradingDisabledComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/YouTradingDisabledComposer.java new file mode 100644 index 0000000..ddb06e5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/trading/YouTradingDisabledComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.trading; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class YouTradingDisabledComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.YouTradingDisabledComposer); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/BuildersClubExpiredComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/BuildersClubExpiredComposer.java new file mode 100644 index 0000000..1be029d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/BuildersClubExpiredComposer.java @@ -0,0 +1,18 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class BuildersClubExpiredComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.BuildersClubExpiredComposer); + this.response.appendInt(Integer.MAX_VALUE); + this.response.appendInt(0); + this.response.appendInt(100); + this.response.appendInt(Integer.MAX_VALUE); + this.response.appendInt(0); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/CloseWebPageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/CloseWebPageComposer.java new file mode 100644 index 0000000..a5b22a2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/CloseWebPageComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class CloseWebPageComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CloseWebPageComposer); + //Empty body + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/CompetitionEntrySubmitResultComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/CompetitionEntrySubmitResultComposer.java new file mode 100644 index 0000000..36db1a9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/CompetitionEntrySubmitResultComposer.java @@ -0,0 +1,41 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.List; + +public class CompetitionEntrySubmitResultComposer extends MessageComposer { + private final int unknownInt1; + private final String unknownString1; + private final int result; + private final List unknownStringList1; + private final List unknownStringList2; + + public CompetitionEntrySubmitResultComposer(int unknownInt1, String unknownString1, int result, List unknownStringList1, List unknownStringList2) { + this.unknownInt1 = unknownInt1; + this.unknownString1 = unknownString1; + this.result = result; + this.unknownStringList1 = unknownStringList1; + this.unknownStringList2 = unknownStringList2; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.CompetitionEntrySubmitResultComposer); + this.response.appendInt(this.unknownInt1); + this.response.appendString(this.unknownString1); + this.response.appendInt(this.result); + this.response.appendInt(this.unknownStringList1.size()); + for (String s : this.unknownStringList1) { + this.response.appendString(s); + } + + this.response.appendInt(this.unknownStringList2.size()); + for (String s : this.unknownStringList2) { + this.response.appendString(s); + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ConvertedForwardToRoomComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ConvertedForwardToRoomComposer.java new file mode 100644 index 0000000..c36eb9f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ConvertedForwardToRoomComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ConvertedForwardToRoomComposer extends MessageComposer { + private final String unknownString1; + private final int unknownInt1; + + public ConvertedForwardToRoomComposer(String unknownString1, int unknownInt1) { + this.unknownString1 = unknownString1; + this.unknownInt1 = unknownInt1; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ConvertedForwardToRoomComposer); + this.response.appendString(this.unknownString1); + this.response.appendInt(this.unknownInt1); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/EpicPopupFrameComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/EpicPopupFrameComposer.java new file mode 100644 index 0000000..0fc2e05 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/EpicPopupFrameComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class EpicPopupFrameComposer extends MessageComposer { + public static final String LIBRARY_URL = "${image.library.url}"; + private final String assetURI; + + public EpicPopupFrameComposer(String assetURI) { + this.assetURI = assetURI; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.EpicPopupFrameComposer); + this.response.appendString(this.assetURI); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ErrorLoginComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ErrorLoginComposer.java new file mode 100644 index 0000000..80546dd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ErrorLoginComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ErrorLoginComposer extends MessageComposer { + private final int errorCode; + + public ErrorLoginComposer(int errorCode) { + this.errorCode = errorCode; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ErrorLoginComposer); + this.response.appendInt(this.errorCode); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ExtendClubMessageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ExtendClubMessageComposer.java new file mode 100644 index 0000000..8225c51 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ExtendClubMessageComposer.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.habbohotel.catalog.ClubOffer; +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.Outgoing; + +public class ExtendClubMessageComposer extends MessageComposer { + private final Habbo habbo; + private final ClubOffer offer; + private final int normalCreditCost; + private final int normalPointsCost; + private final int pointsType; + private final int daysRemaining; + + public ExtendClubMessageComposer(Habbo habbo, ClubOffer offer, int normalCreditCost, int normalPointsCost, int pointsType, int daysRemaining) { + this.habbo = habbo; + this.offer = offer; + this.normalCreditCost = normalCreditCost; + this.normalPointsCost = normalPointsCost; + this.pointsType = pointsType; + this.daysRemaining = daysRemaining; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ExtendClubMessageComposer); + this.offer.serialize(this.response, this.habbo.getHabboStats().getClubExpireTimestamp()); + + this.response.appendInt(this.normalCreditCost); + this.response.appendInt(this.normalPointsCost); + this.response.appendInt(this.pointsType); + this.response.appendInt(this.daysRemaining); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/HabboMallComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/HabboMallComposer.java new file mode 100644 index 0000000..770fdfe --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/HabboMallComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class HabboMallComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.HabboMallComposer); + //Empty body + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/IgnoredUsersComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/IgnoredUsersComposer.java new file mode 100644 index 0000000..6762d80 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/IgnoredUsersComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class IgnoredUsersComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.IgnoredUsersComposer); + this.response.appendInt(0); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/MessengerErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/MessengerErrorComposer.java new file mode 100644 index 0000000..c16dee3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/MessengerErrorComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.Map; + +public class MessengerErrorComposer extends MessageComposer { + private final Map errors; + + public MessengerErrorComposer(Map errors) { + this.errors = errors; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MessengerErrorComposer); + this.response.appendInt(this.errors.size()); + for (Map.Entry entry : this.errors.entrySet()) { + this.response.appendInt(entry.getKey()); + this.response.appendInt(entry.getValue()); + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/MinimailNewMessageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/MinimailNewMessageComposer.java new file mode 100644 index 0000000..d9534a7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/MinimailNewMessageComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class MinimailNewMessageComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MinimailNewMessageComposer); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ModToolComposerOne.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ModToolComposerOne.java new file mode 100644 index 0000000..56bba68 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ModToolComposerOne.java @@ -0,0 +1,15 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ModToolComposerOne extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ModToolComposerOne); + + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ModToolSanctionDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ModToolSanctionDataComposer.java new file mode 100644 index 0000000..4cce883 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/ModToolSanctionDataComposer.java @@ -0,0 +1,55 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ISerialize; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class ModToolSanctionDataComposer extends MessageComposer { + private final int unknownInt1; + private final int accountId; + private final CFHSanction sanction; + + public ModToolSanctionDataComposer(int unknownInt1, int accountId, CFHSanction sanction) { + this.unknownInt1 = unknownInt1; + this.accountId = accountId; + this.sanction = sanction; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ModToolSanctionDataComposer); + this.response.appendInt(this.unknownInt1); + this.response.appendInt(this.accountId); + this.sanction.serialize(this.response); + return this.response; + } + + public static class CFHSanction implements ISerialize { + private final String name; + private final int length; + private final int unknownInt1; + private final boolean avatarOnly; + private final String tradelockInfo; + private final String machineBanInfo; + + public CFHSanction(String name, int length, int unknownInt1, boolean avatarOnly, String tradelockInfo, String machineBanInfo) { + this.name = name; + this.length = length; + this.unknownInt1 = unknownInt1; + this.avatarOnly = avatarOnly; + this.tradelockInfo = tradelockInfo; + this.machineBanInfo = machineBanInfo; + } + + @Override + public void serialize(ServerMessage message) { + message.appendString(this.name); + message.appendInt(this.length); + message.appendInt(this.unknownInt1); + message.appendBoolean(this.avatarOnly); + message.appendString(this.tradelockInfo); + message.appendString(this.machineBanInfo); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/MostUselessErrorAlertComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/MostUselessErrorAlertComposer.java new file mode 100644 index 0000000..6597827 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/MostUselessErrorAlertComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class MostUselessErrorAlertComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MostUselessErrorAlertComposer); + //EMpty Body + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/MysteryPrizeComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/MysteryPrizeComposer.java new file mode 100644 index 0000000..d80cf1f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/MysteryPrizeComposer.java @@ -0,0 +1,19 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class MysteryPrizeComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(427); + this.response.appendString("s"); + this.response.appendInt(230); + return this.response; + + //s -> floorItem. -> itemId + //i -> wallItem. -> itemId + //e -> effect -> effectId + //h -> HabboClub -> 0 + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RemoveRoomEventComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RemoveRoomEventComposer.java new file mode 100644 index 0000000..1f052d5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RemoveRoomEventComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RemoveRoomEventComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RemoveRoomEventComposer); + //Empty Body + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RentableItemBuyOutPriceComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RentableItemBuyOutPriceComposer.java new file mode 100644 index 0000000..75b5f6d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RentableItemBuyOutPriceComposer.java @@ -0,0 +1,35 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RentableItemBuyOutPriceComposer extends MessageComposer { + private final boolean unknownBoolean1; + private final String unknownString1; + private final boolean unknownBoolean2; + private final int credits; + private final int points; + private final int pointsType; + + public RentableItemBuyOutPriceComposer(boolean unknownBoolean1, String unknownString1, boolean unknownBoolean2, int credits, int points, int pointsType) { + this.unknownBoolean1 = unknownBoolean1; + this.unknownString1 = unknownString1; + this.unknownBoolean2 = unknownBoolean2; + this.credits = credits; + this.points = points; + this.pointsType = pointsType; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RentableItemBuyOutPriceComposer); + this.response.appendBoolean(this.unknownBoolean1); + this.response.appendString(this.unknownString1); + this.response.appendBoolean(this.unknownBoolean2); + this.response.appendInt(this.credits); + this.response.appendInt(this.points); + this.response.appendInt(this.pointsType); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomAdErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomAdErrorComposer.java new file mode 100644 index 0000000..0fb0752 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomAdErrorComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomAdErrorComposer extends MessageComposer { + private final int errorCode; + private final String unknownString; + + public RoomAdErrorComposer(int errorCode, String unknownString) { + this.errorCode = errorCode; + this.unknownString = unknownString; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomAdErrorComposer); + this.response.appendInt(this.errorCode); + this.response.appendString(this.unknownString); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomCategoryUpdateMessageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomCategoryUpdateMessageComposer.java new file mode 100644 index 0000000..a726d90 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomCategoryUpdateMessageComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomCategoryUpdateMessageComposer extends MessageComposer { + private final int unknownInt1; + + public RoomCategoryUpdateMessageComposer(int unknownInt1) { + this.unknownInt1 = unknownInt1; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomCategoryUpdateMessageComposer); + this.response.appendInt(this.unknownInt1); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomMessagesPostedCountComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomMessagesPostedCountComposer.java new file mode 100644 index 0000000..8a269fe --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomMessagesPostedCountComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomMessagesPostedCountComposer extends MessageComposer { + private final Room room; + private final int count; + + public RoomMessagesPostedCountComposer(Room room, int count) { + this.room = room; + this.count = count; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomMessagesPostedCountComposer); + this.response.appendInt(this.room.getId()); + this.response.appendString(this.room.getName()); + this.response.appendInt(this.count); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomUnknown3Composer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomUnknown3Composer.java new file mode 100644 index 0000000..0965e3e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomUnknown3Composer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class RoomUnknown3Composer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUnknown3Composer); + //Empty body + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomUserQuestionAnsweredComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomUserQuestionAnsweredComposer.java new file mode 100644 index 0000000..3bd9a87 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/RoomUserQuestionAnsweredComposer.java @@ -0,0 +1,32 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.Map; + +public class RoomUserQuestionAnsweredComposer extends MessageComposer { + private final int userId; + private final String value; + private final Map unknownMap; + + public RoomUserQuestionAnsweredComposer(int userId, String value, Map unknownMap) { + this.userId = userId; + this.value = value; + this.unknownMap = unknownMap; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.RoomUserQuestionAnsweredComposer); + this.response.appendInt(this.userId); + this.response.appendString(this.value); + this.response.appendInt(this.unknownMap.size()); + for (Map.Entry entry : this.unknownMap.entrySet()) { + this.response.appendString(entry.getKey()); + this.response.appendInt(entry.getValue()); + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsAddUserComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsAddUserComposer.java new file mode 100644 index 0000000..a05f934 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsAddUserComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsAddUserComposer extends MessageComposer { + + @Override + protected ServerMessage composeInternal() { + this.response.init(1880); + this.response.appendInt(3); + this.response.appendString("Derpface"); + this.response.appendString("ca-1807-64.lg-275-78.hd-3093-1.hr-802-42.ch-3110-65-62.fa-1211-63"); + this.response.appendString("m"); + this.response.appendInt(-1); //Team Id + this.response.appendInt(0); //Stars + this.response.appendInt(0); //Points + this.response.appendInt(10); //Points for next lvl + this.response.appendBoolean(false); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsCompose1.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsCompose1.java new file mode 100644 index 0000000..5dcdc02 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsCompose1.java @@ -0,0 +1,44 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsCompose1 extends MessageComposer { + private final int header; + + public SnowWarsCompose1(int header) { + this.header = header; + } + + //:test 1604 i:1 s:a i:10 i:2 i:3 i:4 s:1 i:3 i:10 i:1 s:Admin s:%look% s:M i:0 i:0 i:0 i:0 + @Override + protected ServerMessage composeInternal() { + this.response.init(this.header); + this.response.appendInt(1); + this.response.appendString("SnowStorm level " + 9); + this.response.appendInt(0); //Stage ID + this.response.appendInt(9); + this.response.appendInt(4); + this.response.appendInt(8); + this.response.appendString("Admin"); + this.response.appendInt(14); + this.response.appendInt(2); + this.response.appendInt(1); + this.response.appendString("Admin"); + this.response.appendString("ca-1807-64.lg-275-78.hd-3093-1.hr-802-42.ch-3110-65-62.fa-1211-62"); + this.response.appendString("m"); + this.response.appendInt(1); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(10); + this.response.appendInt(2); + this.response.appendString("Droppy"); + this.response.appendString("ca-1807-64.lg-275-78.hd-3093-1.hr-802-42.ch-3110-65-62.fa-1211-62"); + this.response.appendString("m"); + this.response.appendInt(2); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(10); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsFullGameStatusComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsFullGameStatusComposer.java new file mode 100644 index 0000000..c92b41d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsFullGameStatusComposer.java @@ -0,0 +1,36 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsFullGameStatusComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(0); + this.response.appendInt(0); //Unused + this.response.appendInt(0); + this.response.appendInt(0); + + //SnowWarGameObjectData + this.response.appendInt(1); //Count + //{ + this.response.appendInt(3); //type + this.response.appendInt(1); //id? + + this.response.appendInt(1); //variable + this.response.appendInt(1); //variable + this.response.appendInt(1); //variable + this.response.appendInt(1); //variable + this.response.appendInt(1); //variable + this.response.appendInt(1); //variable + this.response.appendInt(1); //variable + + //1: -> 11 variables. + //4: -> 8 variables. + //3: -> 7 variables. + //5: -> 19 variables. + //2: -> 9 variables. + //} + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsGameStartedErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsGameStartedErrorComposer.java new file mode 100644 index 0000000..ebe60a7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsGameStartedErrorComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsGameStartedErrorComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(2860); + this.response.appendInt(1); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsGenericErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsGenericErrorComposer.java new file mode 100644 index 0000000..ffb6698 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsGenericErrorComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsGenericErrorComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(3702); + this.response.appendInt(1); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsInitGameArena.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsInitGameArena.java new file mode 100644 index 0000000..c9b2339 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsInitGameArena.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsInitGameArena extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(3924); + this.response.appendInt(0); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsJoinErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsJoinErrorComposer.java new file mode 100644 index 0000000..326a0d5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsJoinErrorComposer.java @@ -0,0 +1,17 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsJoinErrorComposer extends MessageComposer { + public static final int ERROR_HAS_ACTIVE_INSTANCE = 6; + public static final int ERROR_NO_FREE_GAMES_LEFT = 8; + public static final int ERROR_DUPLICATE_MACHINE_ID = 2; + + @Override + protected ServerMessage composeInternal() { + this.response.init(1437); + this.response.appendInt(2); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsLevelDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsLevelDataComposer.java new file mode 100644 index 0000000..f92e3f5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsLevelDataComposer.java @@ -0,0 +1,87 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsLevelDataComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(3874); + this.response.appendInt(0); + this.response.appendInt(10); //MapID + this.response.appendInt(2); + this.response.appendInt(2); + + this.response.appendInt(0); //PlayerID + this.response.appendString("Admin"); + this.response.appendString("ca-1807-64.lg-275-78.hd-3093-1.hr-802-42.ch-3110-65-62.fa-1211-62"); + this.response.appendString("m"); + this.response.appendInt(1); + + this.response.appendInt(1); //PlayerID + this.response.appendString("Droppy"); + this.response.appendString("ca-1807-64.lg-275-78.hd-3093-1.hr-802-42.ch-3110-65-62.fa-1211-62"); + this.response.appendString("m"); + this.response.appendInt(2); + + this.response.appendInt(50); + this.response.appendInt(1); + + this.response.appendString("00000000000000000000000000000000000000000000000000" + (char) 13 + + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxx000000000000000xxxxxxxxxxxxxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxx00000000000000000xxxxxxxxxxxxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxx0000000000000000000xxxxxxxxxxxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxx000000000000000000000xxxxxxxxxxxxxxxxxx" + (char) 13 + + "xxxxxxxxxx00000000000000000000000xxxxxxxxxxxxxxxxx" + (char) 13 + + "xxxxxxxxx0000000000000000000000000xxxxxxxxxxxxxxxx" + (char) 13 + + "xxxxxxxx000000000000000000000000000xxxxxxxxxxxxxxx" + (char) 13 + + "xxxxxxx00000000000000000000000000000xxxxxxxxxxxxxx" + (char) 13 + + "xxxxxx0000000000000000000000000000000xxxxxxxxxxxxx" + (char) 13 + + "xxxxx000000000000000000000000000000000xxxxxxxxxxxx" + (char) 13 + + "xxxxx0000000000000000000000000000000000xxxxxxxxxxx" + (char) 13 + + "xxxxx00000000000000000000000000000000000xxxxxxxxxx" + (char) 13 + + "xxxxx000000000000000000000000000000000000xxxxxxxxx" + (char) 13 + + "xxxxx0000000000000000000000000000000000000xxxxxxxx" + (char) 13 + + "xxxxx00000000000000000000000000000000000000xxxxxxx" + (char) 13 + + "xxxxx000000000000000000000000000000000000000xxxxxx" + (char) 13 + + "xxxxx0000000000000000000000000000000000000000xxxxx" + (char) 13 + + "0xxxx00000000000000000000000000000000000000000xxxx" + (char) 13 + + "xxxxx00000000000000000000000000000000000000000xxxx" + (char) 13 + + "xxxxx00000000000000000000000000000000000000000xxxx" + (char) 13 + + "xxxxx000000000000000000000000000000000000000000xxx" + (char) 13 + + "xxxxx000000000000000000000000000000000000000000xxx" + (char) 13 + + "xxxxx000000000000000000000000000000000000000000xxx" + (char) 13 + + "xxxxxx00000000000000000000000000000000000000000xxx" + (char) 13 + + "xxxxxxx0000000000000000000000000000000000000000xxx" + (char) 13 + + "xxxxxxxx0000000000000000000000000000000000000xxxxx" + (char) 13 + + "xxxxxxxxx00000000000000000000000000000000000xxxxxx" + (char) 13 + + "xxxxxxxxxx000000000000000000000000000000000xxxxxxx" + (char) 13 + + "xxxxxxxxxxx00000000000000000000000000000000xxxx0xx" + (char) 13 + + "xxxxxxxxxxxx0000000000000000000000000000000xxxxxxx" + (char) 13 + + "xxxxxxxxxxxxx00000000000000000000000000000xxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxx0000000000000000000000000000xxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxxx00000000000000000000000000xxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxxxx0000000000000000000000000xxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxxxxx00000000000000000000000xxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxxxxxx0000000000000000000000xxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxxxxxxx00000000000000000000xxxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxxxxxxxxxxx000000000000000xxxxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxxxxxxxxxxxx0000000000000xxxxxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxxxxxxxxxxxxx00000000000xxxxxxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxxxxxxxxxxxxxx0000000xxxxxxxxxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + (char) 13 + + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); + + this.response.appendInt(0); + //{ + //} + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsLoadingArenaComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsLoadingArenaComposer.java new file mode 100644 index 0000000..d6f11a4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsLoadingArenaComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsLoadingArenaComposer extends MessageComposer { + private final int count; + + public SnowWarsLoadingArenaComposer(int count) { + this.count = count; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(3850); + this.response.appendInt(this.count); //GameID? + this.response.appendInt(0); //Count + //this.response.appendInt(1); //ItemID to dispose? + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsLongDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsLongDataComposer.java new file mode 100644 index 0000000..bcd2071 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsLongDataComposer.java @@ -0,0 +1,39 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsLongDataComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(2823); + this.response.appendInt(1); + this.response.appendString("SnowStorm level " + 10); + this.response.appendInt(10); //Stage ID + this.response.appendInt(10); + this.response.appendInt(4); + this.response.appendInt(8); + this.response.appendString("Admin"); + this.response.appendInt(14); + this.response.appendInt(2); + + this.response.appendInt(1); + this.response.appendString("Admin"); + this.response.appendString("ca-1807-64.lg-275-78.hd-3093-1.hr-802-42.ch-3110-65-62.fa-1211-62"); + this.response.appendString("m"); + this.response.appendInt(1); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(10); + + this.response.appendInt(2); + this.response.appendString("Emetophobic"); + this.response.appendString("ca-1807-64.lg-275-78.hd-3093-1.hr-802-42.ch-3110-65-62.fa-1211-63"); + this.response.appendString("m"); + this.response.appendInt(2); //Team Id + this.response.appendInt(0); //Stars + this.response.appendInt(0); //Points + this.response.appendInt(10); //Points for next lvl + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsOnGameEnding.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsOnGameEnding.java new file mode 100644 index 0000000..d071179 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsOnGameEnding.java @@ -0,0 +1,52 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsOnGameEnding extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(1893); + this.response.appendInt(0); //idk + + //Game2GameResult + this.response.appendBoolean(false); + this.response.appendInt(0); //resultType + this.response.appendInt(0); //result? + + this.response.appendInt(1); //Count + //{ + //Game2TeamScoreData + this.response.appendInt(1); //Team ID? + this.response.appendInt(100); //Score + + this.response.appendInt(1); //Count + //{ + //Game2TeamPlayerData + this.response.appendString("Admin"); //username + this.response.appendInt(1); //UserID + this.response.appendString("ca-1807-64.lg-275-78.hd-3093-1.hr-802-42.ch-3110-65-62.fa-1211-62"); //Look + this.response.appendString("m"); //GENDER + this.response.appendInt(1337); //Score + + //Game2PlayerStatsData + this.response.appendInt(1337); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + //} + //} + + //Game2SnowWarGameStats + this.response.appendInt(1337); + this.response.appendInt(1338); + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsOnStageEnding.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsOnStageEnding.java new file mode 100644 index 0000000..1de1d88 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsOnStageEnding.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsOnStageEnding extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(1140); + this.response.appendInt(1); //idk + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsOnStageRunningComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsOnStageRunningComposer.java new file mode 100644 index 0000000..b171aa2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsOnStageRunningComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsOnStageRunningComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(3832); + this.response.appendInt(120); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsOnStageStartComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsOnStageStartComposer.java new file mode 100644 index 0000000..0eb4f63 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsOnStageStartComposer.java @@ -0,0 +1,65 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsOnStageStartComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(889); + this.response.appendInt(0); + this.response.appendString("snowwar_arena_0"); + this.response.appendInt(0); + this.response.appendInt(2); //Count + + this.response.appendInt(5); + this.response.appendInt(1); + this.response.appendInt(64000); + this.response.appendInt(64000); + this.response.appendInt(20); + this.response.appendInt(24); + this.response.appendInt(1); + this.response.appendInt(100); + this.response.appendInt(4); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(20); + this.response.appendInt(24); + this.response.appendInt(64000); + this.response.appendInt(64000); + this.response.appendInt(0); + this.response.appendInt(1); + this.response.appendInt(1); + this.response.appendString("Admin"); + this.response.appendString("Motto"); + this.response.appendString("ca-1807-64.lg-275-78.hd-3093-1.hr-802-42.ch-3110-65-62.fa-1211-62"); + this.response.appendString("m"); + + this.response.appendInt(5); + this.response.appendInt(2); + this.response.appendInt(64000); + this.response.appendInt(64000); + this.response.appendInt(20); + this.response.appendInt(24); + this.response.appendInt(1); + this.response.appendInt(100); + this.response.appendInt(4); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(20); + this.response.appendInt(24); + this.response.appendInt(64000); + this.response.appendInt(64000); + this.response.appendInt(0); + this.response.appendInt(2); + this.response.appendInt(2); + this.response.appendString("Admin"); + this.response.appendString("Motto"); + this.response.appendString("ca-1807-64.lg-275-78.hd-3093-1.hr-802-42.ch-3110-65-62.fa-1211-62"); + this.response.appendString("m"); + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsPlayNowWindowComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsPlayNowWindowComposer.java new file mode 100644 index 0000000..80a9121 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsPlayNowWindowComposer.java @@ -0,0 +1,16 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsPlayNowWindowComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(2276); + this.response.appendInt(0); //status + this.response.appendInt(100); + this.response.appendInt(0); + this.response.appendInt(-1); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsPreviousRoomComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsPreviousRoomComposer.java new file mode 100644 index 0000000..51b8149 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsPreviousRoomComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsPreviousRoomComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(1381); + this.response.appendInt(1); //room Id + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsQuePositionComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsQuePositionComposer.java new file mode 100644 index 0000000..73ede10 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsQuePositionComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsQuePositionComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(2077); + this.response.appendInt(1); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsQuickJoinComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsQuickJoinComposer.java new file mode 100644 index 0000000..02aa00f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsQuickJoinComposer.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsQuickJoinComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(913); + this.response.appendInt(1); + this.response.appendString("SnowStorm level " + 9); + this.response.appendInt(0); //Stage ID + this.response.appendInt(9); + this.response.appendInt(2); + this.response.appendInt(10); + this.response.appendString("Admin"); + this.response.appendInt(0); + this.response.appendInt(2); + this.response.appendInt(1); + this.response.appendString("Admin"); + this.response.appendString("ca-1807-64.lg-275-78.hd-3093-1.hr-802-42.ch-3110-65-62.fa-1211-62"); + this.response.appendString("m"); + this.response.appendInt(-1); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(2); + this.response.appendString("Droppy"); + this.response.appendString("ca-1807-64.lg-275-78.hd-3093-1.hr-802-42.ch-3110-65-62.fa-1211-62"); + this.response.appendString("m"); + this.response.appendInt(-1); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsRemoveUserComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsRemoveUserComposer.java new file mode 100644 index 0000000..01263b5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsRemoveUserComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsRemoveUserComposer extends MessageComposer { + + @Override + protected ServerMessage composeInternal() { + this.response.init(2502); + this.response.appendInt(3); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsResetTimerComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsResetTimerComposer.java new file mode 100644 index 0000000..43336c3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsResetTimerComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsResetTimerComposer extends MessageComposer { + //SnowStageRunning? + @Override + protected ServerMessage composeInternal() { + this.response.init(294); + this.response.appendInt(100); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsStartLobbyCounter.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsStartLobbyCounter.java new file mode 100644 index 0000000..20fa8a5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsStartLobbyCounter.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsStartLobbyCounter extends MessageComposer { + + @Override + protected ServerMessage composeInternal() { + this.response.init(3757); + this.response.appendInt(5); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsUnknownComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsUnknownComposer.java new file mode 100644 index 0000000..1dcfe05 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsUnknownComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsUnknownComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(2869); + this.response.appendString("snowwar"); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendBoolean(true); + this.response.appendBoolean(true); + this.response.appendInt(0); + this.response.appendInt(0); + this.response.appendInt(0); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsUserChatComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsUserChatComposer.java new file mode 100644 index 0000000..d9268e5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsUserChatComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsUserChatComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(2049); + this.response.appendInt(1); //UserID + this.response.appendString("Message"); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsUserEnteredArenaComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsUserEnteredArenaComposer.java new file mode 100644 index 0000000..4bd4de9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsUserEnteredArenaComposer.java @@ -0,0 +1,32 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsUserEnteredArenaComposer extends MessageComposer { + private final int type; + + public SnowWarsUserEnteredArenaComposer(int type) { + this.type = type; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(3425); + + if (this.type == 1) { + this.response.appendInt(1); //userId + this.response.appendString("Admin"); + this.response.appendString("ca-1807-64.lg-275-78.hd-3093-1.hr-802-42.ch-3110-65-62.fa-1211-62"); + this.response.appendString("m"); + this.response.appendInt(1); //team + } else { + this.response.appendInt(0); //userId + this.response.appendString("Droppy"); + this.response.appendString("ca-1807-64.lg-275-78.hd-3093-1.hr-802-42.ch-3110-65-62.fa-1211-62"); + this.response.appendString("m"); + this.response.appendInt(2); //team + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsUserExitArenaComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsUserExitArenaComposer.java new file mode 100644 index 0000000..1962c13 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/SnowWarsUserExitArenaComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; + +public class SnowWarsUserExitArenaComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(3811); + this.response.appendInt(1); //userId + this.response.appendInt(1); //IDK ? TEAM? + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/TalentTrackEmailFailedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/TalentTrackEmailFailedComposer.java new file mode 100644 index 0000000..efcabe5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/TalentTrackEmailFailedComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class TalentTrackEmailFailedComposer extends MessageComposer { + private final int result; + + public TalentTrackEmailFailedComposer(int result) { + this.result = result; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.TalentTrackEmailFailedComposer); + this.response.appendInt(this.result); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/TalentTrackEmailVerifiedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/TalentTrackEmailVerifiedComposer.java new file mode 100644 index 0000000..119a0b3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/TalentTrackEmailVerifiedComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class TalentTrackEmailVerifiedComposer extends MessageComposer { + private final String email; + private final boolean unknownB1; + private final boolean unknownB2; + + public TalentTrackEmailVerifiedComposer(String email, boolean unknownB1, boolean unknownB2) { + this.email = email; + this.unknownB1 = unknownB1; + this.unknownB2 = unknownB2; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.TalentTrackEmailVerifiedComposer); + this.response.appendString(this.email); + this.response.appendBoolean(this.unknownB1); + this.response.appendBoolean(this.unknownB2); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownAdManagerComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownAdManagerComposer.java new file mode 100644 index 0000000..d690e8a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownAdManagerComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UnknownAdManagerComposer extends MessageComposer { + private final boolean unknownBoolean; + + public UnknownAdManagerComposer(boolean unknownBoolean) { + this.unknownBoolean = unknownBoolean; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownAdManagerComposer); + this.response.appendBoolean(this.unknownBoolean); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownAvatarEditorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownAvatarEditorComposer.java new file mode 100644 index 0000000..5ff0d0c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownAvatarEditorComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UnknownAvatarEditorComposer extends MessageComposer { + private final int type; + + public UnknownAvatarEditorComposer(int type) { + this.type = type; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownAvatarEditorComposer); + this.response.appendInt(this.type); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownCatalogPageOfferComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownCatalogPageOfferComposer.java new file mode 100644 index 0000000..0ce8fbd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownCatalogPageOfferComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UnknownCatalogPageOfferComposer extends MessageComposer { + private final int pageId; + private final CatalogItem catalogItem; + + public UnknownCatalogPageOfferComposer(int pageId, CatalogItem catalogItem) { + this.pageId = pageId; + this.catalogItem = catalogItem; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownCatalogPageOfferComposer); + this.response.appendInt(this.pageId); + this.catalogItem.serialize(this.response); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownCompetitionComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownCompetitionComposer.java new file mode 100644 index 0000000..903e322 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownCompetitionComposer.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UnknownCompetitionComposer extends MessageComposer { + private final int unknownInt1; + private final String unknownString1; + private final int unknownInt2; + private final int unknownInt3; + + public UnknownCompetitionComposer(int unknownInt1, String unknownString1, int unknownInt2, int unknownInt3) { + this.unknownInt1 = unknownInt1; + this.unknownString1 = unknownString1; + this.unknownInt2 = unknownInt2; + this.unknownInt3 = unknownInt3; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownCompetitionComposer); + this.response.appendInt(this.unknownInt1); + this.response.appendString(this.unknownString1); + this.response.appendInt(this.unknownInt2); + this.response.appendInt(this.unknownInt3); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownComposer4.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownComposer4.java new file mode 100644 index 0000000..780db47 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownComposer4.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UnknownComposer4 extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.IsFirstLoginOfDayComposer); + this.response.appendBoolean(false); //Think something related to promo. Not sure though. + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownComposer8.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownComposer8.java new file mode 100644 index 0000000..99417c9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownComposer8.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UnknownComposer8 extends MessageComposer { + private final int unknownInt1; + private final int userId; + private final int unknownInt2; + + public UnknownComposer8(int unknownInt1, int userId, int unknownInt2) { + this.unknownInt1 = unknownInt1; + this.userId = userId; + this.unknownInt2 = unknownInt2; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownComposer8); + this.response.appendInt(this.unknownInt1); + this.response.appendInt(this.userId); + this.response.appendInt(this.unknownInt2); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownFurniModelComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownFurniModelComposer.java new file mode 100644 index 0000000..e4c3d62 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownFurniModelComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UnknownFurniModelComposer extends MessageComposer { + private final HabboItem item; + private final int unknownInt; + + public UnknownFurniModelComposer(HabboItem item, int unknownInt) { + this.item = item; + this.unknownInt = unknownInt; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownFurniModelComposer); + this.response.appendInt(this.item.getId()); + this.response.appendInt(this.unknownInt); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownGuild2Composer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownGuild2Composer.java new file mode 100644 index 0000000..dab7e51 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownGuild2Composer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UnknownGuild2Composer extends MessageComposer { + private final int guildId; + + public UnknownGuild2Composer(int guildId) { + this.guildId = guildId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownGuild2Composer); + this.response.appendInt(this.guildId); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownGuildComposer3.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownGuildComposer3.java new file mode 100644 index 0000000..c82577c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownGuildComposer3.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UnknownGuildComposer3 extends MessageComposer { + private final int userId; + + public UnknownGuildComposer3(int userId) { + this.userId = userId; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownGuildComposer3); + this.response.appendInt(this.userId); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownHabboWayQuizComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownHabboWayQuizComposer.java new file mode 100644 index 0000000..5c1a6b0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownHabboWayQuizComposer.java @@ -0,0 +1,28 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.List; + +public class UnknownHabboWayQuizComposer extends MessageComposer { + private final String unknownString; + private final List unknownIntegerList; + + public UnknownHabboWayQuizComposer(String unknownString, List unknownIntegerList) { + this.unknownString = unknownString; + this.unknownIntegerList = unknownIntegerList; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownHabboWayQuizComposer); + this.response.appendString(this.unknownString); + this.response.appendInt(this.unknownIntegerList.size()); + for (Integer i : this.unknownIntegerList) { + this.response.appendInt(i); + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownHelperComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownHelperComposer.java new file mode 100644 index 0000000..ed2f410 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownHelperComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UnknownHelperComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownHelperComposer); + //Empty body + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownHintComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownHintComposer.java new file mode 100644 index 0000000..82ff7d2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownHintComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UnknownHintComposer extends MessageComposer { + private final String key; + + public UnknownHintComposer(String key) { + this.key = key; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownHintComposer); + this.response.appendString(this.key); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownMessengerErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownMessengerErrorComposer.java new file mode 100644 index 0000000..5f62eec --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownMessengerErrorComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UnknownMessengerErrorComposer extends MessageComposer { + private final int errorCode; + private final int userId; + private final String message; + + public UnknownMessengerErrorComposer(int errorCode, int userId, String message) { + this.errorCode = errorCode; + this.userId = userId; + this.message = message; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownMessengerErrorComposer); + this.response.appendInt(this.errorCode); + this.response.appendInt(this.userId); + this.response.appendString(this.message); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownPollQuestionComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownPollQuestionComposer.java new file mode 100644 index 0000000..6170514 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownPollQuestionComposer.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.Map; + +public class UnknownPollQuestionComposer extends MessageComposer { + private final int unknownInt; + private final Map unknownMap; + + public UnknownPollQuestionComposer(int unknownInt, Map unknownMap) { + this.unknownInt = unknownInt; + this.unknownMap = unknownMap; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.SimplePollAnswersComposer); + this.response.appendInt(this.unknownInt); + this.response.appendInt(this.unknownMap.size()); + for (Map.Entry entry : this.unknownMap.entrySet()) { + this.response.appendString(entry.getKey()); + this.response.appendInt(entry.getValue()); + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownRoomDesktopComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownRoomDesktopComposer.java new file mode 100644 index 0000000..d535af2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownRoomDesktopComposer.java @@ -0,0 +1,29 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.Map; + +public class UnknownRoomDesktopComposer extends MessageComposer { + private final int unknownInt1; + private final Map unknownMap; + + public UnknownRoomDesktopComposer(int unknownInt1, Map unknownMap) { + this.unknownInt1 = unknownInt1; + this.unknownMap = unknownMap; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownRoomDesktopComposer); + this.response.appendInt(this.unknownInt1); + this.response.appendInt(this.unknownMap.size()); + for (Map.Entry entry : this.unknownMap.entrySet()) { + this.response.appendInt(entry.getKey()); + this.response.appendString(entry.getValue()); + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownRoomViewerComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownRoomViewerComposer.java new file mode 100644 index 0000000..703a08e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownRoomViewerComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.Map; + +public class UnknownRoomViewerComposer extends MessageComposer { + private final Map unknownMap; + + public UnknownRoomViewerComposer(Map unknownMap) { + this.unknownMap = unknownMap; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownRoomViewerComposer); + this.response.appendInt(this.unknownMap.size()); + for (Map.Entry entry : this.unknownMap.entrySet()) { + this.response.appendInt(entry.getKey()); + this.response.appendString(entry.getValue()); + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownStatusComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownStatusComposer.java new file mode 100644 index 0000000..cfa8c30 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownStatusComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UnknownStatusComposer extends MessageComposer { + public final int STATUS_ZERO = 0; + public final int STATUS_ONE = 1; + + private final int status; + + public UnknownStatusComposer(int status) { + this.status = status; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownStatusComposer); + this.response.appendInt(this.status); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownTradeComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownTradeComposer.java new file mode 100644 index 0000000..052655e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownTradeComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UnknownTradeComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownTradeComposer); + //Empty Body + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnkownPetPackageComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnkownPetPackageComposer.java new file mode 100644 index 0000000..337951a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnkownPetPackageComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.Map; + +public class UnkownPetPackageComposer extends MessageComposer { + private final Map unknownMap; + + public UnkownPetPackageComposer(Map unknownMap) { + this.unknownMap = unknownMap; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnkownPetPackageComposer); + this.response.appendInt(this.unknownMap.size()); + for (Map.Entry entry : this.unknownMap.entrySet()) { + this.response.appendString(entry.getKey()); + this.response.appendString(entry.getValue()); + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UserClassificationComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UserClassificationComposer.java new file mode 100644 index 0000000..f7c3213 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/UserClassificationComposer.java @@ -0,0 +1,28 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import org.apache.commons.math3.util.Pair; + +import java.util.List; + +public class UserClassificationComposer extends MessageComposer { + private final List>> info; + + public UserClassificationComposer(List>> info) { + this.info = info; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserClassificationComposer); + this.response.appendInt(this.info.size()); + for (Pair> set : this.info) { + this.response.appendInt(set.getKey()); + this.response.appendString(set.getValue().getKey()); + this.response.appendString(set.getValue().getValue()); + } + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/VipTutorialsStartComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/VipTutorialsStartComposer.java new file mode 100644 index 0000000..3c2412c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/VipTutorialsStartComposer.java @@ -0,0 +1,14 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class VipTutorialsStartComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.VipTutorialsStartComposer); + //Empty Body + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/WatchAndEarnRewardComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/WatchAndEarnRewardComposer.java new file mode 100644 index 0000000..06dd2b9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/WatchAndEarnRewardComposer.java @@ -0,0 +1,24 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class WatchAndEarnRewardComposer extends MessageComposer { + private final Item item; + + public WatchAndEarnRewardComposer(Item item) { + this.item = item; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.WatchAndEarnRewardComposer); + this.response.appendString(this.item.getType().code); + this.response.appendInt(this.item.getId()); + this.response.appendString(this.item.getName()); + this.response.appendString(this.item.getFullName()); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/WelcomeGiftComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/WelcomeGiftComposer.java new file mode 100644 index 0000000..8345ec6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/WelcomeGiftComposer.java @@ -0,0 +1,32 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class WelcomeGiftComposer extends MessageComposer { + private final String email; + private final boolean unknownB1; + private final boolean unknownB2; + private final int furniId; + private final boolean unknownB3; + + public WelcomeGiftComposer(String email, boolean unknownB1, boolean unknownB2, int furniId, boolean unknownB3) { + this.email = email; + this.unknownB1 = unknownB1; + this.unknownB2 = unknownB2; + this.furniId = furniId; + this.unknownB3 = unknownB3; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.WelcomeGiftComposer); + this.response.appendString(this.email); + this.response.appendBoolean(this.unknownB1); + this.response.appendBoolean(this.unknownB2); + this.response.appendInt(this.furniId); + this.response.appendBoolean(this.unknownB3); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/WelcomeGiftErrorComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/WelcomeGiftErrorComposer.java new file mode 100644 index 0000000..afb1fde --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/unknown/WelcomeGiftErrorComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.unknown; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class WelcomeGiftErrorComposer extends MessageComposer { + public final static int EMAIL_INVALID = 0; + public final static int EMAIL_LENGTH_EXCEEDED = 1; + public final static int EMAIL_IN_USE = 3; + public final static int EMAIL_LIMIT_CHANGE = 4; + + private final int error; + + public WelcomeGiftErrorComposer(int error) { + this.error = error; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.WelcomeGiftErrorComposer); + this.response.appendInt(this.error); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/AddUserBadgeComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/AddUserBadgeComposer.java new file mode 100644 index 0000000..7074188 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/AddUserBadgeComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class AddUserBadgeComposer extends MessageComposer { + private final HabboBadge badge; + + public AddUserBadgeComposer(HabboBadge badge) { + this.badge = badge; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.AddUserBadgeComposer); + this.response.appendInt(this.badge.getId()); + this.response.appendString(this.badge.getCode()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/ChangeNameCheckResultComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/ChangeNameCheckResultComposer.java new file mode 100644 index 0000000..e451a88 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/ChangeNameCheckResultComposer.java @@ -0,0 +1,38 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.List; + +public class ChangeNameCheckResultComposer extends MessageComposer { + public static final int AVAILABLE = 0; + public static final int TOO_SHORT = 2; + public static final int TOO_LONG = 3; + public static final int NOT_VALID = 4; + public static final int TAKEN_WITH_SUGGESTIONS = 5; + public static final int DISABLED = 6; + + private final int status; + private final String name; + private final List suggestions; + + public ChangeNameCheckResultComposer(int status, String name, List suggestions) { + this.status = status; + this.name = name; + this.suggestions = suggestions; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UnknownComposer_2698); + this.response.appendInt(this.status); + this.response.appendString(this.name); + this.response.appendInt(this.suggestions.size()); + for (String suggestion : this.suggestions) { + this.response.appendString(suggestion); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/ClubGiftReceivedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/ClubGiftReceivedComposer.java new file mode 100644 index 0000000..de0755f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/ClubGiftReceivedComposer.java @@ -0,0 +1,32 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import gnu.trove.set.hash.THashSet; + +public class ClubGiftReceivedComposer extends MessageComposer { + //:test 735 s:t i:1 s:s i:230 s:throne i:1 b:1 i:1 i:10; + private final String name; + private final THashSet items; + + public ClubGiftReceivedComposer(String name, THashSet items) { + this.name = name; + this.items = items; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.ClubGiftReceivedComposer); + + this.response.appendString(this.name); + this.response.appendInt(this.items.size()); + + for (Item item : this.items) { + item.serialize(this.response); + } + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/FavoriteRoomsCountComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/FavoriteRoomsCountComposer.java new file mode 100644 index 0000000..36f4c4e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/FavoriteRoomsCountComposer.java @@ -0,0 +1,31 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.Emulator; +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.Outgoing; +import gnu.trove.procedure.TIntProcedure; + +public class FavoriteRoomsCountComposer extends MessageComposer { + private final Habbo habbo; + + public FavoriteRoomsCountComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.FavoriteRoomsCountComposer); + this.response.appendInt(Emulator.getConfig().getInt("hotel.rooms.max.favorite")); + this.response.appendInt(this.habbo.getHabboStats().getFavoriteRooms().size()); + this.habbo.getHabboStats().getFavoriteRooms().forEach(new TIntProcedure() { + @Override + public boolean execute(int value) { + FavoriteRoomsCountComposer.this.response.appendInt(value); + return true; + } + }); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/MeMenuSettingsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/MeMenuSettingsComposer.java new file mode 100644 index 0000000..73b2d1d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/MeMenuSettingsComposer.java @@ -0,0 +1,28 @@ +package com.eu.habbo.messages.outgoing.users; + +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.Outgoing; + +public class MeMenuSettingsComposer extends MessageComposer { + private final Habbo habbo; + + public MeMenuSettingsComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MeMenuSettingsComposer); + this.response.appendInt(this.habbo.getHabboStats().volumeSystem); + this.response.appendInt(this.habbo.getHabboStats().volumeFurni); + this.response.appendInt(this.habbo.getHabboStats().volumeTrax); + this.response.appendBoolean(this.habbo.getHabboStats().preferOldChat); + this.response.appendBoolean(this.habbo.getHabboStats().blockRoomInvites); + this.response.appendBoolean(this.habbo.getHabboStats().blockCameraFollow); + this.response.appendInt(this.habbo.getHabboStats().uiFlags); + this.response.appendInt(this.habbo.getHabboStats().chatColor.getType()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/MutedWhisperComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/MutedWhisperComposer.java new file mode 100644 index 0000000..1db3310 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/MutedWhisperComposer.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class MutedWhisperComposer extends MessageComposer { + private final int seconds; + + public MutedWhisperComposer(int seconds) { + this.seconds = seconds; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.MutedWhisperComposer); + this.response.appendInt(this.seconds); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/ProfileFriendsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/ProfileFriendsComposer.java new file mode 100644 index 0000000..acb7700 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/ProfileFriendsComposer.java @@ -0,0 +1,108 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.habbohotel.messenger.MessengerBuddy; +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.Outgoing; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Random; + +@Slf4j +public class ProfileFriendsComposer extends MessageComposer { + private final List lovers = new ArrayList<>(); + private final List friends = new ArrayList<>(); + private final List haters = new ArrayList<>(); + private final int userId; + + public ProfileFriendsComposer(THashMap> map, int userId) { + this.lovers.addAll(map.get(1)); + this.friends.addAll(map.get(2)); + this.haters.addAll(map.get(3)); + + this.userId = userId; + } + + public ProfileFriendsComposer(Habbo habbo) { + try { + for (Map.Entry map : habbo.getMessenger().getFriends().entrySet()) { + if (map.getValue().getRelation() == 0) + continue; + + switch (map.getValue().getRelation()) { + case 1: + this.lovers.add(map.getValue()); + break; + case 2: + this.friends.add(map.getValue()); + break; + case 3: + this.haters.add(map.getValue()); + break; + } + } + } catch (Exception e) { + log.error("Caught exception", e); + } + + this.userId = habbo.getHabboInfo().getId(); + } + + @Override + protected ServerMessage composeInternal() { + try { + this.response.init(Outgoing.ProfileFriendsComposer); + this.response.appendInt(this.userId); + + int total = 0; + + if (!this.lovers.isEmpty()) + total++; + + if (!this.friends.isEmpty()) + total++; + + if (!this.haters.isEmpty()) + total++; + + this.response.appendInt(total); + + Random random = new Random(); + + if (!this.lovers.isEmpty()) { + int loversIndex = random.nextInt(this.lovers.size()); + this.response.appendInt(1); + this.response.appendInt(this.lovers.size()); + this.response.appendInt(this.lovers.get(loversIndex).getId()); + this.response.appendString(this.lovers.get(loversIndex).getUsername()); + this.response.appendString(this.lovers.get(loversIndex).getLook()); + } + + if (!this.friends.isEmpty()) { + int friendsIndex = random.nextInt(this.friends.size()); + this.response.appendInt(2); + this.response.appendInt(this.friends.size()); + this.response.appendInt(this.friends.get(friendsIndex).getId()); + this.response.appendString(this.friends.get(friendsIndex).getUsername()); + this.response.appendString(this.friends.get(friendsIndex).getLook()); + } + + if (!this.haters.isEmpty()) { + int hatersIndex = random.nextInt(this.haters.size()); + this.response.appendInt(3); + this.response.appendInt(this.haters.size()); + this.response.appendInt(this.haters.get(hatersIndex).getId()); + this.response.appendString(this.haters.get(hatersIndex).getUsername()); + this.response.appendString(this.haters.get(hatersIndex).getLook()); + } + } catch (Exception e) { + log.error("Caught exception", e); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UpdateUserLookComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UpdateUserLookComposer.java new file mode 100644 index 0000000..ebe6f21 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UpdateUserLookComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.users; + +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.Outgoing; + +public class UpdateUserLookComposer extends MessageComposer { + private final Habbo habbo; + + public UpdateUserLookComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UpdateUserLookComposer); + this.response.appendString(this.habbo.getHabboInfo().getLook()); + this.response.appendString(this.habbo.getHabboInfo().getGender().name()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserAchievementScoreComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserAchievementScoreComposer.java new file mode 100644 index 0000000..539481a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserAchievementScoreComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.users; + +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.Outgoing; + +public class UserAchievementScoreComposer extends MessageComposer { + private final Habbo habbo; + + public UserAchievementScoreComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserAchievementScoreComposer); + this.response.appendInt(this.habbo.getHabboStats().getAchievementScore()); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserBCLimitsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserBCLimitsComposer.java new file mode 100644 index 0000000..3b74539 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserBCLimitsComposer.java @@ -0,0 +1,16 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UserBCLimitsComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserBCLimitsComposer); + this.response.appendInt(0); + this.response.appendInt(500); + this.response.appendInt(0); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserBadgesComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserBadgesComposer.java new file mode 100644 index 0000000..7574c3a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserBadgesComposer.java @@ -0,0 +1,32 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.util.ArrayList; + +public class UserBadgesComposer extends MessageComposer { + private final ArrayList badges; + private final int habbo; + + public UserBadgesComposer(ArrayList badges, int habbo) { + this.badges = badges; + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserBadgesComposer); + this.response.appendInt(this.habbo); + synchronized (this.badges) { + this.response.appendInt(this.badges.size()); + for (HabboBadge badge : this.badges) { + this.response.appendInt(badge.getSlot()); + this.response.appendString(badge.getCode()); + } + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserCitizinShipComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserCitizinShipComposer.java new file mode 100644 index 0000000..cbaea5b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserCitizinShipComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UserCitizinShipComposer extends MessageComposer { + private final String name; + + public UserCitizinShipComposer(String name) { + this.name = name; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserCitizinShipComposer); + this.response.appendString(this.name); + this.response.appendInt(4); + this.response.appendInt(4); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserClothesComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserClothesComposer.java new file mode 100644 index 0000000..82c33e9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserClothesComposer.java @@ -0,0 +1,45 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.ClothItem; +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.Outgoing; +import gnu.trove.procedure.TIntProcedure; + +import java.util.ArrayList; + +public class UserClothesComposer extends MessageComposer { + private final ArrayList idList = new ArrayList<>(); + private final ArrayList nameList = new ArrayList<>(); + + public UserClothesComposer(Habbo habbo) { + habbo.getInventory().getWardrobeComponent().getClothing().forEach(new TIntProcedure() { + @Override + public boolean execute(int value) { + ClothItem item = Emulator.getGameEnvironment().getCatalogManager().clothing.get(value); + + if (item != null) { + for (Integer j : item.setId) { + UserClothesComposer.this.idList.add(j); + } + + UserClothesComposer.this.nameList.add(item.name); + } + + return true; + } + }); + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserClothesComposer); + this.response.appendInt(this.idList.size()); + this.idList.forEach(this.response::appendInt); + this.response.appendInt(this.nameList.size()); + this.nameList.forEach(this.response::appendString); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserClubComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserClubComposer.java new file mode 100644 index 0000000..695561d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserClubComposer.java @@ -0,0 +1,163 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.subscriptions.Subscription; +import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionHabboClub; +import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionManager; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +import java.time.Period; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +public class UserClubComposer extends MessageComposer { + private final Habbo habbo; + private final String subscriptionType; + private final int responseType; + + public static int RESPONSE_TYPE_NORMAL = 0; + public static int RESPONSE_TYPE_LOGIN = 1; + public static int RESPONSE_TYPE_PURCHASE = 2; // closes the catalog after buying + public static int RESPONSE_TYPE_DISCOUNT_AVAILABLE = 3; + public static int RESPONSE_TYPE_CITIZENSHIP_DISCOUNT = 4; + + public UserClubComposer(Habbo habbo) { + this.habbo = habbo; + this.subscriptionType = SubscriptionHabboClub.HABBO_CLUB.toLowerCase(); + this.responseType = 0; + } + + public UserClubComposer(Habbo habbo, String subscriptionType) { + this.habbo = habbo; + this.subscriptionType = subscriptionType; + this.responseType = 0; + } + + public UserClubComposer(Habbo habbo, String subscriptionType, int responseType) { + this.habbo = habbo; + this.subscriptionType = subscriptionType; + this.responseType = responseType; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserClubComposer); + + this.response.appendString(this.subscriptionType.toLowerCase()); + + if(Emulator.getGameEnvironment().getSubscriptionManager().getSubscriptionClass(this.subscriptionType.toUpperCase()) == null) { + this.response.appendInt(0); // daysToPeriodEnd + this.response.appendInt(0); // memberPeriods + this.response.appendInt(0); // periodsSubscribedAhead + this.response.appendInt(0); // responseType + this.response.appendBoolean(false); // hasEverBeenMember + this.response.appendBoolean(false); // isVIP + this.response.appendInt(0); // pastClubDays + this.response.appendInt(0); // pastVIPdays + this.response.appendInt(0); // minutesTillExpiration + this.response.appendInt(0); // minutesSinceLastModified + return this.response; + } + + Subscription subscription = this.habbo.getHabboStats().getSubscription(this.subscriptionType); + + int days = 0; + int minutes = 0; + int timeRemaining = 0; + int pastTimeAsHC = this.habbo.getHabboStats().getPastTimeAsClub(); + + if(subscription != null) { + timeRemaining = subscription.getRemaining(); + days = (int) Math.floor(timeRemaining / 86400.0); + minutes = (int) Math.ceil(timeRemaining / 60.0); + + if(days < 1 && minutes > 0) { + days = 1; + } + } + + int responseType = ((this.responseType <= RESPONSE_TYPE_LOGIN) && timeRemaining > 0 && SubscriptionHabboClub.DISCOUNT_ENABLED && days <= SubscriptionHabboClub.DISCOUNT_DAYS_BEFORE_END) ? RESPONSE_TYPE_DISCOUNT_AVAILABLE : this.responseType; + + this.response.appendInt(days); // daysToPeriodEnd + this.response.appendInt(0); // memberPeriods + this.response.appendInt(0); // periodsSubscribedAhead + this.response.appendInt(responseType); // responseType + this.response.appendBoolean(pastTimeAsHC > 0); // hasEverBeenMember + this.response.appendBoolean(true); // isVIP + this.response.appendInt(0); // pastClubDays + this.response.appendInt((int) Math.floor(pastTimeAsHC / 86400.0)); // pastVIPdays + this.response.appendInt(minutes); // minutesTillExpiration + this.response.appendInt((Emulator.getIntUnixTimestamp() - this.habbo.getHabboStats().hcMessageLastModified) / 60); // minutesSinceLastModified + this.habbo.getHabboStats().hcMessageLastModified = Emulator.getIntUnixTimestamp(); + + // int - daysToPeriodEnd + // int - memberPeriods + // int - periodsSubscribedAhead + // int - responseType + // bool - hasEverBeenMember + // bool - isVIP + // int - pastClubDays + // int - pastVIPdays + // int - minutesTillExpiration + // (optional) int - minutesSinceLastModified + + /* + responseType: + 1 = RESPONSE_TYPE_LOGIN + 2 = RESPONSE_TYPE_PURCHASE + 3 = RESPONSE_TYPE_DISCOUNT_AVAILABLE + 4 = RESPONSE_TYPE_CITIZENSHIP_DISCOUNT + */ + + + /* + int endTimestamp = this.habbo.getHabboStats().getClubExpireTimestamp(); + int now = Emulator.getIntUnixTimestamp(); + + if (endTimestamp >= now) { + + + int days = ((endTimestamp - Emulator.getIntUnixTimestamp()) / 86400); + int years = (int) Math.floor(days / 365); + + //if(years > 0) + + + int months = 0; + + if (days > 31) { + months = (int) Math.floor(days / 31); + days = days - (months * 31); + } + + this.response.appendInt(days); + this.response.appendInt(1); + this.response.appendInt(months); + this.response.appendInt(years); + } else { + this.response.appendInt(0); + this.response.appendInt(7); + this.response.appendInt(0); + this.response.appendInt(1); + } + + this.response.appendBoolean(true); + this.response.appendBoolean(true); + this.response.appendInt(0); + this.response.appendInt(0); + + long remaining = (endTimestamp - Emulator.getIntUnixTimestamp()) * 1000; + + if (remaining > Integer.MAX_VALUE || remaining <= 0) { + this.response.appendInt(Integer.MAX_VALUE); + } else { + this.response.appendInt((int) remaining); + } + */ + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserCreditsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserCreditsComposer.java new file mode 100644 index 0000000..70c89ae --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserCreditsComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.users; + +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.Outgoing; + +public class UserCreditsComposer extends MessageComposer { + private final Habbo habbo; + + public UserCreditsComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserCreditsComposer); + this.response.appendString(this.habbo.getHabboInfo().getCredits() + ".0"); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserCurrencyComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserCurrencyComposer.java new file mode 100644 index 0000000..61ac72f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserCurrencyComposer.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.Emulator; +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.Outgoing; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class UserCurrencyComposer extends MessageComposer { + private final Habbo habbo; + + public UserCurrencyComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserCurrencyComposer); + String[] pointsTypes = Emulator.getConfig().getValue("seasonal.types").split(";"); + this.response.appendInt(pointsTypes.length); + for (String s : pointsTypes) { + int type; + try { + type = Integer.valueOf(s); + } catch (Exception e) { + log.error("Caught exception", e); + return null; + } + + this.response.appendInt(type); + this.response.appendInt(this.habbo.getHabboInfo().getCurrencyAmount(type)); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserDataComposer.java new file mode 100644 index 0000000..6b4235d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserDataComposer.java @@ -0,0 +1,36 @@ +package com.eu.habbo.messages.outgoing.users; + +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.Outgoing; + +public class UserDataComposer extends MessageComposer { + private final Habbo habbo; + + public UserDataComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserDataComposer); + + this.response.appendInt(this.habbo.getHabboInfo().getId()); + this.response.appendString(this.habbo.getHabboInfo().getUsername()); + this.response.appendString(this.habbo.getHabboInfo().getLook()); + this.response.appendString(this.habbo.getHabboInfo().getGender().name().toUpperCase()); + this.response.appendString(this.habbo.getHabboInfo().getMotto()); + this.response.appendString(this.habbo.getHabboInfo().getUsername()); + this.response.appendBoolean(false); + this.response.appendInt(this.habbo.getHabboStats().respectPointsReceived); + this.response.appendInt(this.habbo.getHabboStats().respectPointsToGive); + this.response.appendInt(this.habbo.getHabboStats().petRespectPointsToGive); + this.response.appendBoolean(false); + this.response.appendString("01-01-1970 00:00:00"); + this.response.appendBoolean(this.habbo.getHabboStats().allowNameChange); //can change name. + this.response.appendBoolean(false); //safatey locked + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserHomeRoomComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserHomeRoomComposer.java new file mode 100644 index 0000000..4aeae0b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserHomeRoomComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UserHomeRoomComposer extends MessageComposer { + private final int homeRoom; + private final int roomToEnter; + + public UserHomeRoomComposer(int homeRoom, int roomToEnter) { + this.homeRoom = homeRoom; + this.roomToEnter = roomToEnter; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserHomeRoomComposer); + this.response.appendInt(this.homeRoom); + this.response.appendInt(this.roomToEnter); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserPerksComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserPerksComposer.java new file mode 100644 index 0000000..7c81d3c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserPerksComposer.java @@ -0,0 +1,84 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.permissions.Permission; +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.Outgoing; + +public class UserPerksComposer extends MessageComposer { + private final Habbo habbo; + + public UserPerksComposer(Habbo habbo) { + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserPerksComposer); + this.response.appendInt(15); + + this.response.appendString("USE_GUIDE_TOOL"); + this.response.appendString("requirement.unfulfilled.helper_level_4"); + this.response.appendBoolean(Emulator.getGameEnvironment().getPermissionsManager().hasPermission(this.habbo, Permission.ACC_HELPER_USE_GUIDE_TOOL)); + + this.response.appendString("GIVE_GUIDE_TOURS"); + this.response.appendString(""); + this.response.appendBoolean(Emulator.getGameEnvironment().getPermissionsManager().hasPermission(this.habbo, "acc_helper_give_guide_tours")); + + this.response.appendString("JUDGE_CHAT_REVIEWS"); + this.response.appendString("requirement.unfulfilled.helper_level_6"); + this.response.appendBoolean(Emulator.getGameEnvironment().getPermissionsManager().hasPermission(this.habbo, "acc_helper_judge_chat_reviews")); + + this.response.appendString("VOTE_IN_COMPETITIONS"); + this.response.appendString("requirement.unfulfilled.helper_level_2"); + this.response.appendBoolean(true); + + this.response.appendString("CALL_ON_HELPERS"); + this.response.appendString(""); + this.response.appendBoolean(true); + + this.response.appendString("CITIZEN"); + this.response.appendString(""); + this.response.appendBoolean(true); + + this.response.appendString("TRADE"); + this.response.appendString("requirement.unfulfilled.no_trade_lock"); + this.response.appendBoolean(this.habbo.getHabboStats().allowTrade()); + + this.response.appendString("HEIGHTMAP_EDITOR_BETA"); + this.response.appendString("requirement.unfulfilled.feature_disabled"); + this.response.appendBoolean(Emulator.getGameEnvironment().getPermissionsManager().hasPermission(this.habbo, Permission.ACC_FLOORPLAN_EDITOR)); + + this.response.appendString("BUILDER_AT_WORK"); + this.response.appendString(""); + this.response.appendBoolean(true); + + this.response.appendString("CALL_ON_HELPERS"); + this.response.appendString(""); + this.response.appendBoolean(true); + + this.response.appendString("CAMERA"); + this.response.appendString(""); + this.response.appendBoolean(Emulator.getGameEnvironment().getPermissionsManager().hasPermission(this.habbo, "acc_camera")); + + this.response.appendString("NAVIGATOR_PHASE_TWO_2014"); + this.response.appendString(""); + this.response.appendBoolean(true); + + this.response.appendString("MOUSE_ZOOM"); + this.response.appendString(""); + this.response.appendBoolean(true); + + this.response.appendString("NAVIGATOR_ROOM_THUMBNAIL_CAMERA"); + this.response.appendString(""); + this.response.appendBoolean(true); + + this.response.appendString("HABBO_CLUB_OFFER_BETA"); + this.response.appendString(""); + this.response.appendBoolean(true); + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserPermissionsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserPermissionsComposer.java new file mode 100644 index 0000000..d7c5809 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserPermissionsComposer.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.habbohotel.permissions.Permission; +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.Outgoing; + +public class UserPermissionsComposer extends MessageComposer { + private final int clubLevel; + + private final Habbo habbo; + + public UserPermissionsComposer(Habbo habbo) { + this.clubLevel = habbo.getHabboStats().hasActiveClub() ? 2 : 0; + this.habbo = habbo; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserPermissionsComposer); + this.response.appendInt(this.clubLevel); + this.response.appendInt(this.habbo.getHabboInfo().getRank().getLevel()); + this.response.appendBoolean(this.habbo.hasPermission(Permission.ACC_AMBASSADOR)); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserPointsComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserPointsComposer.java new file mode 100644 index 0000000..19ffa00 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserPointsComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UserPointsComposer extends MessageComposer { + private final int currentAmount; + private final int amountAdded; + private final int type; + + public UserPointsComposer(int currentAmount, int amountAdded, int type) { + this.currentAmount = currentAmount; + this.amountAdded = amountAdded; + this.type = type; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserPointsComposer); + this.response.appendInt(this.currentAmount); + this.response.appendInt(this.amountAdded); + this.response.appendInt(this.type); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserProfileComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserProfileComposer.java new file mode 100644 index 0000000..3b09d64 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserProfileComposer.java @@ -0,0 +1,117 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.messenger.Messenger; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import lombok.extern.slf4j.Slf4j; + + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@Slf4j +public class UserProfileComposer extends MessageComposer { + + private final HabboInfo habboInfo; + private Habbo habbo; + private GameClient viewer; + + public UserProfileComposer(HabboInfo habboInfo, GameClient viewer) { + this.habboInfo = habboInfo; + this.viewer = viewer; + } + + public UserProfileComposer(Habbo habbo, GameClient viewer) { + this.habbo = habbo; + this.habboInfo = habbo.getHabboInfo(); + this.viewer = viewer; + } + + @Override + protected ServerMessage composeInternal() { + if (this.habboInfo == null) + return null; + + this.response.init(Outgoing.UserProfileComposer); + + this.response.appendInt(this.habboInfo.getId()); + this.response.appendString(this.habboInfo.getUsername()); + this.response.appendString(this.habboInfo.getLook()); + this.response.appendString(this.habboInfo.getMotto()); + this.response.appendString(new SimpleDateFormat("dd-MM-yyyy").format(new Date(this.habboInfo.getAccountCreated() * 1000L))); + + int achievementScore = 0; + if (this.habbo != null) { + achievementScore = this.habbo.getHabboStats().getAchievementScore(); + } else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT achievement_score FROM users_settings WHERE user_id = ? LIMIT 1")) { + statement.setInt(1, this.habboInfo.getId()); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + achievementScore = set.getInt("achievement_score"); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + this.response.appendInt(achievementScore); + this.response.appendInt(Messenger.getFriendCount(this.habboInfo.getId())); + this.response.appendBoolean(this.viewer.getHabbo().getMessenger().getFriends().containsKey(this.habboInfo.getId())); //Friend + this.response.appendBoolean(Messenger.friendRequested(this.viewer.getHabbo().getHabboInfo().getId(), this.habboInfo.getId())); //Friend Request Send + this.response.appendBoolean(this.habboInfo.isOnline()); + + List guilds = new ArrayList<>(); + if (this.habbo != null) { + List toRemove = new ArrayList<>(); + for (int index = this.habbo.getHabboStats().guilds.size(); index > 0; index--) { + int i = this.habbo.getHabboStats().guilds.get(index - 1); + if (i == 0) + continue; + + Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(i); + + if (guild != null) { + guilds.add(guild); + } else { + toRemove.add(i); + } + } + + for (int i : toRemove) { + this.habbo.getHabboStats().removeGuild(i); + } + } else { + guilds = Emulator.getGameEnvironment().getGuildManager().getGuilds(this.habboInfo.getId()); + } + + this.response.appendInt(guilds.size()); + for (Guild guild : guilds) { + this.response.appendInt(guild.getId()); + this.response.appendString(guild.getName()); + this.response.appendString(guild.getBadge()); + this.response.appendString(Emulator.getGameEnvironment().getGuildManager().getSymbolColor(guild.getColorOne()).valueA); + this.response.appendString(Emulator.getGameEnvironment().getGuildManager().getSymbolColor(guild.getColorTwo()).valueA); + this.response.appendBoolean(this.habbo != null && guild.getId() == this.habbo.getHabboStats().guild); + this.response.appendInt(guild.getOwnerId()); + this.response.appendBoolean(guild.getOwnerId() == this.habboInfo.getId()); + } + + this.response.appendInt(Emulator.getIntUnixTimestamp() - this.habboInfo.getLastOnline()); //Secs ago. + this.response.appendBoolean(true); + + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserWardrobeComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserWardrobeComposer.java new file mode 100644 index 0000000..912fab5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/UserWardrobeComposer.java @@ -0,0 +1,27 @@ +package com.eu.habbo.messages.outgoing.users; + +import com.eu.habbo.habbohotel.users.inventory.WardrobeComponent; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class UserWardrobeComposer extends MessageComposer { + private final WardrobeComponent wardrobeComponent; + + public UserWardrobeComposer(WardrobeComponent wardrobeComponent) { + this.wardrobeComponent = wardrobeComponent; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.UserWardrobeComposer); + this.response.appendInt(1); + this.response.appendInt(this.wardrobeComponent.getLooks().size()); + for (WardrobeComponent.WardrobeItem wardrobeItem : this.wardrobeComponent.getLooks().values()) { + this.response.appendInt(wardrobeItem.getSlotId()); + this.response.appendString(wardrobeItem.getLook()); + this.response.appendString(wardrobeItem.getGender().name().toUpperCase()); + } + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/verification/VerifyMobileNumberComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/verification/VerifyMobileNumberComposer.java new file mode 100644 index 0000000..c763d4b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/verification/VerifyMobileNumberComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.users.verification; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class VerifyMobileNumberComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.VerifyMobileNumberComposer); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/verification/VerifyMobilePhoneCodeWindowComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/verification/VerifyMobilePhoneCodeWindowComposer.java new file mode 100644 index 0000000..f2923d4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/verification/VerifyMobilePhoneCodeWindowComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.users.verification; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class VerifyMobilePhoneCodeWindowComposer extends MessageComposer { + private final int unknownInt1; + private final int unknownInt2; + + public VerifyMobilePhoneCodeWindowComposer(int unknownInt1, int unknownInt2) { + this.unknownInt1 = unknownInt1; + this.unknownInt2 = unknownInt2; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.VerifyMobilePhoneCodeWindowComposer); + this.response.appendInt(this.unknownInt1); + this.response.appendInt(this.unknownInt2); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/verification/VerifyMobilePhoneDoneComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/verification/VerifyMobilePhoneDoneComposer.java new file mode 100644 index 0000000..b91fca9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/verification/VerifyMobilePhoneDoneComposer.java @@ -0,0 +1,23 @@ +package com.eu.habbo.messages.outgoing.users.verification; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class VerifyMobilePhoneDoneComposer extends MessageComposer { + private final int unknownInt1; + private final int unknownInt2; + + public VerifyMobilePhoneDoneComposer(int unknownInt1, int unknownInt2) { + this.unknownInt1 = unknownInt1; + this.unknownInt2 = unknownInt2; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.VerifyMobilePhoneDoneComposer); + this.response.appendInt(this.unknownInt1); + this.response.appendInt(this.unknownInt2); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/verification/VerifyMobilePhoneWindowComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/verification/VerifyMobilePhoneWindowComposer.java new file mode 100644 index 0000000..1476672 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/users/verification/VerifyMobilePhoneWindowComposer.java @@ -0,0 +1,26 @@ +package com.eu.habbo.messages.outgoing.users.verification; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class VerifyMobilePhoneWindowComposer extends MessageComposer { + private final int unknownInt1; + private final int unknownInt2; + private final int unknownInt3; + + public VerifyMobilePhoneWindowComposer(int unknownInt1, int unknownInt2, int unknownInt3) { + this.unknownInt1 = unknownInt1; + this.unknownInt2 = unknownInt2; + this.unknownInt3 = unknownInt3; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.VerifyMobilePhoneWindowComposer); + this.response.appendInt(this.unknownInt1); + this.response.appendInt(this.unknownInt2); + this.response.appendInt(this.unknownInt3); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredConditionDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredConditionDataComposer.java new file mode 100644 index 0000000..b3dcae0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredConditionDataComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.wired; + +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class WiredConditionDataComposer extends MessageComposer { + private final InteractionWiredCondition condition; + private final Room room; + + public WiredConditionDataComposer(InteractionWiredCondition condition, Room room) { + this.condition = condition; + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.WiredConditionDataComposer); + this.condition.serializeWiredData(this.response, this.room); + this.condition.needsUpdate(true); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredEffectDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredEffectDataComposer.java new file mode 100644 index 0000000..73c84f2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredEffectDataComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.wired; + +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class WiredEffectDataComposer extends MessageComposer { + private final InteractionWiredEffect effect; + private final Room room; + + public WiredEffectDataComposer(InteractionWiredEffect effect, Room room) { + this.effect = effect; + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.WiredEffectDataComposer); + this.effect.serializeWiredData(this.response, this.room); + this.effect.needsUpdate(true); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredOpenComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredOpenComposer.java new file mode 100644 index 0000000..d433f63 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredOpenComposer.java @@ -0,0 +1,21 @@ +package com.eu.habbo.messages.outgoing.wired; + +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class WiredOpenComposer extends MessageComposer { + private final HabboItem item; + + public WiredOpenComposer(HabboItem item) { + this.item = item; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.WiredOpenComposer); + this.response.appendInt(this.item.getId()); + return this.response; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredRewardAlertComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredRewardAlertComposer.java new file mode 100644 index 0000000..606a31e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredRewardAlertComposer.java @@ -0,0 +1,30 @@ +package com.eu.habbo.messages.outgoing.wired; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class WiredRewardAlertComposer extends MessageComposer { + public static final int LIMITED_NO_MORE_AVAILABLE = 0; + public static final int REWARD_ALREADY_RECEIVED = 1; + public static final int REWARD_ALREADY_RECEIVED_THIS_TODAY = 2; + public static final int REWARD_ALREADY_RECEIVED_THIS_HOUR = 3; + public static final int REWARD_ALREADY_RECEIVED_THIS_MINUTE = 8; + public static final int UNLUCKY_NO_REWARD = 4; + public static final int REWARD_ALL_COLLECTED = 5; + public static final int REWARD_RECEIVED_ITEM = 6; + public static final int REWARD_RECEIVED_BADGE = 7; + + private final int code; + + public WiredRewardAlertComposer(int code) { + this.code = code; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.WiredRewardAlertComposer); + this.response.appendInt(this.code); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredSavedComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredSavedComposer.java new file mode 100644 index 0000000..17be832 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredSavedComposer.java @@ -0,0 +1,13 @@ +package com.eu.habbo.messages.outgoing.wired; + +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class WiredSavedComposer extends MessageComposer { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.WiredSavedComposer); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredTriggerDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredTriggerDataComposer.java new file mode 100644 index 0000000..8541e81 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/wired/WiredTriggerDataComposer.java @@ -0,0 +1,25 @@ +package com.eu.habbo.messages.outgoing.wired; + +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; + +public class WiredTriggerDataComposer extends MessageComposer { + private final InteractionWiredTrigger trigger; + private final Room room; + + public WiredTriggerDataComposer(InteractionWiredTrigger trigger, Room room) { + this.trigger = trigger; + this.room = room; + } + + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.WiredTriggerDataComposer); + this.trigger.serializeWiredData(this.response, this.room); + this.trigger.needsUpdate(true); + return this.response; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/AlertUser.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/AlertUser.java new file mode 100644 index 0000000..b5a2342 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/AlertUser.java @@ -0,0 +1,31 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.google.gson.Gson; + +public class AlertUser extends RCONMessage { + + public AlertUser() { + super(JSONAlertUser.class); + } + + @Override + public void handle(Gson gson, JSONAlertUser object) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(object.user_id); + + if (habbo != null) { + habbo.alert(object.message); + } + + this.status = RCONMessage.HABBO_NOT_FOUND; + } + + static class JSONAlertUser { + + int user_id; + + + String message; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/ChangeRoomOwner.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/ChangeRoomOwner.java new file mode 100644 index 0000000..262b60b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/ChangeRoomOwner.java @@ -0,0 +1,35 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.google.gson.Gson; + +public class ChangeRoomOwner extends RCONMessage { + public ChangeRoomOwner() { + super(JSON.class); + } + + @Override + public void handle(Gson gson, JSON json) { + Room room = Emulator.getGameEnvironment().getRoomManager().loadRoom(json.room_id); + + if (room != null) { + room.setOwnerId(json.user_id); + room.setOwnerName(json.username); + room.setNeedsUpdate(true); + room.save(); + Emulator.getGameEnvironment().getRoomManager().unloadRoom(room); + } + } + + static class JSON { + + public int room_id; + + + public int user_id; + + + public String username; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/ChangeUsername.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/ChangeUsername.java new file mode 100644 index 0000000..631f1fc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/ChangeUsername.java @@ -0,0 +1,70 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.subscriptions.Subscription; +import com.eu.habbo.messages.outgoing.users.UserDataComposer; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class ChangeUsername extends RCONMessage { + + public ChangeUsername() { + super(ChangeUsername.JSON.class); + } + + @Override + public void handle(Gson gson, JSON json) { + try { + if (json.user_id <= 0) { + this.status = RCONMessage.HABBO_NOT_FOUND; + this.message = "User not found"; + return; + } + + boolean success = true; + + Habbo habbo = Emulator.getGameServer().getGameClientManager().getHabbo(json.user_id); + if (habbo != null) { + if (json.canChange) + habbo.alert(Emulator.getTexts().getValue("rcon.alert.user.change_username")); + + habbo.getHabboStats().allowNameChange = json.canChange; + habbo.getClient().sendResponse(new UserDataComposer(habbo)); + } else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE users_settings SET allow_name_change = ? WHERE user_id = ? LIMIT 1")) { + statement.setBoolean(1, json.canChange); + statement.setInt(2, json.user_id); + + success = statement.executeUpdate() >= 1; + } catch (SQLException sqlException) { + sqlException.printStackTrace(); + } + } catch (SQLException sqlException) { + sqlException.printStackTrace(); + } + } + + this.status = success ? RCONMessage.STATUS_OK : RCONMessage.STATUS_ERROR; + this.message = success ? "Sent successfully." : "There was an error updating this user."; + } + catch (Exception e) { + this.status = RCONMessage.SYSTEM_ERROR; + this.message = "Exception occurred"; + log.error("Exception occurred", e); + } + } + + static class JSON { + public int user_id; + + public boolean canChange; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/CreateModToolTicket.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/CreateModToolTicket.java new file mode 100644 index 0000000..aa9a033 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/CreateModToolTicket.java @@ -0,0 +1,39 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.habbohotel.modtool.ModToolTicketType; +import com.google.gson.Gson; + +public class CreateModToolTicket extends RCONMessage { + public CreateModToolTicket() { + super(JSON.class); + } + + @Override + public void handle(Gson gson, JSON json) { + ModToolIssue issue = new ModToolIssue(json.sender_id, json.sender_username, json.reported_id, json.reported_username, json.reported_room_id, json.message, ModToolTicketType.NORMAL); + Emulator.getGameEnvironment().getModToolManager().addTicket(issue); + Emulator.getGameEnvironment().getModToolManager().updateTicketToMods(issue); + } + + static class JSON { + + public int sender_id; + + + public String sender_username; + + + public int reported_id; + + + public String reported_username; + + + public int reported_room_id = 0; + + + public String message; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/DisconnectUser.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/DisconnectUser.java new file mode 100644 index 0000000..8b768ac --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/DisconnectUser.java @@ -0,0 +1,43 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.google.gson.Gson; + +public class DisconnectUser extends RCONMessage { + + public DisconnectUser() { + super(DisconnectUserJSON.class); + } + + @Override + public void handle(Gson gson, DisconnectUserJSON json) { + Habbo target; + + if (json.user_id >= 0) { + target = Emulator.getGameEnvironment().getHabboManager().getHabbo(json.user_id); + } else if (!json.username.isEmpty()) { + target = Emulator.getGameEnvironment().getHabboManager().getHabbo(json.username); + } else { + this.status = RCONMessage.HABBO_NOT_FOUND; + return; + } + + if (target == null) { + this.status = RCONMessage.STATUS_ERROR; + this.message = Emulator.getTexts().getValue("commands.error.cmd_disconnect.user_offline"); + return; + } + + Emulator.getGameServer().getGameClientManager().disposeClient(target.getClient()); + this.message = Emulator.getTexts().getValue("commands.succes.cmd_disconnect.disconnected").replace("%user%", target.getHabboInfo().getUsername()); + } + + static class DisconnectUserJSON { + + public int user_id = -1; + + + public String username; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/ExecuteCommand.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/ExecuteCommand.java new file mode 100644 index 0000000..d83bb3d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/ExecuteCommand.java @@ -0,0 +1,37 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.commands.CommandHandler; +import com.eu.habbo.habbohotel.users.Habbo; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ExecuteCommand extends RCONMessage { + public ExecuteCommand() { + super(JSONExecuteCommand.class); + } + + @Override + public void handle(Gson gson, JSONExecuteCommand json) { + try { + Habbo habbo = Emulator.getGameServer().getGameClientManager().getHabbo(json.user_id); + + if (habbo == null) { + this.status = HABBO_NOT_FOUND; + return; + } + + + CommandHandler.handleCommand(habbo.getClient(), json.command); + } catch (Exception e) { + this.status = STATUS_ERROR; + log.error("Caught exception", e); + } + } + + static class JSONExecuteCommand { + public int user_id; + public String command; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/ForwardUser.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/ForwardUser.java new file mode 100644 index 0000000..b6f18b6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/ForwardUser.java @@ -0,0 +1,44 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.ForwardToRoomComposer; +import com.google.gson.Gson; + +public class ForwardUser extends RCONMessage { + + public ForwardUser() { + super(ForwardUserJSON.class); + } + + @Override + public void handle(Gson gson, ForwardUserJSON object) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(object.user_id); + + if (habbo != null) { + Room room = Emulator.getGameEnvironment().getRoomManager().loadRoom(object.room_id); + + if (room != null) { + if (habbo.getHabboInfo().getCurrentRoom() != null) { + Emulator.getGameEnvironment().getRoomManager().leaveRoom(habbo, habbo.getHabboInfo().getCurrentRoom()); + } + + habbo.getClient().sendResponse(new ForwardToRoomComposer(object.room_id)); + Emulator.getGameEnvironment().getRoomManager().enterRoom(habbo, object.room_id, "", true); + } else { + this.status = RCONMessage.ROOM_NOT_FOUND; + } + } + + this.status = RCONMessage.HABBO_NOT_FOUND; + } + + static class ForwardUserJSON { + + public int user_id; + + + public int room_id; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/FriendRequest.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/FriendRequest.java new file mode 100644 index 0000000..59d0bf3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/FriendRequest.java @@ -0,0 +1,57 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.messenger.Messenger; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.MessageComposer; +import com.eu.habbo.messages.outgoing.Outgoing; +import com.eu.habbo.messages.outgoing.friends.FriendRequestComposer; +import com.google.gson.Gson; + +public class FriendRequest extends RCONMessage { + public FriendRequest() { + super(FriendRequest.JSON.class); + } + + @Override + public void handle(Gson gson, JSON json) { + if (!Messenger.friendRequested(json.user_id, json.target_id)) { + Messenger.makeFriendRequest(json.user_id, json.target_id); + + Habbo target = Emulator.getGameEnvironment().getHabboManager().getHabbo(json.target_id); + if (target != null) { + Habbo from = Emulator.getGameEnvironment().getHabboManager().getHabbo(json.user_id); + + if (from != null) { + target.getClient().sendResponse(new FriendRequestComposer(from)); + } else { + final HabboInfo info = HabboManager.getOfflineHabboInfo(json.user_id); + + if (info != null) { + target.getClient().sendResponse(new MessageComposer() { + @Override + protected ServerMessage composeInternal() { + this.response.init(Outgoing.FriendRequestComposer); + this.response.appendInt(info.getId()); + this.response.appendString(info.getUsername()); + this.response.appendString(info.getLook()); + return this.response; + } + }); + } + } + } + } + } + + static class JSON { + + public int user_id; + + + public int target_id; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/GiveBadge.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/GiveBadge.java new file mode 100644 index 0000000..e220fee --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/GiveBadge.java @@ -0,0 +1,93 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboBadge; +import com.eu.habbo.messages.outgoing.users.AddUserBadgeComposer; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; +import java.sql.*; + +@Slf4j +public class GiveBadge extends RCONMessage { + public GiveBadge() { + super(GiveBadgeJSON.class); + } + + @Override + public void handle(Gson gson, GiveBadgeJSON json) { + if (json.user_id == -1) { + this.status = RCONMessage.HABBO_NOT_FOUND; + return; + } + + if (json.badge.isEmpty()) { + this.status = RCONMessage.SYSTEM_ERROR; + return; + } + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(json.user_id); + + String username = json.user_id + ""; + if (habbo != null) { + username = habbo.getHabboInfo().getUsername(); + + for (String badgeCode : json.badge.split(";")) { + if (habbo.getInventory().getBadgesComponent().hasBadge(badgeCode)) { + this.status = RCONMessage.STATUS_ERROR; + this.message += Emulator.getTexts().getValue("commands.error.cmd_badge.already_owned").replace("%user%", username).replace("%badge%", badgeCode) + "\r"; + continue; + } + + HabboBadge badge = new HabboBadge(0, badgeCode, 0, habbo); + + badge.run(); + + habbo.getInventory().getBadgesComponent().addBadge(badge); + habbo.getClient().sendResponse(new AddUserBadgeComposer(badge)); + + this.message = Emulator.getTexts().getValue("commands.succes.cmd_badge.given").replace("%user%", username).replace("%badge%", badgeCode); + } + } else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + for (String badgeCode : json.badge.split(";")) { + int numberOfRows = 0; + try (PreparedStatement statement = connection.prepareStatement("SELECT COUNT(slot_id) FROM users_badges INNER JOIN users ON users.id = user_id WHERE users.id = ? AND badge_code = ? LIMIT 1")) { + statement.setInt(1, json.user_id); + statement.setString(2, badgeCode); + try (ResultSet set = statement.executeQuery()) { + if (set.next()){ + numberOfRows = set.getInt(1); + } + } + } + + if (numberOfRows != 0) { + this.status = RCONMessage.STATUS_ERROR; + this.message += Emulator.getTexts().getValue("commands.error.cmd_badge.already_owns").replace("%user%", username).replace("%badge%", badgeCode) + "\r"; + } else { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO users_badges VALUES (null, (SELECT id FROM users WHERE users.id = ? LIMIT 1), 0, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, json.user_id); + statement.setString(2, badgeCode); + statement.execute(); + } + + this.message = Emulator.getTexts().getValue("commands.succes.cmd_badge.given").replace("%user%", username).replace("%badge%", badgeCode); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + this.status = RCONMessage.STATUS_ERROR; + this.message = e.getMessage(); + } + } + } + + static class GiveBadgeJSON { + + public int user_id = -1; + + + public String badge; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/GiveCredits.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/GiveCredits.java new file mode 100644 index 0000000..a83840d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/GiveCredits.java @@ -0,0 +1,40 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class GiveCredits extends RCONMessage { + public GiveCredits() { + super(JSONGiveCredits.class); + } + + @Override + public void handle(Gson gson, JSONGiveCredits object) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(object.user_id); + + if (habbo != null) { + habbo.giveCredits(object.credits); + } else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users SET credits = credits + ? WHERE id = ? LIMIT 1")) { + statement.setInt(1, object.credits); + statement.setInt(2, object.user_id); + statement.execute(); + } catch (SQLException e) { + this.status = RCONMessage.SYSTEM_ERROR; + log.error("Caught SQL exception", e); + } + this.message = "offline"; + } + } + + static class JSONGiveCredits { + public int user_id; + public int credits; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/GivePixels.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/GivePixels.java new file mode 100644 index 0000000..2ed9f5d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/GivePixels.java @@ -0,0 +1,43 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; + + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class GivePixels extends RCONMessage { + public GivePixels() { + super(JSONGivePixels.class); + } + + @Override + public void handle(Gson gson, JSONGivePixels object) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(object.user_id); + + if (habbo != null) { + habbo.givePixels(object.pixels); + } else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users_currency SET users_currency.amount = users_currency.amount + ? WHERE users_currency.user_id = ? AND users_currency.type = 0")) { + statement.setInt(1, object.pixels); + statement.setInt(2, object.user_id); + statement.execute(); + } catch (SQLException e) { + this.status = RCONMessage.SYSTEM_ERROR; + log.error("Caught SQL exception", e); + } + + this.message = "offline"; + } + } + + static class JSONGivePixels { + public int user_id; + public int pixels; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/GivePoints.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/GivePoints.java new file mode 100644 index 0000000..c4b7732 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/GivePoints.java @@ -0,0 +1,44 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class GivePoints extends RCONMessage { + public GivePoints() { + super(JSONGivePoints.class); + } + + @Override + public void handle(Gson gson, JSONGivePoints object) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(object.user_id); + + if (habbo != null) { + habbo.givePoints(object.type, object.points); + } else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO users_currency (`user_id`, `type`, `amount`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE amount = amount + ?")) { + statement.setInt(1, object.user_id); + statement.setInt(2, object.type); + statement.setInt(3, object.points); + statement.setInt(4, object.points); + statement.execute(); + } catch (SQLException e) { + this.status = RCONMessage.SYSTEM_ERROR; + log.error("Caught SQL exception", e); + } + + this.message = "offline"; + } + } + + static class JSONGivePoints { + public int user_id; + public int points; + public int type; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/GiveRespect.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/GiveRespect.java new file mode 100644 index 0000000..ce2b172 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/GiveRespect.java @@ -0,0 +1,50 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.users.UserDataComposer; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class GiveRespect extends RCONMessage { + + public GiveRespect() { + super(JSONGiveRespect.class); + } + + @Override + public void handle(Gson gson, JSONGiveRespect object) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(object.user_id); + + if (habbo != null) { + habbo.getHabboStats().respectPointsReceived += object.respect_received; + habbo.getHabboStats().respectPointsGiven += object.respect_given; + habbo.getHabboStats().respectPointsToGive += object.daily_respects; + habbo.getClient().sendResponse(new UserDataComposer(habbo)); + } else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users_settings SET respects_given = respects_give + ?, respects_received = respects_received + ?, daily_respect_points = daily_respect_points + ? WHERE user_id = ? LIMIT 1")) { + statement.setInt(1, object.respect_received); + statement.setInt(2, object.respect_given); + statement.setInt(3, object.daily_respects); + statement.setInt(4, object.user_id); + statement.execute(); + } catch (SQLException e) { + this.status = RCONMessage.SYSTEM_ERROR; + log.error("Caught SQL exception", e); + } + + this.message = "offline"; + } + } + + static class JSONGiveRespect { + public int user_id; + public int respect_given = 0; + public int respect_received = 0; + public int daily_respects = 0; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/GiveUserClothing.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/GiveUserClothing.java new file mode 100644 index 0000000..5c366cb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/GiveUserClothing.java @@ -0,0 +1,48 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys; +import com.eu.habbo.messages.outgoing.users.UserClothesComposer; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class GiveUserClothing extends RCONMessage { + public GiveUserClothing() { + super(GiveUserClothing.JSONGiveUserClothing.class); + } + + @Override + public void handle(Gson gson, GiveUserClothing.JSONGiveUserClothing object) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(object.user_id); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO users_clothing (user_id, clothing_id) VALUES (?, ?)")) { + statement.setInt(1, object.user_id); + statement.setInt(2, object.clothing_id); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + if (habbo != null) { + GameClient client = habbo.getClient(); + + if (client != null) { + habbo.getInventory().getWardrobeComponent().getClothing().add(object.clothing_id); + client.sendResponse(new UserClothesComposer(habbo)); + client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FIGURESET_REDEEMED.key)); + } + } + } + + static class JSONGiveUserClothing { + public int user_id; + public int clothing_id; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/HotelAlert.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/HotelAlert.java new file mode 100644 index 0000000..7098923 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/HotelAlert.java @@ -0,0 +1,45 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.generic.alerts.GenericAlertComposer; +import com.eu.habbo.messages.outgoing.generic.alerts.StaffAlertWithLinkComposer; +import com.google.gson.Gson; + +import java.util.Map; + +public class HotelAlert extends RCONMessage { + + public HotelAlert() { + super(JSONHotelAlert.class); + } + + @Override + public void handle(Gson gson, JSONHotelAlert object) { + ServerMessage serverMessage; + if (object.url.isEmpty()) { + serverMessage = new GenericAlertComposer(object.message).compose(); + } else { + serverMessage = new StaffAlertWithLinkComposer(object.message, object.url).compose(); + } + + if (serverMessage != null) { + for (Map.Entry set : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + Habbo habbo = set.getValue(); + if (habbo.getHabboStats().blockStaffAlerts) + continue; + + habbo.getClient().sendResponse(serverMessage); + } + } + } + + static class JSONHotelAlert { + + public String message; + + + public String url = ""; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/IgnoreUser.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/IgnoreUser.java new file mode 100644 index 0000000..f2f4d8d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/IgnoreUser.java @@ -0,0 +1,41 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class IgnoreUser extends RCONMessage { + public IgnoreUser() { + super(JSONIgnoreUser.class); + } + + @Override + public void handle(Gson gson, JSONIgnoreUser object) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(object.user_id); + + if (habbo != null) { + habbo.getHabboStats().ignoreUser(habbo.getClient(), object.target_id); + } else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("INSERT INTO users_ignored (user_id, target_id) VALUES (?, ?)")) { + statement.setInt(1, object.user_id); + statement.setInt(2, object.target_id); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.message = "offline"; + } + } + + static class JSONIgnoreUser { + public int user_id; + public int target_id; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/ImageAlertUser.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/ImageAlertUser.java new file mode 100644 index 0000000..12afed2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/ImageAlertUser.java @@ -0,0 +1,77 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.google.gson.Gson; +import gnu.trove.map.hash.THashMap; + +public class ImageAlertUser extends RCONMessage { + public ImageAlertUser() { + super(ImageAlertUser.JSON.class); + } + + @Override + public void handle(Gson gson, JSON json) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(json.user_id); + + if (habbo == null) { + this.status = HABBO_NOT_FOUND; + return; + } + + THashMap keys = new THashMap<>(); + + if (!json.message.isEmpty()) { + keys.put("message", json.message); + } + + if (!json.url.isEmpty()) { + keys.put("linkUrl", json.url); + } + + if (!json.url_message.isEmpty()) { + keys.put("linkTitle", json.url_message); + } + + if (!json.title.isEmpty()) { + keys.put("title", json.title); + } + + if (!json.display_type.isEmpty()) { + keys.put("display", json.display_type); + } + + if (!json.image.isEmpty()) { + keys.put("image", json.image); + } + + habbo.getClient().sendResponse(new BubbleAlertComposer(json.bubble_key, keys)); + } + + static class JSON { + + public int user_id; + + + public String bubble_key = ""; + + + public String message = ""; + + + public String url = ""; + + + public String url_message = ""; + + + public String title = ""; + + + public String display_type = ""; + + + public String image = ""; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/ImageHotelAlert.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/ImageHotelAlert.java new file mode 100644 index 0000000..d392a6b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/ImageHotelAlert.java @@ -0,0 +1,78 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import com.google.gson.Gson; +import gnu.trove.map.hash.THashMap; + +import java.util.Map; + +public class ImageHotelAlert extends RCONMessage { + public ImageHotelAlert() { + super(ImageHotelAlert.JSON.class); + } + + @Override + public void handle(Gson gson, JSON json) { + THashMap keys = new THashMap<>(); + + if (!json.message.isEmpty()) { + keys.put("message", json.message); + } + + if (!json.url.isEmpty()) { + keys.put("linkUrl", json.url); + } + + if (!json.url_message.isEmpty()) { + keys.put("linkTitle", json.url_message); + } + + if (!json.title.isEmpty()) { + keys.put("title", json.title); + } + + if (!json.display_type.isEmpty()) { + keys.put("display", json.display_type); + } + + if (!json.image.isEmpty()) { + keys.put("image", json.image); + } + + ServerMessage message = new BubbleAlertComposer(json.bubble_key, keys).compose(); + + for (Map.Entry set : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + Habbo habbo = set.getValue(); + if (habbo.getHabboStats().blockStaffAlerts) + continue; + + habbo.getClient().sendResponse(message); + } + } + + static class JSON { + + public String bubble_key = ""; + + + public String message = ""; + + + public String url = ""; + + + public String url_message = ""; + + + public String title = ""; + + + public String display_type = ""; + + + public String image = ""; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/ModifyUserSubscription.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/ModifyUserSubscription.java new file mode 100644 index 0000000..ee93250 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/ModifyUserSubscription.java @@ -0,0 +1,105 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.subscriptions.Subscription; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer; +import com.eu.habbo.messages.outgoing.users.MeMenuSettingsComposer; +import com.eu.habbo.messages.outgoing.users.UpdateUserLookComposer; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class ModifyUserSubscription extends RCONMessage { + public ModifyUserSubscription() { + super(ModifyUserSubscription.JSON.class); + } + + @Override + public void handle(Gson gson, JSON json) { + try { + + if(json.user_id <= 0) { + this.status = RCONMessage.HABBO_NOT_FOUND; + this.message = "User not found"; + return; + } + + if (!Emulator.getGameEnvironment().getSubscriptionManager().types.containsKey(json.type)) { + this.status = RCONMessage.STATUS_ERROR; + this.message = "%subscription% is not a valid subscription type".replace("%subscription%", json.type); + return; + } + + HabboInfo habbo = Emulator.getGameEnvironment().getHabboManager().getHabboInfo(json.user_id); + + if (habbo == null) { + this.status = RCONMessage.HABBO_NOT_FOUND; + this.message = "User not found"; + return; + } + + if (json.action.equalsIgnoreCase("add") || json.action.equalsIgnoreCase("+") || json.action.equalsIgnoreCase("a")) { + if (json.duration < 1) { + this.status = RCONMessage.STATUS_ERROR; + this.message = "duration must be > 0"; + return; + } + + habbo.getHabboStats().createSubscription(json.type, json.duration); + this.status = RCONMessage.STATUS_OK; + this.message = "Successfully added %time% seconds to %subscription% on %user%".replace("%time%", json.duration + "").replace("%user%", habbo.getUsername()).replace("%subscription%", json.type); + } else if (json.action.equalsIgnoreCase("remove") || json.action.equalsIgnoreCase("-") || json.action.equalsIgnoreCase("r")) { + Subscription s = habbo.getHabboStats().getSubscription(json.type); + + if (s == null) { + this.status = RCONMessage.STATUS_ERROR; + this.message = "%user% does not have the %subscription% subscription".replace("%user%", habbo.getUsername()).replace("%subscription%", json.type); + return; + } + + if (json.duration != -1) { + if (json.duration < 1) { + this.status = RCONMessage.STATUS_ERROR; + this.message = "duration must be > 0 or -1 to remove all time"; + return; + } + + s.addDuration(-json.duration); + this.status = RCONMessage.STATUS_OK; + this.message = "Successfully removed %time% seconds from %subscription% on %user%".replace("%time%", json.duration + "").replace("%user%", habbo.getUsername()).replace("%subscription%", json.type); + } else { + s.addDuration(-s.getRemaining()); + this.status = RCONMessage.STATUS_OK; + this.message = "Successfully removed %subscription% sub from %user%".replace("%user%", habbo.getUsername()).replace("%subscription%", json.type); + } + } + else { + this.status = RCONMessage.STATUS_ERROR; + this.message = "Invalid action specified. Must be add, +, remove or -"; + } + } + catch (Exception e) { + this.status = RCONMessage.SYSTEM_ERROR; + this.message = "Exception occurred"; + log.error("Exception occurred", e); + } + } + + static class JSON { + + public int user_id; + + public String type = ""; // Subscription type e.g. HABBO_CLUB + + public String action = ""; // Can be add or remove + + public int duration = -1; // Time to add/remove in seconds. -1 means remove subscription entirely + + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/MuteUser.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/MuteUser.java new file mode 100644 index 0000000..b506b76 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/MuteUser.java @@ -0,0 +1,45 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class MuteUser extends RCONMessage { + public MuteUser() { + super(MuteUser.JSON.class); + } + + @Override + public void handle(Gson gson, JSON json) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(json.user_id); + + if (habbo != null) { + if (json.duration == 0) { + habbo.unMute(); + } else { + habbo.mute(json.duration, false); + } + } else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users_settings SET mute_end_timestamp = ? WHERE user_id = ? LIMIT 1")) { + statement.setInt(1, Emulator.getIntUnixTimestamp() + json.duration); + statement.setInt(2, json.user_id); + if (statement.executeUpdate() == 0) { + this.status = HABBO_NOT_FOUND; + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + + static class JSON { + + public int user_id; + public int duration; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/ProgressAchievement.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/ProgressAchievement.java new file mode 100644 index 0000000..69cc6d5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/ProgressAchievement.java @@ -0,0 +1,41 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.users.Habbo; +import com.google.gson.Gson; + +public class ProgressAchievement extends RCONMessage { + + public ProgressAchievement() { + super(ProgressAchievementJSON.class); + } + + @Override + public void handle(Gson gson, ProgressAchievementJSON json) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(json.user_id); + + if (habbo != null) { + Achievement achievement = Emulator.getGameEnvironment().getAchievementManager().getAchievement(json.achievement_id); + if (achievement != null) { + AchievementManager.progressAchievement(habbo, achievement, json.progress); + } else { + this.status = RCONMessage.STATUS_ERROR; + } + } else { + this.status = RCONMessage.HABBO_NOT_FOUND; + } + } + + static class ProgressAchievementJSON { + + public int user_id; + + + public int achievement_id; + + + public int progress; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/RCONMessage.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/RCONMessage.java new file mode 100644 index 0000000..736625f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/RCONMessage.java @@ -0,0 +1,43 @@ +package com.eu.habbo.messages.rcon; + +import com.google.gson.*; + +import java.lang.reflect.Type; + +public abstract class RCONMessage { + + public final static int STATUS_OK = 0; + + + public final static int STATUS_ERROR = 1; + + + public final static int HABBO_NOT_FOUND = 2; + + + public final static int ROOM_NOT_FOUND = 3; + + + public final static int SYSTEM_ERROR = 4; + + + public final Class type; + public int status = STATUS_OK; + public String message = ""; + + public RCONMessage(Class type) { + this.type = type; + } + + public abstract void handle(Gson gson, T json); + + public static class RCONMessageSerializer implements JsonSerializer { + @Override + public JsonElement serialize(final RCONMessage rconMessage, final Type type, final JsonSerializationContext context) { + JsonObject result = new JsonObject(); + result.add("status", new JsonPrimitive(rconMessage.status)); + result.add("message", new JsonPrimitive(rconMessage.message)); + return result; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/SendGift.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/SendGift.java new file mode 100644 index 0000000..d79c0c0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/SendGift.java @@ -0,0 +1,98 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +public class SendGift extends RCONMessage { + + public SendGift() { + super(SendGiftJSON.class); + } + + @Override + public void handle(Gson gson, SendGiftJSON json) { + if (json.user_id < 0) { + this.status = RCONMessage.STATUS_ERROR; + this.message = Emulator.getTexts().getValue("commands.error.cmd_gift.user_not_found").replace("%username%", json.user_id + ""); + return; + } + + if (json.itemid < 0) { + this.status = RCONMessage.STATUS_ERROR; + this.message = Emulator.getTexts().getValue("commands.error.cmd_gift.not_a_number"); + return; + } + + Item baseItem = Emulator.getGameEnvironment().getItemManager().getItem(json.itemid); + if (baseItem == null) { + this.status = RCONMessage.STATUS_ERROR; + this.message = Emulator.getTexts().getValue("commands.error.cmd_gift.not_found").replace("%itemid%", json.itemid + ""); + return; + } + + boolean userFound; + Habbo habbo; + + habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(json.user_id); + + userFound = habbo != null; + String username = ""; + if (!userFound) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM users WHERE id = ? LIMIT 1")) { + statement.setInt(1, json.user_id); + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + username = set.getString("username"); + userFound = true; + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } else { + username = habbo.getHabboInfo().getUsername(); + } + + if (!userFound) { + this.status = RCONMessage.STATUS_ERROR; + this.message = Emulator.getTexts().getValue("commands.error.cmd_gift.user_not_found").replace("%username%", username); + return; + } + + HabboItem item = Emulator.getGameEnvironment().getItemManager().createItem(0, baseItem, 0, 0, ""); + Item giftItem = Emulator.getGameEnvironment().getItemManager().getItem((Integer) Emulator.getGameEnvironment().getCatalogManager().giftFurnis.values().toArray()[Emulator.getRandom().nextInt(Emulator.getGameEnvironment().getCatalogManager().giftFurnis.size())]); + + String extraData = "1\t" + item.getId(); + extraData += "\t0\t0\t0\t" + json.message + "\t0\t0"; + + Emulator.getGameEnvironment().getItemManager().createGift(username, giftItem, extraData, 0, 0); + + this.message = Emulator.getTexts().getValue("commands.succes.cmd_gift").replace("%username%", username).replace("%itemname%", item.getBaseItem().getName()); + + if (habbo != null) { + habbo.getClient().sendResponse(new InventoryRefreshComposer()); + } + } + + static class SendGiftJSON { + + public int user_id = -1; + + + public int itemid = -1; + + + public String message = ""; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/SendRoomBundle.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/SendRoomBundle.java new file mode 100644 index 0000000..25b276a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/SendRoomBundle.java @@ -0,0 +1,43 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.catalog.CatalogPage; +import com.eu.habbo.habbohotel.catalog.layouts.RoomBundleLayout; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.google.gson.Gson; + +public class SendRoomBundle extends RCONMessage { + public SendRoomBundle() { + super(JSON.class); + } + + @Override + public void handle(Gson gson, JSON json) { + if (json.catalog_page > 0 && json.user_id > 0) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(json.user_id); + CatalogPage page = Emulator.getGameEnvironment().getCatalogManager().getCatalogPage(json.catalog_page); + + if ((page instanceof RoomBundleLayout)) { + if (habbo != null) { + ((RoomBundleLayout) page).buyRoom(habbo); + } else { + HabboInfo info = HabboManager.getOfflineHabboInfo(json.user_id); + + if (info != null) { + ((RoomBundleLayout) page).buyRoom(null, json.user_id, info.getUsername()); + } + } + } + } + } + + static class JSON { + + public int user_id; + + + public int catalog_page; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/SetMotto.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/SetMotto.java new file mode 100644 index 0000000..686ab0f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/SetMotto.java @@ -0,0 +1,47 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class SetMotto extends RCONMessage { + + public SetMotto() { + super(SetMottoJSON.class); + } + + @Override + public void handle(Gson gson, SetMottoJSON json) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(json.user_id); + + if (habbo != null) { + habbo.getHabboInfo().setMotto(json.motto); + habbo.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserDataComposer(habbo).compose()); + } else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE users SET motto = ? WHERE id = ? LIMIT 1")) { + statement.setString(1, json.motto); + statement.setInt(2, json.user_id); + statement.execute(); + } + } catch (SQLException e) { + log.error("Caught exception", e); + } + } + } + + static class SetMottoJSON { + + public int user_id; + + + public String motto; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/SetRank.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/SetRank.java new file mode 100644 index 0000000..639f967 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/SetRank.java @@ -0,0 +1,39 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.google.gson.Gson; + +public class SetRank extends RCONMessage { + + public SetRank() { + super(JSONSetRank.class); + } + + @Override + public void handle(Gson gson, JSONSetRank object) { + try { + Emulator.getGameEnvironment().getHabboManager().setRank(object.user_id, object.rank); + } catch (Exception e) { + this.status = RCONMessage.SYSTEM_ERROR; + this.message = "invalid rank"; + return; + } + + this.message = "updated offline user"; + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(object.user_id); + + if (habbo != null) { + this.message = "updated online user"; + } + } + + static class JSONSetRank { + + public int user_id; + + + public int rank; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/StaffAlert.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/StaffAlert.java new file mode 100644 index 0000000..d494827 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/StaffAlert.java @@ -0,0 +1,20 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.google.gson.Gson; + +public class StaffAlert extends RCONMessage { + public StaffAlert() { + super(JSON.class); + } + + @Override + public void handle(Gson gson, JSON json) { + Emulator.getGameEnvironment().getHabboManager().staffAlert(json.message); + } + + static class JSON { + + public String message; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/StalkUser.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/StalkUser.java new file mode 100644 index 0000000..f72e503 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/StalkUser.java @@ -0,0 +1,57 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.ForwardToRoomComposer; +import com.google.gson.Gson; + +public class StalkUser extends RCONMessage { + public StalkUser() { + super(StalkUserJSON.class); + } + + @Override + public void handle(Gson gson, StalkUserJSON json) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(json.user_id); + + if (habbo != null) { + Habbo target = Emulator.getGameEnvironment().getHabboManager().getHabbo(json.follow_id); + + if (target == null) { + this.message = Emulator.getTexts().getValue("commands.error.cmd_stalk.not_found").replace("%user%", json.user_id + ""); + this.status = STATUS_ERROR; + return; + } + + if (target.getHabboInfo().getCurrentRoom() == null) { + this.message = Emulator.getTexts().getValue("commands.error.cmd_stalk.not_room").replace("%user%", json.user_id + ""); + this.status = STATUS_ERROR; + return; + } + + if (target.getHabboInfo().getUsername().equals(habbo.getHabboInfo().getUsername())) { + this.message = Emulator.getTexts().getValue("commands.generic.cmd_stalk.self").replace("%user%", json.user_id + ""); + this.status = STATUS_ERROR; + return; + } + + if (target.getHabboInfo().getCurrentRoom() == habbo.getHabboInfo().getCurrentRoom()) { + this.message = Emulator.getTexts().getValue("commands.generic.cmd_stalk.same_room").replace("%user%", json.user_id + ""); + this.status = STATUS_ERROR; + return; + } + + if (this.status == 0) { + habbo.getClient().sendResponse(new ForwardToRoomComposer(target.getHabboInfo().getCurrentRoom().getId())); + } + } + } + + static class StalkUserJSON { + + public int user_id; + + + public int follow_id; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/TalkUser.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/TalkUser.java new file mode 100644 index 0000000..1f190cc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/TalkUser.java @@ -0,0 +1,52 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.users.Habbo; +import com.google.gson.Gson; + +public class TalkUser extends RCONMessage { + public TalkUser() { + super(JSON.class); + } + + @Override + public void handle(Gson gson, JSON json) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(json.user_id); + + if (habbo != null) { + json.type = json.type.toLowerCase(); + switch (json.type) { + case "talk": + habbo.talk(json.message, json.bubble_id != -1 ? RoomChatMessageBubbles.getBubble(json.bubble_id) : habbo.getHabboStats().chatColor); + break; + case "whisper": + habbo.whisper(json.message, json.bubble_id != -1 ? RoomChatMessageBubbles.getBubble(json.bubble_id) : habbo.getHabboStats().chatColor); + break; + case "shout": + habbo.shout(json.message, json.bubble_id != -1 ? RoomChatMessageBubbles.getBubble(json.bubble_id) : habbo.getHabboStats().chatColor); + break; + default: + this.status = STATUS_ERROR; + this.message = "Talk type: " + json.type + " not found! Use talk, whisper or shout!"; + } + } else { + this.status = HABBO_NOT_FOUND; + this.message = "offline"; + } + } + + static class JSON { + + public String type; + + + public int user_id; + + + public int bubble_id = -1; + + + public String message; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/UpdateCatalog.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/UpdateCatalog.java new file mode 100644 index 0000000..7fc897c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/UpdateCatalog.java @@ -0,0 +1,28 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.outgoing.catalog.*; +import com.eu.habbo.messages.outgoing.catalog.marketplace.MarketplaceConfigComposer; +import com.google.gson.Gson; + +public class UpdateCatalog extends RCONMessage { + + public UpdateCatalog() { + super(JSONUpdateCatalog.class); + } + + @Override + public void handle(Gson gson, JSONUpdateCatalog json) { + Emulator.getGameEnvironment().getCatalogManager().initialize(); + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new CatalogUpdatedComposer()); + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new CatalogModeComposer(0)); + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new DiscountComposer()); + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new MarketplaceConfigComposer()); + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new GiftConfigurationComposer()); + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new RecyclerLogicComposer()); + Emulator.getGameEnvironment().getCraftingManager().reload(); + } + + static class JSONUpdateCatalog { + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/UpdateUser.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/UpdateUser.java new file mode 100644 index 0000000..9202b06 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/UpdateUser.java @@ -0,0 +1,143 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer; +import com.eu.habbo.messages.outgoing.users.MeMenuSettingsComposer; +import com.eu.habbo.messages.outgoing.users.UpdateUserLookComposer; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class UpdateUser extends RCONMessage { + + public UpdateUser() { + super(UpdateUser.JSON.class); + } + + @Override + public void handle(Gson gson, JSON json) { + if (json.user_id > 0) { + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(json.user_id); + + if (habbo != null) { + habbo.getHabboStats().addAchievementScore(json.achievement_score); + + if (json.block_following != -1) { + habbo.getHabboStats().blockFollowing = json.block_following == 1; + } + + if (json.block_friendrequests != -1) { + habbo.getHabboStats().blockFriendRequests = json.block_friendrequests == 1; + } + + if (json.block_roominvites != -1) { + habbo.getHabboStats().blockRoomInvites = json.block_roominvites == 1; + } + + if (json.old_chat != -1) { + habbo.getHabboStats().preferOldChat = json.old_chat == 1; + } + + if (json.block_camera_follow != -1) { + habbo.getHabboStats().blockCameraFollow = json.block_camera_follow == 1; + } + + if (!json.look.isEmpty()) { + habbo.getHabboInfo().setLook(json.look); + if (habbo.getClient() != null) { + habbo.getClient().sendResponse(new UpdateUserLookComposer(habbo).compose()); + } + + if (habbo.getHabboInfo().getCurrentRoom() != null) { + habbo.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserDataComposer(habbo).compose()); + } + } + + habbo.getHabboStats().run(); + habbo.getClient().sendResponse(new MeMenuSettingsComposer(habbo)); + } else { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE users_settings SET achievement_score = achievement_score + ? " + + (json.block_following != -1 ? ", block_following = ?" : "") + + (json.block_friendrequests != -1 ? ", block_friendrequests = ?" : "") + + (json.block_roominvites != -1 ? ", block_roominvites = ?" : "") + + (json.old_chat != -1 ? ", old_chat = ?" : "") + + (json.block_camera_follow != -1 ? ", block_camera_follow = ?" : "") + + " WHERE user_id = ? LIMIT 1")) + + { + int index = 1; + statement.setInt(index, json.achievement_score); + index++; + + if (json.block_following != -1) { + statement.setString(index, json.block_following == 1 ? "1" : "0"); + index++; + } + if (json.block_friendrequests != -1) { + statement.setString(index, json.block_friendrequests == 1 ? "1" : "0"); + index++; + } + if (json.block_roominvites != -1) { + statement.setString(index, json.block_roominvites == 1 ? "1" : "0"); + index++; + } + if (json.old_chat != -1) { + statement.setString(index, json.old_chat == 1 ? "1" : "0"); + index++; + } + if (json.block_camera_follow != -1) { + statement.setString(index, json.block_camera_follow == 1 ? "1" : "0"); + index++; + } + statement.setInt(index, json.user_id); + statement.execute(); + } + + if (!json.look.isEmpty()) { + try (PreparedStatement statement = connection.prepareStatement("UPDATE users SET look = ? WHERE id = ? LIMIT 1")) { + statement.setString(1, json.look); + statement.setInt(2, json.user_id); + statement.execute(); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + } + } + + static class JSON { + + public int user_id; + + + public int achievement_score = 0; + + + public int block_following = -1; + + + public int block_friendrequests = -1; + + + public int block_roominvites = -1; + + + public int old_chat = -1; + + + public int block_camera_follow = -1; + + + public String look = ""; + + public boolean strip_unredeemed_clothing = false; + //More could be added in the future. + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/rcon/UpdateWordfilter.java b/Emulator/src/main/java/com/eu/habbo/messages/rcon/UpdateWordfilter.java new file mode 100644 index 0000000..d1b4808 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/rcon/UpdateWordfilter.java @@ -0,0 +1,19 @@ +package com.eu.habbo.messages.rcon; + +import com.eu.habbo.Emulator; +import com.google.gson.Gson; + +public class UpdateWordfilter extends RCONMessage { + + public UpdateWordfilter() { + super(WordFilterJSON.class); + } + + @Override + public void handle(Gson gson, WordFilterJSON object) { + Emulator.getGameEnvironment().getWordFilter().reload(); + } + + static class WordFilterJSON { + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/Server.java b/Emulator/src/main/java/com/eu/habbo/networking/Server.java new file mode 100644 index 0000000..81269b5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/Server.java @@ -0,0 +1,91 @@ +package com.eu.habbo.networking; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.buffer.UnpooledByteBufAllocator; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.FixedRecvByteBufAllocator; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.util.concurrent.DefaultThreadFactory; +import lombok.extern.slf4j.Slf4j; +import java.util.concurrent.TimeUnit; + +@Slf4j +public abstract class Server { + protected final ServerBootstrap serverBootstrap; + protected final EventLoopGroup bossGroup; + protected final EventLoopGroup workerGroup; + private final String name; + private final String host; + private final int port; + + public Server(String name, String host, int port, int bossGroupThreads, int workerGroupThreads) throws Exception { + this.name = name; + this.host = host; + this.port = port; + + String threadName = name.replace("Server", "").replace(" ", ""); + + this.bossGroup = new NioEventLoopGroup(bossGroupThreads, new DefaultThreadFactory(threadName + "Boss")); + this.workerGroup = new NioEventLoopGroup(workerGroupThreads, new DefaultThreadFactory(threadName + "Worker")); + this.serverBootstrap = new ServerBootstrap(); + } + + public void initializePipeline() { + this.serverBootstrap.group(this.bossGroup, this.workerGroup); + this.serverBootstrap.channel(NioServerSocketChannel.class); + this.serverBootstrap.childOption(ChannelOption.TCP_NODELAY, true); + this.serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true); + this.serverBootstrap.childOption(ChannelOption.SO_REUSEADDR, true); + this.serverBootstrap.childOption(ChannelOption.SO_RCVBUF, 4096); + this.serverBootstrap.childOption(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(4096)); + this.serverBootstrap.childOption(ChannelOption.ALLOCATOR, new UnpooledByteBufAllocator(false)); + } + + public void connect() { + ChannelFuture channelFuture = this.serverBootstrap.bind(this.host, this.port); + + while (!channelFuture.isDone()) { + } + + if (!channelFuture.isSuccess()) { + log.info("Failed to connect to the host (" + this.host + ":" + this.port + ")@" + this.name); + System.exit(0); + } else { + log.info("Started GameServer on " + this.host + ":" + this.port + "@" + this.name); + } + } + + public void stop() { + log.info("Stopping " + this.name); + try { + this.workerGroup.shutdownGracefully(0, 0, TimeUnit.MILLISECONDS).sync(); + this.bossGroup.shutdownGracefully(0, 0, TimeUnit.MILLISECONDS).sync(); + } catch(InterruptedException e) { + log.error("Exception during {} shutdown... HARD STOP", this.name, e); + } + log.info("GameServer Stopped!"); + } + + public ServerBootstrap getServerBootstrap() { + return this.serverBootstrap; + } + + public EventLoopGroup getBossGroup() { + return this.bossGroup; + } + + public EventLoopGroup getWorkerGroup() { + return this.workerGroup; + } + + public String getHost() { + return this.host; + } + + public int getPort() { + return this.port; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraClient.java b/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraClient.java new file mode 100644 index 0000000..d84732d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraClient.java @@ -0,0 +1,89 @@ +package com.eu.habbo.networking.camera; + +import com.eu.habbo.networking.camera.messages.outgoing.CameraLoginComposer; +import io.netty.bootstrap.Bootstrap; +import io.netty.buffer.UnpooledByteBufAllocator; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CameraClient { + private static final String host = "google.com"; + private static final int port = 1232; + public static ChannelFuture channelFuture; + public static boolean isLoggedIn = false; + public static boolean attemptReconnect = true; + private static Channel channel; + private final Bootstrap bootstrap = new Bootstrap(); + + public CameraClient() { + + EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); + this.bootstrap.group(eventLoopGroup); + this.bootstrap.channel(NioSocketChannel.class); + this.bootstrap.option(ChannelOption.TCP_NODELAY, true); + this.bootstrap.option(ChannelOption.SO_KEEPALIVE, false); + this.bootstrap.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + ch.pipeline().addLast(new CameraDecoder()); + ch.pipeline().addLast(new CameraHandler()); + } + }); + this.bootstrap.option(ChannelOption.SO_RCVBUF, 5120); + this.bootstrap.option(ChannelOption.SO_REUSEADDR, true); + this.bootstrap.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(5120)); + this.bootstrap.option(ChannelOption.ALLOCATOR, new UnpooledByteBufAllocator(false)); + } + + public void connect() { + CameraClient.channelFuture = this.bootstrap.connect(host, port); + + while (!CameraClient.channelFuture.isDone()) { + } + + if (CameraClient.channelFuture.isSuccess()) { + CameraClient.attemptReconnect = false; + CameraClient.channel = channelFuture.channel(); + log.info("Connected to the Camera Server. Attempting to login."); + this.sendMessage(new CameraLoginComposer()); + } else { + log.error("Failed to connect to the Camera Server. Server unreachable."); + CameraClient.channel = null; + CameraClient.channelFuture.channel().close(); + CameraClient.channelFuture = null; + CameraClient.attemptReconnect = true; + } + } + + public void disconnect() { + if (channelFuture != null) { + try { + channelFuture.channel().close().sync(); + channelFuture = null; + } catch (Exception e) { + e.printStackTrace(); + } + } + + channel = null; + isLoggedIn = false; + + log.info("Disconnected from the camera server."); + } + + public void sendMessage(CameraOutgoingMessage outgoingMessage) { + try { + if (isLoggedIn || outgoingMessage instanceof CameraLoginComposer) { + outgoingMessage.compose(channel); + channel.write(outgoingMessage.get().copy(), channel.voidPromise()); + channel.flush(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraDecoder.java b/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraDecoder.java new file mode 100644 index 0000000..7d09561 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraDecoder.java @@ -0,0 +1,29 @@ +package com.eu.habbo.networking.camera; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; + +import java.util.List; + +class CameraDecoder extends ByteToMessageDecoder { + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List objects) { + int readerIndex = byteBuf.readerIndex(); + if (byteBuf.readableBytes() < 6) { + byteBuf.readerIndex(readerIndex); + return; + } + + int length = byteBuf.readInt(); + byteBuf.readerIndex(readerIndex); + + if (byteBuf.readableBytes() < (length)) { + byteBuf.readerIndex(readerIndex); + return; + } + + byteBuf.readerIndex(readerIndex); + objects.add(byteBuf.readBytes(length + 4)); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraHandler.java b/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraHandler.java new file mode 100644 index 0000000..6d8abb2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraHandler.java @@ -0,0 +1,50 @@ +package com.eu.habbo.networking.camera; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; + +public class CameraHandler extends ChannelInboundHandlerAdapter { + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) { + try { + ByteBuf message = (ByteBuf) msg; + ((ByteBuf) msg).readerIndex(0); + int length = message.readInt(); + + ByteBuf b = Unpooled.wrappedBuffer(message.readBytes(length)); + + short header = b.readShort(); + + try { + CameraPacketHandler.instance().handle(ctx.channel(), header, b); + } catch (Exception e) { + + } finally { + try { + + b.release(); + } catch (Exception e) { + } + try { + + ((ByteBuf) msg).release(); + } catch (Exception e) { + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + CameraClient.attemptReconnect = true; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + cause.printStackTrace(); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraIncomingMessage.java b/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraIncomingMessage.java new file mode 100644 index 0000000..4625a2b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraIncomingMessage.java @@ -0,0 +1,63 @@ +package com.eu.habbo.networking.camera; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; + +import java.nio.charset.Charset; + +public abstract class CameraIncomingMessage extends CameraMessage { + public CameraIncomingMessage(Short header, ByteBuf body) { + super(header); + this.buffer.writerIndex(0).writeBytes(body); + } + + public int readShort() { + return this.buffer.readShort(); + } + + public Integer readInt() { + try { + return this.buffer.readInt(); + } catch (Exception e) { + } + + return 0; + } + + public boolean readBoolean() { + try { + return this.buffer.readByte() == 1; + } catch (Exception e) { + } + + return false; + } + + + public String readString() { + try { + int length = this.readInt(); + byte[] data = new byte[length]; + this.buffer.readBytes(data); + return new String(data); + } catch (Exception e) { + return ""; + } + } + + public String getMessageBody() { + String consoleText = this.buffer.toString(Charset.defaultCharset()); + + for (int i = -1; i < 31; i++) { + consoleText = consoleText.replace(Character.toString((char) i), "[" + i + "]"); + } + + return consoleText; + } + + public int bytesAvailable() { + return this.buffer.readableBytes(); + } + + public abstract void handle(Channel client) throws Exception; +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraMessage.java b/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraMessage.java new file mode 100644 index 0000000..fbcceb1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraMessage.java @@ -0,0 +1,18 @@ +package com.eu.habbo.networking.camera; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +public class CameraMessage { + protected final short header; + protected final ByteBuf buffer; + + public CameraMessage(short header) { + this.header = header; + this.buffer = Unpooled.buffer(); + } + + public short getHeader() { + return this.header; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraOutgoingMessage.java b/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraOutgoingMessage.java new file mode 100644 index 0000000..a1b3f08 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraOutgoingMessage.java @@ -0,0 +1,128 @@ +package com.eu.habbo.networking.camera; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufOutputStream; +import io.netty.channel.Channel; + +import java.io.IOException; +import java.nio.charset.Charset; + +public abstract class CameraOutgoingMessage extends CameraMessage { + private final ByteBufOutputStream stream; + + public CameraOutgoingMessage(short header) { + super(header); + + this.stream = new ByteBufOutputStream(this.buffer); + try { + this.stream.writeInt(0); + this.stream.writeShort(header); + } catch (Exception e) { + } + } + + public void appendRawBytes(byte[] bytes) { + try { + this.stream.write(bytes); + } catch (IOException e) { + } + } + + public void appendString(String obj) { + try { + byte[] data = obj.getBytes(); + this.stream.writeInt(data.length); + this.stream.write(data); + } catch (IOException e) { + } + } + + public void appendChar(int obj) { + try { + this.stream.writeChar(obj); + } catch (IOException e) { + } + } + + public void appendChars(Object obj) { + try { + this.stream.writeChars(obj.toString()); + } catch (IOException e) { + } + } + + public void appendInt32(Integer obj) { + try { + this.stream.writeInt(obj); + } catch (IOException e) { + } + } + + public void appendInt32(Byte obj) { + try { + this.stream.writeInt((int) obj); + } catch (IOException e) { + } + } + + public void appendInt32(Boolean obj) { + try { + this.stream.writeInt(obj ? 1 : 0); + } catch (IOException e) { + } + } + + public void appendShort(int obj) { + try { + this.stream.writeShort((short) obj); + } catch (IOException e) { + } + } + + public void appendByte(Integer b) { + try { + this.stream.writeByte(b); + } catch (IOException e) { + } + } + + public void appendBoolean(Boolean obj) { + try { + this.stream.writeBoolean(obj); + } catch (IOException e) { + } + } + + public CameraOutgoingMessage appendResponse(CameraOutgoingMessage obj) { + try { + this.stream.write(obj.get().array()); + } catch (IOException e) { + } + + return this; + } + + public String getBodyString() { + ByteBuf buffer = this.stream.buffer().duplicate(); + + buffer.setInt(0, buffer.writerIndex() - 4); + + String consoleText = buffer.toString(Charset.forName("UTF-8")); + + for (int i = 0; i < 14; i++) { + consoleText = consoleText.replace(Character.toString((char) i), "[" + i + "]"); + } + + buffer.discardSomeReadBytes(); + + return consoleText; + } + + public ByteBuf get() { + this.buffer.setInt(0, this.buffer.writerIndex() - 4); + + return this.buffer.copy(); + } + + public abstract void compose(Channel channel); +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraPacketHandler.java b/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraPacketHandler.java new file mode 100644 index 0000000..77af6d7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/camera/CameraPacketHandler.java @@ -0,0 +1,45 @@ +package com.eu.habbo.networking.camera; + +import com.eu.habbo.networking.camera.messages.incoming.*; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import lombok.extern.slf4j.Slf4j; +import java.util.HashMap; + +@Slf4j +public class CameraPacketHandler { + private static CameraPacketHandler INSTANCE; + private final HashMap> packetDefinitions; + + public CameraPacketHandler() { + this.packetDefinitions = new HashMap<>(); + + this.packetDefinitions.put((short) 1, CameraLoginStatusEvent.class); + this.packetDefinitions.put((short) 2, CameraResultURLEvent.class); + this.packetDefinitions.put((short) 3, CameraRoomThumbnailGeneratedEvent.class); + this.packetDefinitions.put((short) 4, CameraUpdateNotification.class); + this.packetDefinitions.put((short) 5, CameraAuthenticationTicketEvent.class); + } + + public static CameraPacketHandler instance() { + if (INSTANCE == null) { + INSTANCE = new CameraPacketHandler(); + } + + return INSTANCE; + } + + public void handle(Channel channel, short i, ByteBuf ii) { + Class declaredClass = this.packetDefinitions.get(i); + + if (declaredClass != null) { + try { + CameraIncomingMessage message = declaredClass.getDeclaredConstructor(new Class[]{Short.class, ByteBuf.class}).newInstance(i, ii); + message.handle(channel); + message.buffer.release(); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/CameraOutgoingHeaders.java b/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/CameraOutgoingHeaders.java new file mode 100644 index 0000000..e989203 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/CameraOutgoingHeaders.java @@ -0,0 +1,6 @@ +package com.eu.habbo.networking.camera.messages; + +public class CameraOutgoingHeaders { + public final static short LoginComposer = 1; + public final static short RenderImageComposer = 2; +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraAuthenticationTicketEvent.java b/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraAuthenticationTicketEvent.java new file mode 100644 index 0000000..08f1014 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraAuthenticationTicketEvent.java @@ -0,0 +1,21 @@ +package com.eu.habbo.networking.camera.messages.incoming; + +import com.eu.habbo.messages.outgoing.gamecenter.basejump.BaseJumpLoadGameComposer; +import com.eu.habbo.networking.camera.CameraIncomingMessage; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; + +public class CameraAuthenticationTicketEvent extends CameraIncomingMessage { + public CameraAuthenticationTicketEvent(Short header, ByteBuf body) { + super(header, body); + } + + @Override + public void handle(Channel client) throws Exception { + String ticket = this.readString(); + + if (ticket.startsWith("FASTFOOD")) { + BaseJumpLoadGameComposer.FASTFOOD_KEY = ticket; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraLoginStatusEvent.java b/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraLoginStatusEvent.java new file mode 100644 index 0000000..5ee261a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraLoginStatusEvent.java @@ -0,0 +1,53 @@ +package com.eu.habbo.networking.camera.messages.incoming; + +import com.eu.habbo.networking.camera.CameraClient; +import com.eu.habbo.networking.camera.CameraIncomingMessage; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CameraLoginStatusEvent extends CameraIncomingMessage { + public final static int LOGIN_OK = 0; + public final static int LOGIN_ERROR = 1; + public final static int NO_ACCOUNT = 2; + public final static int ALREADY_LOGGED_IN = 3; + public final static int BANNED = 4; + public final static int OLD_BUILD = 5; + public final static int NO_CAMERA_SUBSCRIPTION = 6; + + public CameraLoginStatusEvent(Short header, ByteBuf body) { + super(header, body); + } + + @Override + public void handle(Channel client) throws Exception { + int status = this.readInt(); + + if (status == LOGIN_ERROR) { + log.error("Failed to login to Camera Server: Incorrect Details"); + } else if (status == NO_ACCOUNT) { + log.error("Failed to login to Camera Server: No Account Found. Register for free on the Arcturus Forums! Visit http://arcturus.pw/"); + } else if (status == BANNED) { + log.error("Sorry but you seem to be banned from the Arcturus forums and therefor cant use the Camera Server :'("); + } else if (status == ALREADY_LOGGED_IN) { + log.error("You seem to be already connected to the Camera Server"); + } else if (status == OLD_BUILD) { + log.error("This version of Arcturus Emulator is no longer supported by the Camera Server. Upgrade your emulator."); + } else if (status == NO_CAMERA_SUBSCRIPTION) { + log.error("You don't have a Camera Subscription and therefor cannot use the camera!"); + log.error("Please consider making a donation to keep this project going. The emulator can be used free of charge!"); + log.error("A trial version is available for $2.5. A year subscription is only $10 and a permanent subscription is $25."); + log.error("By donating this subscription you support the development of the emulator you are using :)"); + log.error("Visit http://arcturus.pw/mysubscriptions.php to buy your subscription!"); + log.error("Please Consider getting a subscription. Regards: The General"); + } + + if (status == LOGIN_OK) { + CameraClient.isLoggedIn = true; + log.info("Succesfully connected to the Arcturus Camera Server!"); + } else { + CameraClient.attemptReconnect = false; + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraResultURLEvent.java b/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraResultURLEvent.java new file mode 100644 index 0000000..61e0f01 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraResultURLEvent.java @@ -0,0 +1,56 @@ +package com.eu.habbo.networking.camera.messages.incoming; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.camera.CameraURLComposer; +import com.eu.habbo.networking.camera.CameraIncomingMessage; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; + +public class CameraResultURLEvent extends CameraIncomingMessage { + public final static int STATUS_OK = 0; + public final static int STATUS_ERROR = 1; + + public CameraResultURLEvent(Short header, ByteBuf body) { + super(header, body); + } + + @Override + public void handle(Channel client) throws Exception { + int userId = this.readInt(); + int status = this.readInt(); + String URL = this.readString(); + + if (!Emulator.getConfig().getBoolean("camera.use.https", true)) { + URL = URL.replace("https://", "http://"); + } + + int roomId = this.readInt(); + int timestamp = this.readInt(); + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + + if (status == STATUS_ERROR) { + if (habbo != null) { + habbo.getHabboInfo().setPhotoTimestamp(0); + habbo.getHabboInfo().setPhotoJSON(""); + habbo.getHabboInfo().setPhotoURL(""); + + habbo.alert(Emulator.getTexts().getValue("camera.error.creation")); + return; + } + } + + if (status == STATUS_OK) { + if (habbo != null) { + if (timestamp == habbo.getHabboInfo().getPhotoTimestamp()) { + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("CameraPhotoCount"), 1); + habbo.getClient().sendResponse(new CameraURLComposer(URL)); + habbo.getHabboInfo().setPhotoJSON(habbo.getHabboInfo().getPhotoJSON().replace("%room_id%", roomId + "").replace("%url%", URL)); + habbo.getHabboInfo().setPhotoURL(URL); + } + } + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraRoomThumbnailGeneratedEvent.java b/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraRoomThumbnailGeneratedEvent.java new file mode 100644 index 0000000..96783a2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraRoomThumbnailGeneratedEvent.java @@ -0,0 +1,25 @@ +package com.eu.habbo.networking.camera.messages.incoming; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.camera.CameraRoomThumbnailSavedComposer; +import com.eu.habbo.networking.camera.CameraIncomingMessage; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; + +public class CameraRoomThumbnailGeneratedEvent extends CameraIncomingMessage { + public CameraRoomThumbnailGeneratedEvent(Short header, ByteBuf body) { + super(header, body); + } + + @Override + public void handle(Channel client) throws Exception { + int userId = this.readInt(); + + Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId); + + if (habbo != null) { + habbo.getClient().sendResponse(new CameraRoomThumbnailSavedComposer()); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraUpdateNotification.java b/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraUpdateNotification.java new file mode 100644 index 0000000..566c37f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/incoming/CameraUpdateNotification.java @@ -0,0 +1,35 @@ +package com.eu.habbo.networking.camera.messages.incoming; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.outgoing.generic.alerts.GenericAlertComposer; +import com.eu.habbo.networking.camera.CameraIncomingMessage; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CameraUpdateNotification extends CameraIncomingMessage { + + public CameraUpdateNotification(Short header, ByteBuf body) { + super(header, body); + } + + @Override + public void handle(Channel client) throws Exception { + boolean alert = this.readBoolean(); + String message = this.readString(); + int type = this.readInt(); + + if (type == 0) { + log.info("Camera update: {}", message); + } else if (type == 1) { + log.warn("Camera update: {}", message); + } else if (type == 2) { + log.error("Camera update: {}", message); + } + + if (alert) { + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new GenericAlertComposer(message).compose()); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/outgoing/CameraLoginComposer.java b/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/outgoing/CameraLoginComposer.java new file mode 100644 index 0000000..f8b97a0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/outgoing/CameraLoginComposer.java @@ -0,0 +1,19 @@ +package com.eu.habbo.networking.camera.messages.outgoing; + +import com.eu.habbo.Emulator; +import com.eu.habbo.networking.camera.CameraOutgoingMessage; +import com.eu.habbo.networking.camera.messages.CameraOutgoingHeaders; +import io.netty.channel.Channel; + +public class CameraLoginComposer extends CameraOutgoingMessage { + public CameraLoginComposer() { + super(CameraOutgoingHeaders.LoginComposer); + } + + @Override + public void compose(Channel channel) { + this.appendString(Emulator.getConfig().getValue("username").trim()); + this.appendString(Emulator.getConfig().getValue("password").trim()); + this.appendString(Emulator.version); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/outgoing/CameraRenderImageComposer.java b/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/outgoing/CameraRenderImageComposer.java new file mode 100644 index 0000000..07c1087 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/camera/messages/outgoing/CameraRenderImageComposer.java @@ -0,0 +1,36 @@ +package com.eu.habbo.networking.camera.messages.outgoing; + +import com.eu.habbo.Emulator; +import com.eu.habbo.networking.camera.CameraOutgoingMessage; +import com.eu.habbo.networking.camera.messages.CameraOutgoingHeaders; +import io.netty.channel.Channel; + +public class CameraRenderImageComposer extends CameraOutgoingMessage { + public final int timestamp; + final int userId; + final int backgroundColor; + final int width; + final int height; + final String JSON; + + public CameraRenderImageComposer(int userId, int backgroundColor, int width, int height, String json) { + super(CameraOutgoingHeaders.RenderImageComposer); + + this.userId = userId; + this.timestamp = Emulator.getIntUnixTimestamp(); + this.backgroundColor = backgroundColor; + this.width = width; + this.height = height; + this.JSON = json; + } + + @Override + public void compose(Channel channel) { + this.appendInt32(this.userId); + this.appendInt32(this.timestamp); + this.appendInt32(this.backgroundColor); + this.appendInt32(this.width); + this.appendInt32(this.height); + this.appendString(this.JSON); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/gameserver/GameServer.java b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/GameServer.java new file mode 100644 index 0000000..98647cc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/GameServer.java @@ -0,0 +1,64 @@ +package com.eu.habbo.networking.gameserver; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClientManager; +import com.eu.habbo.messages.PacketManager; +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; + private final GameClientManager gameClientManager; + + public GameServer(String host, int port) throws Exception { + super("Game Server", host, port, Emulator.getConfig().getInt("io.bossgroup.threads"), Emulator.getConfig().getInt("io.workergroup.threads")); + this.packetManager = new PacketManager(); + this.gameClientManager = new GameClientManager(); + } + + @Override + public void initializePipeline() { + super.initializePipeline(); + + this.serverBootstrap.childHandler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + ch.pipeline().addLast("logger", new LoggingHandler()); + + // Decoders. + ch.pipeline().addLast(new GamePolicyDecoder()); + ch.pipeline().addLast(new GameByteFrameDecoder()); + ch.pipeline().addLast(new GameByteDecoder()); + + if (PacketManager.DEBUG_SHOW_PACKETS) { + ch.pipeline().addLast(new GameClientMessageLogger()); + } + ch.pipeline().addLast("idleEventHandler", new IdleTimeoutHandler(30, 60)); + ch.pipeline().addLast(new GameMessageRateLimit()); + ch.pipeline().addLast(new GameMessageHandler()); + + // Encoders. + ch.pipeline().addLast(new GameServerMessageEncoder()); + + if (PacketManager.DEBUG_SHOW_PACKETS) { + ch.pipeline().addLast(new GameServerMessageLogger()); + } + } + }); + } + + public PacketManager getPacketManager() { + return this.packetManager; + } + + public GameClientManager getGameClientManager() { + return this.gameClientManager; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/gameserver/GameServerAttributes.java b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/GameServerAttributes.java new file mode 100644 index 0000000..fca0073 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/GameServerAttributes.java @@ -0,0 +1,13 @@ +package com.eu.habbo.networking.gameserver; + +import com.eu.habbo.crypto.HabboRC4; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import io.netty.util.AttributeKey; + +public class GameServerAttributes { + + public static final AttributeKey CLIENT = AttributeKey.valueOf("GameClient"); + public static final AttributeKey CRYPTO_CLIENT = AttributeKey.valueOf("CryptoClient"); + public static final AttributeKey CRYPTO_SERVER = AttributeKey.valueOf("CryptoServer"); + +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameByteDecoder.java b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameByteDecoder.java new file mode 100644 index 0000000..e905eee --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameByteDecoder.java @@ -0,0 +1,19 @@ +package com.eu.habbo.networking.gameserver.decoders; + +import com.eu.habbo.messages.ClientMessage; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; + +import java.util.List; + +public class GameByteDecoder extends ByteToMessageDecoder { + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + short header = in.readShort(); + ByteBuf body = Unpooled.copiedBuffer(in.readBytes(in.readableBytes())); + + out.add(new ClientMessage(header, body)); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameByteDecryption.java b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameByteDecryption.java new file mode 100644 index 0000000..b1c91b7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameByteDecryption.java @@ -0,0 +1,29 @@ +package com.eu.habbo.networking.gameserver.decoders; + +import com.eu.habbo.networking.gameserver.GameServerAttributes; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; + +import java.util.List; + +public class GameByteDecryption extends ByteToMessageDecoder { + + public GameByteDecryption() { + setSingleDecode(true); + } + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + // Read all available bytes. + ByteBuf data = in.readBytes(in.readableBytes()); + + // Decrypt. + ctx.channel().attr(GameServerAttributes.CRYPTO_CLIENT).get().parse(data.array()); + + // Continue in the pipeline. + out.add(data); + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameByteFrameDecoder.java b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameByteFrameDecoder.java new file mode 100644 index 0000000..3007425 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameByteFrameDecoder.java @@ -0,0 +1,41 @@ +package com.eu.habbo.networking.gameserver.decoders; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; + +public class GameByteFrameDecoder extends LengthFieldBasedFrameDecoder { + + private static final int MAX_PACKET_LENGTH = 2097152; // 2 MB + private static final int LENGTH_FIELD_OFFSET = 0; + private static final int LENGTH_FIELD_LENGTH = 4; + private static final int LENGTH_FIELD_ADJUSTMENT = 0; + private static final int INITIAL_BYTES_TO_STRIP = 4; + + public GameByteFrameDecoder() { + super(MAX_PACKET_LENGTH, LENGTH_FIELD_OFFSET, LENGTH_FIELD_LENGTH, LENGTH_FIELD_ADJUSTMENT, INITIAL_BYTES_TO_STRIP); + } + + @Override + protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { + if (in.readableBytes() < LENGTH_FIELD_LENGTH) { + // Wait until we have at least LENGTH_FIELD_LENGTH bytes available + return null; + } + + int packetLength = in.getInt(in.readerIndex()); + if (packetLength > MAX_PACKET_LENGTH) { + // Packet exceeds limit, could be an indication of problem or attack + ctx.close(); // Close channel + return null; + } + + if (in.readableBytes() < LENGTH_FIELD_LENGTH + packetLength) { + // Wait until we have all packet bytes available + return null; + } + + // Everything seems to be in order, continue with normal decoding + return super.decode(ctx, in); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameClientMessageLogger.java b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameClientMessageLogger.java new file mode 100644 index 0000000..63b9caa --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameClientMessageLogger.java @@ -0,0 +1,30 @@ +package com.eu.habbo.networking.gameserver.decoders; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.PacketNames; +import com.eu.habbo.util.ANSI; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageDecoder; +import lombok.extern.slf4j.Slf4j; +import java.util.List; + +@Slf4j +public class GameClientMessageLogger extends MessageToMessageDecoder { + private final PacketNames names; + + public GameClientMessageLogger() { + this.names = Emulator.getGameServer().getPacketManager().getNames(); + } + + @Override + protected void decode(ChannelHandlerContext ctx, ClientMessage message, List out) { + log.debug(String.format("[" + ANSI.GREEN + "CLIENT" + ANSI.DEFAULT + "][%-4d][%-41s] => %s", + message.getMessageId(), + this.names.getIncomingName(message.getMessageId()), + message.getMessageBody())); + + out.add(message); + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameMessageHandler.java b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameMessageHandler.java new file mode 100644 index 0000000..1e3a4a3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameMessageHandler.java @@ -0,0 +1,104 @@ +package com.eu.habbo.networking.gameserver.decoders; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.PacketManager; +import com.eu.habbo.threading.runnables.ChannelReadHandler; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.handler.codec.DecoderException; +import io.netty.handler.codec.TooLongFrameException; +import io.netty.handler.codec.UnsupportedMessageTypeException; +import io.netty.handler.ssl.NotSslRecordException; +import io.netty.util.AttributeKey; +import lombok.extern.slf4j.Slf4j; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLHandshakeException; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; + +@ChannelHandler.Sharable +@Slf4j +public class GameMessageHandler extends ChannelInboundHandlerAdapter { + @Override + public void channelRegistered(ChannelHandlerContext ctx) { + if (!Emulator.getGameServer().getGameClientManager().addClient(ctx)) { + ctx.channel().close(); + } + } + + @Override + public void channelUnregistered(ChannelHandlerContext ctx) { + ctx.channel().close(); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + ClientMessage message = (ClientMessage) msg; + + try { + ChannelReadHandler handler = new ChannelReadHandler(ctx, message); + + if (PacketManager.MULTI_THREADED_PACKET_HANDLING) { + Emulator.getThreading().run(handler); + return; + } + + handler.run(); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + ctx.channel().close(); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + if (cause instanceof IOException) { + ctx.channel().close(); + return; + } + if (Emulator.getConfig().getBoolean("debug.mode")) { + String clientIpAddress = ctx.channel().remoteAddress().toString(); + String xForwardedFor = (String) ctx.channel().attr(AttributeKey.valueOf("X-Forwarded-For")).get(); + if (xForwardedFor != null && !xForwardedFor.isEmpty()) { + clientIpAddress = xForwardedFor; + } + clientIpAddress = clientIpAddress.substring(1, clientIpAddress.lastIndexOf(':')); + + if (cause instanceof NotSslRecordException) { + log.error("Someone speaks transport plaintext instead of SSL, IP: {}", clientIpAddress); + } + else if (cause instanceof DecoderException) { + log.error("Someone speaks transport plaintext instead of SSL, IP: {}", clientIpAddress); + } + else if (cause instanceof TooLongFrameException) { + log.error("Disconnecting client, reason: {}", cause.getMessage()); + } + else if (cause instanceof SSLHandshakeException) { + log.error("URL Request error from source: {}", clientIpAddress); + } + else if (cause instanceof NoSuchAlgorithmException) { + log.error("Invalid SSL algorithm, only TLSv1.2 supported in the request, IP: {}", clientIpAddress); + } + else if (cause instanceof KeyManagementException) { + log.error("Invalid SSL algorithm, only TLSv1.2 supported in the request, IP: {}", clientIpAddress); + } + else if (cause instanceof UnsupportedMessageTypeException) { + log.error("There was an illegal SSL request from (X-forwarded-for/CF-Connecting-IP has not being injected yet!) {}", clientIpAddress); + } + else if (cause instanceof SSLException) { + log.error("SSL Problem: {}", cause.getMessage() + cause); + } + else { + log.error("Disconnecting client, exception in GameMessageHandler.", cause); + } + } + ctx.channel().close(); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameMessageRateLimit.java b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameMessageRateLimit.java new file mode 100644 index 0000000..6f0db54 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GameMessageRateLimit.java @@ -0,0 +1,44 @@ +package com.eu.habbo.networking.gameserver.decoders; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.networking.gameserver.GameServerAttributes; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageDecoder; + +import java.util.List; +import java.util.logging.Logger; + +public class GameMessageRateLimit extends MessageToMessageDecoder { + private static final int RESET_TIME = 1; + private static final int MAX_COUNTER = 10; + private static final Logger logger = Logger.getLogger(GameMessageRateLimit.class.getName()); + + @Override + protected void decode(ChannelHandlerContext ctx, ClientMessage message, List out) throws Exception { + GameClient client = ctx.channel().attr(GameServerAttributes.CLIENT).get(); + + if (client == null) { + return; + } + + int timestamp = Emulator.getIntUnixTimestamp(); + if (timestamp - client.lastPacketCounterCleared > RESET_TIME) { + client.incomingPacketCounter.clear(); + client.lastPacketCounterCleared = timestamp; + } + + int count = client.incomingPacketCounter.getOrDefault(message.getMessageId(), 0); + + if (count > MAX_COUNTER) { + String userIP = ctx.channel().remoteAddress().toString(); + logger.warning(String.format("User with IP %s exceeded the message rate limit for message ID %s", userIP, message.getMessageId())); + return; + } + + client.incomingPacketCounter.put(message.getMessageId(), count + 1); + + out.add(message); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GamePolicyDecoder.java b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GamePolicyDecoder.java new file mode 100644 index 0000000..8293809 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/decoders/GamePolicyDecoder.java @@ -0,0 +1,39 @@ +package com.eu.habbo.networking.gameserver.decoders; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; +import io.netty.util.CharsetUtil; + +import java.util.List; + +public class GamePolicyDecoder extends ByteToMessageDecoder { + + private static final String POLICY = "\n" + + " \n" + + " \n" + + " \n" + + " " + (char) 0; + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + in.markReaderIndex(); + + byte b = in.readByte(); + if (b == '<') { + in.resetReaderIndex(); + ctx.writeAndFlush(Unpooled.copiedBuffer(POLICY, CharsetUtil.UTF_8)) + .addListener(ChannelFutureListener.CLOSE); + return; + } + + // Remove ourselves since the first packet was not a policy request. + ctx.pipeline().remove(this); + + // Continue to the other pipelines. + in.resetReaderIndex(); + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/gameserver/encoders/GameByteEncryption.java b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/encoders/GameByteEncryption.java new file mode 100644 index 0000000..0c20b97 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/encoders/GameByteEncryption.java @@ -0,0 +1,30 @@ +package com.eu.habbo.networking.gameserver.encoders; + +import com.eu.habbo.networking.gameserver.GameServerAttributes; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelOutboundHandlerAdapter; +import io.netty.channel.ChannelPromise; +import io.netty.util.ReferenceCountUtil; + +public class GameByteEncryption extends ChannelOutboundHandlerAdapter { + + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + // convert to Bytebuf + ByteBuf in = (ByteBuf) msg; + + // read available bytes + ByteBuf data = (in).readBytes(in.readableBytes()); + + //release old object + ReferenceCountUtil.release(in); + + // Encrypt. + ctx.channel().attr(GameServerAttributes.CRYPTO_SERVER).get().parse(data.array()); + + // Continue in the pipeline. + ctx.write(data, promise); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/gameserver/encoders/GameServerMessageEncoder.java b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/encoders/GameServerMessageEncoder.java new file mode 100644 index 0000000..51fdacf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/encoders/GameServerMessageEncoder.java @@ -0,0 +1,29 @@ +package com.eu.habbo.networking.gameserver.encoders; + +import com.eu.habbo.messages.ServerMessage; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; +import io.netty.util.IllegalReferenceCountException; + +import java.io.IOException; + +public class GameServerMessageEncoder extends MessageToByteEncoder { + + @Override + protected void encode(ChannelHandlerContext ctx, ServerMessage message, ByteBuf out) throws Exception { + try { + ByteBuf buf = message.get(); + + try { + out.writeBytes(buf); + } finally { + // Release copied buffer. + buf.release(); + } + } catch (IllegalReferenceCountException e) { + throw new IOException(String.format("IllegalReferenceCountException happened for ServerMessage with packet id %d.", message.getHeader()), e); + } + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/gameserver/encoders/GameServerMessageLogger.java b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/encoders/GameServerMessageLogger.java new file mode 100644 index 0000000..5ae445a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/encoders/GameServerMessageLogger.java @@ -0,0 +1,30 @@ +package com.eu.habbo.networking.gameserver.encoders; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.PacketNames; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.util.ANSI; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageEncoder; +import lombok.extern.slf4j.Slf4j; +import java.util.List; + +@Slf4j +public class GameServerMessageLogger extends MessageToMessageEncoder { + private final PacketNames names; + + public GameServerMessageLogger() { + this.names = Emulator.getGameServer().getPacketManager().getNames(); + } + + @Override + protected void encode(ChannelHandlerContext ctx, ServerMessage message, List out) { + log.debug(String.format("[" + ANSI.BLUE + "SERVER" + ANSI.DEFAULT + "][%-4d][%-41s] => %s", + message.getHeader(), + this.names.getOutgoingName(message.getHeader()), + message.getBodyString())); + + out.add(message); + } + +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/gameserver/handlers/IdleTimeoutHandler.java b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/handlers/IdleTimeoutHandler.java new file mode 100644 index 0000000..e17e2d9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/gameserver/handlers/IdleTimeoutHandler.java @@ -0,0 +1,148 @@ +package com.eu.habbo.networking.gameserver.handlers; + +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.messages.incoming.Incoming; +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 java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +public class IdleTimeoutHandler extends ChannelDuplexHandler { + private static final long MIN_TIMEOUT_NANOS = TimeUnit.MILLISECONDS.toNanos(1); + + private final long pingScheduleNanos; + private final long pongTimeoutNanos; + + volatile ScheduledFuture pingScheduleFuture; + volatile boolean sentPing; + volatile long lastPingTime; // in nanoseconds + volatile long lastPongTime; // in nanoseconds + + private volatile int state; // 0 - none, 1 - initialized, 2 - destroyed + + public IdleTimeoutHandler(int pingScheduleSeconds, int pongTimeoutSeconds) { + this.pingScheduleNanos = Math.max(MIN_TIMEOUT_NANOS, TimeUnit.SECONDS.toNanos(pingScheduleSeconds)); + this.pongTimeoutNanos = Math.max(MIN_TIMEOUT_NANOS, TimeUnit.SECONDS.toNanos(pongTimeoutSeconds)); + } + + private void initialize(ChannelHandlerContext ctx) { + // Avoid the case where destroy() is called before scheduling timeouts. + // See: https://github.com/netty/netty/issues/143 + switch (state) { + case 1: + case 2: + return; + } + + state = 1; + + lastPongTime = System.nanoTime(); + if (pingScheduleNanos > 0) { + pingScheduleFuture = ctx.executor().schedule(new PingScheduledTask(ctx), pingScheduleNanos, TimeUnit.NANOSECONDS); + } + } + + private void destroy() { + state = 2; + + if (pingScheduleFuture != null) { + pingScheduleFuture.cancel(false); + pingScheduleFuture = null; + } + } + + @Override + public void handlerAdded(ChannelHandlerContext ctx) throws Exception { + if (ctx.channel().isActive() && ctx.channel().isRegistered()) { + // channelActvie() event has been fired already, which means this.channelActive() will + // not be invoked. We have to initialize here instead. + initialize(ctx); + } else { + // channelActive() event has not been fired yet. this.channelActive() will be invoked + // and initialization will occur there. + } + } + + @Override + public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { + destroy(); + } + + @Override + public void channelRegistered(ChannelHandlerContext ctx) throws Exception { + // Initialize early if channel is active already. + if (ctx.channel().isActive()) { + initialize(ctx); + } + super.channelRegistered(ctx); + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + // This method will be invoked only if this handler was added + // before channelActive() event is fired. If a user adds this handler + // after the channelActive() event, initialize() will be called by beforeAdd(). + initialize(ctx); + super.channelActive(ctx); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + destroy(); + super.channelInactive(ctx); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + // check if its a pong message + if (msg instanceof ClientMessage) { + ClientMessage packet = (ClientMessage) msg; + if (packet.getMessageId() == Incoming.PongEvent) { + this.lastPongTime = System.nanoTime(); + + final GameClient client = ctx.channel().attr(GameServerAttributes.CLIENT).get(); + if (client != null) { + if (sentPing) { + sentPing = false; + client.getLatencyTracker().update(lastPongTime - lastPingTime); + } + } + } + } + super.channelRead(ctx, msg); + } + + private final class PingScheduledTask implements Runnable { + private final ChannelHandlerContext ctx; + + public PingScheduledTask(ChannelHandlerContext ctx) { + this.ctx = ctx; + } + + @Override + public void run() { + if (!ctx.channel().isOpen()) { + return; + } + + long currentTime = System.nanoTime(); + if (currentTime - lastPongTime > pongTimeoutNanos) { + ctx.close();// add a promise here ? + return; + } + + final GameClient client = ctx.channel().attr(GameServerAttributes.CLIENT).get(); + if (client != null) { + lastPingTime = System.nanoTime(); + sentPing = true; + client.sendResponse(new PingComposer()); + } + + pingScheduleFuture = ctx.executor().schedule(this, pingScheduleNanos, TimeUnit.NANOSECONDS); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/rconserver/RCONServer.java b/Emulator/src/main/java/com/eu/habbo/networking/rconserver/RCONServer.java new file mode 100644 index 0000000..0d29e43 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/rconserver/RCONServer.java @@ -0,0 +1,110 @@ +package com.eu.habbo.networking.rconserver; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.rcon.*; +import com.eu.habbo.networking.Server; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import gnu.trove.map.hash.THashMap; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.socket.SocketChannel; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Slf4j +public class RCONServer extends Server { + private final THashMap> messages; + private final GsonBuilder gsonBuilder; + List allowedAdresses = new ArrayList<>(); + + public RCONServer(String host, int port) throws Exception { + super("RCON Server", host, port, 1, 2); + this.messages = new THashMap<>(); + this.gsonBuilder = new GsonBuilder(); + this.gsonBuilder.registerTypeAdapter(RCONMessage.class, new RCONMessage.RCONMessageSerializer()); + this.addRCONMessage("alertuser", AlertUser.class); + this.addRCONMessage("disconnect", DisconnectUser.class); + this.addRCONMessage("forwarduser", ForwardUser.class); + this.addRCONMessage("givebadge", GiveBadge.class); + this.addRCONMessage("givecredits", GiveCredits.class); + this.addRCONMessage("givepixels", GivePixels.class); + this.addRCONMessage("givepoints", GivePoints.class); + this.addRCONMessage("hotelalert", HotelAlert.class); + this.addRCONMessage("sendgift", SendGift.class); + this.addRCONMessage("sendroombundle", SendRoomBundle.class); + this.addRCONMessage("setrank", SetRank.class); + this.addRCONMessage("updatewordfilter", UpdateWordfilter.class); + this.addRCONMessage("updatecatalog", UpdateCatalog.class); + this.addRCONMessage("executecommand", ExecuteCommand.class); + this.addRCONMessage("progressachievement", ProgressAchievement.class); + this.addRCONMessage("updateuser", UpdateUser.class); + this.addRCONMessage("friendrequest", FriendRequest.class); + this.addRCONMessage("imagehotelalert", ImageHotelAlert.class); + this.addRCONMessage("imagealertuser", ImageAlertUser.class); + this.addRCONMessage("stalkuser", StalkUser.class); + this.addRCONMessage("staffalert", StaffAlert.class); + this.addRCONMessage("modticket", CreateModToolTicket.class); + this.addRCONMessage("talkuser", TalkUser.class); + this.addRCONMessage("changeroomowner", ChangeRoomOwner.class); + this.addRCONMessage("muteuser", MuteUser.class); + this.addRCONMessage("giverespect", GiveRespect.class); + this.addRCONMessage("ignoreuser", IgnoreUser.class); + this.addRCONMessage("setmotto", SetMotto.class); + this.addRCONMessage("giveuserclothing", GiveUserClothing.class); + this.addRCONMessage("modifysubscription", ModifyUserSubscription.class); + this.addRCONMessage("changeusername", ChangeUsername.class); + + Collections.addAll(this.allowedAdresses, Emulator.getConfig().getValue("rcon.allowed", "127.0.0.1").split(";")); + } + + @Override + public void initializePipeline() { + super.initializePipeline(); + + this.serverBootstrap.childHandler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + ch.pipeline().addLast(new RCONServerHandler()); + } + }); + } + + + public void addRCONMessage(String key, Class clazz) { + this.messages.put(key, clazz); + } + + public String handle(ChannelHandlerContext ctx, String key, String body) throws Exception { + Class message = this.messages.get(key.replace("_", "").toLowerCase()); + + String result; + if (message != null) { + try { + RCONMessage rcon = message.getDeclaredConstructor().newInstance(); + Gson gson = this.gsonBuilder.create(); + rcon.handle(gson, gson.fromJson(body, rcon.type)); + log.info("Handled RCON Message: {}", message.getSimpleName()); + result = gson.toJson(rcon, RCONMessage.class); + + if (Emulator.debugging) { + log.debug("RCON Data {} RCON Result {}", body, result); + } + + return result; + } catch (Exception ex) { + log.error("Failed to handle RCONMessage", ex); + } + } else { + log.error("Couldn't find: {}", key); + } + + throw new ArrayIndexOutOfBoundsException("Unhandled RCON Message"); + } + + public List getCommands() { + return new ArrayList<>(this.messages.keySet()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/rconserver/RCONServerHandler.java b/Emulator/src/main/java/com/eu/habbo/networking/rconserver/RCONServerHandler.java new file mode 100644 index 0000000..7279823 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/rconserver/RCONServerHandler.java @@ -0,0 +1,57 @@ +package com.eu.habbo.networking.rconserver; + +import com.eu.habbo.Emulator; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RCONServerHandler extends ChannelInboundHandlerAdapter { + @Override + public void channelRegistered(ChannelHandlerContext ctx) throws Exception { + String adress = ctx.channel().remoteAddress().toString().split(":")[0].replace("/", ""); + + for (String s : Emulator.getRconServer().allowedAdresses) { + if (s.equalsIgnoreCase(adress)) { + return; + } + } + + ctx.channel().close(); + + log.warn("RCON Remote connection closed: {}. IP not allowed!", adress); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + ByteBuf data = (ByteBuf) msg; + + byte[] d = new byte[data.readableBytes()]; + data.getBytes(0, d); + String message = new String(d); + Gson gson = new Gson(); + String response = "ERROR"; + String key = ""; + try { + JsonObject object = gson.fromJson(message, JsonObject.class); + key = object.get("key").getAsString(); + response = Emulator.getRconServer().handle(ctx, key, object.get("data").toString()); + } catch (ArrayIndexOutOfBoundsException e) { + log.error("Unknown RCON Message: {}", key); + } catch (Exception e) { + log.error("Invalid RCON Message: {}", message); + e.printStackTrace(); + } + + ChannelFuture f = ctx.channel().write(Unpooled.copiedBuffer(response.getBytes()), ctx.channel().voidPromise()); + ctx.channel().flush(); + ctx.flush(); + f.channel().close(); + data.release(); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/websockets/NetworkChannelInitializer.java b/Emulator/src/main/java/com/eu/habbo/networking/websockets/NetworkChannelInitializer.java new file mode 100644 index 0000000..4902242 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/websockets/NetworkChannelInitializer.java @@ -0,0 +1,74 @@ +package com.eu.habbo.networking.websockets; + +import com.eu.habbo.messages.PacketManager; +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 com.eu.habbo.networking.websockets.codec.WebSocketCodec; +import com.eu.habbo.networking.websockets.handlers.CustomHTTPHandler; +import com.eu.habbo.networking.websockets.ssl.SSLCertificateLoader; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.socket.SocketChannel; +import io.netty.handler.codec.http.HttpObjectAggregator; +import io.netty.handler.codec.http.HttpServerCodec; +import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolConfig; +import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; +import io.netty.handler.logging.LoggingHandler; +import io.netty.handler.ssl.SslContext; + +public class NetworkChannelInitializer extends ChannelInitializer { + private static final int MAX_FRAME_SIZE = 500000; + + private final SslContext context; + private final boolean isSSL; + private final WebSocketServerProtocolConfig config; + + public NetworkChannelInitializer() { + context = SSLCertificateLoader.getContext(); + isSSL = context != null; + config = WebSocketServerProtocolConfig.newBuilder() + .websocketPath("/") + .checkStartsWith(true) + .maxFramePayloadLength(MAX_FRAME_SIZE) + .build(); + } + + @Override + public void initChannel(SocketChannel ch) { + ch.pipeline().addLast("logger", new LoggingHandler()); + + if(isSSL) { + ch.pipeline().addLast(context.newHandler(ch.alloc())); + } + ch.pipeline().addLast("httpCodec", new HttpServerCodec()); + ch.pipeline().addLast("objectAggregator", new HttpObjectAggregator(MAX_FRAME_SIZE)); + ch.pipeline().addLast("customHttpHandler", new CustomHTTPHandler()); + ch.pipeline().addLast("protocolHandler", new WebSocketServerProtocolHandler(config)); + ch.pipeline().addLast("websocketCodec", new WebSocketCodec()); + + // Decoders. + ch.pipeline().addLast(new GamePolicyDecoder()); + ch.pipeline().addLast(new GameByteFrameDecoder()); + ch.pipeline().addLast(new GameByteDecoder()); + + if (PacketManager.DEBUG_SHOW_PACKETS) { + ch.pipeline().addLast(new GameClientMessageLogger()); + } + + ch.pipeline().addLast("idleEventHandler", new IdleTimeoutHandler(30, 60)); + ch.pipeline().addLast(new GameMessageRateLimit()); + ch.pipeline().addLast(new GameMessageHandler()); + + // Encoders. + ch.pipeline().addLast("messageEncoder", new GameServerMessageEncoder()); + + if (PacketManager.DEBUG_SHOW_PACKETS) { + ch.pipeline().addLast(new GameServerMessageLogger()); + } + } + + public boolean isSSL() { + return isSSL; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/websockets/codec/WebSocketCodec.java b/Emulator/src/main/java/com/eu/habbo/networking/websockets/codec/WebSocketCodec.java new file mode 100644 index 0000000..6c36f54 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/websockets/codec/WebSocketCodec.java @@ -0,0 +1,22 @@ +package com.eu.habbo.networking.websockets.codec; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageCodec; +import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; +import io.netty.handler.codec.http.websocketx.WebSocketFrame; + +import java.util.List; + +public class WebSocketCodec extends MessageToMessageCodec { + @Override + protected void encode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + out.add(new BinaryWebSocketFrame(in).retain()); + } + + @Override + protected void decode(ChannelHandlerContext ctx, WebSocketFrame in, List out) { + out.add(in.content().retain()); + } +} + diff --git a/Emulator/src/main/java/com/eu/habbo/networking/websockets/handlers/CustomHTTPHandler.java b/Emulator/src/main/java/com/eu/habbo/networking/websockets/handlers/CustomHTTPHandler.java new file mode 100644 index 0000000..e77c99c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/websockets/handlers/CustomHTTPHandler.java @@ -0,0 +1,64 @@ +package com.eu.habbo.networking.websockets.handlers; + +import com.eu.habbo.Emulator; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.handler.codec.http.*; +import io.netty.util.ReferenceCountUtil; +import com.eu.habbo.networking.websockets.utils.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CustomHTTPHandler extends ChannelInboundHandlerAdapter { + private static final String ORIGIN_HEADER = "Origin"; + private static final Logger LOGGER = LoggerFactory.getLogger(CustomHTTPHandler.class); + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + if(msg instanceof HttpMessage) { + if(!handleHttpRequest(ctx, (HttpMessage) msg)) + { + ReferenceCountUtil.release(msg);//discard message + return; + } + } + super.channelRead(ctx, msg); + ctx.pipeline().remove(this); + } + + public boolean handleHttpRequest(ChannelHandlerContext ctx, HttpMessage req) { + String origin = "error"; + String clientIP; + String header = Emulator.getConfig().getValue("ws.nitro.ip.header", ""); + + // Check if X-Forwarded-For header is present and use the first IP as the client IP if available + if (req.headers().contains(header)) { + String xForwardedFor = req.headers().get(header); + clientIP = xForwardedFor.split(",")[0].trim(); // Get the first IP in the list + } else { + clientIP = ctx.channel().remoteAddress().toString().substring(1).split(":")[0]; // Get the client's IP address + } + + try { + if(req.headers().contains(ORIGIN_HEADER)) { + origin = Utils.getDomainNameFromUrl(req.headers().get(ORIGIN_HEADER)); + } + } catch (Exception ignored) { } + + if(!Utils.isWhitelisted(origin, Emulator.getConfig().getValue("websockets.whitelist", "localhost").split(","))) { + LOGGER.warn("Access denied for IP: {}", clientIP); + + FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.FORBIDDEN, Unpooled.wrappedBuffer("W.T.F are you doing?".getBytes())); + ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); + return false; + } + + if(!header.isEmpty() && req.headers().contains(header)) { + String ip = req.headers().get(header); + ctx.channel().attr(Emulator.WS_IP).set(ip); + } + return true; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/networking/websockets/ssl/SSLCertificateLoader.java b/Emulator/src/main/java/com/eu/habbo/networking/websockets/ssl/SSLCertificateLoader.java new file mode 100644 index 0000000..623568f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/websockets/ssl/SSLCertificateLoader.java @@ -0,0 +1,24 @@ +package com.eu.habbo.networking.websockets.ssl; + +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; + +public class SSLCertificateLoader { + private static final String filePath = "ssl"; + private static final Logger LOGGER = LoggerFactory.getLogger(SSLCertificateLoader.class); + + public static SslContext getContext() { + SslContext context; + try { + context = SslContextBuilder.forServer(new File( filePath + File.separator + "cert.pem" ), new File( filePath + File.separator + "privkey.pem" )).build(); + } catch ( Exception e ) { + LOGGER.info("Unable to load ssl: " + e.getMessage()); + context = null; + } + return context; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/networking/websockets/utils/Utils.java b/Emulator/src/main/java/com/eu/habbo/networking/websockets/utils/Utils.java new file mode 100644 index 0000000..30f8217 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/networking/websockets/utils/Utils.java @@ -0,0 +1,22 @@ +package com.eu.habbo.networking.websockets.utils; + +import java.net.URI; + +public class Utils { + public static String getDomainNameFromUrl(String url) throws Exception { + URI uri = new URI(url); + String domain = uri.getHost(); + return domain.startsWith("www.") ? domain.substring(4) : domain; + } + + public static boolean isWhitelisted(String toCheck, String[] whitelist) { + for(String whitelistEntry : whitelist) { + if(whitelistEntry.startsWith("*")) { + if(toCheck.endsWith(whitelistEntry.substring(1)) || ("." + toCheck).equals(whitelistEntry.substring(1))) return true; + } else { + if(toCheck.equals(whitelistEntry)) return true; + } + } + return false; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/Event.java b/Emulator/src/main/java/com/eu/habbo/plugin/Event.java new file mode 100644 index 0000000..91da0f3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/Event.java @@ -0,0 +1,13 @@ +package com.eu.habbo.plugin; + +public abstract class Event { + private boolean cancelled = false; + + public boolean isCancelled() { + return this.cancelled; + } + + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/EventHandler.java b/Emulator/src/main/java/com/eu/habbo/plugin/EventHandler.java new file mode 100644 index 0000000..218811a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/EventHandler.java @@ -0,0 +1,18 @@ +package com.eu.habbo.plugin; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface EventHandler { + + + EventPriority priority() default EventPriority.NORMAL; + + + boolean ignoreCancelled() default false; +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/EventListener.java b/Emulator/src/main/java/com/eu/habbo/plugin/EventListener.java new file mode 100644 index 0000000..f5b5995 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/EventListener.java @@ -0,0 +1,4 @@ +package com.eu.habbo.plugin; + +public interface EventListener { +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/EventPriority.java b/Emulator/src/main/java/com/eu/habbo/plugin/EventPriority.java new file mode 100644 index 0000000..62488f5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/EventPriority.java @@ -0,0 +1,26 @@ +package com.eu.habbo.plugin; + +public enum EventPriority { + + LOWEST(0), + + LOW(1), + + NORMAL(2), + + HIGH(3), + + HIGHEST(4), + + MONITOR(5); + + private final int slot; + + EventPriority(int slot) { + this.slot = slot; + } + + public int getSlot() { + return this.slot; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/HabboPlugin.java b/Emulator/src/main/java/com/eu/habbo/plugin/HabboPlugin.java new file mode 100644 index 0000000..56d2da1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/HabboPlugin.java @@ -0,0 +1,27 @@ +package com.eu.habbo.plugin; + +import com.eu.habbo.habbohotel.users.Habbo; +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + +import java.io.InputStream; +import java.lang.reflect.Method; +import java.net.URLClassLoader; + +public abstract class HabboPlugin { + public final THashMap, THashSet> registeredEvents = new THashMap<>(); + + public HabboPluginConfiguration configuration; + public URLClassLoader classLoader; + public InputStream stream; + + public abstract void onEnable() throws Exception; + + public abstract void onDisable() throws Exception; + + public boolean isRegistered(Class clazz) { + return this.registeredEvents.containsKey(clazz); + } + + public abstract boolean hasPermission(Habbo habbo, String key); +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/HabboPluginConfiguration.java b/Emulator/src/main/java/com/eu/habbo/plugin/HabboPluginConfiguration.java new file mode 100644 index 0000000..621845a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/HabboPluginConfiguration.java @@ -0,0 +1,7 @@ +package com.eu.habbo.plugin; + +public class HabboPluginConfiguration { + public String name; + public String author; + public String main; +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/PluginManager.java b/Emulator/src/main/java/com/eu/habbo/plugin/PluginManager.java new file mode 100644 index 0000000..5cfbd07 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/PluginManager.java @@ -0,0 +1,429 @@ +package com.eu.habbo.plugin; + +import com.eu.habbo.Emulator; +import com.eu.habbo.core.Easter; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.bots.BotManager; +import com.eu.habbo.habbohotel.catalog.CatalogManager; +import com.eu.habbo.habbohotel.catalog.TargetOffer; +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlace; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.games.freeze.FreezeGame; +import com.eu.habbo.habbohotel.games.tag.TagGame; +import com.eu.habbo.habbohotel.items.ItemManager; +import com.eu.habbo.habbohotel.items.interactions.InteractionPostIt; +import com.eu.habbo.habbohotel.items.interactions.InteractionRoller; +import com.eu.habbo.habbohotel.items.interactions.games.football.InteractionFootballGate; +import com.eu.habbo.habbohotel.messenger.Messenger; +import com.eu.habbo.habbohotel.modtool.WordFilter; +import com.eu.habbo.habbohotel.navigation.EventCategory; +import com.eu.habbo.habbohotel.navigation.NavigatorManager; +import com.eu.habbo.habbohotel.pets.PetManager; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.HabboInventory; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.eu.habbo.habbohotel.users.clothingvalidation.ClothingValidationManager; +import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionHabboClub; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.messages.PacketManager; +import com.eu.habbo.messages.incoming.camera.CameraPublishToWebEvent; +import com.eu.habbo.messages.incoming.camera.CameraPurchaseEvent; +import com.eu.habbo.messages.incoming.catalog.CheckPetNameEvent; +import com.eu.habbo.messages.incoming.floorplaneditor.FloorPlanEditorSaveEvent; +import com.eu.habbo.messages.incoming.hotelview.HotelViewRequestLTDAvailabilityEvent; +import com.eu.habbo.messages.incoming.rooms.promotions.BuyRoomPromotionEvent; +import com.eu.habbo.messages.incoming.users.ChangeNameCheckUsernameEvent; +import com.eu.habbo.messages.outgoing.catalog.DiscountComposer; +import com.eu.habbo.messages.outgoing.catalog.GiftConfigurationComposer; +import com.eu.habbo.messages.outgoing.navigator.NewNavigatorEventCategoriesComposer; +import com.eu.habbo.plugin.events.emulator.EmulatorConfigUpdatedEvent; +import com.eu.habbo.plugin.events.roomunit.RoomUnitLookAtPointEvent; +import com.eu.habbo.plugin.events.users.*; +import com.eu.habbo.threading.runnables.RoomTrashing; +import com.eu.habbo.threading.runnables.ShutdownEmulator; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import gnu.trove.iterator.hash.TObjectHashIterator; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Arrays; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +@Slf4j +public class PluginManager { + private final THashSet plugins = new THashSet<>(); + private final THashSet methods = new THashSet<>(); + + @EventHandler + public static void globalOnConfigurationUpdated(EmulatorConfigUpdatedEvent event) { + + ItemManager.RECYCLER_ENABLED = Emulator.getConfig().getBoolean("hotel.catalog.recycler.enabled"); + MarketPlace.MARKETPLACE_ENABLED = Emulator.getConfig().getBoolean("hotel.marketplace.enabled"); + MarketPlace.MARKETPLACE_CURRENCY = Emulator.getConfig().getInt("hotel.marketplace.currency"); + Messenger.SAVE_PRIVATE_CHATS = Emulator.getConfig().getBoolean("save.private.chats", false); + 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); + RoomTrade.TRADING_ENABLED = Emulator.getConfig().getBoolean("hotel.trading.enabled") && !ShutdownEmulator.instantiated; + RoomTrade.TRADING_REQUIRES_PERK = Emulator.getConfig().getBoolean("hotel.trading.requires.perk"); + WordFilter.ENABLED_FRIENDCHAT = Emulator.getConfig().getBoolean("hotel.wordfilter.messenger"); + DiscountComposer.MAXIMUM_ALLOWED_ITEMS = Emulator.getConfig().getInt("discount.max.allowed.items", 100); + DiscountComposer.DISCOUNT_BATCH_SIZE = Emulator.getConfig().getInt("discount.batch.size", 6); + DiscountComposer.DISCOUNT_AMOUNT_PER_BATCH = Emulator.getConfig().getInt("discount.batch.free.items", 1); + DiscountComposer.MINIMUM_DISCOUNTS_FOR_BONUS = Emulator.getConfig().getInt("discount.bonus.min.discounts", 1); + DiscountComposer.ADDITIONAL_DISCOUNT_THRESHOLDS = Arrays.stream(Emulator.getConfig().getValue("discount.additional.thresholds", "40;99").split(";")).mapToInt(Integer::parseInt).toArray(); + + BotManager.MINIMUM_CHAT_SPEED = Emulator.getConfig().getInt("hotel.bot.chat.minimum.interval"); + BotManager.MAXIMUM_CHAT_LENGTH = Emulator.getConfig().getInt("hotel.bot.max.chatlength"); + BotManager.MAXIMUM_NAME_LENGTH = Emulator.getConfig().getInt("hotel.bot.max.namelength"); + BotManager.MAXIMUM_CHAT_SPEED = Emulator.getConfig().getInt("hotel.bot.max.chatdelay"); + Bot.PLACEMENT_MESSAGES = Emulator.getConfig().getValue("hotel.bot.placement.messages", "Yo!;Hello I'm a real party animal!;Hello!").split(";"); + + HabboInventory.MAXIMUM_ITEMS = Emulator.getConfig().getInt("hotel.inventory.max.items"); + Messenger.MAXIMUM_FRIENDS = Emulator.getConfig().getInt("hotel.users.max.friends", 300); + Messenger.MAXIMUM_FRIENDS_HC = Emulator.getConfig().getInt("hotel.users.max.friends.hc", 1100); + Room.MAXIMUM_BOTS = Emulator.getConfig().getInt("hotel.max.bots.room"); + Room.MAXIMUM_PETS = Emulator.getConfig().getInt("hotel.pets.max.room"); + Room.MAXIMUM_FURNI = Emulator.getConfig().getInt("hotel.room.furni.max", 3000); + Room.MAXIMUM_POSTITNOTES = Emulator.getConfig().getInt("hotel.room.stickies.max", 200); + Room.HAND_ITEM_TIME = Emulator.getConfig().getInt("hotel.rooms.handitem.time"); + Room.IDLE_CYCLES = Emulator.getConfig().getInt("hotel.roomuser.idle.cycles", 240); + Room.IDLE_CYCLES_KICK = Emulator.getConfig().getInt("hotel.roomuser.idle.cycles.kick", 480); + Room.ROLLERS_MAXIMUM_ROLL_AVATARS = Emulator.getConfig().getInt("hotel.room.rollers.roll_avatars.max", 1); + RoomManager.MAXIMUM_ROOMS_USER = Emulator.getConfig().getInt("hotel.users.max.rooms", 50); + RoomManager.MAXIMUM_ROOMS_HC = Emulator.getConfig().getInt("hotel.users.max.rooms.hc", 75); + RoomManager.HOME_ROOM_ID = Emulator.getConfig().getInt("hotel.home.room"); + WiredHandler.MAXIMUM_FURNI_SELECTION = Emulator.getConfig().getInt("hotel.wired.furni.selection.count"); + WiredHandler.TELEPORT_DELAY = Emulator.getConfig().getInt("wired.effect.teleport.delay", 500); + NavigatorManager.MAXIMUM_RESULTS_PER_PAGE = Emulator.getConfig().getInt("hotel.navigator.search.maxresults"); + NavigatorManager.CATEGORY_SORT_USING_ORDER_NUM = Emulator.getConfig().getBoolean("hotel.navigator.sort.ordernum"); + RoomChatMessage.MAXIMUM_LENGTH = Emulator.getConfig().getInt("hotel.chat.max.length"); + TraxManager.LARGE_JUKEBOX_LIMIT = Emulator.getConfig().getInt("hotel.jukebox.limit.large"); + TraxManager.NORMAL_JUKEBOX_LIMIT = Emulator.getConfig().getInt("hotel.jukebox.limit.normal"); + + String[] bannedBubbles = Emulator.getConfig().getValue("commands.cmd_chatcolor.banned_numbers").split(";"); + RoomChatMessage.BANNED_BUBBLES = new int[bannedBubbles.length]; + for (int i = 0; i < RoomChatMessage.BANNED_BUBBLES.length; i++) { + try { + RoomChatMessage.BANNED_BUBBLES[i] = Integer.valueOf(bannedBubbles[i]); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + HabboManager.WELCOME_MESSAGE = Emulator.getConfig().getValue("hotel.welcome.alert.message").replace("
", "
").replace("
", "
").replace("\\r", "\r").replace("\\n", "\n").replace("\\t", "\t"); + Room.PREFIX_FORMAT = Emulator.getConfig().getValue("room.chat.prefix.format"); + FloorPlanEditorSaveEvent.MAXIMUM_FLOORPLAN_WIDTH_LENGTH = Emulator.getConfig().getInt("hotel.floorplan.max.widthlength"); + FloorPlanEditorSaveEvent.MAXIMUM_FLOORPLAN_SIZE = Emulator.getConfig().getInt("hotel.floorplan.max.totalarea"); + + HotelViewRequestLTDAvailabilityEvent.ENABLED = Emulator.getConfig().getBoolean("hotel.view.ltdcountdown.enabled"); + HotelViewRequestLTDAvailabilityEvent.TIMESTAMP = Emulator.getConfig().getInt("hotel.view.ltdcountdown.timestamp"); + HotelViewRequestLTDAvailabilityEvent.ITEM_ID = Emulator.getConfig().getInt("hotel.view.ltdcountdown.itemid"); + HotelViewRequestLTDAvailabilityEvent.PAGE_ID = Emulator.getConfig().getInt("hotel.view.ltdcountdown.pageid"); + HotelViewRequestLTDAvailabilityEvent.ITEM_NAME = Emulator.getConfig().getValue("hotel.view.ltdcountdown.itemname"); + InteractionPostIt.STICKYPOLE_PREFIX_TEXT = Emulator.getConfig().getValue("hotel.room.stickypole.prefix"); + TargetOffer.ACTIVE_TARGET_OFFER_ID = Emulator.getConfig().getInt("hotel.targetoffer.id"); + WordFilter.DEFAULT_REPLACEMENT = Emulator.getConfig().getValue("hotel.wordfilter.replacement"); + CatalogManager.PURCHASE_COOLDOWN = Emulator.getConfig().getInt("hotel.catalog.purchase.cooldown"); + CatalogManager.SORT_USING_ORDERNUM = Emulator.getConfig().getBoolean("hotel.catalog.items.display.ordernum"); + AchievementManager.TALENTTRACK_ENABLED = Emulator.getConfig().getBoolean("hotel.talenttrack.enabled"); + InteractionRoller.NO_RULES = Emulator.getConfig().getBoolean("hotel.room.rollers.norules"); + RoomManager.SHOW_PUBLIC_IN_POPULAR_TAB = Emulator.getConfig().getBoolean("hotel.navigator.populartab.publics"); + CheckPetNameEvent.PET_NAME_LENGTH_MINIMUM = Emulator.getConfig().getInt("hotel.pets.name.length.min"); + CheckPetNameEvent.PET_NAME_LENGTH_MAXIMUM = Emulator.getConfig().getInt("hotel.pets.name.length.max"); + + + ChangeNameCheckUsernameEvent.VALID_CHARACTERS = Emulator.getConfig().getValue("allowed.username.characters", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-=!?@:,."); + CameraPublishToWebEvent.CAMERA_PUBLISH_POINTS = Emulator.getConfig().getInt("camera.price.points.publish", 5); + CameraPublishToWebEvent.CAMERA_PUBLISH_POINTS_TYPE = Emulator.getConfig().getInt("camera.price.points.publish.type", 0); + CameraPurchaseEvent.CAMERA_PURCHASE_CREDITS = Emulator.getConfig().getInt("camera.price.credits", 5); + CameraPurchaseEvent.CAMERA_PURCHASE_POINTS = Emulator.getConfig().getInt("camera.price.points", 5); + CameraPurchaseEvent.CAMERA_PURCHASE_POINTS_TYPE = Emulator.getConfig().getInt("camera.price.points.type", 0); + + BuyRoomPromotionEvent.ROOM_PROMOTION_BADGE = Emulator.getConfig().getValue("room.promotion.badge", "RADZZ"); + BotManager.MAXIMUM_BOT_INVENTORY_SIZE = Emulator.getConfig().getInt("hotel.bots.max.inventory"); + PetManager.MAXIMUM_PET_INVENTORY_SIZE = Emulator.getConfig().getInt("hotel.pets.max.inventory"); + + + SubscriptionHabboClub.HC_PAYDAY_ENABLED = Emulator.getConfig().getBoolean("subscriptions.hc.payday.enabled", false); + + try { + SubscriptionHabboClub.HC_PAYDAY_NEXT_DATE = (int) (Emulator.stringToDate(Emulator.getConfig().getValue("subscriptions.hc.payday.next_date")).getTime() / 1000); + } + catch(Exception e) { SubscriptionHabboClub.HC_PAYDAY_NEXT_DATE = Integer.MAX_VALUE; } + + SubscriptionHabboClub.HC_PAYDAY_INTERVAL = Emulator.getConfig().getValue("subscriptions.hc.payday.interval"); + SubscriptionHabboClub.HC_PAYDAY_QUERY = Emulator.getConfig().getValue("subscriptions.hc.payday.query"); + SubscriptionHabboClub.HC_PAYDAY_CURRENCY = Emulator.getConfig().getValue("subscriptions.hc.payday.currency"); + SubscriptionHabboClub.HC_PAYDAY_KICKBACK_PERCENTAGE = Emulator.getConfig().getInt("subscriptions.hc.payday.percentage", 10) / 100.0; + SubscriptionHabboClub.HC_PAYDAY_COINSSPENT_RESET_ON_EXPIRE = Emulator.getConfig().getBoolean("subscriptions.hc.payday.creditsspent_reset_on_expire", false); + SubscriptionHabboClub.ACHIEVEMENT_NAME = Emulator.getConfig().getValue("subscriptions.hc.achievement", "VipHC"); + SubscriptionHabboClub.DISCOUNT_ENABLED = Emulator.getConfig().getBoolean("subscriptions.hc.discount.enabled", false); + SubscriptionHabboClub.DISCOUNT_DAYS_BEFORE_END = Emulator.getConfig().getInt("subscriptions.hc.discount.days_before_end", 7); + + SubscriptionHabboClub.HC_PAYDAY_STREAK.clear(); + for (String streak : Emulator.getConfig().getValue("subscriptions.hc.payday.streak", "7=5;30=10;60=15;90=20;180=25;365=30").split(Pattern.quote(";"))) { + if(streak.contains("=")) { + SubscriptionHabboClub.HC_PAYDAY_STREAK.put(Integer.parseInt(streak.split(Pattern.quote("="))[0]), Integer.parseInt(streak.split(Pattern.quote("="))[1])); + } + } + + ClothingValidationManager.VALIDATE_ON_HC_EXPIRE = Emulator.getConfig().getBoolean("hotel.users.clothingvalidation.onhcexpired", false); + ClothingValidationManager.VALIDATE_ON_LOGIN = Emulator.getConfig().getBoolean("hotel.users.clothingvalidation.onlogin", false); + ClothingValidationManager.VALIDATE_ON_CHANGE_LOOKS = Emulator.getConfig().getBoolean("hotel.users.clothingvalidation.onchangelooks", false); + ClothingValidationManager.VALIDATE_ON_MIMIC = Emulator.getConfig().getBoolean("hotel.users.clothingvalidation.onmimic", false); + ClothingValidationManager.VALIDATE_ON_MANNEQUIN = Emulator.getConfig().getBoolean("hotel.users.clothingvalidation.onmannequin", false); + ClothingValidationManager.VALIDATE_ON_FBALLGATE = Emulator.getConfig().getBoolean("hotel.users.clothingvalidation.onfballgate", false); + + String newUrl = Emulator.getConfig().getValue("gamedata.figuredata.url"); + if(!ClothingValidationManager.FIGUREDATA_URL.equals(newUrl)) { + ClothingValidationManager.FIGUREDATA_URL = newUrl; + ClothingValidationManager.reloadFiguredata(newUrl); + } + + if(newUrl.isEmpty()) { + ClothingValidationManager.VALIDATE_ON_HC_EXPIRE = false; + ClothingValidationManager.VALIDATE_ON_LOGIN = false; + ClothingValidationManager.VALIDATE_ON_CHANGE_LOOKS = false; + ClothingValidationManager.VALIDATE_ON_MIMIC = false; + ClothingValidationManager.VALIDATE_ON_MANNEQUIN = false; + ClothingValidationManager.VALIDATE_ON_FBALLGATE = false; + } + + + NewNavigatorEventCategoriesComposer.CATEGORIES.clear(); + for (String category : Emulator.getConfig().getValue("navigator.eventcategories", "").split(";")) { + try { + NewNavigatorEventCategoriesComposer.CATEGORIES.add(new EventCategory(category)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (Emulator.isReady) { + GiftConfigurationComposer.BOX_TYPES = Arrays.stream(Emulator.getConfig().getValue("hotel.gifts.box_types").split(",")).mapToInt(Integer::parseInt).boxed().collect(Collectors.toList()); + GiftConfigurationComposer.RIBBON_TYPES = Arrays.stream(Emulator.getConfig().getValue("hotel.gifts.ribbon_types").split(",")).mapToInt(Integer::parseInt).boxed().collect(Collectors.toList()); + + Emulator.getGameEnvironment().getCreditsScheduler().reloadConfig(); + Emulator.getGameEnvironment().getPointsScheduler().reloadConfig(); + Emulator.getGameEnvironment().getPixelScheduler().reloadConfig(); + Emulator.getGameEnvironment().getGotwPointsScheduler().reloadConfig(); + Emulator.getGameEnvironment().subscriptionScheduler.reloadConfig(); + } + } + + public void loadPlugins() { + this.disposePlugins(); + + File loc = new File("plugins"); + + if (!loc.exists()) { + if (loc.mkdirs()) { + log.info("Created plugins directory!"); + } + } + + for (File file : Objects.requireNonNull(loc.listFiles(file -> file.getPath().toLowerCase().endsWith(".jar")))) { + URLClassLoader urlClassLoader; + InputStream stream; + try { + urlClassLoader = URLClassLoader.newInstance(new URL[]{file.toURI().toURL()}); + stream = urlClassLoader.getResourceAsStream("plugin.json"); + + if (stream == null) { + throw new RuntimeException("Invalid Jar! Missing plugin.json in: " + file.getName()); + } + + byte[] content = new byte[stream.available()]; + + if (stream.read(content) > 0) { + String body = new String(content); + + Gson gson = new GsonBuilder().create(); + HabboPluginConfiguration pluginConfigurtion = gson.fromJson(body, HabboPluginConfiguration.class); + + try { + Class clazz = urlClassLoader.loadClass(pluginConfigurtion.main); + Class stackClazz = clazz.asSubclass(HabboPlugin.class); + Constructor constructor = stackClazz.getConstructor(); + HabboPlugin plugin = constructor.newInstance(); + plugin.configuration = pluginConfigurtion; + plugin.classLoader = urlClassLoader; + plugin.stream = stream; + this.plugins.add(plugin); + plugin.onEnable(); + } catch (Exception e) { + log.error("Could not load plugin {}!", pluginConfigurtion.name); + log.error("Caught exception", e); + } + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } + } + + public void registerEvents(HabboPlugin plugin, EventListener listener) { + synchronized (plugin.registeredEvents) { + Method[] methods = listener.getClass().getMethods(); + + for (Method method : methods) { + if (method.getAnnotation(EventHandler.class) != null) { + if (method.getParameterTypes().length == 1) { + if (Event.class.isAssignableFrom(method.getParameterTypes()[0])) { + final Class eventClass = method.getParameterTypes()[0]; + + if (!plugin.registeredEvents.containsKey(eventClass.asSubclass(Event.class))) { + plugin.registeredEvents.put(eventClass.asSubclass(Event.class), new THashSet<>()); + } + + plugin.registeredEvents.get(eventClass.asSubclass(Event.class)).add(method); + } + } + } + } + } + } + + public T fireEvent(T event) { + for (Method method : this.methods) { + if (method.getParameterTypes().length == 1 && method.getParameterTypes()[0].isAssignableFrom(event.getClass())) { + try { + method.invoke(null, event); + } catch (Exception e) { + log.error("Could not pass default event {} to {}: {}!", event.getClass().getName(), method.getClass().getName(), method.getName()); + log.error("Caught exception", e); + } + } + } + + TObjectHashIterator iterator = this.plugins.iterator(); + while (iterator.hasNext()) { + try { + HabboPlugin plugin = iterator.next(); + + if (plugin != null) { + THashSet methods = plugin.registeredEvents.get(event.getClass().asSubclass(Event.class)); + + if (methods != null) { + for (Method method : methods) { + try { + method.invoke(plugin, event); + } catch (Exception e) { + log.error("Could not pass event {} to {}", event.getClass().getName(), plugin.configuration.name); + log.error("Caught exception", e); + } + } + } + } + } catch (NoSuchElementException e) { + break; + } + } + + return event; + } + + public boolean isRegistered(Class clazz, boolean pluginsOnly) { + TObjectHashIterator iterator = this.plugins.iterator(); + while (iterator.hasNext()) { + try { + HabboPlugin plugin = iterator.next(); + if (plugin.isRegistered(clazz)) + return true; + } catch (NoSuchElementException e) { + break; + } + } + + if (!pluginsOnly) { + for (Method method : this.methods) { + if (method.getParameterTypes().length == 1 && method.getParameterTypes()[0].isAssignableFrom(clazz)) { + return true; + } + } + } + + return false; + } + + public void dispose() { + this.disposePlugins(); + + log.info("Disposed Plugin Manager!"); + } + + private void disposePlugins() { + TObjectHashIterator iterator = this.plugins.iterator(); + while (iterator.hasNext()) { + try { + HabboPlugin p = iterator.next(); + + if (p != null) { + + try { + p.onDisable(); + p.stream.close(); + p.classLoader.close(); + } catch (IOException e) { + log.error("Caught exception", e); + } catch (Exception ex) { + log.error("Failed to disable {} because of an exception.", p.configuration.name, ex); + } + } + } catch (NoSuchElementException e) { + break; + } + } + this.plugins.clear(); + } + + public void reload() { + long millis = System.currentTimeMillis(); + + this.methods.clear(); + + this.loadPlugins(); + + log.info("Plugin Manager -> Loaded! " + this.plugins.size() + " plugins! (" + (System.currentTimeMillis() - millis) + " MS)"); + + this.registerDefaultEvents(); + } + + private void registerDefaultEvents() { + try { + this.methods.add(RoomTrashing.class.getMethod("onUserWalkEvent", UserTakeStepEvent.class)); + this.methods.add(Easter.class.getMethod("onUserChangeMotto", UserSavedMottoEvent.class)); + this.methods.add(TagGame.class.getMethod("onUserLookAtPoint", RoomUnitLookAtPointEvent.class)); + this.methods.add(TagGame.class.getMethod("onUserWalkEvent", UserTakeStepEvent.class)); + this.methods.add(FreezeGame.class.getMethod("onConfigurationUpdated", EmulatorConfigUpdatedEvent.class)); + this.methods.add(PacketManager.class.getMethod("onConfigurationUpdated", EmulatorConfigUpdatedEvent.class)); + this.methods.add(InteractionFootballGate.class.getMethod("onUserDisconnectEvent", UserDisconnectEvent.class)); + this.methods.add(InteractionFootballGate.class.getMethod("onUserExitRoomEvent", UserExitRoomEvent.class)); + this.methods.add(InteractionFootballGate.class.getMethod("onUserSavedLookEvent", UserSavedLookEvent.class)); + this.methods.add(PluginManager.class.getMethod("globalOnConfigurationUpdated", EmulatorConfigUpdatedEvent.class)); + } catch (NoSuchMethodException e) { + log.info("Failed to define default events!"); + log.error("Caught exception", e); + } + } + + public THashSet getPlugins() { + return this.plugins; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotChatEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotChatEvent.java new file mode 100644 index 0000000..1a5dcd1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotChatEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.plugin.events.bots; + +import com.eu.habbo.habbohotel.bots.Bot; + +public abstract class BotChatEvent extends BotEvent { + + public String message; + + + public BotChatEvent(Bot bot, String message) { + super(bot); + + this.message = message; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotEvent.java new file mode 100644 index 0000000..d23c299 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.plugin.events.bots; + +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.plugin.Event; + +public abstract class BotEvent extends Event { + + public final Bot bot; + + + public BotEvent(Bot bot) { + this.bot = bot; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotPickUpEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotPickUpEvent.java new file mode 100644 index 0000000..4dd068f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotPickUpEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.bots; + +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.users.Habbo; + +public class BotPickUpEvent extends BotEvent { + + public final Habbo picker; + + + public BotPickUpEvent(Bot bot, Habbo picker) { + super(bot); + + this.picker = picker; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotPlacedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotPlacedEvent.java new file mode 100644 index 0000000..f77062d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotPlacedEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.plugin.events.bots; + +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; + +public class BotPlacedEvent extends BotEvent { + + public final RoomTile location; + + + public final Habbo placer; + + public BotPlacedEvent(Bot bot, RoomTile location, Habbo placer) { + super(bot); + + this.location = location; + this.placer = placer; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotSavedChatEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotSavedChatEvent.java new file mode 100644 index 0000000..fa5bbd6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotSavedChatEvent.java @@ -0,0 +1,29 @@ +package com.eu.habbo.plugin.events.bots; + +import com.eu.habbo.habbohotel.bots.Bot; + +import java.util.ArrayList; + +public class BotSavedChatEvent extends BotEvent { + + public boolean autoChat; + + + public boolean randomChat; + + + public int chatDelay; + + + public ArrayList chat; + + + public BotSavedChatEvent(Bot bot, boolean autoChat, boolean randomChat, int chatDelay, ArrayList chat) { + super(bot); + + this.autoChat = autoChat; + this.randomChat = randomChat; + this.chatDelay = chatDelay; + this.chat = chat; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotSavedLookEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotSavedLookEvent.java new file mode 100644 index 0000000..0f3aba1 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotSavedLookEvent.java @@ -0,0 +1,24 @@ +package com.eu.habbo.plugin.events.bots; + +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.users.HabboGender; + +public class BotSavedLookEvent extends BotEvent { + + public HabboGender gender; + + + public String newLook; + + + public int effect; + + + public BotSavedLookEvent(Bot bot, HabboGender gender, String newLook, int effect) { + super(bot); + + this.gender = gender; + this.newLook = newLook; + this.effect = effect; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotSavedNameEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotSavedNameEvent.java new file mode 100644 index 0000000..3109166 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotSavedNameEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.plugin.events.bots; + +import com.eu.habbo.habbohotel.bots.Bot; + +public class BotSavedNameEvent extends BotEvent { + + public String name; + + + public BotSavedNameEvent(Bot bot, String name) { + super(bot); + + this.name = name; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotServerItemEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotServerItemEvent.java new file mode 100644 index 0000000..b9e073a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotServerItemEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.plugin.events.bots; + +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.users.Habbo; + +public class BotServerItemEvent extends BotEvent { + + public Habbo habbo; + + public int itemId; + + + public BotServerItemEvent(Bot bot, Habbo habbo, int itemId) { + super(bot); + + this.habbo = habbo; + this.itemId = itemId; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotShoutEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotShoutEvent.java new file mode 100644 index 0000000..ec44b24 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotShoutEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.plugin.events.bots; + +import com.eu.habbo.habbohotel.bots.Bot; + +public class BotShoutEvent extends BotChatEvent { + + public BotShoutEvent(Bot bot, String message) { + super(bot, message); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotTalkEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotTalkEvent.java new file mode 100644 index 0000000..4b4ecdc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotTalkEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.plugin.events.bots; + +import com.eu.habbo.habbohotel.bots.Bot; + +public class BotTalkEvent extends BotChatEvent { + + public BotTalkEvent(Bot bot, String message) { + super(bot, message); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotWhisperEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotWhisperEvent.java new file mode 100644 index 0000000..5be8bb4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/bots/BotWhisperEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.bots; + +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.users.Habbo; + +public class BotWhisperEvent extends BotChatEvent { + + public Habbo target; + + + public BotWhisperEvent(Bot bot, String message, Habbo target) { + super(bot, message); + + this.target = target; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorConfigUpdatedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorConfigUpdatedEvent.java new file mode 100644 index 0000000..ad091bc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorConfigUpdatedEvent.java @@ -0,0 +1,4 @@ +package com.eu.habbo.plugin.events.emulator; + +public class EmulatorConfigUpdatedEvent extends EmulatorEvent { +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorEvent.java new file mode 100644 index 0000000..00935ee --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorEvent.java @@ -0,0 +1,6 @@ +package com.eu.habbo.plugin.events.emulator; + +import com.eu.habbo.plugin.Event; + +public abstract class EmulatorEvent extends Event { +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorLoadCatalogManagerEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorLoadCatalogManagerEvent.java new file mode 100644 index 0000000..9636988 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorLoadCatalogManagerEvent.java @@ -0,0 +1,7 @@ +package com.eu.habbo.plugin.events.emulator; + +public class EmulatorLoadCatalogManagerEvent extends EmulatorEvent { + + public EmulatorLoadCatalogManagerEvent() { + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorLoadItemsManagerEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorLoadItemsManagerEvent.java new file mode 100644 index 0000000..10ec915 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorLoadItemsManagerEvent.java @@ -0,0 +1,7 @@ +package com.eu.habbo.plugin.events.emulator; + +public class EmulatorLoadItemsManagerEvent extends EmulatorEvent { + + public EmulatorLoadItemsManagerEvent() { + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorLoadedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorLoadedEvent.java new file mode 100644 index 0000000..2d92690 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorLoadedEvent.java @@ -0,0 +1,9 @@ +package com.eu.habbo.plugin.events.emulator; + +import com.eu.habbo.plugin.Event; + +public class EmulatorLoadedEvent extends Event { + + public EmulatorLoadedEvent() { + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorStartShutdownEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorStartShutdownEvent.java new file mode 100644 index 0000000..bee5998 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorStartShutdownEvent.java @@ -0,0 +1,7 @@ +package com.eu.habbo.plugin.events.emulator; + +public class EmulatorStartShutdownEvent extends EmulatorEvent { + + public EmulatorStartShutdownEvent() { + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorStoppedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorStoppedEvent.java new file mode 100644 index 0000000..e3a00e2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/EmulatorStoppedEvent.java @@ -0,0 +1,7 @@ +package com.eu.habbo.plugin.events.emulator; + +public class EmulatorStoppedEvent extends EmulatorEvent { + + public EmulatorStoppedEvent() { + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/SSOAuthenticationEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/SSOAuthenticationEvent.java new file mode 100644 index 0000000..31dbd33 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/emulator/SSOAuthenticationEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.plugin.events.emulator; + +import com.eu.habbo.plugin.Event; + +public class SSOAuthenticationEvent extends Event { + public final String sso; + + public SSOAuthenticationEvent(String sso) { + this.sso = sso; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureBuildheightEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureBuildheightEvent.java new file mode 100644 index 0000000..ada589e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureBuildheightEvent.java @@ -0,0 +1,30 @@ +package com.eu.habbo.plugin.events.furniture; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class FurnitureBuildheightEvent extends FurnitureUserEvent { + + public final double oldHeight; + public final double newHeight; + + private double updatedHeight; + + private boolean changedHeight = false; + + public FurnitureBuildheightEvent(HabboItem furniture, Habbo habbo, double oldHeight, double newHeight) { + super(furniture, habbo); + + this.oldHeight = oldHeight; + this.newHeight = newHeight; + } + + public void setNewHeight(double updatedHeight) { + this.updatedHeight = updatedHeight; + this.changedHeight = true; + } + + public boolean hasChangedHeight() { return changedHeight; } + + public double getUpdatedHeight() { return updatedHeight; } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureDiceRolledEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureDiceRolledEvent.java new file mode 100644 index 0000000..5bad718 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureDiceRolledEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.furniture; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class FurnitureDiceRolledEvent extends FurnitureUserEvent { + + public int result; + + + public FurnitureDiceRolledEvent(HabboItem furniture, Habbo habbo, int result) { + super(furniture, habbo); + + this.result = result; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureEvent.java new file mode 100644 index 0000000..00e5db8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.plugin.events.furniture; + +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.plugin.Event; + +public abstract class FurnitureEvent extends Event { + + public final HabboItem furniture; + + + public FurnitureEvent(HabboItem furniture) { + this.furniture = furniture; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureMovedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureMovedEvent.java new file mode 100644 index 0000000..cbf4e1e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureMovedEvent.java @@ -0,0 +1,29 @@ +package com.eu.habbo.plugin.events.furniture; + +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class FurnitureMovedEvent extends FurnitureUserEvent { + + public final RoomTile oldPosition; + public final RoomTile newPosition; + private boolean pluginHelper; + + + public FurnitureMovedEvent(HabboItem furniture, Habbo habbo, RoomTile oldPosition, RoomTile newPosition) { + super(furniture, habbo); + + this.oldPosition = oldPosition; + this.newPosition = newPosition; + this.pluginHelper = false; + } + + public void setPluginHelper(boolean helper) { + this.pluginHelper = helper; + } + + public boolean hasPluginHelper() { + return this.pluginHelper; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurniturePickedUpEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurniturePickedUpEvent.java new file mode 100644 index 0000000..37114d2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurniturePickedUpEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.plugin.events.furniture; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class FurniturePickedUpEvent extends FurnitureUserEvent { + + public FurniturePickedUpEvent(HabboItem furniture, Habbo habbo) { + super(furniture, habbo); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurniturePlacedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurniturePlacedEvent.java new file mode 100644 index 0000000..6af5747 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurniturePlacedEvent.java @@ -0,0 +1,26 @@ +package com.eu.habbo.plugin.events.furniture; + +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class FurniturePlacedEvent extends FurnitureUserEvent { + + public final RoomTile location; + private boolean pluginHelper; + + public FurniturePlacedEvent(HabboItem furniture, Habbo habbo, RoomTile location) { + super(furniture, habbo); + + this.location = location; + this.pluginHelper = false; + } + + public void setPluginHelper(boolean helper) { + this.pluginHelper = helper; + } + + public boolean hasPluginHelper() { + return this.pluginHelper; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRedeemedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRedeemedEvent.java new file mode 100644 index 0000000..5cdbc11 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRedeemedEvent.java @@ -0,0 +1,22 @@ +package com.eu.habbo.plugin.events.furniture; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class FurnitureRedeemedEvent extends FurnitureUserEvent { + public static final int CREDITS = -1; + public static final int PIXELS = 0; + public static final int DIAMONDS = 5; + public static final int NFT = 4; + + + public final int amount; + public final int currencyID; + + public FurnitureRedeemedEvent(HabboItem furniture, Habbo habbo, int amount, int currencyID) { + super(furniture, habbo); + + this.amount = amount; + this.currencyID = currencyID; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRolledEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRolledEvent.java new file mode 100644 index 0000000..92da1e6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRolledEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.plugin.events.furniture; + +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class FurnitureRolledEvent extends FurnitureEvent { + + public final HabboItem roller; + + + public final RoomTile newLocation; + + + public FurnitureRolledEvent(HabboItem furniture, HabboItem roller, RoomTile newLocation) { + super(furniture); + + this.roller = roller; + this.newLocation = newLocation; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRoomTonerEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRoomTonerEvent.java new file mode 100644 index 0000000..4ee8521 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRoomTonerEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.plugin.events.furniture; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class FurnitureRoomTonerEvent extends FurnitureUserEvent { + public int hue; + public int saturation; + public int brightness; + + + public FurnitureRoomTonerEvent(HabboItem furniture, Habbo habbo, int hue, int saturation, int brightness) { + super(furniture, habbo); + + this.hue = hue; + this.saturation = saturation; + this.brightness = brightness; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRotatedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRotatedEvent.java new file mode 100644 index 0000000..da314b5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureRotatedEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.furniture; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class FurnitureRotatedEvent extends FurnitureUserEvent { + + public final int oldRotation; + + + public FurnitureRotatedEvent(HabboItem furniture, Habbo habbo, int oldRotation) { + super(furniture, habbo); + + this.oldRotation = oldRotation; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureStackHeightEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureStackHeightEvent.java new file mode 100644 index 0000000..80bb8e8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureStackHeightEvent.java @@ -0,0 +1,37 @@ +package com.eu.habbo.plugin.events.furniture; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.plugin.Event; + +public class FurnitureStackHeightEvent extends Event { + + public final short x; + public final short y; + public final Room room; + private boolean pluginHelper; + private Double height; + + public FurnitureStackHeightEvent(short x, short y, Room room) { + this.x = x; + this.y = y; + this.room = room; + this.pluginHelper = false; + this.height = 0.0D; + } + + public void setPluginHelper(boolean helper) { + this.pluginHelper = helper; + } + + public boolean hasPluginHelper() { + return this.pluginHelper; + } + + public void setHeight(Double height) { + this.height = height; + } + + public Double getHeight() { + return this.height; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureToggleEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureToggleEvent.java new file mode 100644 index 0000000..01dd9c9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureToggleEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.plugin.events.furniture; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class FurnitureToggleEvent extends FurnitureUserEvent { + public int state; + + public FurnitureToggleEvent(HabboItem furniture, Habbo habbo, int state) { + super(furniture, habbo); + + this.state = state; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureUserEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureUserEvent.java new file mode 100644 index 0000000..54017a4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/FurnitureUserEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.plugin.events.furniture; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; + +public abstract class FurnitureUserEvent extends FurnitureEvent { + + public final Habbo habbo; + + + public FurnitureUserEvent(HabboItem furniture, Habbo habbo) { + super(furniture); + this.habbo = habbo; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/wired/WiredConditionFailedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/wired/WiredConditionFailedEvent.java new file mode 100644 index 0000000..c8e420f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/wired/WiredConditionFailedEvent.java @@ -0,0 +1,22 @@ +package com.eu.habbo.plugin.events.furniture.wired; + +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.plugin.events.roomunit.RoomUnitEvent; + +public class WiredConditionFailedEvent extends RoomUnitEvent { + + public final InteractionWiredTrigger trigger; + + + public final InteractionWiredCondition condition; + + + public WiredConditionFailedEvent(Room room, RoomUnit roomUnit, InteractionWiredTrigger trigger, InteractionWiredCondition condition) { + super(room, roomUnit); + this.trigger = trigger; + this.condition = condition; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/wired/WiredStackExecutedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/wired/WiredStackExecutedEvent.java new file mode 100644 index 0000000..9ed4385 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/wired/WiredStackExecutedEvent.java @@ -0,0 +1,29 @@ +package com.eu.habbo.plugin.events.furniture.wired; + +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.plugin.events.roomunit.RoomUnitEvent; +import gnu.trove.set.hash.THashSet; + +public class WiredStackExecutedEvent extends RoomUnitEvent { + + public final InteractionWiredTrigger trigger; + + + public final THashSet effects; + + + public final THashSet conditions; + + + public WiredStackExecutedEvent(Room room, RoomUnit roomUnit, InteractionWiredTrigger trigger, THashSet effects, THashSet conditions) { + super(room, roomUnit); + + this.trigger = trigger; + this.effects = effects; + this.conditions = conditions; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/wired/WiredStackTriggeredEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/wired/WiredStackTriggeredEvent.java new file mode 100644 index 0000000..59e3f8a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/furniture/wired/WiredStackTriggeredEvent.java @@ -0,0 +1,29 @@ +package com.eu.habbo.plugin.events.furniture.wired; + +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.plugin.events.roomunit.RoomUnitEvent; +import gnu.trove.set.hash.THashSet; + +public class WiredStackTriggeredEvent extends RoomUnitEvent { + + public final InteractionWiredTrigger trigger; + + + public final THashSet effects; + + + public final THashSet conditions; + + + public WiredStackTriggeredEvent(Room room, RoomUnit roomUnit, InteractionWiredTrigger trigger, THashSet effects, THashSet conditions) { + super(room, roomUnit); + + this.trigger = trigger; + this.effects = effects; + this.conditions = conditions; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameEvent.java new file mode 100644 index 0000000..21930be --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.plugin.events.games; + +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.plugin.Event; + +public abstract class GameEvent extends Event { + + public final Game game; + + + public GameEvent(Game game) { + this.game = game; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameHabboJoinEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameHabboJoinEvent.java new file mode 100644 index 0000000..560271f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameHabboJoinEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.plugin.events.games; + +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.users.Habbo; + +public class GameHabboJoinEvent extends GameUserEvent { + + public GameHabboJoinEvent(Game game, Habbo habbo) { + super(game, habbo); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameHabboLeaveEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameHabboLeaveEvent.java new file mode 100644 index 0000000..1dd267b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameHabboLeaveEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.plugin.events.games; + +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.users.Habbo; + +public class GameHabboLeaveEvent extends GameUserEvent { + + public GameHabboLeaveEvent(Game game, Habbo habbo) { + super(game, habbo); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameStartedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameStartedEvent.java new file mode 100644 index 0000000..d4b14ce --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameStartedEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.plugin.events.games; + +import com.eu.habbo.habbohotel.games.Game; + +public class GameStartedEvent extends GameEvent { + + public GameStartedEvent(Game game) { + super(game); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameStoppedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameStoppedEvent.java new file mode 100644 index 0000000..dc59593 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameStoppedEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.plugin.events.games; + +import com.eu.habbo.habbohotel.games.Game; + +public class GameStoppedEvent extends GameEvent { + + public GameStoppedEvent(Game game) { + super(game); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameUserEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameUserEvent.java new file mode 100644 index 0000000..aaf2e98 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/games/GameUserEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.games; + +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.users.Habbo; + +public abstract class GameUserEvent extends GameEvent { + + public final Habbo habbo; + + + public GameUserEvent(Game game, Habbo habbo) { + super(game); + + this.habbo = habbo; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildAcceptedMembershipEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildAcceptedMembershipEvent.java new file mode 100644 index 0000000..ab700f0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildAcceptedMembershipEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.plugin.events.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.users.Habbo; + +public class GuildAcceptedMembershipEvent extends GuildEvent { + + public final int userId; + + + public final Habbo user; + + + public GuildAcceptedMembershipEvent(Guild guild, int userId, Habbo user) { + super(guild); + + this.userId = userId; + this.user = user; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildChangedBadgeEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildChangedBadgeEvent.java new file mode 100644 index 0000000..fac0988 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildChangedBadgeEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.plugin.events.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; + +public class GuildChangedBadgeEvent extends GuildEvent { + + public String badge; + + + public GuildChangedBadgeEvent(Guild guild, String badge) { + super(guild); + + this.badge = badge; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildChangedColorsEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildChangedColorsEvent.java new file mode 100644 index 0000000..6beb563 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildChangedColorsEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.plugin.events.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; + +public class GuildChangedColorsEvent extends GuildEvent { + + public int colorOne; + + + public int colorTwo; + + + public GuildChangedColorsEvent(Guild guild, int colorOne, int colorTwo) { + super(guild); + + this.colorOne = colorOne; + this.colorTwo = colorTwo; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildChangedNameEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildChangedNameEvent.java new file mode 100644 index 0000000..0a52395 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildChangedNameEvent.java @@ -0,0 +1,18 @@ +package com.eu.habbo.plugin.events.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; + +public class GuildChangedNameEvent extends GuildEvent { + + public String name; + + + public String description; + + + public GuildChangedNameEvent(Guild guild, String name, String description) { + super(guild); + this.name = name; + this.description = description; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildChangedSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildChangedSettingsEvent.java new file mode 100644 index 0000000..8c72a07 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildChangedSettingsEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; + +public class GuildChangedSettingsEvent extends GuildEvent { + + public int state; + + public boolean rights; + + public GuildChangedSettingsEvent(Guild guild, int state, boolean rights) { + super(guild); + this.state = state; + this.rights = rights; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildDeclinedMembershipEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildDeclinedMembershipEvent.java new file mode 100644 index 0000000..836c519 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildDeclinedMembershipEvent.java @@ -0,0 +1,24 @@ +package com.eu.habbo.plugin.events.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.users.Habbo; + +public class GuildDeclinedMembershipEvent extends GuildEvent { + + public final int userId; + + + public final Habbo user; + + + public final Habbo admin; + + + public GuildDeclinedMembershipEvent(Guild guild, int userId, Habbo user, Habbo admin) { + super(guild); + + this.userId = userId; + this.user = user; + this.admin = admin; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildDeletedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildDeletedEvent.java new file mode 100644 index 0000000..bd650d0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildDeletedEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.users.Habbo; + +public class GuildDeletedEvent extends GuildEvent { + + public final Habbo deleter; + + + public GuildDeletedEvent(Guild guild, Habbo deleter) { + super(guild); + + this.deleter = deleter; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildEvent.java new file mode 100644 index 0000000..e327d89 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.plugin.events.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.plugin.Event; + +public abstract class GuildEvent extends Event { + + public final Guild guild; + + + public GuildEvent(Guild guild) { + this.guild = guild; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildFavoriteSetEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildFavoriteSetEvent.java new file mode 100644 index 0000000..bb77246 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildFavoriteSetEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.users.Habbo; + +public class GuildFavoriteSetEvent extends GuildEvent { + + public final Habbo habbo; + + + public GuildFavoriteSetEvent(Guild guild, Habbo habbo) { + super(guild); + + this.habbo = habbo; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildGivenAdminEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildGivenAdminEvent.java new file mode 100644 index 0000000..4c0b14a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildGivenAdminEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.plugin.events.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.users.Habbo; + +public class GuildGivenAdminEvent extends GuildEvent { + + public final int userId; + + + public final Habbo habbo; + + + public final Habbo admin; + + + public GuildGivenAdminEvent(Guild guild, int userId, Habbo habbo, Habbo admin) { + super(guild); + this.userId = userId; + this.habbo = habbo; + this.admin = admin; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildPurchasedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildPurchasedEvent.java new file mode 100644 index 0000000..05c0c51 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildPurchasedEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.plugin.events.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.users.Habbo; + +public class GuildPurchasedEvent extends GuildEvent { + + public final Habbo habbo; + + + public GuildPurchasedEvent(Guild guild, Habbo habbo) { + super(guild); + this.habbo = habbo; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildRemovedAdminEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildRemovedAdminEvent.java new file mode 100644 index 0000000..64f400e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildRemovedAdminEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.plugin.events.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.users.Habbo; + +public class GuildRemovedAdminEvent extends GuildEvent { + + public final int userId; + + + public final Habbo admin; + + + public GuildRemovedAdminEvent(Guild guild, int userId, Habbo admin) { + super(guild); + this.userId = userId; + this.admin = admin; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildRemovedFavoriteEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildRemovedFavoriteEvent.java new file mode 100644 index 0000000..a69459e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildRemovedFavoriteEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.plugin.events.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.users.Habbo; + +public class GuildRemovedFavoriteEvent extends GuildEvent { + + public final Habbo habbo; + + + public GuildRemovedFavoriteEvent(Guild guild, Habbo habbo) { + super(guild); + this.habbo = habbo; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildRemovedMemberEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildRemovedMemberEvent.java new file mode 100644 index 0000000..622fa40 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/GuildRemovedMemberEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.plugin.events.guilds; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.users.Habbo; + +public class GuildRemovedMemberEvent extends GuildEvent { + + public final int userId; + + + public final Habbo guildMember; + + + public GuildRemovedMemberEvent(Guild guild, int userId, Habbo guildMember) { + super(guild); + this.guildMember = guildMember; + this.userId = userId; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/forums/GuildForumThreadBeforeCreated.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/forums/GuildForumThreadBeforeCreated.java new file mode 100644 index 0000000..3e3fb45 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/forums/GuildForumThreadBeforeCreated.java @@ -0,0 +1,19 @@ +package com.eu.habbo.plugin.events.guilds.forums; + +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.Event; + +public class GuildForumThreadBeforeCreated extends Event { + public final Guild guild; + public final Habbo opener; + public final String subject; + public final String message; + + public GuildForumThreadBeforeCreated(Guild guild, Habbo opener, String subject, String message) { + this.guild = guild; + this.opener = opener; + this.subject = subject; + this.message = message; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/forums/GuildForumThreadCommentBeforeCreated.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/forums/GuildForumThreadCommentBeforeCreated.java new file mode 100644 index 0000000..04d85e6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/forums/GuildForumThreadCommentBeforeCreated.java @@ -0,0 +1,17 @@ +package com.eu.habbo.plugin.events.guilds.forums; + +import com.eu.habbo.habbohotel.guilds.forums.ForumThread; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.Event; + +public class GuildForumThreadCommentBeforeCreated extends Event { + public final ForumThread thread; + public final Habbo poster; + public final String message; + + public GuildForumThreadCommentBeforeCreated(ForumThread thread, Habbo poster, String message) { + this.thread = thread; + this.poster = poster; + this.message = message; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/forums/GuildForumThreadCommentCreated.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/forums/GuildForumThreadCommentCreated.java new file mode 100644 index 0000000..35459a4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/forums/GuildForumThreadCommentCreated.java @@ -0,0 +1,12 @@ +package com.eu.habbo.plugin.events.guilds.forums; + +import com.eu.habbo.habbohotel.guilds.forums.ForumThreadComment; +import com.eu.habbo.plugin.Event; + +public class GuildForumThreadCommentCreated extends Event { + public final ForumThreadComment comment; + + public GuildForumThreadCommentCreated(ForumThreadComment comment) { + this.comment = comment; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/forums/GuildForumThreadCreated.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/forums/GuildForumThreadCreated.java new file mode 100644 index 0000000..e0c3913 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/guilds/forums/GuildForumThreadCreated.java @@ -0,0 +1,12 @@ +package com.eu.habbo.plugin.events.guilds.forums; + +import com.eu.habbo.habbohotel.guilds.forums.ForumThread; +import com.eu.habbo.plugin.Event; + +public class GuildForumThreadCreated extends Event { + public final ForumThread thread; + + public GuildForumThreadCreated(ForumThread thread) { + this.thread = thread; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryEvent.java new file mode 100644 index 0000000..5d9502a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryEvent.java @@ -0,0 +1,12 @@ +package com.eu.habbo.plugin.events.inventory; + +import com.eu.habbo.habbohotel.users.HabboInventory; +import com.eu.habbo.plugin.Event; + +public abstract class InventoryEvent extends Event { + public final HabboInventory inventory; + + protected InventoryEvent(HabboInventory inventory) { + this.inventory = inventory; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemAddedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemAddedEvent.java new file mode 100644 index 0000000..af3ed72 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemAddedEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.plugin.events.inventory; + +import com.eu.habbo.habbohotel.users.HabboInventory; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class InventoryItemAddedEvent extends InventoryItemEvent { + public InventoryItemAddedEvent(HabboInventory inventory, HabboItem item) { + super(inventory, item); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemEvent.java new file mode 100644 index 0000000..1b93cf8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.plugin.events.inventory; + +import com.eu.habbo.habbohotel.users.HabboInventory; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class InventoryItemEvent extends InventoryEvent { + public HabboItem item; + + public InventoryItemEvent(HabboInventory inventory, HabboItem item) { + super(inventory); + + this.item = item; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemRemovedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemRemovedEvent.java new file mode 100644 index 0000000..26330b8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemRemovedEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.plugin.events.inventory; + +import com.eu.habbo.habbohotel.users.HabboInventory; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class InventoryItemRemovedEvent extends InventoryItemEvent { + public InventoryItemRemovedEvent(HabboInventory inventory, HabboItem item) { + super(inventory, item); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemsAddedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemsAddedEvent.java new file mode 100644 index 0000000..a0ead84 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/inventory/InventoryItemsAddedEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.plugin.events.inventory; + +import com.eu.habbo.habbohotel.users.HabboInventory; +import com.eu.habbo.habbohotel.users.HabboItem; +import gnu.trove.set.hash.THashSet; + +public class InventoryItemsAddedEvent extends InventoryEvent { + public final THashSet items; + + public InventoryItemsAddedEvent(HabboInventory inventory, THashSet items) { + super(inventory); + this.items = items; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/marketplace/MarketPlaceEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/marketplace/MarketPlaceEvent.java new file mode 100644 index 0000000..da5e5a4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/marketplace/MarketPlaceEvent.java @@ -0,0 +1,6 @@ +package com.eu.habbo.plugin.events.marketplace; + +import com.eu.habbo.plugin.Event; + +public class MarketPlaceEvent extends Event { +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/marketplace/MarketPlaceItemCancelledEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/marketplace/MarketPlaceItemCancelledEvent.java new file mode 100644 index 0000000..993d4cc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/marketplace/MarketPlaceItemCancelledEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.plugin.events.marketplace; + +import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlaceOffer; + +public class MarketPlaceItemCancelledEvent extends MarketPlaceEvent { + public final MarketPlaceOffer offer; + + public MarketPlaceItemCancelledEvent(MarketPlaceOffer offer) { + this.offer = offer; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/marketplace/MarketPlaceItemOfferedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/marketplace/MarketPlaceItemOfferedEvent.java new file mode 100644 index 0000000..fa351db --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/marketplace/MarketPlaceItemOfferedEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.marketplace; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class MarketPlaceItemOfferedEvent extends MarketPlaceEvent { + public final Habbo habbo; + public final HabboItem item; + public int price; + + public MarketPlaceItemOfferedEvent(Habbo habbo, HabboItem item, int price) { + this.habbo = habbo; + this.item = item; + this.price = price; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/marketplace/MarketPlaceItemSoldEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/marketplace/MarketPlaceItemSoldEvent.java new file mode 100644 index 0000000..2f6957b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/marketplace/MarketPlaceItemSoldEvent.java @@ -0,0 +1,18 @@ +package com.eu.habbo.plugin.events.marketplace; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class MarketPlaceItemSoldEvent extends MarketPlaceEvent { + public final Habbo seller; + public final Habbo purchaser; + public final HabboItem item; + public int price; + + public MarketPlaceItemSoldEvent(Habbo seller, Habbo purchaser, HabboItem item, int price) { + this.seller = seller; + this.purchaser = purchaser; + this.item = item; + this.price = price; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorPopularRoomsEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorPopularRoomsEvent.java new file mode 100644 index 0000000..73dafe2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorPopularRoomsEvent.java @@ -0,0 +1,18 @@ +package com.eu.habbo.plugin.events.navigator; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.util.ArrayList; + +public class NavigatorPopularRoomsEvent extends NavigatorRoomsEvent { + + public final ArrayList rooms; + + + public NavigatorPopularRoomsEvent(Habbo habbo, ArrayList rooms) { + super(habbo, rooms); + + this.rooms = rooms; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorRoomCreatedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorRoomCreatedEvent.java new file mode 100644 index 0000000..8e0215a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorRoomCreatedEvent.java @@ -0,0 +1,17 @@ +package com.eu.habbo.plugin.events.navigator; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.events.users.UserEvent; + +public class NavigatorRoomCreatedEvent extends UserEvent { + + public final Room room; + + + public NavigatorRoomCreatedEvent(Habbo habbo, Room room) { + super(habbo); + + this.room = room; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorRoomDeletedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorRoomDeletedEvent.java new file mode 100644 index 0000000..581813a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorRoomDeletedEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.plugin.events.navigator; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.events.users.UserEvent; + +public class NavigatorRoomDeletedEvent extends UserEvent { + public final Room room; + + public NavigatorRoomDeletedEvent(Habbo habbo, Room room) { + super(habbo); + + this.room = room; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorRoomsEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorRoomsEvent.java new file mode 100644 index 0000000..4326283 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorRoomsEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.plugin.events.navigator; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.events.users.UserEvent; + +import java.util.ArrayList; + +public abstract class NavigatorRoomsEvent extends UserEvent { + + public final ArrayList rooms; + + + public NavigatorRoomsEvent(Habbo habbo, ArrayList rooms) { + super(habbo); + + this.rooms = rooms; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorSearchResultEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorSearchResultEvent.java new file mode 100644 index 0000000..d6c7a78 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/navigator/NavigatorSearchResultEvent.java @@ -0,0 +1,22 @@ +package com.eu.habbo.plugin.events.navigator; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.util.ArrayList; + +public class NavigatorSearchResultEvent extends NavigatorRoomsEvent { + + public final String prefix; + + + public final String query; + + + public NavigatorSearchResultEvent(Habbo habbo, String prefix, String query, ArrayList rooms) { + super(habbo, rooms); + + this.prefix = prefix; + this.query = query; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/pets/PetEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/pets/PetEvent.java new file mode 100644 index 0000000..f888cb3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/pets/PetEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.plugin.events.pets; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.plugin.Event; + +public abstract class PetEvent extends Event { + + public final Pet pet; + + + public PetEvent(Pet pet) { + this.pet = pet; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/pets/PetTalkEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/pets/PetTalkEvent.java new file mode 100644 index 0000000..8fefd42 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/pets/PetTalkEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.plugin.events.pets; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; + +public class PetTalkEvent extends PetEvent { + + public RoomChatMessage message; + + public PetTalkEvent(Pet pet, RoomChatMessage message) { + super(pet); + + this.message = message; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomEvent.java new file mode 100644 index 0000000..a6df776 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.plugin.events.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.plugin.Event; + +public abstract class RoomEvent extends Event { + + public final Room room; + + + public RoomEvent(Room room) { + this.room = room; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomFloorItemsLoadEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomFloorItemsLoadEvent.java new file mode 100644 index 0000000..01bea30 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomFloorItemsLoadEvent.java @@ -0,0 +1,30 @@ +package com.eu.habbo.plugin.events.rooms; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.plugin.events.users.UserEvent; +import gnu.trove.set.hash.THashSet; + +public class RoomFloorItemsLoadEvent extends UserEvent { + private THashSet floorItems; + private boolean changedFloorItems; + + public RoomFloorItemsLoadEvent(Habbo habbo, THashSet floorItems) { + super(habbo); + this.floorItems = floorItems; + this.changedFloorItems = false; + } + + public void setFloorItems(THashSet floorItems) { + this.changedFloorItems = true; + this.floorItems = floorItems; + } + + public boolean hasChangedFloorItems() { + return this.changedFloorItems; + } + + public THashSet getFloorItems() { + return this.floorItems; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomLoadedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomLoadedEvent.java new file mode 100644 index 0000000..a5452cf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomLoadedEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.plugin.events.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; + +public class RoomLoadedEvent extends RoomEvent { + + public RoomLoadedEvent(Room room) { + super(room); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomUncachedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomUncachedEvent.java new file mode 100644 index 0000000..dd4c132 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomUncachedEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.plugin.events.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; + +public class RoomUncachedEvent extends RoomEvent { + + public RoomUncachedEvent(Room room) { + super(room); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomUnloadedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomUnloadedEvent.java new file mode 100644 index 0000000..f312604 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomUnloadedEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.plugin.events.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; + +public class RoomUnloadedEvent extends RoomEvent { + + public RoomUnloadedEvent(Room room) { + super(room); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomUnloadingEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomUnloadingEvent.java new file mode 100644 index 0000000..af8af26 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/RoomUnloadingEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.plugin.events.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; + +public class RoomUnloadingEvent extends RoomEvent { + + public RoomUnloadingEvent(Room room) { + super(room); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/UserVoteRoomEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/UserVoteRoomEvent.java new file mode 100644 index 0000000..cac45ea --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/rooms/UserVoteRoomEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.plugin.events.rooms; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.Event; + +public class UserVoteRoomEvent extends Event { + public final Room room; + public final Habbo habbo; + + public UserVoteRoomEvent(Room room, Habbo habbo) { + this.room = room; + this.habbo = habbo; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/roomunit/RoomUnitEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/roomunit/RoomUnitEvent.java new file mode 100644 index 0000000..6979df5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/roomunit/RoomUnitEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.plugin.events.roomunit; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.plugin.Event; + +public abstract class RoomUnitEvent extends Event { + + public final Room room; + + + public final RoomUnit roomUnit; + + + public RoomUnitEvent(Room room, RoomUnit roomUnit) { + this.room = room; + this.roomUnit = roomUnit; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/roomunit/RoomUnitLookAtPointEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/roomunit/RoomUnitLookAtPointEvent.java new file mode 100644 index 0000000..b1e5c28 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/roomunit/RoomUnitLookAtPointEvent.java @@ -0,0 +1,17 @@ +package com.eu.habbo.plugin.events.roomunit; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; + +public class RoomUnitLookAtPointEvent extends RoomUnitEvent { + + public final RoomTile location; + + + public RoomUnitLookAtPointEvent(Room room, RoomUnit roomUnit, RoomTile location) { + super(room, roomUnit); + + this.location = location; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/roomunit/RoomUnitSetGoalEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/roomunit/RoomUnitSetGoalEvent.java new file mode 100644 index 0000000..c758327 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/roomunit/RoomUnitSetGoalEvent.java @@ -0,0 +1,21 @@ +package com.eu.habbo.plugin.events.roomunit; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; + +public class RoomUnitSetGoalEvent extends RoomUnitEvent { + + public final RoomTile goal; + + public RoomUnitSetGoalEvent(Room room, RoomUnit roomUnit, RoomTile goal) { + super(room, roomUnit); + + this.goal = goal; + } + + + public void setGoal(RoomTile t) { + super.roomUnit.setGoalLocation(t); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/sanctions/SanctionEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/sanctions/SanctionEvent.java new file mode 100644 index 0000000..1a73c4f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/sanctions/SanctionEvent.java @@ -0,0 +1,17 @@ +package com.eu.habbo.plugin.events.sanctions; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.events.support.SupportEvent; + +public class SanctionEvent extends SupportEvent { + public Habbo target; + + public int sanctionLevel; + + public SanctionEvent(Habbo moderator, Habbo target, int sanctionLevel) { + super(moderator); + + this.target = target; + this.sanctionLevel = sanctionLevel; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportEvent.java new file mode 100644 index 0000000..b198ecd --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.plugin.events.support; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.Event; + +public abstract class SupportEvent extends Event { + + public Habbo moderator; + + + public SupportEvent(Habbo moderator) { + this.moderator = moderator; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportRoomActionEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportRoomActionEvent.java new file mode 100644 index 0000000..f05df35 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportRoomActionEvent.java @@ -0,0 +1,28 @@ +package com.eu.habbo.plugin.events.support; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; + +public class SupportRoomActionEvent extends SupportEvent { + + public final Room room; + + + public boolean kickUsers; + + + public boolean lockDoor; + + + public boolean changeTitle; + + + public SupportRoomActionEvent(Habbo moderator, Room room, boolean kickUsers, boolean lockDoor, boolean changeTitle) { + super(moderator); + + this.room = room; + this.kickUsers = kickUsers; + this.lockDoor = lockDoor; + this.changeTitle = changeTitle; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportTicketEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportTicketEvent.java new file mode 100644 index 0000000..2d5a410 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportTicketEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.plugin.events.support; + +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.habbohotel.users.Habbo; + +public class SupportTicketEvent extends SupportEvent { + public final ModToolIssue ticket; + + + public SupportTicketEvent(Habbo moderator, ModToolIssue ticket) { + super(moderator); + + this.ticket = ticket; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportTicketStatusChangedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportTicketStatusChangedEvent.java new file mode 100644 index 0000000..16d8f00 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportTicketStatusChangedEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.plugin.events.support; + +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import com.eu.habbo.habbohotel.users.Habbo; + +public class SupportTicketStatusChangedEvent extends SupportTicketEvent { + + public SupportTicketStatusChangedEvent(Habbo moderator, ModToolIssue ticket) { + super(moderator, ticket); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportUserAlertedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportUserAlertedEvent.java new file mode 100644 index 0000000..de3dc54 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportUserAlertedEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.plugin.events.support; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class SupportUserAlertedEvent extends SupportEvent { + + public Habbo target; + + public String message; + + public SupportUserAlertedReason reason; + + public SupportUserAlertedEvent(Habbo moderator, Habbo target, String message, SupportUserAlertedReason reason) { + super(moderator); + + this.message = message; + this.target = target; + this.reason = reason; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportUserAlertedReason.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportUserAlertedReason.java new file mode 100644 index 0000000..b1afb34 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportUserAlertedReason.java @@ -0,0 +1,22 @@ +package com.eu.habbo.plugin.events.support; + +public enum SupportUserAlertedReason { + + ALERT(0), + + CAUTION(1), + + KICKED(2), + + AMBASSADOR(3); + + private final int code; + + SupportUserAlertedReason(int code) { + this.code = code; + } + + public int getCode() { + return this.code; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportUserBannedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportUserBannedEvent.java new file mode 100644 index 0000000..7712dd7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportUserBannedEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.plugin.events.support; + +import com.eu.habbo.habbohotel.modtool.ModToolBan; +import com.eu.habbo.habbohotel.users.Habbo; + +public class SupportUserBannedEvent extends SupportEvent { + + public final Habbo target; + + + public final ModToolBan ban; + + + public SupportUserBannedEvent(Habbo moderator, Habbo target, ModToolBan ban) { + super(moderator); + + this.target = target; + this.ban = ban; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportUserKickEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportUserKickEvent.java new file mode 100644 index 0000000..9a28a94 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/support/SupportUserKickEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.plugin.events.support; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class SupportUserKickEvent extends SupportEvent { + + public Habbo target; + + + public String message; + + + public SupportUserKickEvent(Habbo moderator, Habbo target, String message) { + super(moderator); + + this.target = target; + this.message = message; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/trading/TradeConfirmEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/trading/TradeConfirmEvent.java new file mode 100644 index 0000000..ee42fd2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/trading/TradeConfirmEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.plugin.events.trading; + +import com.eu.habbo.habbohotel.rooms.RoomTradeUser; +import com.eu.habbo.plugin.Event; + +public class TradeConfirmEvent extends Event { + public final RoomTradeUser userOne; + public final RoomTradeUser userTwo; + + public TradeConfirmEvent(RoomTradeUser userOne, RoomTradeUser userTwo) { + this.userOne = userOne; + this.userTwo = userTwo; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/HabboAddedToRoomEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/HabboAddedToRoomEvent.java new file mode 100644 index 0000000..8753b8b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/HabboAddedToRoomEvent.java @@ -0,0 +1,21 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.util.Collection; + +public class HabboAddedToRoomEvent extends UserEvent { + + public final Room room; + public Collection habbosToSendEnter; + public Collection visibleHabbos; + + public HabboAddedToRoomEvent(Habbo habbo, Room room, Collection habbosToSendEnter, Collection visibleHabbos) { + super(habbo); + + this.room = room; + this.habbosToSendEnter = habbosToSendEnter; + this.visibleHabbos = visibleHabbos; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserCommandEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserCommandEvent.java new file mode 100644 index 0000000..0695261 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserCommandEvent.java @@ -0,0 +1,18 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserCommandEvent extends UserEvent { + + public final String[] args; + + + public final boolean succes; + + + public UserCommandEvent(Habbo habbo, String[] args, boolean succes) { + super(habbo); + this.args = args; + this.succes = succes; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserCreditsEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserCreditsEvent.java new file mode 100644 index 0000000..0186e98 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserCreditsEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserCreditsEvent extends UserEvent { + + public int credits; + + + public UserCreditsEvent(Habbo habbo, int credits) { + super(habbo); + + this.credits = credits; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserDisconnectEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserDisconnectEvent.java new file mode 100644 index 0000000..a3c4304 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserDisconnectEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserDisconnectEvent extends UserEvent { + + public UserDisconnectEvent(Habbo habbo) { + super(habbo); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserEnterRoomEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserEnterRoomEvent.java new file mode 100644 index 0000000..05ae0a8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserEnterRoomEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserEnterRoomEvent extends UserEvent { + + public final Room room; + + + public UserEnterRoomEvent(Habbo habbo, Room room) { + super(habbo); + + this.room = room; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserEvent.java new file mode 100644 index 0000000..14876e8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.Event; + +public abstract class UserEvent extends Event { + + public final Habbo habbo; + + + public UserEvent(Habbo habbo) { + this.habbo = habbo; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserExecuteCommandEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserExecuteCommandEvent.java new file mode 100644 index 0000000..2da7d34 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserExecuteCommandEvent.java @@ -0,0 +1,27 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.commands.Command; +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserExecuteCommandEvent extends UserEvent { + + public final Command command; + public final String[] params; + private boolean success; + + public UserExecuteCommandEvent(Habbo habbo, Command command, String[] params) { + super(habbo); + + this.command = command; + this.params = params; + this.success = true; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public boolean isSuccess() { + return success; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserExitRoomEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserExitRoomEvent.java new file mode 100644 index 0000000..c63ae3d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserExitRoomEvent.java @@ -0,0 +1,26 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserExitRoomEvent extends UserEvent { + public final UserExitRoomReason reason; + + public UserExitRoomEvent(Habbo habbo, UserExitRoomReason reason) { + super(habbo); + this.reason = reason; + } + + + public enum UserExitRoomReason { + DOOR(false), + KICKED_HABBO(false), + KICKED_IDLE(true), + TELEPORT(false); + + public final boolean cancellable; + + UserExitRoomReason(boolean cancellable) { + this.cancellable = cancellable; + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserGetIPAddressEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserGetIPAddressEvent.java new file mode 100644 index 0000000..c77b363 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserGetIPAddressEvent.java @@ -0,0 +1,28 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserGetIPAddressEvent extends UserEvent{ + public final String oldIp; + + private String updatedIp; + private boolean changedIP = false; + + public UserGetIPAddressEvent(Habbo habbo, String ip) { + super(habbo); + this.oldIp = ip; + } + + public void setUpdatedIp(String updatedIp) { + this.updatedIp = updatedIp; + this.changedIP = true; + } + + public boolean hasChangedIP() { + return changedIP; + } + + public String getUpdatedIp() { + return updatedIp; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserIdleEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserIdleEvent.java new file mode 100644 index 0000000..5e5b778 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserIdleEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserIdleEvent extends UserEvent { + public final IdleReason reason; + public boolean idle; + public UserIdleEvent(Habbo habbo, IdleReason reason, boolean idle) { + super(habbo); + + this.reason = reason; + this.idle = idle; + } + + + public enum IdleReason { + ACTION, + DANCE, + TIMEOUT, + WALKED, + TALKED + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserKickEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserKickEvent.java new file mode 100644 index 0000000..5e4feb0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserKickEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserKickEvent extends UserEvent { + + public final Habbo target; + + + public UserKickEvent(Habbo habbo, Habbo target) { + super(habbo); + + this.target = target; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserLoginEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserLoginEvent.java new file mode 100644 index 0000000..d864a5f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserLoginEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +import java.net.SocketAddress; + +public class UserLoginEvent extends UserEvent { + + public final String ip; + + public UserLoginEvent(Habbo habbo, String ip) { + super(habbo); + + this.ip = ip; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserNameChangedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserNameChangedEvent.java new file mode 100644 index 0000000..2e7384c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserNameChangedEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserNameChangedEvent extends UserEvent { + public final String oldName; + + + public UserNameChangedEvent(Habbo habbo, String oldName) { + super(habbo); + + this.oldName = oldName; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserPickGiftEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserPickGiftEvent.java new file mode 100644 index 0000000..22c27a7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserPickGiftEvent.java @@ -0,0 +1,17 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserPickGiftEvent extends UserEvent { + public final int keyA; + public final int keyB; + public final int index; + + + public UserPickGiftEvent(Habbo habbo, int keyA, int keyB, int index) { + super(habbo); + this.keyA = keyA; + this.keyB = keyB; + this.index = index; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserPointsEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserPointsEvent.java new file mode 100644 index 0000000..d014e41 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserPointsEvent.java @@ -0,0 +1,19 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserPointsEvent extends UserEvent { + + public int points; + + + public int type; + + + public UserPointsEvent(Habbo habbo, int points, int type) { + super(habbo); + + this.points = points; + this.type = type; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserPublishPictureEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserPublishPictureEvent.java new file mode 100644 index 0000000..7c794fb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserPublishPictureEvent.java @@ -0,0 +1,22 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserPublishPictureEvent extends UserEvent { + + public String URL; + + + public int timestamp; + + + public int roomId; + + + public UserPublishPictureEvent(Habbo habbo, String url, int timestamp, int roomId) { + super(habbo); + this.URL = url; + this.timestamp = timestamp; + this.roomId = roomId; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserPurchasePictureEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserPurchasePictureEvent.java new file mode 100644 index 0000000..b79fbb2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserPurchasePictureEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserPurchasePictureEvent extends UserEvent { + + public String url; + + + public int roomId; + + + public int timestamp; + + + public UserPurchasePictureEvent(Habbo habbo, String url, int roomId, int timestamp) { + super(habbo); + + this.url = url; + this.roomId = roomId; + this.timestamp = timestamp; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRankChangedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRankChangedEvent.java new file mode 100644 index 0000000..41cb109 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRankChangedEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserRankChangedEvent extends UserEvent { + + public UserRankChangedEvent(Habbo habbo) { + super(habbo); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRegisteredEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRegisteredEvent.java new file mode 100644 index 0000000..3aa7904 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRegisteredEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserRegisteredEvent extends UserEvent { + + public UserRegisteredEvent(Habbo habbo) { + super(habbo); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRespectedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRespectedEvent.java new file mode 100644 index 0000000..6834835 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRespectedEvent.java @@ -0,0 +1,13 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserRespectedEvent extends UserEvent { + public final Habbo from; + + public UserRespectedEvent(Habbo habbo, Habbo from) { + super(habbo); + + this.from = from; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRightsGivenEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRightsGivenEvent.java new file mode 100644 index 0000000..ba84083 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRightsGivenEvent.java @@ -0,0 +1,13 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserRightsGivenEvent extends UserEvent { + public final Habbo receiver; + + public UserRightsGivenEvent(Habbo habbo, Habbo receiver) { + super(habbo); + + this.receiver = receiver; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRightsTakenEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRightsTakenEvent.java new file mode 100644 index 0000000..ee55630 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRightsTakenEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserRightsTakenEvent extends UserEvent { + public final int victimId; + public final Habbo victim; + + + public UserRightsTakenEvent(Habbo habbo, int victimId, Habbo victim) { + super(habbo); + + this.victimId = victimId; + this.victim = victim; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRolledEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRolledEvent.java new file mode 100644 index 0000000..c38f36a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserRolledEvent.java @@ -0,0 +1,21 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class UserRolledEvent extends UserEvent { + + public final HabboItem roller; + + + public final RoomTile location; + + + public UserRolledEvent(Habbo habbo, HabboItem roller, RoomTile location) { + super(habbo); + + this.roller = roller; + this.location = location; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSavedLookEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSavedLookEvent.java new file mode 100644 index 0000000..096cbe3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSavedLookEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboGender; + +public class UserSavedLookEvent extends UserEvent { + public HabboGender gender; + public String newLook; + + + public UserSavedLookEvent(Habbo habbo, HabboGender gender, String newLook) { + super(habbo); + this.gender = gender; + this.newLook = newLook; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSavedMottoEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSavedMottoEvent.java new file mode 100644 index 0000000..0b64b44 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSavedMottoEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserSavedMottoEvent extends UserEvent { + public final String oldMotto; + public String newMotto; + + + public UserSavedMottoEvent(Habbo habbo, String oldMotto, String newMotto) { + super(habbo); + this.oldMotto = oldMotto; + this.newMotto = newMotto; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSavedSettingsEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSavedSettingsEvent.java new file mode 100644 index 0000000..687eeea --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSavedSettingsEvent.java @@ -0,0 +1,10 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserSavedSettingsEvent extends UserEvent { + + public UserSavedSettingsEvent(Habbo habbo) { + super(habbo); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSavedWardrobeEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSavedWardrobeEvent.java new file mode 100644 index 0000000..f1d57c6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSavedWardrobeEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.inventory.WardrobeComponent; + +public class UserSavedWardrobeEvent extends UserEvent { + public final WardrobeComponent.WardrobeItem wardrobeItem; + + + public UserSavedWardrobeEvent(Habbo habbo, WardrobeComponent.WardrobeItem wardrobeItem) { + super(habbo); + this.wardrobeItem = wardrobeItem; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSignEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSignEvent.java new file mode 100644 index 0000000..0489946 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserSignEvent.java @@ -0,0 +1,14 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserSignEvent extends UserEvent { + + + public int sign; + + public UserSignEvent(Habbo habbo, int sign) { + super(habbo); + this.sign = sign; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserTakeStepEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserTakeStepEvent.java new file mode 100644 index 0000000..133016f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserTakeStepEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserTakeStepEvent extends UserEvent { + + public final RoomTile fromLocation; + + + public final RoomTile toLocation; + + + public UserTakeStepEvent(Habbo habbo, RoomTile fromLocation, RoomTile toLocation) { + super(habbo); + + this.fromLocation = fromLocation; + this.toLocation = toLocation; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserTalkEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserTalkEvent.java new file mode 100644 index 0000000..853e364 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserTalkEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.habbohotel.rooms.RoomChatType; +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserTalkEvent extends UserEvent { + public final RoomChatMessage chatMessage; + public final RoomChatType chatType; + + public UserTalkEvent(Habbo habbo, RoomChatMessage chatMessage, RoomChatType chatType) { + super(habbo); + this.chatMessage = chatMessage; + this.chatType = chatType; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserTriggerWordFilterEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserTriggerWordFilterEvent.java new file mode 100644 index 0000000..e7fa981 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserTriggerWordFilterEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.modtool.WordFilterWord; +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserTriggerWordFilterEvent extends UserEvent { + + public final WordFilterWord word; + + + public UserTriggerWordFilterEvent(Habbo habbo, WordFilterWord word) { + super(habbo); + + this.word = word; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserWiredRewardReceived.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserWiredRewardReceived.java new file mode 100644 index 0000000..c2c16e3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UserWiredRewardReceived.java @@ -0,0 +1,24 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.items.interactions.wired.effects.WiredEffectGiveReward; +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserWiredRewardReceived extends UserEvent { + + public final WiredEffectGiveReward wiredEffectGiveReward; + + + public final String type; + + + public String value; + + + public UserWiredRewardReceived(Habbo habbo, WiredEffectGiveReward wiredEffectGiveReward, String type, String value) { + super(habbo); + + this.wiredEffectGiveReward = wiredEffectGiveReward; + this.type = type; + this.value = value; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UsernameTalkEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UsernameTalkEvent.java new file mode 100644 index 0000000..752afdc --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/UsernameTalkEvent.java @@ -0,0 +1,31 @@ +package com.eu.habbo.plugin.events.users; + +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.habbohotel.rooms.RoomChatType; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.ServerMessage; + +public class UsernameTalkEvent extends UserEvent { + public final RoomChatMessage chatMessage; + public final RoomChatType chatType; + + private ServerMessage customComposer = null; + + public UsernameTalkEvent(Habbo habbo, RoomChatMessage chatMessage, RoomChatType chatType) { + super(habbo); + this.chatMessage = chatMessage; + this.chatType = chatType; + } + + public void setCustomComposer(ServerMessage customComposer) { + this.customComposer = customComposer; + } + + public boolean hasCustomComposer() { + return this.customComposer != null; + } + + public ServerMessage getCustomComposer() { + return this.customComposer; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/achievements/UserAchievementEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/achievements/UserAchievementEvent.java new file mode 100644 index 0000000..5d50f75 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/achievements/UserAchievementEvent.java @@ -0,0 +1,17 @@ +package com.eu.habbo.plugin.events.users.achievements; + +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.events.users.UserEvent; + +public abstract class UserAchievementEvent extends UserEvent { + + public final Achievement achievement; + + + public UserAchievementEvent(Habbo habbo, Achievement achievement) { + super(habbo); + + this.achievement = achievement; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/achievements/UserAchievementLeveledEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/achievements/UserAchievementLeveledEvent.java new file mode 100644 index 0000000..825b871 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/achievements/UserAchievementLeveledEvent.java @@ -0,0 +1,21 @@ +package com.eu.habbo.plugin.events.users.achievements; + +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.achievements.AchievementLevel; +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserAchievementLeveledEvent extends UserAchievementEvent { + + public final AchievementLevel oldLevel; + + + public final AchievementLevel newLevel; + + + public UserAchievementLeveledEvent(Habbo habbo, Achievement achievement, AchievementLevel oldLevel, AchievementLevel newLevel) { + super(habbo, achievement); + + this.oldLevel = oldLevel; + this.newLevel = newLevel; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/achievements/UserAchievementProgressEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/achievements/UserAchievementProgressEvent.java new file mode 100644 index 0000000..8074f19 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/achievements/UserAchievementProgressEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.users.achievements; + +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserAchievementProgressEvent extends UserAchievementEvent { + + public final int progressed; + + + public UserAchievementProgressEvent(Habbo habbo, Achievement achievement, int progressed) { + super(habbo, achievement); + + this.progressed = progressed; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/calendar/UserClaimRewardEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/calendar/UserClaimRewardEvent.java new file mode 100644 index 0000000..c57f60d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/calendar/UserClaimRewardEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.plugin.events.users.calendar; + +import com.eu.habbo.habbohotel.campaign.calendar.CalendarCampaign; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarRewardObject; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.events.users.UserEvent; + +public class UserClaimRewardEvent extends UserEvent { + + public CalendarCampaign campaign; + public int day; + public CalendarRewardObject reward; + public boolean force; + + public UserClaimRewardEvent(Habbo habbo, CalendarCampaign campaign, int day, CalendarRewardObject reward, boolean force) { + super(habbo); + + this.campaign = campaign; + this.day = day; + this.reward = reward; + this.force = force; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/catalog/UserCatalogEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/catalog/UserCatalogEvent.java new file mode 100644 index 0000000..6fe222a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/catalog/UserCatalogEvent.java @@ -0,0 +1,17 @@ +package com.eu.habbo.plugin.events.users.catalog; + +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.events.users.UserEvent; + +public class UserCatalogEvent extends UserEvent { + + public CatalogItem catalogItem; + + + public UserCatalogEvent(Habbo habbo, CatalogItem catalogItem) { + super(habbo); + + this.catalogItem = catalogItem; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/catalog/UserCatalogFurnitureBoughtEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/catalog/UserCatalogFurnitureBoughtEvent.java new file mode 100644 index 0000000..2e38aa8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/catalog/UserCatalogFurnitureBoughtEvent.java @@ -0,0 +1,18 @@ +package com.eu.habbo.plugin.events.users.catalog; + +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import gnu.trove.set.hash.THashSet; + +public class UserCatalogFurnitureBoughtEvent extends UserCatalogEvent { + + public final THashSet furniture; + + + public UserCatalogFurnitureBoughtEvent(Habbo habbo, CatalogItem catalogItem, THashSet furniture) { + super(habbo, catalogItem); + + this.furniture = furniture; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/catalog/UserCatalogItemPurchasedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/catalog/UserCatalogItemPurchasedEvent.java new file mode 100644 index 0000000..d95bc22 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/catalog/UserCatalogItemPurchasedEvent.java @@ -0,0 +1,32 @@ +package com.eu.habbo.plugin.events.users.catalog; + +import com.eu.habbo.habbohotel.catalog.CatalogItem; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import gnu.trove.set.hash.THashSet; + +import java.util.List; + +public class UserCatalogItemPurchasedEvent extends UserCatalogEvent { + + public final THashSet itemsList; + + + public int totalCredits; + + + public int totalPoints; + + + public List badges; + + + public UserCatalogItemPurchasedEvent(Habbo habbo, CatalogItem catalogItem, THashSet itemsList, int totalCredits, int totalPoints, List badges) { + super(habbo, catalogItem); + + this.itemsList = itemsList; + this.totalCredits = totalCredits; + this.totalPoints = totalPoints; + this.badges = badges; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserAcceptFriendRequestEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserAcceptFriendRequestEvent.java new file mode 100644 index 0000000..12b5456 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserAcceptFriendRequestEvent.java @@ -0,0 +1,11 @@ +package com.eu.habbo.plugin.events.users.friends; + +import com.eu.habbo.habbohotel.messenger.MessengerBuddy; +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserAcceptFriendRequestEvent extends UserFriendEvent { + + public UserAcceptFriendRequestEvent(Habbo habbo, MessengerBuddy friend) { + super(habbo, friend); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserFriendChatEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserFriendChatEvent.java new file mode 100644 index 0000000..144ef54 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserFriendChatEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.users.friends; + +import com.eu.habbo.habbohotel.messenger.MessengerBuddy; +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserFriendChatEvent extends UserFriendEvent { + + public String message; + + + public UserFriendChatEvent(Habbo habbo, MessengerBuddy friend, String message) { + super(habbo, friend); + + this.message = message; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserFriendEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserFriendEvent.java new file mode 100644 index 0000000..4cf600e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserFriendEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.users.friends; + +import com.eu.habbo.habbohotel.messenger.MessengerBuddy; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.events.users.UserEvent; + +public abstract class UserFriendEvent extends UserEvent { + public final MessengerBuddy friend; + + + public UserFriendEvent(Habbo habbo, MessengerBuddy friend) { + super(habbo); + + this.friend = friend; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserRelationShipEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserRelationShipEvent.java new file mode 100644 index 0000000..416c58a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserRelationShipEvent.java @@ -0,0 +1,15 @@ +package com.eu.habbo.plugin.events.users.friends; + +import com.eu.habbo.habbohotel.messenger.MessengerBuddy; +import com.eu.habbo.habbohotel.users.Habbo; + +public class UserRelationShipEvent extends UserFriendEvent { + public int relationShip; + + + public UserRelationShipEvent(Habbo habbo, MessengerBuddy friend, int relationShip) { + super(habbo, friend); + + this.relationShip = relationShip; + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserRequestFriendshipEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserRequestFriendshipEvent.java new file mode 100644 index 0000000..7e82559 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/friends/UserRequestFriendshipEvent.java @@ -0,0 +1,20 @@ +package com.eu.habbo.plugin.events.users.friends; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.events.users.UserEvent; + +public class UserRequestFriendshipEvent extends UserEvent { + + public final String name; + + + public final Habbo friend; + + + public UserRequestFriendshipEvent(Habbo habbo, String name, Habbo friend) { + super(habbo); + + this.name = name; + this.friend = friend; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/subscriptions/UserSubscriptionCreatedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/subscriptions/UserSubscriptionCreatedEvent.java new file mode 100644 index 0000000..6a6ce5e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/subscriptions/UserSubscriptionCreatedEvent.java @@ -0,0 +1,17 @@ +package com.eu.habbo.plugin.events.users.subscriptions; + +import com.eu.habbo.plugin.Event; + +public class UserSubscriptionCreatedEvent extends Event { + public final int userId; + public final String subscriptionType; + public final int duration; + + public UserSubscriptionCreatedEvent(int userId, String subscriptionType, int duration) { + super(); + + this.userId = userId; + this.subscriptionType = subscriptionType; + this.duration = duration; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/subscriptions/UserSubscriptionExpiredEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/subscriptions/UserSubscriptionExpiredEvent.java new file mode 100644 index 0000000..7090066 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/subscriptions/UserSubscriptionExpiredEvent.java @@ -0,0 +1,16 @@ +package com.eu.habbo.plugin.events.users.subscriptions; + +import com.eu.habbo.habbohotel.users.subscriptions.Subscription; +import com.eu.habbo.plugin.Event; + +public class UserSubscriptionExpiredEvent extends Event { + public final int userId; + public final Subscription subscription; + + public UserSubscriptionExpiredEvent(int userId, Subscription subscription) { + super(); + + this.userId = userId; + this.subscription = subscription; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/plugin/events/users/subscriptions/UserSubscriptionExtendedEvent.java b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/subscriptions/UserSubscriptionExtendedEvent.java new file mode 100644 index 0000000..3e1c24e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/plugin/events/users/subscriptions/UserSubscriptionExtendedEvent.java @@ -0,0 +1,17 @@ +package com.eu.habbo.plugin.events.users.subscriptions; + +import com.eu.habbo.habbohotel.users.subscriptions.Subscription; +import com.eu.habbo.plugin.Event; + +public class UserSubscriptionExtendedEvent extends Event { + public final int userId; + public final Subscription subscription; + public final int duration; + + public UserSubscriptionExtendedEvent(int userId, Subscription subscription, int duration) { + super(); + this.userId = userId; + this.subscription = subscription; + this.duration = duration; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/HabboExecutorService.java b/Emulator/src/main/java/com/eu/habbo/threading/HabboExecutorService.java new file mode 100644 index 0000000..e165200 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/HabboExecutorService.java @@ -0,0 +1,22 @@ +package com.eu.habbo.threading; + +import lombok.extern.slf4j.Slf4j; +import java.io.IOException; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; + +@Slf4j +public class HabboExecutorService extends ScheduledThreadPoolExecutor { + public HabboExecutorService(int corePoolSize, ThreadFactory threadFactory) { + super(corePoolSize, threadFactory); + } + + @Override + protected void afterExecute(Runnable r, Throwable t) { + super.afterExecute(r, t); + + if (t != null && !(t instanceof IOException)) { + log.error("Error in HabboExecutorService", t); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/RejectedExecutionHandlerImpl.java b/Emulator/src/main/java/com/eu/habbo/threading/RejectedExecutionHandlerImpl.java new file mode 100644 index 0000000..59ba0f8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/RejectedExecutionHandlerImpl.java @@ -0,0 +1,14 @@ +package com.eu.habbo.threading; + +import lombok.extern.slf4j.Slf4j; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadPoolExecutor; + +@Slf4j +public class RejectedExecutionHandlerImpl implements RejectedExecutionHandler { + + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + log.error(r.toString() + " is rejected"); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/ThreadPooling.java b/Emulator/src/main/java/com/eu/habbo/threading/ThreadPooling.java new file mode 100644 index 0000000..7652a79 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/ThreadPooling.java @@ -0,0 +1,76 @@ +package com.eu.habbo.threading; + +import com.eu.habbo.Emulator; +import io.netty.util.concurrent.DefaultThreadFactory; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +@Slf4j +public class ThreadPooling { + + public final int threads; + private final ScheduledExecutorService scheduledPool; + private volatile boolean canAdd; + + + public ThreadPooling(Integer threads) { + this.threads = threads; + this.scheduledPool = new HabboExecutorService(this.threads, new DefaultThreadFactory("HabExec")); + this.canAdd = true; + log.info("Thread Pool -> Loaded!"); + } + + public ScheduledFuture run(Runnable run) { + try { + if (this.canAdd) { + return this.run(run, 0); + } else { + if (Emulator.isShuttingDown) { + run.run(); + } + } + } catch (Exception e) { + log.error("Caught exception", e); + } + + return null; + } + + public ScheduledFuture run(Runnable run, long delay) { + try { + if (this.canAdd) { + return this.scheduledPool.schedule(() -> { + try { + run.run(); + } catch (Exception e) { + log.error("Caught exception", e); + } + }, delay, TimeUnit.MILLISECONDS); + } + } catch (Exception e) { + log.error("Caught exception", e); + } + + return null; + } + + public void shutDown() { + this.canAdd = false; + this.scheduledPool.shutdownNow(); + + log.info("Threading -> Disposed!"); + } + + public void setCanAdd(boolean canAdd) { + this.canAdd = canAdd; + } + + public ScheduledExecutorService getService() { + return this.scheduledPool; + } + + +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/AchievementUpdater.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/AchievementUpdater.java new file mode 100644 index 0000000..2ee1dcb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/AchievementUpdater.java @@ -0,0 +1,36 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.Achievement; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.users.Habbo; + +import java.util.Map; + +public class AchievementUpdater implements Runnable { + public static final int INTERVAL = 5 * 60; + public int lastExecutionTimestamp = Emulator.getIntUnixTimestamp(); + + @Override + public void run() { + if (!Emulator.isShuttingDown) { + Emulator.getThreading().run(this, INTERVAL * 1000); + } + + if (Emulator.isReady) { + Achievement onlineTime = Emulator.getGameEnvironment().getAchievementManager().getAchievement("AllTimeHotelPresence"); + + int timestamp = Emulator.getIntUnixTimestamp(); + for (Map.Entry set : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) { + int timeOnlineSinceLastInterval = INTERVAL; + Habbo habbo = set.getValue(); + if (habbo.getHabboInfo().getLastOnline() > this.lastExecutionTimestamp) { + timeOnlineSinceLastInterval = timestamp - habbo.getHabboInfo().getLastOnline(); + } + AchievementManager.progressAchievement(habbo, onlineTime, (int) Math.floor((timeOnlineSinceLastInterval) / 60)); + } + + this.lastExecutionTimestamp = timestamp; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/BackgroundAnimation.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/BackgroundAnimation.java new file mode 100644 index 0000000..e3fafa5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/BackgroundAnimation.java @@ -0,0 +1,31 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class BackgroundAnimation implements Runnable { + private final HabboItem toner; + private final Room room; + private int length = 1000; + private int state = 0; + + public BackgroundAnimation(HabboItem toner, Room room) { + this.toner = toner; + this.room = room; + } + + @Override + public void run() { + if (this.room.isLoaded() && !this.room.isPreLoaded()) { + this.toner.setExtradata("1:" + this.state + ":126:126"); + this.state = (this.state + 1) % 256; + this.room.updateItem(this.toner); + + if (this.toner.getRoomId() > 0 && this.length > 0) { + Emulator.getThreading().run(this, 500); + this.length--; + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/BanzaiRandomTeleport.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/BanzaiRandomTeleport.java new file mode 100644 index 0000000..d559dae --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/BanzaiRandomTeleport.java @@ -0,0 +1,74 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.habbohotel.users.HabboItem; +import org.slf4j.LoggerFactory; + +public class BanzaiRandomTeleport implements Runnable { + private final HabboItem item; + private final HabboItem toItem; + private final RoomUnit habbo; + private final Room room; + + public BanzaiRandomTeleport(HabboItem item, HabboItem toItem, RoomUnit habbo, Room room) { + this.item = item; + this.toItem = toItem; + this.habbo = habbo; + this.room = room; + } + + @Override + public void run() { + HabboItem topItemNow = this.room.getTopItemAt(this.habbo.getX(), this.habbo.getY()); + RoomTile lastLocation = this.habbo.getCurrentLocation(); + RoomTile newLocation = this.room.getLayout().getTile(toItem.getX(), toItem.getY()); + + if(topItemNow != null) { + try { + topItemNow.onWalkOff(this.habbo, this.room, new Object[] { lastLocation, newLocation, this }); + } catch (Exception e) { + LoggerFactory.getLogger(BanzaiRandomTeleport.class).error("BanzaiRandomTeleport exception", e); + } + } + + Emulator.getThreading().run(() -> { + if (this.item.getExtradata().equals("1")) { + this.item.setExtradata("0"); + this.room.updateItemState(this.item); + } + }, 500); + + if(!this.toItem.getExtradata().equals("1")) { + this.toItem.setExtradata("1"); + this.room.updateItemState(this.toItem); + } + + Emulator.getThreading().run(() -> { + this.habbo.setCanWalk(true); + HabboItem topItemNext = this.room.getTopItemAt(this.habbo.getX(), this.habbo.getY()); + + if(topItemNext != null) { + try { + topItemNext.onWalkOn(this.habbo, this.room, new Object[] { lastLocation, newLocation, this }); + } catch (Exception e) { + LoggerFactory.getLogger(BanzaiRandomTeleport.class).error("BanzaiRandomTeleport exception", e); + } + } + + if (this.toItem.getExtradata().equals("1")) { + this.toItem.setExtradata("0"); + this.room.updateItemState(this.toItem); + } + }, 750); + + Emulator.getThreading().run(() -> { + this.habbo.setRotation(RoomUserRotation.fromValue(Emulator.getRandom().nextInt(8))); + this.room.teleportRoomUnitToLocation(this.habbo, newLocation.x, newLocation.y, newLocation.getStackHeight()); + }, 250); + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/BattleBanzaiTilesFlicker.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/BattleBanzaiTilesFlicker.java new file mode 100644 index 0000000..0993c1b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/BattleBanzaiTilesFlicker.java @@ -0,0 +1,56 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.games.GameTeamColors; +import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiSphere; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.rooms.items.ItemsDataUpdateComposer; +import gnu.trove.set.hash.THashSet; + +public class BattleBanzaiTilesFlicker implements Runnable { + private final THashSet items; + private final GameTeamColors color; + private final Room room; + + private boolean on = false; + private int count = 0; + + public BattleBanzaiTilesFlicker(THashSet items, GameTeamColors color, Room room) { + this.items = items; + this.color = color; + this.room = room; + } + + @Override + public void run() { + if (this.items == null || this.room == null) + return; + + int state = 0; + if (this.on) { + state = (this.color.type * 3) + 2; + this.on = false; + } else { + this.on = true; + } + + for (HabboItem item : this.items) { + item.setExtradata(state + ""); + } + + this.room.sendComposer(new ItemsDataUpdateComposer(this.items).compose()); + + if (this.count == 9) { + for (HabboItem item : this.room.getRoomSpecialTypes().getItemsOfType(InteractionBattleBanzaiSphere.class)) { + item.setExtradata("0"); + this.room.updateItemState(item); + } + return; + } + + this.count++; + + Emulator.getThreading().run(this, 500); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/BotFollowHabbo.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/BotFollowHabbo.java new file mode 100644 index 0000000..1164207 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/BotFollowHabbo.java @@ -0,0 +1,59 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; + +public class BotFollowHabbo implements Runnable { + private final Bot bot; + private final Habbo habbo; + private final Room room; + private boolean hasReached; + + public BotFollowHabbo(Bot bot, Habbo habbo, Room room) { + this.bot = bot; + this.habbo = habbo; + this.room = room; + this.hasReached = false; + } + + @Override + public void run() { + if (this.bot != null) { + if (this.habbo != null && this.bot.getFollowingHabboId() == this.habbo.getHabboInfo().getId()) { + if (this.habbo.getHabboInfo().getCurrentRoom() != null && this.habbo.getHabboInfo().getCurrentRoom() == this.room) { + if (this.habbo.getRoomUnit() != null) { + if (this.bot.getRoomUnit() != null) { + RoomTile target = this.room.getLayout().getTileInFront(this.habbo.getRoomUnit().getCurrentLocation(), Math.abs((this.habbo.getRoomUnit().getBodyRotation().getValue() + 4)) % 8); + + if (target != null) { + if (target.x < 0 || target.y < 0) + target = this.room.getLayout().getTileInFront(this.habbo.getRoomUnit().getCurrentLocation(), this.habbo.getRoomUnit().getBodyRotation().getValue()); + + if(this.habbo.getRoomUnit().getCurrentLocation().distance(this.bot.getRoomUnit().getCurrentLocation()) < 2) { + if(!hasReached) { + WiredHandler.handle(WiredTriggerType.BOT_REACHED_AVTR, bot.getRoomUnit(), room, new Object[]{}); + hasReached = true; + } + } + else { + hasReached = false; + } + + if (target.x >= 0 && target.y >= 0) { + this.bot.getRoomUnit().setGoalLocation(target); + this.bot.getRoomUnit().setCanWalk(true); + Emulator.getThreading().run(this, 500); + } + } + } + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/CameraClientAutoReconnect.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/CameraClientAutoReconnect.java new file mode 100644 index 0000000..0eedee3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/CameraClientAutoReconnect.java @@ -0,0 +1,33 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.networking.camera.CameraClient; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CameraClientAutoReconnect implements Runnable { + + @Override + public void run() { + if (CameraClient.attemptReconnect && !Emulator.isShuttingDown) { + if (!(CameraClient.channelFuture != null && CameraClient.channelFuture.channel().isRegistered())) { + log.info("Attempting to connect to the Camera server."); + if (Emulator.getCameraClient() != null) { + Emulator.getCameraClient().disconnect(); + } else { + Emulator.setCameraClient(new CameraClient()); + } + + try { + Emulator.getCameraClient().connect(); + } catch (Exception e) { + log.error("Failed to start the camera client.", e); + } + } else { + CameraClient.attemptReconnect = false; + log.info("Already connected to the camera. Reconnecting not needed!"); + } + } + Emulator.getThreading().run(this, 5000); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/CannonKickAction.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/CannonKickAction.java new file mode 100644 index 0000000..7154f94 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/CannonKickAction.java @@ -0,0 +1,50 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.interactions.InteractionCannon; +import com.eu.habbo.habbohotel.permissions.Permission; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; +import gnu.trove.map.hash.THashMap; + +import java.util.List; + +public class CannonKickAction implements Runnable { + private final InteractionCannon cannon; + private final Room room; + private final GameClient client; + + public CannonKickAction(InteractionCannon cannon, Room room, GameClient client) { + this.cannon = cannon; + this.room = room; + this.client = client; + } + + @Override + public void run() { + if (this.client != null) { + this.client.getHabbo().getRoomUnit().setCanWalk(true); + } + THashMap dater = new THashMap<>(); + dater.put("title", "${notification.room.kick.cannonball.title}"); + dater.put("message", "${notification.room.kick.cannonball.message}"); + + int rotation = this.cannon.getRotation(); + List tiles = this.room.getLayout().getTilesInFront(this.room.getLayout().getTile(this.cannon.getX(), this.cannon.getY()), rotation + 6, 3); + + ServerMessage message = new BubbleAlertComposer("cannon.png", dater).compose(); + + for (RoomTile t : tiles) { + for (Habbo habbo : this.room.getHabbosAt(t.x, t.y)) { + if (!habbo.hasPermission(Permission.ACC_UNKICKABLE) && !this.room.isOwner(habbo)) { + Emulator.getGameEnvironment().getRoomManager().leaveRoom(habbo, this.room); + habbo.getClient().sendResponse(message); //kicked composer + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/CannonResetCooldownAction.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/CannonResetCooldownAction.java new file mode 100644 index 0000000..5155a6e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/CannonResetCooldownAction.java @@ -0,0 +1,18 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.habbohotel.items.interactions.InteractionCannon; + +public class CannonResetCooldownAction implements Runnable { + private final InteractionCannon cannon; + + public CannonResetCooldownAction(InteractionCannon cannon) { + this.cannon = cannon; + } + + @Override + public void run() { + if (this.cannon != null) { + this.cannon.cooldown = false; + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/ChannelReadHandler.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/ChannelReadHandler.java new file mode 100644 index 0000000..a4caf09 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/ChannelReadHandler.java @@ -0,0 +1,30 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.messages.ClientMessage; +import com.eu.habbo.networking.gameserver.GameServerAttributes; +import io.netty.channel.ChannelHandlerContext; + +public class ChannelReadHandler implements Runnable { + + private final ChannelHandlerContext ctx; + private final ClientMessage message; + + public ChannelReadHandler(ChannelHandlerContext ctx, ClientMessage message) { + this.ctx = ctx; + this.message = message; + } + + public void run() { + try { + GameClient client = this.ctx.channel().attr(GameServerAttributes.CLIENT).get(); + + if (client != null) { + Emulator.getGameServer().getPacketManager().handlePacket(client, message); + } + } finally { + this.message.release(); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/ClearRentedSpace.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/ClearRentedSpace.java new file mode 100644 index 0000000..0349a43 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/ClearRentedSpace.java @@ -0,0 +1,47 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionRentableSpace; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import gnu.trove.set.hash.THashSet; + +public class ClearRentedSpace implements Runnable { + private final InteractionRentableSpace item; + private final Room room; + + public ClearRentedSpace(InteractionRentableSpace item, Room room) { + this.item = item; + this.room = room; + } + + @Override + public void run() { + THashSet items = new THashSet<>(); + + for (RoomTile t : this.room.getLayout().getTilesAt(this.room.getLayout().getTile(this.item.getX(), this.item.getY()), this.item.getBaseItem().getWidth(), this.item.getBaseItem().getLength(), this.item.getRotation())) { + for (HabboItem i : this.room.getItemsAt(t)) { + if (i.getUserId() == this.item.getRenterId()) { + items.add(i); + i.setRoomId(0); + i.needsUpdate(true); + } + } + } + + Habbo owner = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.item.getRenterId()); + + if (owner != null) { + owner.getClient().sendResponse(new AddHabboItemComposer(items)); + owner.getHabboStats().rentedItemId = 0; + owner.getHabboStats().rentedTimeEnd = 0; + } else { + for (HabboItem i : items) { + i.run(); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/CloseGate.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/CloseGate.java new file mode 100644 index 0000000..1637bc7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/CloseGate.java @@ -0,0 +1,27 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class CloseGate implements Runnable { + private final HabboItem gate; + private final Room room; + + public CloseGate(HabboItem gate, Room room) { + this.gate = gate; + this.room = room; + } + + @Override + public void run() { + if (this.gate.getRoomId() == this.room.getId()) { + if (this.room.isLoaded()) { + if (this.room.getHabbosAt(this.gate.getX(), this.gate.getY()).isEmpty()) { + this.gate.setExtradata("0"); + this.room.updateItem(this.gate); + this.gate.needsUpdate(true); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/CrackableExplode.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/CrackableExplode.java new file mode 100644 index 0000000..f5da2ca --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/CrackableExplode.java @@ -0,0 +1,74 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.FurnitureType; +import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.items.interactions.InteractionCrackable; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.rooms.items.AddFloorItemComposer; +import com.eu.habbo.messages.outgoing.rooms.items.RemoveFloorItemComposer; + +public class CrackableExplode implements Runnable { + private final Room room; + private final InteractionCrackable habboItem; + private final Habbo habbo; + private final boolean toInventory; + private final short x; + private final short y; + + public CrackableExplode(Room room, InteractionCrackable item, Habbo habbo, boolean toInventory, short x, short y) { + this.room = room; + this.habboItem = item; + this.habbo = habbo; + this.toInventory = toInventory; + + this.x = x; + this.y = y; + } + + @Override + public void run() { + if (this.habboItem.getRoomId() == 0) { + return; + } + + if (!this.habboItem.resetable()) { + this.room.removeHabboItem(this.habboItem); + this.room.sendComposer(new RemoveFloorItemComposer(this.habboItem, true).compose()); + this.habboItem.setRoomId(0); + Emulator.getGameEnvironment().getItemManager().deleteItem(this.habboItem); + } else { + this.habboItem.reset(this.room); + } + + Item rewardItem = Emulator.getGameEnvironment().getItemManager().getCrackableReward(this.habboItem.getBaseItem().getId()); + + if (rewardItem != null) { + HabboItem newItem = Emulator.getGameEnvironment().getItemManager().createItem(this.habboItem.allowAnyone() ? this.habbo.getHabboInfo().getId() : this.habboItem.getUserId(), rewardItem, 0, 0, ""); + + if (newItem != null) { + //Add to inventory in case if isn't possible place the item or in case is wall item + if (this.toInventory || newItem.getBaseItem().getType() == FurnitureType.WALL) { + this.habbo.getInventory().getItemsComponent().addItem(newItem); + this.habbo.getClient().sendResponse(new AddHabboItemComposer(newItem)); + this.habbo.getClient().sendResponse(new InventoryRefreshComposer()); + } else { + newItem.setX(this.x); + newItem.setY(this.y); + newItem.setZ(this.room.getStackHeight(this.x, this.y, false)); + newItem.setRoomId(this.room.getId()); + newItem.needsUpdate(true); + this.room.addHabboItem(newItem); + this.room.updateItem(newItem); + this.room.sendComposer(new AddFloorItemComposer(newItem, this.room.getFurniOwnerNames().get(newItem.getUserId())).compose()); + } + } + } + + this.room.updateTile(this.room.getLayout().getTile(this.x, this.y)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/GuardianNotAccepted.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/GuardianNotAccepted.java new file mode 100644 index 0000000..8885ef9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/GuardianNotAccepted.java @@ -0,0 +1,28 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuardianTicket; +import com.eu.habbo.habbohotel.guides.GuardianVote; +import com.eu.habbo.habbohotel.guides.GuardianVoteType; +import com.eu.habbo.habbohotel.users.Habbo; + +public class GuardianNotAccepted implements Runnable { + private final GuardianTicket ticket; + private final Habbo habbo; + + public GuardianNotAccepted(GuardianTicket ticket, Habbo habbo) { + this.ticket = ticket; + this.habbo = habbo; + } + + @Override + public void run() { + GuardianVote vote = this.ticket.getVoteForGuardian(this.habbo); + + if (vote != null) { + if (vote.type == GuardianVoteType.SEARCHING) { + Emulator.getGameEnvironment().getGuideManager().acceptTicket(this.habbo, false); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/GuardianTicketFindMoreSlaves.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/GuardianTicketFindMoreSlaves.java new file mode 100644 index 0000000..b0434c6 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/GuardianTicketFindMoreSlaves.java @@ -0,0 +1,17 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuardianTicket; + +public class GuardianTicketFindMoreSlaves implements Runnable { + private final GuardianTicket ticket; + + public GuardianTicketFindMoreSlaves(GuardianTicket ticket) { + this.ticket = ticket; + } + + @Override + public void run() { + Emulator.getGameEnvironment().getGuideManager().findGuardians(this.ticket); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/GuardianVotingFinish.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/GuardianVotingFinish.java new file mode 100644 index 0000000..15a361e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/GuardianVotingFinish.java @@ -0,0 +1,22 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.habbohotel.guides.GuardianTicket; + +public class GuardianVotingFinish implements Runnable { + private final GuardianTicket ticket; + private int checkSum; + + public GuardianVotingFinish(GuardianTicket ticket) { + this.ticket = ticket; + this.checkSum = this.ticket.getCheckSum(); + } + + @Override + public void run() { + if (this.ticket.inProgress()) { + if (this.ticket.getCheckSum() == this.checkSum) { + this.ticket.finish(); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/GuideFindNewHelper.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/GuideFindNewHelper.java new file mode 100644 index 0000000..cb87309 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/GuideFindNewHelper.java @@ -0,0 +1,29 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guides.GuideTour; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.guides.GuideSessionDetachedComposer; + +public class GuideFindNewHelper implements Runnable { + private final GuideTour tour; + private final Habbo helper; + private final int checkSum; + + public GuideFindNewHelper(GuideTour tour, Habbo helper) { + this.tour = tour; + this.helper = helper; + this.checkSum = tour.checkSum; + } + + @Override + public void run() { + if (!this.tour.isEnded() && this.tour.checkSum == this.checkSum && this.tour.getHelper() == null) { + if (this.helper != null && this.helper.getClient() != null) { + this.helper.getClient().sendResponse(new GuideSessionDetachedComposer()); + } + + Emulator.getGameEnvironment().getGuideManager().findHelper(this.tour); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/HabboGiveHandItemToHabbo.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/HabboGiveHandItemToHabbo.java new file mode 100644 index 0000000..16a59ec --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/HabboGiveHandItemToHabbo.java @@ -0,0 +1,36 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserHandItemComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserReceivedHandItemComposer; + +public class HabboGiveHandItemToHabbo implements Runnable { + private final Habbo target; + private final Habbo from; + + public HabboGiveHandItemToHabbo(Habbo from, Habbo target) { + this.target = target; + this.from = from; + } + + @Override + public void run() { + if (this.from.getHabboInfo().getCurrentRoom() == null || this.target.getHabboInfo().getCurrentRoom() == null) + return; + + if (this.from.getHabboInfo().getCurrentRoom() != this.target.getHabboInfo().getCurrentRoom()) + return; + + int itemId = this.from.getRoomUnit().getHandItem(); + + if (itemId > 0) { + this.from.getRoomUnit().setHandItem(0); + this.from.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserHandItemComposer(this.from.getRoomUnit()).compose()); + this.target.getRoomUnit().lookAtPoint(this.from.getRoomUnit().getCurrentLocation()); + this.target.getRoomUnit().statusUpdate(true); + this.target.getClient().sendResponse(new RoomUserReceivedHandItemComposer(this.from.getRoomUnit(), itemId)); + this.target.getRoomUnit().setHandItem(itemId); + this.target.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserHandItemComposer(this.target.getRoomUnit()).compose()); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/HabboItemNewState.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/HabboItemNewState.java new file mode 100644 index 0000000..4bb3875 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/HabboItemNewState.java @@ -0,0 +1,25 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class HabboItemNewState implements Runnable { + private final HabboItem item; + private final Room room; + private final String state; + + public HabboItemNewState(HabboItem item, Room room, String state) { + this.item = item; + this.room = room; + this.state = state; + } + + @Override + public void run() { + this.item.setExtradata(this.state); + + if (this.item.getRoomId() == this.room.getId()) { + this.room.updateItemState(this.item); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/InsertModToolIssue.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/InsertModToolIssue.java new file mode 100644 index 0000000..97cc4be --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/InsertModToolIssue.java @@ -0,0 +1,51 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import lombok.extern.slf4j.Slf4j; +import java.sql.*; + +@Slf4j +public class InsertModToolIssue implements Runnable { + private final ModToolIssue issue; + + public InsertModToolIssue(ModToolIssue issue) { + this.issue = issue; + } + + @Override + public void run() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO support_tickets (state, timestamp, score, sender_id, reported_id, room_id, mod_id, issue, category, group_id, thread_id, comment_id, photo_item_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setInt(1, this.issue.state.getState()); + statement.setInt(2, this.issue.timestamp); + statement.setInt(3, this.issue.priority); + statement.setInt(4, this.issue.senderId); + statement.setInt(5, this.issue.reportedId); + statement.setInt(6, this.issue.roomId); + statement.setInt(7, this.issue.modId); + statement.setString(8, this.issue.message); + statement.setInt(9, this.issue.category); + statement.setInt(10, this.issue.groupId); + statement.setInt(11, this.issue.threadId); + statement.setInt(12, this.issue.commentId); + statement.setInt(13, this.issue.photoItem != null ? this.issue.photoItem.getId() : -1); + statement.execute(); + + try (ResultSet key = statement.getGeneratedKeys()) { + if (key.first()) { + this.issue.id = key.getInt(1); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("UPDATE users_settings SET cfh_send = cfh_send + 1 WHERE user_id = ?")) { + statement.setInt(1, this.issue.senderId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/KickBallAction.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/KickBallAction.java new file mode 100644 index 0000000..0bc8505 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/KickBallAction.java @@ -0,0 +1,79 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionPushable; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; + + +public class KickBallAction implements Runnable { + + private final InteractionPushable ball; //The item which is moving + private final Room room; //The room that the item belongs to + private final RoomUnit kicker; //The Habbo which initiated the move of the item + private final int totalSteps; //The total number of steps in the move sequence + public boolean dead = false; //When true the run() function will not execute. Used when another user kicks the ball whilst it is arleady moving. + private RoomUserRotation currentDirection; //The current direction the item is moving in + private int currentStep; //The current step of the move sequence + public final boolean isDrag; + + public KickBallAction(InteractionPushable ball, Room room, RoomUnit kicker, RoomUserRotation direction, int steps, boolean isDrag) { + this.ball = ball; + this.room = room; + this.kicker = kicker; + this.currentDirection = direction; + this.totalSteps = steps; + this.currentStep = 0; + this.isDrag = isDrag; + } + + @Override + public void run() { + if (this.dead || !this.room.isLoaded()) + return; + + if (this.currentStep < this.totalSteps) { + RoomTile currentTile = this.room.getLayout().getTile(this.ball.getX(), this.ball.getY()); + RoomTile next = this.room.getLayout().getTileInFront(currentTile, this.currentDirection.getValue()); + + if (next == null || !this.ball.validMove(this.room, this.room.getLayout().getTile(this.ball.getX(), this.ball.getY()), next)) { + RoomUserRotation oldDirection = this.currentDirection; + + if(!this.isDrag) { + this.currentDirection = this.ball.getBounceDirection(this.room, this.currentDirection); + } + + if (this.currentDirection != oldDirection) { + this.ball.onBounce(this.room, oldDirection, this.currentDirection, this.kicker); + } else { + this.currentStep = this.totalSteps; //End the move sequence, the ball can't bounce anywhere + } + this.run(); + } else { + //Move the ball & run again + this.currentStep++; + + int delay = this.ball.getNextRollDelay(this.currentStep, this.totalSteps); //Algorithm to work out the delay till next run + + if (this.ball.canStillMove(this.room, this.room.getLayout().getTile(this.ball.getX(), this.ball.getY()), next, this.currentDirection, this.kicker, delay, this.currentStep, this.totalSteps)) { + this.ball.onMove(this.room, this.room.getLayout().getTile(this.ball.getX(), this.ball.getY()), next, this.currentDirection, this.kicker, delay, this.currentStep, this.totalSteps); + + this.room.sendComposer(new FloorItemOnRollerComposer(this.ball, null, next, next.getStackHeight() - this.ball.getZ(), this.room).compose()); + + Emulator.getThreading().run(this, (long) delay); + } else { + this.currentStep = this.totalSteps; //End the move sequence, the ball can't bounce anywhere + this.run(); + } + } + } else { + //We're done with the move sequence. Stop it the sequence & end the thread. + this.ball.onStop(this.room, this.kicker, this.currentStep, this.totalSteps); + this.dead = true; + } + } + +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/LoadCustomHeightMap.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/LoadCustomHeightMap.java new file mode 100644 index 0000000..5de407f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/LoadCustomHeightMap.java @@ -0,0 +1,17 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; + +public class LoadCustomHeightMap implements Runnable { + private final Room room; + + public LoadCustomHeightMap(Room room) { + this.room = room; + } + + @Override + public void run() { + this.room.setLayout(Emulator.getGameEnvironment().getRoomManager().loadCustomLayout(this.room)); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/OneWayGateActionOne.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/OneWayGateActionOne.java new file mode 100644 index 0000000..0cb6ae5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/OneWayGateActionOne.java @@ -0,0 +1,50 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; + +public class OneWayGateActionOne implements Runnable { + private HabboItem oneWayGate; + private Room room; + private GameClient client; + + public OneWayGateActionOne(GameClient client, Room room, HabboItem item) { + this.oneWayGate = item; + this.room = room; + this.client = client; + } + + @Override + public void run() { + this.room.sendComposer(new RoomUserStatusComposer(this.client.getHabbo().getRoomUnit()).compose()); + + RoomTile t = this.room.getLayout().getTileInFront(this.room.getLayout().getTile(this.oneWayGate.getX(), this.oneWayGate.getY()), (this.oneWayGate.getRotation() + 4) % 8); + + if (this.client.getHabbo().getRoomUnit().animateWalk) { + this.client.getHabbo().getRoomUnit().animateWalk = false; + } + + if (t.isWalkable()) { + if (this.room.tileWalkable(t) && this.client.getHabbo().getRoomUnit().getX() == this.oneWayGate.getX() && this.client.getHabbo().getRoomUnit().getY() == this.oneWayGate.getY()) { + this.client.getHabbo().getRoomUnit().setGoalLocation(t); + + if (!this.oneWayGate.getExtradata().equals("0")) { + Emulator.getThreading().run(new HabboItemNewState(this.oneWayGate, this.room, "0"), 1000); + } + } + //else if (this.client.getHabbo().getRoomUnit().getX() == this.oneWayGate.getX() && this.client.getHabbo().getRoomUnit().getY() == this.oneWayGate.getY()) + //{ + + //} + else { + if (!this.oneWayGate.getExtradata().equals("0")) { + Emulator.getThreading().run(new HabboItemNewState(this.oneWayGate, this.room, "0"), 1000); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/OpenGift.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/OpenGift.java new file mode 100644 index 0000000..2edb688 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/OpenGift.java @@ -0,0 +1,107 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionGift; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import com.eu.habbo.messages.outgoing.inventory.InventoryUpdateItemComposer; +import com.eu.habbo.messages.outgoing.rooms.items.PresentItemOpenedComposer; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Slf4j +public class OpenGift implements Runnable { + private final HabboItem item; + private final Habbo habbo; + private final Room room; + + public OpenGift(HabboItem item, Habbo habbo, Room room) { + this.item = item; + this.habbo = habbo; + this.room = room; + } + + @Override + public void run() { + try { + HabboItem inside = null; + + THashSet items = ((InteractionGift) this.item).loadItems(); + for (HabboItem i : items) { + if (inside == null) + inside = i; + + i.setUserId(this.habbo.getHabboInfo().getId()); + i.needsUpdate(true); + i.run(); + } + + if (inside != null) inside.setFromGift(true); + + this.habbo.getInventory().getItemsComponent().addItems(items); + + RoomTile tile = this.room.getLayout().getTile(this.item.getX(), this.item.getY()); + if (tile != null) { + this.room.updateTile(tile); + } + + Emulator.getThreading().run(new QueryDeleteHabboItem(this.item.getId())); + Emulator.getThreading().run(new RemoveFloorItemTask(this.room, this.item), this.item.getBaseItem().getName().contains("present_wrap") ? 5000 : 0); + + this.habbo.getClient().sendResponse(new InventoryRefreshComposer()); + + Map> unseenItems = new HashMap<>(); + + for (HabboItem item : items) { + switch (item.getBaseItem().getType()) { + case WALL: + case FLOOR: + if (!unseenItems.containsKey(AddHabboItemComposer.AddHabboItemCategory.OWNED_FURNI)) + unseenItems.put(AddHabboItemComposer.AddHabboItemCategory.OWNED_FURNI, new ArrayList<>()); + + unseenItems.get(AddHabboItemComposer.AddHabboItemCategory.OWNED_FURNI).add(item.getGiftAdjustedId()); + + break; + + case BADGE: + if (!unseenItems.containsKey(AddHabboItemComposer.AddHabboItemCategory.BADGE)) + unseenItems.put(AddHabboItemComposer.AddHabboItemCategory.BADGE, new ArrayList<>()); + + unseenItems.get(AddHabboItemComposer.AddHabboItemCategory.BADGE).add(item.getId()); // badges cannot be placed so no need for gift adjusted ID + break; + + case PET: + if (!unseenItems.containsKey(AddHabboItemComposer.AddHabboItemCategory.PET)) + unseenItems.put(AddHabboItemComposer.AddHabboItemCategory.PET, new ArrayList<>()); + + unseenItems.get(AddHabboItemComposer.AddHabboItemCategory.PET).add(item.getGiftAdjustedId()); + break; + + case ROBOT: + if (!unseenItems.containsKey(AddHabboItemComposer.AddHabboItemCategory.BOT)) + unseenItems.put(AddHabboItemComposer.AddHabboItemCategory.BOT, new ArrayList<>()); + + unseenItems.get(AddHabboItemComposer.AddHabboItemCategory.BOT).add(item.getGiftAdjustedId()); + break; + } + } + + this.habbo.getClient().sendResponse(new AddHabboItemComposer(unseenItems)); + + if (inside != null) { + this.habbo.getClient().sendResponse(new InventoryUpdateItemComposer(inside)); + this.habbo.getClient().sendResponse(new PresentItemOpenedComposer(inside, "", false)); + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/PetClearPosture.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/PetClearPosture.java new file mode 100644 index 0000000..199faf4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/PetClearPosture.java @@ -0,0 +1,35 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; + +public class PetClearPosture implements Runnable { + private final Pet pet; + private final RoomUnitStatus key; + private final PetTasks newTask; + private final boolean clearTask; + + public PetClearPosture(Pet pet, RoomUnitStatus key, PetTasks newTask, boolean clearTask) { + this.pet = pet; + this.key = key; + this.newTask = newTask; + this.clearTask = clearTask; + } + + @Override + public void run() { + if (this.pet != null) { + if (this.pet.getRoom() != null) { + if (this.pet.getRoomUnit() != null) { + this.pet.getRoomUnit().removeStatus(this.key); + + if (this.clearTask) + this.pet.setTask(PetTasks.FREE); + else if (this.newTask != null) + this.pet.setTask(this.newTask); + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/PetEatAction.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/PetEatAction.java new file mode 100644 index 0000000..331e594 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/PetEatAction.java @@ -0,0 +1,60 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.items.interactions.pets.InteractionPetFood; +import com.eu.habbo.habbohotel.pets.GnomePet; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.messages.outgoing.rooms.items.RemoveFloorItemComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; + +public class PetEatAction implements Runnable { + private final Pet pet; + private final InteractionPetFood food; + + public PetEatAction(Pet pet, InteractionPetFood food) { + this.pet = pet; + this.food = food; + } + + @Override + public void run() { + if (this.pet.getRoomUnit() != null && this.pet.getRoom() != null) { + if (this.pet.levelHunger >= 20 && this.food != null && Integer.valueOf(this.food.getExtradata()) < this.food.getBaseItem().getStateCount()) { + this.pet.addHunger(-20); + this.pet.setTask(PetTasks.EAT); + this.pet.getRoomUnit().setCanWalk(false); + + this.food.setExtradata(Integer.valueOf(this.food.getExtradata()) + 1 + ""); + this.pet.getRoom().updateItem(this.food); + + if (this.pet instanceof GnomePet) { + if (this.pet.getPetData().getType() == 26) { + AchievementManager.progressAchievement(Emulator.getGameEnvironment().getHabboManager().getHabbo(this.pet.getUserId()), Emulator.getGameEnvironment().getAchievementManager().getAchievement("GnomeFeeding"), 20); + } else { + AchievementManager.progressAchievement(Emulator.getGameEnvironment().getHabboManager().getHabbo(this.pet.getUserId()), Emulator.getGameEnvironment().getAchievementManager().getAchievement("LeprechaunFeeding"), 20); + } + } else { + AchievementManager.progressAchievement(Emulator.getGameEnvironment().getHabboManager().getHabbo(this.pet.getUserId()), Emulator.getGameEnvironment().getAchievementManager().getAchievement("PetFeeding"), 20); + } + + Emulator.getThreading().run(this, 1000); + } else { + if (this.food != null && Integer.valueOf(this.food.getExtradata()) == this.food.getBaseItem().getStateCount()) { + Emulator.getThreading().run(new QueryDeleteHabboItem(this.food.getId()), 500); + if (this.pet.getRoom() != null) { + this.pet.getRoom().removeHabboItem(this.food); + this.pet.getRoom().sendComposer(new RemoveFloorItemComposer(this.food, true).compose()); + } + } + + this.pet.setTask(PetTasks.FREE); + this.pet.getRoomUnit().removeStatus(RoomUnitStatus.EAT); + this.pet.getRoomUnit().setCanWalk(true); + this.pet.getRoom().sendComposer(new RoomUserStatusComposer(this.pet.getRoomUnit()).compose()); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/PetFollowHabbo.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/PetFollowHabbo.java new file mode 100644 index 0000000..b790916 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/PetFollowHabbo.java @@ -0,0 +1,49 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.Pet; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; + +public class PetFollowHabbo implements Runnable { + private final int directionOffset; + private final Habbo habbo; + private final Pet pet; + + public PetFollowHabbo(Pet pet, Habbo habbo, int offset) { + this.pet = pet; + this.habbo = habbo; + this.directionOffset = offset; + } + + @Override + public void run() { + if (this.pet != null) { + if (this.pet.getTask() != PetTasks.FOLLOW) + return; + + if (this.habbo != null) { + if (this.habbo.getRoomUnit() != null) { + if (this.pet.getRoomUnit() != null) { + RoomTile target = this.habbo.getHabboInfo().getCurrentRoom().getLayout().getTileInFront(this.habbo.getRoomUnit().getCurrentLocation(), Math.abs((this.habbo.getRoomUnit().getBodyRotation().getValue() + this.directionOffset + 4) % 8)); + + if (target != null) { + if (target.x < 0 || target.y < 0) + target = this.habbo.getHabboInfo().getCurrentRoom().getLayout().getTileInFront(this.habbo.getRoomUnit().getCurrentLocation(), this.habbo.getRoomUnit().getBodyRotation().getValue()); + + if (target.x >= 0 && target.y >= 0) { + if (this.pet.getRoom().getLayout().tileWalkable(target.x, target.y)) { + this.pet.getRoomUnit().setGoalLocation(target); + this.pet.getRoomUnit().setCanWalk(true); + this.pet.setTask(PetTasks.FOLLOW); + } + } + Emulator.getThreading().run(this, 500); + } + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/QueryDeleteHabboBadge.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/QueryDeleteHabboBadge.java new file mode 100644 index 0000000..239499d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/QueryDeleteHabboBadge.java @@ -0,0 +1,30 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +class QueryDeleteHabboBadge implements Runnable { + private final String name; + private final Habbo habbo; + + public QueryDeleteHabboBadge(Habbo habbo, String name) { + this.name = name; + this.habbo = habbo; + } + + @Override + public void run() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM user_badges WHERE users_id = ? AND badge_code = ?")) { + statement.setInt(1, this.habbo.getHabboInfo().getId()); + statement.setString(2, this.name); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/QueryDeleteHabboItem.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/QueryDeleteHabboItem.java new file mode 100644 index 0000000..d1627b2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/QueryDeleteHabboItem.java @@ -0,0 +1,31 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.HabboItem; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class QueryDeleteHabboItem implements Runnable { + private final int itemId; + + public QueryDeleteHabboItem(int itemId) { + this.itemId = itemId; + } + + public QueryDeleteHabboItem(HabboItem item) { + this.itemId = item.getId(); + } + + @Override + public void run() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM items WHERE id = ?")) { + statement.setInt(1, this.itemId); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/QueryDeleteHabboItems.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/QueryDeleteHabboItems.java new file mode 100644 index 0000000..025d2f0 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/QueryDeleteHabboItems.java @@ -0,0 +1,37 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.HabboItem; +import gnu.trove.map.TIntObjectMap; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class QueryDeleteHabboItems implements Runnable { + private TIntObjectMap items; + + public QueryDeleteHabboItems(TIntObjectMap items) { + this.items = items; + } + + @Override + public void run() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM items WHERE id = ?")) { + for (HabboItem item : this.items.valueCollection()) { + if (item.getRoomId() > 0) + continue; + + statement.setInt(1, item.getId()); + statement.addBatch(); + } + + statement.executeBatch(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + this.items.clear(); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/RandomDiceNumber.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RandomDiceNumber.java new file mode 100644 index 0000000..f621e0b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RandomDiceNumber.java @@ -0,0 +1,42 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionColorWheel; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; + +public class RandomDiceNumber implements Runnable { + private final HabboItem item; + private final Room room; + private final int maxNumber; + private int result; + + public RandomDiceNumber(HabboItem item, Room room, int maxNumber) { + this.item = item; + this.room = room; + this.maxNumber = maxNumber; + this.result = -1; + } + + public RandomDiceNumber(Room room, HabboItem item, int result) { + this.item = item; + this.room = room; + this.maxNumber = -1; + this.result = result; + } + + @Override + public void run() { + if (this.result <= 0) + this.result = (Emulator.getRandomDice().nextInt(this.maxNumber) + 1); + + this.item.setExtradata(this.result + ""); + this.item.needsUpdate(true); + Emulator.getThreading().run(this.item); + + this.room.updateItem(this.item); + if (this.item instanceof InteractionColorWheel) { + ((InteractionColorWheel) this.item).clearRunnable(); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/RemoveFloorItemTask.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RemoveFloorItemTask.java new file mode 100644 index 0000000..3a5b7aa --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RemoveFloorItemTask.java @@ -0,0 +1,29 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.rooms.UpdateStackHeightComposer; +import com.eu.habbo.messages.outgoing.rooms.items.RemoveFloorItemComposer; + +class RemoveFloorItemTask implements Runnable { + private final Room room; + private final HabboItem item; + + public RemoveFloorItemTask(Room room, HabboItem item) { + this.room = room; + this.item = item; + } + + @Override + public void run() { + if (this.item == null || this.room == null) + return; + + RoomTile tile = this.room.getLayout().getTile(this.item.getX(), this.item.getY()); + this.room.removeHabboItem(this.item); + this.room.updateTile(tile); + this.room.sendComposer(new RemoveFloorItemComposer(this.item, true).compose()); + this.room.sendComposer(new UpdateStackHeightComposer(this.item.getX(), this.item.getY(), tile.z, tile.relativeHeight()).compose()); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomTrashing.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomTrashing.java new file mode 100644 index 0000000..4e64538 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomTrashing.java @@ -0,0 +1,143 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; +import com.eu.habbo.plugin.EventHandler; +import com.eu.habbo.plugin.events.users.UserTakeStepEvent; +import gnu.trove.set.hash.THashSet; + +public class RoomTrashing implements Runnable { + public static RoomTrashing INSTANCE; + + private Habbo habbo; + private Room room; + + public RoomTrashing(Habbo habbo, Room room) { + this.habbo = habbo; + this.room = room; + + RoomTrashing.INSTANCE = this; + } + + @EventHandler + public static void onUserWalkEvent(UserTakeStepEvent event) { + if (INSTANCE == null) + return; + + if (INSTANCE.habbo == null) + return; + + if (!INSTANCE.habbo.isOnline()) + INSTANCE.habbo = null; + + if (INSTANCE.habbo == event.habbo) { + if (event.habbo.getHabboInfo().getCurrentRoom() != null) { + if (event.habbo.getHabboInfo().getCurrentRoom().equals(INSTANCE.room)) { + THashSet messages = new THashSet<>(); + + THashSet items = INSTANCE.room.getItemsAt(event.toLocation); + + int offset = Emulator.getRandom().nextInt(4) + 2; + + RoomTile t = null; + while (offset > 0) { + t = INSTANCE.room.getLayout().getTileInFront(INSTANCE.room.getLayout().getTile(event.toLocation.x, event.toLocation.y), event.habbo.getRoomUnit().getBodyRotation().getValue(), (short) offset); + + if (!INSTANCE.room.getLayout().tileWalkable(t.x, t.y)) { + offset--; + } else { + break; + } + } + + for (HabboItem item : items) { + double offsetZ = (INSTANCE.room.getTopHeightAt(t.x, t.y)) - item.getZ(); + + messages.add(new FloorItemOnRollerComposer(item, null, t, offsetZ, INSTANCE.room).compose()); + } + + + offset = Emulator.getRandom().nextInt(4) + 2; + + t = null; + while (offset > 0) { + t = INSTANCE.room.getLayout().getTileInFront(INSTANCE.room.getLayout().getTile(event.toLocation.x, event.toLocation.y), event.habbo.getRoomUnit().getBodyRotation().getValue() + 7, (short) offset); + + if (!INSTANCE.room.getLayout().tileWalkable(t.x, t.y)) { + offset--; + } else { + break; + } + } + + RoomTile s = INSTANCE.room.getLayout().getTileInFront(INSTANCE.habbo.getRoomUnit().getCurrentLocation(), INSTANCE.habbo.getRoomUnit().getBodyRotation().getValue() + 7); + + if (s != null) { + items = INSTANCE.room.getItemsAt(s); + } + + for (HabboItem item : items) { + double offsetZ = (INSTANCE.room.getTopHeightAt(t.x, t.y)) - item.getZ(); + + messages.add(new FloorItemOnRollerComposer(item, null, t, offsetZ, INSTANCE.room).compose()); + } + + offset = Emulator.getRandom().nextInt(4) + 2; + + t = null; + while (offset > 0) { + t = INSTANCE.getRoom().getLayout().getTileInFront(event.toLocation, event.habbo.getRoomUnit().getBodyRotation().getValue() + 1, (short) offset); + + if (!INSTANCE.room.getLayout().tileWalkable(t.x, t.y)) { + offset--; + } else { + break; + } + } + + s = INSTANCE.getRoom().getLayout().getTileInFront(INSTANCE.habbo.getRoomUnit().getCurrentLocation(), INSTANCE.habbo.getRoomUnit().getBodyRotation().getValue() + 1); + items = INSTANCE.room.getItemsAt(s); + + for (HabboItem item : items) { + double offsetZ = (INSTANCE.room.getTopHeightAt(t.x, t.y)) - item.getZ(); + + messages.add(new FloorItemOnRollerComposer(item, null, t, offsetZ, INSTANCE.room).compose()); + } + + for (ServerMessage message : messages) { + INSTANCE.room.sendComposer(message); + } + } else { + INSTANCE.habbo = null; + INSTANCE.room = null; + } + } + } + } + + @Override + public void run() { + + } + + public Habbo getHabbo() { + return this.habbo; + } + + public void setHabbo(Habbo habbo) { + this.habbo = habbo; + } + + public Room getRoom() { + return this.room; + } + + public void setRoom(Room room) { + this.room = room; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitGiveHanditem.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitGiveHanditem.java new file mode 100644 index 0000000..d70a684 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitGiveHanditem.java @@ -0,0 +1,25 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserHandItemComposer; + +public class RoomUnitGiveHanditem implements Runnable { + private final RoomUnit roomUnit; + private final Room room; + private final int itemId; + + public RoomUnitGiveHanditem(RoomUnit roomUnit, Room room, int itemId) { + this.roomUnit = roomUnit; + this.room = room; + this.itemId = itemId; + } + + @Override + public void run() { + if (this.room != null && this.roomUnit.isInRoom()) { + this.roomUnit.setHandItem(this.itemId); + this.room.sendComposer(new RoomUserHandItemComposer(this.roomUnit).compose()); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitKick.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitKick.java new file mode 100644 index 0000000..7d2cce5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitKick.java @@ -0,0 +1,26 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; + +public class RoomUnitKick implements Runnable { + private final Habbo habbo; + private final Room room; + private final boolean removeEffect; + + public RoomUnitKick(Habbo habbo, Room room, boolean removeEffect) { + this.habbo = habbo; + this.room = room; + this.removeEffect = removeEffect; + } + + @Override + public void run() { + if (this.removeEffect) { + this.habbo.getRoomUnit().setEffectId(0, 0); + } + + Emulator.getGameEnvironment().getRoomManager().leaveRoom(this.habbo, this.room); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitRidePet.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitRidePet.java new file mode 100644 index 0000000..bcfd8ef --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitRidePet.java @@ -0,0 +1,48 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.pets.PetTasks; +import com.eu.habbo.habbohotel.pets.RideablePet; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserEffectComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; + +public class RoomUnitRidePet implements Runnable { + private RideablePet pet; + private Habbo habbo; + private RoomTile goalTile; + + public RoomUnitRidePet(RideablePet pet, Habbo habbo, RoomTile goalTile) { + this.pet = pet; + this.habbo = habbo; + this.goalTile = goalTile; + } + + @Override + public void run() { + if (this.habbo.getRoomUnit() == null || this.pet.getRoomUnit() == null || this.pet.getRoom() != this.habbo.getHabboInfo().getCurrentRoom() || this.goalTile == null || this.habbo.getRoomUnit().getGoal() != this.goalTile) + return; + + if (habbo.getRoomUnit().getCurrentLocation().distance(pet.getRoomUnit().getCurrentLocation()) <= 1) { + habbo.getRoomUnit().stopWalking(); + habbo.getHabboInfo().getCurrentRoom().giveEffect(habbo, 77, -1); + habbo.getHabboInfo().setRiding(pet); + habbo.getRoomUnit().setCurrentLocation(this.pet.getRoomUnit().getCurrentLocation()); + habbo.getRoomUnit().setPreviousLocation(this.pet.getRoomUnit().getCurrentLocation()); + habbo.getRoomUnit().setZ(this.pet.getRoomUnit().getZ() + 1); + habbo.getRoomUnit().setPreviousLocationZ(this.pet.getRoomUnit().getZ() + 1); + habbo.getRoomUnit().setRotation(this.pet.getRoomUnit().getBodyRotation()); + habbo.getRoomUnit().statusUpdate(true); + pet.setRider(habbo); + habbo.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserStatusComposer(habbo.getRoomUnit()).compose()); + habbo.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserEffectComposer(habbo.getRoomUnit()).compose()); + pet.setTask(PetTasks.RIDE); + } else { + pet.getRoomUnit().setWalkTimeOut(3 + Emulator.getIntUnixTimestamp()); + pet.getRoomUnit().stopWalking(); + habbo.getRoomUnit().setGoalLocation(goalTile); + Emulator.getThreading().run(this, 500); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitTeleport.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitTeleport.java new file mode 100644 index 0000000..6cec89a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitTeleport.java @@ -0,0 +1,73 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.ServerMessage; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUnitOnRollerComposer; +import lombok.extern.slf4j.Slf4j; + +import java.util.LinkedList; + +@Slf4j +public class RoomUnitTeleport implements Runnable { + + private RoomUnit roomUnit; + private Room room; + private int x; + private int y; + private double z; + + private int newEffect; + + public RoomUnitTeleport(RoomUnit roomUnit, Room room, int x, int y, double z, int newEffect) { + this.roomUnit = roomUnit; + this.room = room; + this.x = x; + this.y = y; + this.z = z; + this.newEffect = newEffect; + } + + @Override + public void run() { + if (roomUnit == null || roomUnit.getRoom() == null || room.getLayout() == null || roomUnit.isLeavingTeleporter) + return; + + RoomTile lastLocation = this.roomUnit.getCurrentLocation(); + RoomTile newLocation = this.room.getLayout().getTile((short) this.x, (short) this.y); + + HabboItem topItem = this.room.getTopItemAt(this.roomUnit.getCurrentLocation().x, this.roomUnit.getCurrentLocation().y); + if (topItem != null) { + try { + topItem.onWalkOff(this.roomUnit, this.room, new Object[]{this}); + } catch (Exception e) { + log.error("Caught exception", e); + } + } + this.roomUnit.setPath(new LinkedList<>()); + this.roomUnit.setCurrentLocation(newLocation); + this.roomUnit.setPreviousLocation(newLocation); + this.roomUnit.setZ(this.z); + this.roomUnit.setPreviousLocationZ(this.z); + this.roomUnit.removeStatus(RoomUnitStatus.MOVE); + //ServerMessage teleportMessage = new RoomUnitOnRollerComposer(this.roomUnit, newLocation, this.room).compose(); + this.roomUnit.setLocation(newLocation); + //this.room.sendComposer(teleportMessage); + this.roomUnit.statusUpdate(true); + roomUnit.isWiredTeleporting = false; + + this.room.updateHabbosAt(newLocation.x, newLocation.y); + this.room.updateBotsAt(newLocation.x, newLocation.y); + + topItem = room.getTopItemAt(x, y); + if (topItem != null && roomUnit.getCurrentLocation().equals(room.getLayout().getTile((short) x, (short) y))) { + try { + topItem.onWalkOn(roomUnit, room, new Object[]{ lastLocation, newLocation, this }); + } catch (Exception e) { + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitTeleportWalkToAction.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitTeleportWalkToAction.java new file mode 100644 index 0000000..895dcbf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitTeleportWalkToAction.java @@ -0,0 +1,47 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RoomUnitTeleportWalkToAction implements Runnable { + private final Habbo habbo; + private final HabboItem habboItem; + private final Room room; + + public RoomUnitTeleportWalkToAction(Habbo habbo, HabboItem habboItem, Room room) { + this.habbo = habbo; + this.habboItem = habboItem; + this.room = room; + } + + @Override + public void run() { + if (this.habbo.getHabboInfo().getCurrentRoom() == this.room) { + if (this.habboItem.getRoomId() == this.room.getId()) { + RoomTile tile = HabboItem.getSquareInFront(this.room.getLayout(), this.habboItem); + + if (tile != null) { + if (this.habbo.getRoomUnit().getGoal().equals(tile)) { + if (this.habbo.getRoomUnit().getCurrentLocation().equals(tile)) { + try { + this.habboItem.onClick(this.habbo.getClient(), this.room, new Object[]{0}); + } catch (Exception e) { + log.error("Caught exception", e); + } + } else { + if (tile.isWalkable()) { + this.habbo.getRoomUnit().setGoalLocation(tile); + Emulator.getThreading().run(this, this.habbo.getRoomUnit().getPath().size() + 2 * 510); + } + } + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitVendingMachineAction.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitVendingMachineAction.java new file mode 100644 index 0000000..212ca28 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitVendingMachineAction.java @@ -0,0 +1,47 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RoomUnitVendingMachineAction implements Runnable { + + private final Habbo habbo; + private final HabboItem habboItem; + private final Room room; + + public RoomUnitVendingMachineAction(Habbo habbo, HabboItem habboItem, Room room) { + this.habbo = habbo; + this.habboItem = habboItem; + this.room = room; + } + + @Override + public void run() { + if (this.habbo.getHabboInfo().getCurrentRoom() == this.room) { + if (this.habboItem.getRoomId() == this.room.getId()) { + RoomTile tile = HabboItem.getSquareInFront(this.room.getLayout(), this.habboItem); + if (tile != null) { + if (this.habbo.getRoomUnit().getGoal().equals(tile)) { + if (this.habbo.getRoomUnit().getCurrentLocation().equals(tile)) { + try { + this.habboItem.onClick(this.habbo.getClient(), this.room, new Object[]{0}); + } catch (Exception e) { + log.error("Caught exception", e); + } + } else { + if (this.room.getLayout().getTile(tile.x, tile.y).isWalkable()) { + this.habbo.getRoomUnit().setGoalLocation(tile); + Emulator.getThreading().run(this, this.habbo.getRoomUnit().getPath().size() + 2 * 510); + } + } + } + } + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitWalkToLocation.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitWalkToLocation.java new file mode 100644 index 0000000..a2f65db --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitWalkToLocation.java @@ -0,0 +1,68 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; + +import java.util.ArrayList; +import java.util.List; + +public class RoomUnitWalkToLocation implements Runnable { + private RoomUnit walker; + private RoomTile goalTile; + private Room room; + private List targetReached; + private List failedReached; + + public RoomUnitWalkToLocation(RoomUnit walker, RoomTile goalTile, Room room, Runnable targetReached, Runnable failedReached) { + this.walker = walker; + this.goalTile = goalTile; + this.room = room; + + this.targetReached = new ArrayList<>(); + if (targetReached != null) this.targetReached.add(targetReached); + + this.failedReached = new ArrayList<>(); + if (failedReached != null) this.targetReached.add(failedReached); + } + + public RoomUnitWalkToLocation(RoomUnit walker, RoomTile goalTile, Room room, List targetReached, List failedReached) { + this.walker = walker; + this.goalTile = goalTile; + this.room = room; + this.targetReached = targetReached; + this.failedReached = failedReached; + } + + @Override + public void run() { + if (this.goalTile == null || this.walker == null || this.room == null || this.walker.getRoom() == null || this.walker.getRoom().getId() != this.room.getId()) { + onFail(); + return; + } + + if (this.walker.getCurrentLocation().equals(this.goalTile)) { + onSuccess(); + return; + } + + if (!this.walker.getGoal().equals(this.goalTile) || (this.walker.getPath().size() == 0 && !this.walker.hasStatus(RoomUnitStatus.MOVE))) { + onFail(); + return; + } + + Emulator.getThreading().run(this, 250); + } + + private void onSuccess() { + for (Runnable r : this.targetReached) + Emulator.getThreading().run(r); + } + + private void onFail() { + for (Runnable r : this.failedReached) + Emulator.getThreading().run(r); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitWalkToRoomUnit.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitWalkToRoomUnit.java new file mode 100644 index 0000000..3ff6ae3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RoomUnitWalkToRoomUnit.java @@ -0,0 +1,82 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; + +import java.util.List; + +public class RoomUnitWalkToRoomUnit implements Runnable { + private final int minDistance; + private RoomUnit walker; + private RoomUnit target; + private Room room; + private List targetReached; + private List failedReached; + + private RoomTile goalTile = null; + + public RoomUnitWalkToRoomUnit(RoomUnit walker, RoomUnit target, Room room, List targetReached, List failedReached) { + this.walker = walker; + this.target = target; + this.room = room; + this.targetReached = targetReached; + this.failedReached = failedReached; + this.minDistance = 1; + } + + public RoomUnitWalkToRoomUnit(RoomUnit walker, RoomUnit target, Room room, List targetReached, List failedReached, int minDistance) { + this.walker = walker; + this.target = target; + this.room = room; + this.targetReached = targetReached; + this.failedReached = failedReached; + this.minDistance = minDistance; + } + + @Override + public void run() { + if (this.goalTile == null) { + this.findNewLocation(); + Emulator.getThreading().run(this, 500); + return; + } + + if (this.walker.getGoal().equals(this.goalTile)) { // check that the action hasn't been cancelled by changing the goal + if (this.walker.getCurrentLocation().distance(this.goalTile) <= this.minDistance) { + for (Runnable r : this.targetReached) { + Emulator.getThreading().run(r); + + WiredHandler.handle(WiredTriggerType.BOT_REACHED_AVTR, this.target, this.room, new Object[]{ this.walker }); + } + } else { + Emulator.getThreading().run(this, 500); + } + } + } + + private void findNewLocation() { + this.goalTile = this.walker.getClosestAdjacentTile(this.target.getCurrentLocation().x, this.target.getCurrentLocation().y, true); + + if (this.goalTile == null) { + if (this.failedReached != null) { + for (Runnable r : this.failedReached) { + Emulator.getThreading().run(r); + } + } + + return; + } + + this.walker.setGoalLocation(this.goalTile); + + if (this.walker.getPath().isEmpty() && this.failedReached != null) { + for (Runnable r : this.failedReached) { + Emulator.getThreading().run(r); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/SaveScoreForTeam.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/SaveScoreForTeam.java new file mode 100644 index 0000000..97e2cc7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/SaveScoreForTeam.java @@ -0,0 +1,44 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.games.Game; +import com.eu.habbo.habbohotel.games.GamePlayer; +import com.eu.habbo.habbohotel.games.GameTeam; +import lombok.extern.slf4j.Slf4j; + + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class SaveScoreForTeam implements Runnable { + + public final GameTeam team; + public final Game game; + + public SaveScoreForTeam(GameTeam team, Game game) { + this.team = team; + this.game = game; + } + + @Override + public void run() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO room_game_scores (room_id, game_start_timestamp, game_name, user_id, team_id, score, team_score) VALUES (?, ?, ?, ?, ?, ?, ?)")) { + for (GamePlayer player : this.team.getMembers()) { + statement.setInt(1, this.game.getRoom().getId()); + statement.setInt(2, this.game.getStartTime()); + statement.setString(3, this.game.getClass().getName()); + statement.setInt(4, player.getHabbo().getHabboInfo().getId()); + statement.setInt(5, player.getTeamColor().type); + statement.setInt(6, player.getScore()); + statement.setInt(7, this.team.getTeamScore()); + statement.addBatch(); + } + + statement.executeBatch(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/SendRoomUnitEffectComposer.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/SendRoomUnitEffectComposer.java new file mode 100644 index 0000000..9b24eae --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/SendRoomUnitEffectComposer.java @@ -0,0 +1,22 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserEffectComposer; + +public class SendRoomUnitEffectComposer implements Runnable { + private final Room room; + private final RoomUnit roomUnit; + + public SendRoomUnitEffectComposer(Room room, RoomUnit roomUnit) { + this.room = room; + this.roomUnit = roomUnit; + } + + @Override + public void run() { + if (this.room != null && this.roomUnit != null) { + this.room.sendComposer(new RoomUserEffectComposer(roomUnit).compose()); + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/ShutdownEmulator.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/ShutdownEmulator.java new file mode 100644 index 0000000..8ba9ff8 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/ShutdownEmulator.java @@ -0,0 +1,24 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.messages.ServerMessage; + +public class ShutdownEmulator implements Runnable { + public static boolean instantiated = false; + public static int timestamp = 0; + + public ShutdownEmulator(ServerMessage message) { + if (!instantiated) { + instantiated = true; + + if (message != null) { + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(message); + } + } + } + + @Override + public void run() { + Emulator.getRuntime().exit(0); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/TeleportInteraction.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/TeleportInteraction.java new file mode 100644 index 0000000..b829f9c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/TeleportInteraction.java @@ -0,0 +1,129 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserEffectComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserRemoveComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUsersComposer; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +class TeleportInteraction extends Thread { + private final Room room; + private final GameClient client; + private final HabboItem teleportOne; + private int state; + private Room targetRoom; + private HabboItem teleportTwo; + + @Deprecated + public TeleportInteraction(Room room, GameClient client, HabboItem teleportOne) { + this.room = room; + this.client = client; + this.teleportOne = teleportOne; + this.teleportTwo = null; + this.targetRoom = null; + this.state = 1; + } + + @Override + public void run() { + try { + if (this.state == 5) { + this.teleportTwo.setExtradata("1"); + this.targetRoom.updateItem(this.teleportTwo); + this.room.updateItem(this.teleportOne); + RoomTile tile = HabboItem.getSquareInFront(this.room.getLayout(), this.teleportTwo); + if (tile != null) { + this.client.getHabbo().getRoomUnit().setGoalLocation(tile); + } + Emulator.getThreading().run(this.teleportTwo, 500); + Emulator.getThreading().run(this.teleportOne, 500); + } else if (this.state == 4) { + int[] data = Emulator.getGameEnvironment().getItemManager().getTargetTeleportRoomId(this.teleportOne); + if (data.length == 2 && data[0] != 0) { + if (this.room.getId() == data[0]) { + this.targetRoom = this.room; + this.teleportTwo = this.room.getHabboItem(data[1]); + + if (this.teleportTwo == null) { + this.teleportTwo = this.teleportOne; + } + } else { + this.targetRoom = Emulator.getGameEnvironment().getRoomManager().loadRoom(data[0]); + this.teleportTwo = this.targetRoom.getHabboItem(data[1]); + } + } else { + this.targetRoom = this.room; + this.teleportTwo = this.teleportOne; + } + + this.teleportOne.setExtradata("2"); + this.teleportTwo.setExtradata("2"); + + if (this.room != this.targetRoom) { + Emulator.getGameEnvironment().getRoomManager().logExit(this.client.getHabbo()); + this.room.removeHabbo(this.client.getHabbo(), true); + Emulator.getGameEnvironment().getRoomManager().enterRoom(this.client.getHabbo(), this.targetRoom); + } + + this.client.getHabbo().getRoomUnit().setRotation(RoomUserRotation.values()[this.teleportTwo.getRotation()]); + this.client.getHabbo().getRoomUnit().setLocation(this.room.getLayout().getTile(this.teleportTwo.getX(), this.teleportTwo.getY())); + this.client.getHabbo().getRoomUnit().setZ(this.teleportTwo.getZ()); + + this.room.sendComposer(new RoomUserRemoveComposer(this.client.getHabbo().getRoomUnit()).compose()); + this.targetRoom.sendComposer(new RoomUserRemoveComposer(this.client.getHabbo().getRoomUnit()).compose()); + this.targetRoom.sendComposer(new RoomUsersComposer(this.client.getHabbo()).compose()); + this.targetRoom.sendComposer(new RoomUserStatusComposer(this.client.getHabbo().getRoomUnit()).compose()); + this.targetRoom.sendComposer(new RoomUserEffectComposer(this.client.getHabbo().getRoomUnit()).compose()); + this.room.updateItem(this.teleportOne); + this.targetRoom.updateItem(this.teleportTwo); + + this.state = 5; + + Emulator.getThreading().run(this, 500); + } else if (this.state == 3) { + this.teleportOne.setExtradata("0"); + this.room.updateItem(this.teleportOne); + this.state = 4; + Emulator.getThreading().run(this, 500); + } else if (this.state == 2) { + this.client.getHabbo().getRoomUnit().setGoalLocation(this.room.getLayout().getTile(this.teleportOne.getX(), this.teleportOne.getY())); + this.client.getHabbo().getRoomUnit().setRotation(RoomUserRotation.values()[this.newRotation(this.teleportOne.getRotation())]); + this.client.getHabbo().getRoomUnit().setStatus(RoomUnitStatus.MOVE, this.teleportOne.getX() + "," + this.teleportOne.getY() + "," + this.teleportOne.getZ()); + //room.sendComposer(new RoomUserStatusComposer(this.client.getHabbo().getRoomUnit())); + + this.state = 3; + + Emulator.getThreading().run(this, 500); + } else if (this.state == 1) { + RoomTile loc = HabboItem.getSquareInFront(this.room.getLayout(), this.teleportOne); + + if (this.client.getHabbo().getRoomUnit().getX() == loc.x && this.client.getHabbo().getRoomUnit().getY() == loc.y) { + this.teleportOne.setExtradata("1"); + this.room.updateItem(this.teleportOne); + this.state = 2; + + Emulator.getThreading().run(this, 250); + } + } + } catch (Exception e) { + log.error("Caught exception", e); + } + } + + private int newRotation(int rotation) { + if (rotation == 4) + return 0; + if (rotation == 6) + return 2; + else + return rotation + 4; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/UpdateModToolIssue.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/UpdateModToolIssue.java new file mode 100644 index 0000000..2cda500 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/UpdateModToolIssue.java @@ -0,0 +1,33 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.modtool.ModToolIssue; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@Slf4j +public class UpdateModToolIssue implements Runnable { + + private final ModToolIssue issue; + + public UpdateModToolIssue(ModToolIssue issue) { + this.issue = issue; + } + + @Override + public void run() { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); + PreparedStatement statement = connection.prepareStatement("UPDATE support_tickets SET state = ?, type = ?, mod_id = ?, category = ? WHERE id = ?")) { + statement.setInt(1, this.issue.state.getState()); + statement.setInt(2, this.issue.type.getType()); + statement.setInt(3, this.issue.modId); + statement.setInt(4, this.issue.category); + statement.setInt(5, this.issue.id); + statement.execute(); + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/WiredCollissionRunnable.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/WiredCollissionRunnable.java new file mode 100644 index 0000000..26fb4c9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/WiredCollissionRunnable.java @@ -0,0 +1,24 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; + +public class WiredCollissionRunnable implements Runnable { + public final RoomUnit roomUnit; + public final Room room; + public final Object[] objects; + + public WiredCollissionRunnable(RoomUnit roomUnit, Room room, Object[] objects) { + this.roomUnit = roomUnit; + this.room = room; + this.objects = objects; + } + + + @Override + public void run() { + WiredHandler.handle(WiredTriggerType.COLLISION, roomUnit, room, objects); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/WiredExecuteTask.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/WiredExecuteTask.java new file mode 100644 index 0000000..a7479cf --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/WiredExecuteTask.java @@ -0,0 +1,42 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger; +import com.eu.habbo.habbohotel.items.interactions.wired.triggers.WiredTriggerAtSetTime; +import com.eu.habbo.habbohotel.items.interactions.wired.triggers.WiredTriggerAtTimeLong; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.wired.WiredHandler; + +public class WiredExecuteTask implements Runnable { + private final InteractionWiredTrigger task; + private final Room room; + private int taskId; + + public WiredExecuteTask(InteractionWiredTrigger trigger, Room room) { + this.task = trigger; + this.room = room; + + if (this.task instanceof WiredTriggerAtSetTime) + this.taskId = ((WiredTriggerAtSetTime) this.task).taskId; + + if (this.task instanceof WiredTriggerAtTimeLong) + this.taskId = ((WiredTriggerAtTimeLong) this.task).taskId; + } + + @Override + public void run() { + if (!Emulator.isShuttingDown && Emulator.isReady) { + if (this.room != null && this.room.getId() == this.task.getRoomId()) { + if (this.task instanceof WiredTriggerAtSetTime) { + if (((WiredTriggerAtSetTime) this.task).taskId != this.taskId) + return; + } + if (this.task instanceof WiredTriggerAtTimeLong) { + if (((WiredTriggerAtTimeLong) this.task).taskId != this.taskId) + return; + } + WiredHandler.handle(this.task, null, this.room, null); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/WiredRepeatEffectTask.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/WiredRepeatEffectTask.java new file mode 100644 index 0000000..a6ccde4 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/WiredRepeatEffectTask.java @@ -0,0 +1,28 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect; +import com.eu.habbo.habbohotel.rooms.Room; + +class WiredRepeatEffectTask implements Runnable { + private final InteractionWiredEffect effect; + private final Room room; + private final int delay; + + public WiredRepeatEffectTask(InteractionWiredEffect effect, Room room, int delay) { + this.effect = effect; + this.room = room; + this.delay = delay; + } + + @Override + public void run() { + if (!Emulator.isShuttingDown && Emulator.isReady) { + if (this.room != null && this.room.getId() == this.effect.getRoomId()) { + this.effect.execute(null, this.room, null); + + Emulator.getThreading().run(this, this.delay); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/WiredResetTimers.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/WiredResetTimers.java new file mode 100644 index 0000000..7ea428b --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/WiredResetTimers.java @@ -0,0 +1,20 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.wired.WiredHandler; + +public class WiredResetTimers implements Runnable { + private Room room; + + public WiredResetTimers(Room room) { + this.room = room; + } + + @Override + public void run() { + if (!Emulator.isShuttingDown && Emulator.isReady) { + WiredHandler.resetTimers(this.room); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/YouAreAPirate.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/YouAreAPirate.java new file mode 100644 index 0000000..a9eb50a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/YouAreAPirate.java @@ -0,0 +1,103 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomChatMessage; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.habbohotel.rooms.RoomChatType; +import com.eu.habbo.habbohotel.users.Habbo; + +public class YouAreAPirate implements Runnable { + public static String[] iamapirate = new String[]{ + "Do what you want, 'cause a pirate is free,", + "You are a pirate!", + "", + "Yar har, fiddle di dee,", + "Being a pirate is all right with me,", + "Do what you want 'cause a pirate is free, ", + "You are a pirate!", + "Yo Ho, ahoy and avast,", + "Being a pirate is really badass!", + "Hang the black flag at the end of the mast!", + "You are a pirate!", + "", + "You are a pirate! - Yay!", + "", + "We've got us a map, (a map! )", + "To lead us to a hidden box,", + "That's all locked up with locks! (with locks! )", + "And buried deep away!", + "", + "We'll dig up the box, (the box! )", + "We know it's full of precious booty! ", + "Burst open the locks!", + "And then we'll say hooray! ", + "", + "Yar har, fiddle di dee,", + "Being a pirate is all right with me!", + "Do what you want 'cause a pirate is free, ", + "", + "You are a pirate!", + "Yo Ho, ahoy and avast,", + "Being a Pirate is really badass!", + "Hang the black flag", + "At the end of the mast!", + "You are a pirate!", + "", + "Hahaha!", + "", + "", + "We're sailing away (set sail! ), ", + "Adventure awaits on every shore!", + "We set sail and explore (ya-har! )", + "And run and jump all day (Yay! )", + "We float on our boat (the boat! )", + "Until it's time to drop the anchor, ", + "Then hang up our coats (aye-aye! )", + "Until we sail again!", + "", + "Yar har, fiddle di dee,", + "Being a pirate is all right with me!", + "Do what you want 'cause a pirate is free, ", + "You are a pirate!", + "", + "Yar har, wind at your back, lads,", + "Wherever you go!", + "", + "", + "Blue sky above and blue ocean below,", + "You are a pirate!", + "", + "You are a pirate!" + }; + + public final Habbo habbo; + public final Room room; + + private int index = 0; + private int oldEffect; + + public YouAreAPirate(Habbo habbo, Room room) { + this.habbo = habbo; + this.room = room; + this.oldEffect = this.habbo.getRoomUnit().getEffectId(); + this.room.giveEffect(this.habbo, 161, -1); + } + + @Override + public void run() { + if (this.room == this.habbo.getHabboInfo().getCurrentRoom()) { + if (!iamapirate[this.index].isEmpty()) { + this.room.talk(this.habbo, new RoomChatMessage(iamapirate[this.index], this.habbo, RoomChatMessageBubbles.PIRATE), RoomChatType.SHOUT); + } + this.index++; + + if (this.index == iamapirate.length) { + this.room.giveEffect(this.habbo, this.oldEffect, -1); + return; + } + + Emulator.getThreading().run(this, iamapirate[this.index - 1].length() * 100); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/YoutubeAdvanceVideo.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/YoutubeAdvanceVideo.java new file mode 100644 index 0000000..0a14064 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/YoutubeAdvanceVideo.java @@ -0,0 +1,33 @@ +package com.eu.habbo.threading.runnables; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.InteractionYoutubeTV; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.messages.outgoing.rooms.items.youtube.YoutubeVideoComposer; + +public class YoutubeAdvanceVideo implements Runnable { + private final InteractionYoutubeTV tv; + + public YoutubeAdvanceVideo(InteractionYoutubeTV tv) { + this.tv = tv; + } + + @Override + public void run() { + if (this.tv.autoAdvance == null) return; + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.tv.getRoomId()); + + if (room == null) return; + + int nextIndex = tv.currentPlaylist.getVideos().indexOf(tv.currentVideo) + 1; + if (nextIndex >= tv.currentPlaylist.getVideos().size()) nextIndex = 0; + tv.currentVideo = tv.currentPlaylist.getVideos().get(nextIndex); + tv.startedWatchingAt = Emulator.getIntUnixTimestamp(); + tv.offset = 0; + room.updateItem(this.tv); + room.sendComposer(new YoutubeVideoComposer(tv.getId(), tv.currentVideo, true, 0).compose()); + + tv.autoAdvance = Emulator.getThreading().run(new YoutubeAdvanceVideo(this.tv), tv.currentVideo.getDuration() * 1000); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/freeze/FreezeClearEffects.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/freeze/FreezeClearEffects.java new file mode 100644 index 0000000..27de582 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/freeze/FreezeClearEffects.java @@ -0,0 +1,21 @@ +package com.eu.habbo.threading.runnables.freeze; + +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserEffectComposer; + +public class FreezeClearEffects implements Runnable { + private final Habbo habbo; + + public FreezeClearEffects(Habbo habbo) { + this.habbo = habbo; + } + + @Override + public void run() { + this.habbo.getRoomUnit().setEffectId(0, 0); + this.habbo.getRoomUnit().setCanWalk(true); + if (this.habbo.getHabboInfo().getCurrentRoom() != null) { + this.habbo.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserEffectComposer(this.habbo.getRoomUnit()).compose()); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/freeze/FreezeHandleSnowballExplosion.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/freeze/FreezeHandleSnowballExplosion.java new file mode 100644 index 0000000..f617a7f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/freeze/FreezeHandleSnowballExplosion.java @@ -0,0 +1,108 @@ +package com.eu.habbo.threading.runnables.freeze; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.games.freeze.FreezeGame; +import com.eu.habbo.habbohotel.games.freeze.FreezeGamePlayer; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeBlock; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeTile; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import gnu.trove.set.hash.THashSet; +import lombok.extern.slf4j.Slf4j; +@Slf4j +class FreezeHandleSnowballExplosion implements Runnable { + + private final FreezeThrowSnowball thrownData; + + public FreezeHandleSnowballExplosion(FreezeThrowSnowball thrownData) { + this.thrownData = thrownData; + } + + @Override + public void run() { + try { + if (this.thrownData == null || this.thrownData.habbo.getHabboInfo().getGamePlayer() == null) + return; + + FreezeGamePlayer player = (FreezeGamePlayer) this.thrownData.habbo.getHabboInfo().getGamePlayer(); + + if (player == null) + return; + + player.addSnowball(); + + THashSet tiles = new THashSet<>(); + + FreezeGame game = ((FreezeGame) this.thrownData.room.getGame(FreezeGame.class)); + + if (game == null) + return; + + if (player.nextHorizontal) { + tiles.addAll(game.affectedTilesByExplosion(this.thrownData.targetTile.getX(), this.thrownData.targetTile.getY(), this.thrownData.radius + 1)); + } + + if (player.nextDiagonal) { + tiles.addAll(game.affectedTilesByExplosionDiagonal(this.thrownData.targetTile.getX(), this.thrownData.targetTile.getY(), this.thrownData.radius + 1)); + player.nextDiagonal = false; + } + + THashSet freezeTiles = new THashSet<>(); + + for (RoomTile roomTile : tiles) { + THashSet items = this.thrownData.room.getItemsAt(roomTile); + + for (HabboItem freezeTile : items) { + if (freezeTile instanceof InteractionFreezeTile || freezeTile instanceof InteractionFreezeBlock) { + int distance = 0; + if (freezeTile.getX() != this.thrownData.targetTile.getX() && freezeTile.getY() != this.thrownData.targetTile.getY()) { + distance = Math.abs(freezeTile.getX() - this.thrownData.targetTile.getX()); + } else { + distance = (int) Math.ceil(this.thrownData.room.getLayout().getTile(this.thrownData.targetTile.getX(), this.thrownData.targetTile.getY()).distance(roomTile)); + } + + if (freezeTile instanceof InteractionFreezeTile) { + freezeTile.setExtradata("11" + String.format("%03d", distance * 100)); //TODO Investigate this further. Probably height dependent or something. + freezeTiles.add((InteractionFreezeTile) freezeTile); + this.thrownData.room.updateItem(freezeTile); + + + THashSet habbos = new THashSet<>(); + habbos.addAll(this.thrownData.room.getHabbosAt(freezeTile.getX(), freezeTile.getY())); + + for (Habbo habbo : habbos) { + if (habbo.getHabboInfo().getGamePlayer() != null && habbo.getHabboInfo().getGamePlayer() instanceof FreezeGamePlayer) { + FreezeGamePlayer hPlayer = (FreezeGamePlayer) habbo.getHabboInfo().getGamePlayer(); + if (!hPlayer.canGetFrozen()) + continue; + + if (hPlayer.getTeamColor().equals(player.getTeamColor())) + player.addScore(-FreezeGame.FREEZE_LOOSE_POINTS); + else + player.addScore(FreezeGame.FREEZE_LOOSE_POINTS); + + ((FreezeGamePlayer) habbo.getHabboInfo().getGamePlayer()).freeze(); + + if (this.thrownData.habbo != habbo) { + AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("EsA")); + } + } + } + } else if (freezeTile instanceof InteractionFreezeBlock) { + if (freezeTile.getExtradata().equalsIgnoreCase("0")) { + game.explodeBox((InteractionFreezeBlock) freezeTile, distance * 100); + player.addScore(FreezeGame.DESTROY_BLOCK_POINTS); + } + } + } + } + } + + Emulator.getThreading().run(new FreezeResetExplosionTiles(freezeTiles, this.thrownData.room), 1000); + } catch (Exception e) { + log.error("Caught exception", e); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/freeze/FreezeResetExplosionTiles.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/freeze/FreezeResetExplosionTiles.java new file mode 100644 index 0000000..80b06f7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/freeze/FreezeResetExplosionTiles.java @@ -0,0 +1,24 @@ +package com.eu.habbo.threading.runnables.freeze; + +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeTile; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import gnu.trove.set.hash.THashSet; + +class FreezeResetExplosionTiles implements Runnable { + private final THashSet tiles; + private final Room room; + + public FreezeResetExplosionTiles(THashSet tiles, Room room) { + this.tiles = tiles; + this.room = room; + } + + @Override + public void run() { + for (HabboItem item : this.tiles) { + item.setExtradata("0"); + this.room.updateItem(item); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/freeze/FreezeThrowSnowball.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/freeze/FreezeThrowSnowball.java new file mode 100644 index 0000000..a610152 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/freeze/FreezeThrowSnowball.java @@ -0,0 +1,33 @@ +package com.eu.habbo.threading.runnables.freeze; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.games.freeze.FreezeGamePlayer; +import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreezeTile; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.threading.runnables.HabboItemNewState; + +public class FreezeThrowSnowball implements Runnable { + public final Habbo habbo; + public final InteractionFreezeTile targetTile; + public final Room room; + public final int radius; + + public FreezeThrowSnowball(Habbo habbo, HabboItem targetTile, Room room) { + this.habbo = habbo; + this.targetTile = (InteractionFreezeTile) targetTile; + this.room = room; + this.radius = ((FreezeGamePlayer) habbo.getHabboInfo().getGamePlayer()).getExplosionBoost(); + } + + @Override + public void run() { + ((FreezeGamePlayer) this.habbo.getHabboInfo().getGamePlayer()).takeSnowball(); + this.targetTile.setExtradata((this.radius + 1) * 1000 + ""); + this.room.updateItem(this.targetTile); + Emulator.getThreading().run(new FreezeHandleSnowballExplosion(this), 2000); + Emulator.getThreading().run(new HabboItemNewState(this.targetTile, this.room, "11000"), 2000); + Emulator.getThreading().run(new HabboItemNewState(this.targetTile, this.room, "0"), 3000); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/games/GameTimer.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/games/GameTimer.java new file mode 100644 index 0000000..f1e903e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/games/GameTimer.java @@ -0,0 +1,46 @@ +package com.eu.habbo.threading.runnables.games; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTimer; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.wired.WiredHandler; +import com.eu.habbo.habbohotel.wired.WiredTriggerType; + +public class GameTimer implements Runnable { + + private final InteractionGameTimer timer; + + public GameTimer(InteractionGameTimer timer) { + this.timer = timer; + } + + @Override + public void run() { + if (timer.getRoomId() == 0) { + timer.setRunning(false); + return; + } + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(timer.getRoomId()); + + if (room == null || !timer.isRunning() || timer.isPaused()) { + timer.setThreadActive(false); + return; + } + + timer.reduceTime(); + if (timer.getTimeNow() < 0) timer.setTimeNow(0); + + if (timer.getTimeNow() > 0) { + timer.setThreadActive(true); + Emulator.getThreading().run(this, 1000); + } else { + timer.setThreadActive(false); + timer.setTimeNow(0); + timer.endGame(room); + WiredHandler.handle(WiredTriggerType.GAME_ENDS, null, room, new Object[]{}); + } + + room.updateItem(timer); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionFive.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionFive.java new file mode 100644 index 0000000..15ac831 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionFive.java @@ -0,0 +1,31 @@ +package com.eu.habbo.threading.runnables.hopper; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.threading.runnables.HabboItemNewState; + +class HopperActionFive implements Runnable { + private final HabboItem currentTeleport; + private final Room room; + private final GameClient client; + + public HopperActionFive(HabboItem currentTeleport, Room room, GameClient client) { + this.currentTeleport = currentTeleport; + this.client = client; + this.room = room; + } + + @Override + public void run() { + this.client.getHabbo().getRoomUnit().isTeleporting = false; + RoomTile tile = this.room.getLayout().getTileInFront(this.room.getLayout().getTile(this.currentTeleport.getX(), this.currentTeleport.getY()), this.currentTeleport.getRotation()); + if (tile != null) { + this.client.getHabbo().getRoomUnit().setGoalLocation(tile); + } + + Emulator.getThreading().run(new HabboItemNewState(this.currentTeleport, this.room, "0"), 1000); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionFour.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionFour.java new file mode 100644 index 0000000..2938a6d --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionFour.java @@ -0,0 +1,26 @@ +package com.eu.habbo.threading.runnables.hopper; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; + +class HopperActionFour implements Runnable { + private final HabboItem currentTeleport; + private final Room room; + private final GameClient client; + + public HopperActionFour(HabboItem currentTeleport, Room room, GameClient client) { + this.currentTeleport = currentTeleport; + this.client = client; + this.room = room; + } + + @Override + public void run() { + this.currentTeleport.setExtradata("1"); + this.room.updateItem(this.currentTeleport); + + Emulator.getThreading().run(new HopperActionFive(this.currentTeleport, this.room, this.client), 500); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionOne.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionOne.java new file mode 100644 index 0000000..25319d2 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionOne.java @@ -0,0 +1,39 @@ +package com.eu.habbo.threading.runnables.hopper; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; + +public class HopperActionOne implements Runnable { + private final HabboItem teleportOne; + private final Room room; + private final GameClient client; + + public HopperActionOne(HabboItem teleportOne, Room room, GameClient client) { + this.teleportOne = teleportOne; + this.room = room; + this.client = client; + } + + @Override + public void run() { + //this.client.getHabbo().getRoomUnit().setGoalLocation(this.teleportOne.getX(), this.teleportOne.getY()); + this.client.getHabbo().getRoomUnit().setRotation(RoomUserRotation.values()[(this.teleportOne.getRotation() + 4) % 8]); + this.client.getHabbo().getRoomUnit().setStatus(RoomUnitStatus.MOVE, this.teleportOne.getX() + "," + this.teleportOne.getY() + "," + this.teleportOne.getZ()); + this.room.scheduledComposers.add(new RoomUserStatusComposer(this.client.getHabbo().getRoomUnit()).compose()); + this.client.getHabbo().getRoomUnit().setLocation(this.room.getLayout().getTile(this.teleportOne.getX(), this.teleportOne.getY())); + this.client.getHabbo().getRoomUnit().setZ(this.teleportOne.getZ()); + this.client.getHabbo().getRoomUnit().setPreviousLocationZ(this.teleportOne.getZ()); + + Emulator.getThreading().run(() -> { + HopperActionOne.this.client.getHabbo().getRoomUnit().removeStatus(RoomUnitStatus.MOVE); + HopperActionOne.this.room.sendComposer(new RoomUserStatusComposer(HopperActionOne.this.client.getHabbo().getRoomUnit()).compose()); + }, 750); + + Emulator.getThreading().run(new HopperActionTwo(this.teleportOne, this.room, this.client), 1250); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionThree.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionThree.java new file mode 100644 index 0000000..724a426 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionThree.java @@ -0,0 +1,64 @@ +package com.eu.habbo.threading.runnables.hopper; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.interactions.InteractionCostumeHopper; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import com.eu.habbo.threading.runnables.HabboItemNewState; + +class HopperActionThree implements Runnable { + private final HabboItem teleportOne; + private final Room room; + private final GameClient client; + private final int targetRoomId; + private final int targetItemId; + + public HopperActionThree(HabboItem teleportOne, Room room, GameClient client, int targetRoomId, int targetItemId) { + this.teleportOne = teleportOne; + this.room = room; + this.client = client; + this.targetRoomId = targetRoomId; + this.targetItemId = targetItemId; + } + + @Override + public void run() { + HabboItem targetTeleport; + Room targetRoom = this.room; + + if (this.teleportOne.getRoomId() != this.targetRoomId) { + Emulator.getGameEnvironment().getRoomManager().leaveRoom(this.client.getHabbo(), this.room, false); + targetRoom = Emulator.getGameEnvironment().getRoomManager().loadRoom(this.targetRoomId); + Emulator.getGameEnvironment().getRoomManager().enterRoom(this.client.getHabbo(), targetRoom.getId(), "", false); + } + + targetTeleport = targetRoom.getHabboItem(this.targetItemId); + + if (targetTeleport == null) { + this.client.getHabbo().getRoomUnit().removeStatus(RoomUnitStatus.MOVE); + this.client.getHabbo().getRoomUnit().setCanWalk(true); + return; + } + + targetTeleport.setExtradata("2"); + targetRoom.updateItem(targetTeleport); + this.client.getHabbo().getRoomUnit().setLocation(this.room.getLayout().getTile(targetTeleport.getX(), targetTeleport.getY())); + this.client.getHabbo().getRoomUnit().setPreviousLocationZ(targetTeleport.getZ()); + this.client.getHabbo().getRoomUnit().setZ(targetTeleport.getZ()); + this.client.getHabbo().getRoomUnit().setRotation(RoomUserRotation.values()[targetTeleport.getRotation() % 8]); + this.client.getHabbo().getRoomUnit().removeStatus(RoomUnitStatus.MOVE); + targetRoom.sendComposer(new RoomUserStatusComposer(this.client.getHabbo().getRoomUnit()).compose()); + + Emulator.getThreading().run(new HabboItemNewState(this.teleportOne, this.room, "0"), 500); + Emulator.getThreading().run(new HopperActionFour(targetTeleport, targetRoom, this.client), 500); + + if (targetTeleport instanceof InteractionCostumeHopper) { + AchievementManager.progressAchievement(this.client.getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("CostumeHopper")); + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionTwo.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionTwo.java new file mode 100644 index 0000000..baa826c --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/hopper/HopperActionTwo.java @@ -0,0 +1,57 @@ +package com.eu.habbo.threading.runnables.hopper; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; +import lombok.extern.slf4j.Slf4j; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +class HopperActionTwo implements Runnable { + private final HabboItem teleportOne; + private final Room room; + private final GameClient client; + + public HopperActionTwo(HabboItem teleportOne, Room room, GameClient client) { + this.teleportOne = teleportOne; + this.room = room; + this.client = client; + } + + @Override + public void run() { + this.teleportOne.setExtradata("2"); + + int targetRoomId = 0; + int targetItemId = 0; + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT items.id, items.room_id FROM items_hoppers INNER JOIN items ON items_hoppers.item_id = items.id WHERE base_item = ? AND items.id != ? AND room_id > 0 ORDER BY RAND() LIMIT 1")) { + statement.setInt(1, this.teleportOne.getBaseItem().getId()); + statement.setInt(2, this.teleportOne.getId()); + + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + targetItemId = set.getInt("id"); + targetRoomId = set.getInt("room_id"); + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + + if (targetRoomId != 0 && targetItemId != 0) { + Emulator.getThreading().run(new HopperActionThree(this.teleportOne, this.room, this.client, targetRoomId, targetItemId), 500); + } else { + this.teleportOne.setExtradata("0"); + this.client.getHabbo().getRoomUnit().setCanWalk(true); + this.client.getHabbo().getRoomUnit().isTeleporting = false; + Emulator.getThreading().run(new HopperActionFour(this.teleportOne, this.room, this.client), 500); + } + + this.room.updateItem(this.teleportOne); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFive.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFive.java new file mode 100644 index 0000000..9072a33 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFive.java @@ -0,0 +1,77 @@ +package com.eu.habbo.threading.runnables.teleport; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.interactions.InteractionTeleportTile; +import com.eu.habbo.habbohotel.rooms.*; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import com.eu.habbo.threading.runnables.HabboItemNewState; +import com.eu.habbo.threading.runnables.RoomUnitWalkToLocation; + +import java.util.ArrayList; +import java.util.List; + +class TeleportActionFive implements Runnable { + private final HabboItem currentTeleport; + private final Room room; + private final GameClient client; + + public TeleportActionFive(HabboItem currentTeleport, Room room, GameClient client) { + this.currentTeleport = currentTeleport; + this.client = client; + this.room = room; + } + + @Override + public void run() { + RoomUnit unit = this.client.getHabbo().getRoomUnit(); + + unit.isLeavingTeleporter = false; + unit.isTeleporting = false; + unit.setCanWalk(true); + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != this.room) + return; + + //if (!(this.currentTeleport instanceof InteractionTeleportTile)) + + if (this.room.getLayout() == null || this.currentTeleport == null) return; + + RoomTile currentLocation = this.room.getLayout().getTile(this.currentTeleport.getX(), this.currentTeleport.getY()); + RoomTile tile = this.room.getLayout().getTileInFront(currentLocation, this.currentTeleport.getRotation()); + + if (tile != null) { + List onSuccess = new ArrayList(); + onSuccess.add(() -> { + unit.setCanLeaveRoomByDoor(true); + + Emulator.getThreading().run(() -> { + unit.isLeavingTeleporter = false; + }, 300); + }); + + unit.setCanLeaveRoomByDoor(false); + unit.setGoalLocation(tile); + unit.statusUpdate(true); + unit.isLeavingTeleporter = true; + Emulator.getThreading().run(new RoomUnitWalkToLocation(unit, tile, room, onSuccess, onSuccess)); + } + + this.currentTeleport.setExtradata("1"); + this.room.updateItem(this.currentTeleport); + + Emulator.getThreading().run(new HabboItemNewState(this.currentTeleport, this.room, "0"), 1000); + + HabboItem teleportTile = this.room.getTopItemAt(unit.getX(), unit.getY()); + + if (teleportTile != null && teleportTile instanceof InteractionTeleportTile && teleportTile != this.currentTeleport) { + try { + teleportTile.onWalkOn(unit, this.room, new Object[]{}); + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFour.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFour.java new file mode 100644 index 0000000..6379fa9 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionFour.java @@ -0,0 +1,34 @@ +package com.eu.habbo.threading.runnables.teleport; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.users.HabboItem; + +class TeleportActionFour implements Runnable { + private final HabboItem currentTeleport; + private final Room room; + private final GameClient client; + + public TeleportActionFour(HabboItem currentTeleport, Room room, GameClient client) { + this.currentTeleport = currentTeleport; + this.client = client; + this.room = room; + } + + @Override + public void run() { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != this.room) { + this.client.getHabbo().getRoomUnit().setCanWalk(true); + this.currentTeleport.setExtradata("0"); + this.room.updateItem(this.currentTeleport); + return; + } + + if(this.client.getHabbo().getRoomUnit() != null) { + this.client.getHabbo().getRoomUnit().isLeavingTeleporter = true; + } + + Emulator.getThreading().run(new TeleportActionFive(this.currentTeleport, this.room, this.client), 500); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionOne.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionOne.java new file mode 100644 index 0000000..760c2d7 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionOne.java @@ -0,0 +1,44 @@ +package com.eu.habbo.threading.runnables.teleport; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.interactions.InteractionTeleportTile; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; + +public class TeleportActionOne implements Runnable { + private final HabboItem currentTeleport; + private final Room room; + private final GameClient client; + + public TeleportActionOne(HabboItem currentTeleport, Room room, GameClient client) { + this.currentTeleport = currentTeleport; + this.client = client; + this.room = room; + } + + @Override + public void run() { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != this.room) + return; + + int delay = 500; + + if (this.currentTeleport instanceof InteractionTeleportTile) { + delay = 0; + } + + if (this.client.getHabbo().getRoomUnit().getCurrentLocation() != this.room.getLayout().getTile(this.currentTeleport.getX(), this.currentTeleport.getY())) { + this.client.getHabbo().getRoomUnit().setLocation(this.room.getLayout().getTile(this.currentTeleport.getX(), this.currentTeleport.getY())); + this.client.getHabbo().getRoomUnit().setRotation(RoomUserRotation.values()[(this.currentTeleport.getRotation() + 4) % 8]); + this.client.getHabbo().getRoomUnit().setStatus(RoomUnitStatus.MOVE, this.currentTeleport.getX() + "," + this.currentTeleport.getY() + "," + this.currentTeleport.getZ()); + this.room.scheduledComposers.add(new RoomUserStatusComposer(this.client.getHabbo().getRoomUnit()).compose()); + this.client.getHabbo().getRoomUnit().setLocation(this.room.getLayout().getTile(this.currentTeleport.getX(), this.currentTeleport.getY())); + } + + Emulator.getThreading().run(new TeleportActionTwo(this.currentTeleport, this.room, this.client), delay); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionThree.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionThree.java new file mode 100644 index 0000000..907fcb5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionThree.java @@ -0,0 +1,80 @@ +package com.eu.habbo.threading.runnables.teleport; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.interactions.InteractionTeleport; +import com.eu.habbo.habbohotel.items.interactions.InteractionTeleportTile; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.habbohotel.users.HabboItem; + +class TeleportActionThree implements Runnable { + private final HabboItem currentTeleport; + private final Room room; + private final GameClient client; + + public TeleportActionThree(HabboItem currentTeleport, Room room, GameClient client) { + this.currentTeleport = currentTeleport; + this.client = client; + this.room = room; + } + + @Override + public void run() { + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != this.room) + return; + + HabboItem targetTeleport; + Room targetRoom = this.room; + + if (this.currentTeleport.getRoomId() != ((InteractionTeleport) this.currentTeleport).getTargetRoomId()) { + targetRoom = Emulator.getGameEnvironment().getRoomManager().loadRoom(((InteractionTeleport) this.currentTeleport).getTargetRoomId()); + } + + if (targetRoom == null) { + Emulator.getThreading().run(new TeleportActionFive(this.currentTeleport, this.room, this.client), 0); + return; + } + + if (targetRoom.isPreLoaded()) { + targetRoom.loadData(); + } + + targetTeleport = targetRoom.getHabboItem(((InteractionTeleport) this.currentTeleport).getTargetId()); + + if (targetTeleport == null) { + Emulator.getThreading().run(new TeleportActionFive(this.currentTeleport, this.room, this.client), 0); + return; + } + + RoomTile teleportLocation = targetRoom.getLayout().getTile(targetTeleport.getX(), targetTeleport.getY()); + + if (teleportLocation == null) { + Emulator.getThreading().run(new TeleportActionFive(this.currentTeleport, this.room, this.client), 0); + return; + } + this.client.getHabbo().getRoomUnit().setLocation(teleportLocation); + this.client.getHabbo().getRoomUnit().getPath().clear(); + this.client.getHabbo().getRoomUnit().removeStatus(RoomUnitStatus.MOVE); + this.client.getHabbo().getRoomUnit().setZ(teleportLocation.getStackHeight()); + this.client.getHabbo().getRoomUnit().setPreviousLocationZ(teleportLocation.getStackHeight()); + + if (targetRoom != this.room) { + this.room.removeHabbo(this.client.getHabbo(), false); + Emulator.getGameEnvironment().getRoomManager().enterRoom(this.client.getHabbo(), targetRoom.getId(), "", Emulator.getConfig().getBoolean("hotel.teleport.locked.allowed"), teleportLocation); + } + + this.client.getHabbo().getRoomUnit().setRotation(RoomUserRotation.values()[targetTeleport.getRotation() % 8]); + this.client.getHabbo().getRoomUnit().statusUpdate(true); + + targetTeleport.setExtradata("2"); + targetRoom.updateItem(targetTeleport); + //targetRoom.updateHabbo(this.client.getHabbo()); + this.client.getHabbo().getHabboInfo().setCurrentRoom(targetRoom); + //Emulator.getThreading().run(new HabboItemNewState(this.currentTeleport, this.room, "0"), 500); + Emulator.getThreading().run(new TeleportActionFour(targetTeleport, targetRoom, this.client), this.currentTeleport instanceof InteractionTeleportTile ? 0 : 500); + + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionTwo.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionTwo.java new file mode 100644 index 0000000..1c19529 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionTwo.java @@ -0,0 +1,99 @@ +package com.eu.habbo.threading.runnables.teleport; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.items.interactions.InteractionTeleport; +import com.eu.habbo.habbohotel.items.interactions.InteractionTeleportTile; +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomUnitStatus; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer; +import com.eu.habbo.threading.runnables.HabboItemNewState; +import lombok.extern.slf4j.Slf4j; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +@Slf4j +class TeleportActionTwo implements Runnable { + + private final HabboItem currentTeleport; + private final Room room; + private final GameClient client; + + public TeleportActionTwo(HabboItem currentTeleport, Room room, GameClient client) { + this.currentTeleport = currentTeleport; + this.client = client; + this.room = room; + } + + @Override + public void run() { + int delayOffset = 500; + + if (this.currentTeleport instanceof InteractionTeleportTile) { + delayOffset = 0; + } + + if(this.client.getHabbo() == null) { + return; + } + + if (this.client.getHabbo().getHabboInfo().getCurrentRoom() != this.room) + return; + + this.client.getHabbo().getRoomUnit().removeStatus(RoomUnitStatus.MOVE); + this.room.sendComposer(new RoomUserStatusComposer(this.client.getHabbo().getRoomUnit()).compose()); + + if (((InteractionTeleport) this.currentTeleport).getTargetRoomId() > 0 && ((InteractionTeleport) this.currentTeleport).getTargetId() > 0) { + HabboItem item = this.room.getHabboItem(((InteractionTeleport) this.currentTeleport).getTargetId()); + if (item == null) { + ((InteractionTeleport) this.currentTeleport).setTargetRoomId(0); + ((InteractionTeleport) this.currentTeleport).setTargetId(0); + } else if (((InteractionTeleport) item).getTargetRoomId() != ((InteractionTeleport) this.currentTeleport).getTargetRoomId()) { + ((InteractionTeleport) this.currentTeleport).setTargetId(0); + ((InteractionTeleport) this.currentTeleport).setTargetRoomId(0); + ((InteractionTeleport) item).setTargetId(0); + ((InteractionTeleport) item).setTargetRoomId(0); + } + } else { + ((InteractionTeleport) this.currentTeleport).setTargetRoomId(0); + ((InteractionTeleport) this.currentTeleport).setTargetId(0); + } + if (((InteractionTeleport) this.currentTeleport).getTargetId() == 0) { + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT items_teleports.*, A.room_id as a_room_id, A.id as a_id, B.room_id as b_room_id, B.id as b_id FROM items_teleports INNER JOIN items AS A ON items_teleports.teleport_one_id = A.id INNER JOIN items AS B ON items_teleports.teleport_two_id = B.id WHERE (teleport_one_id = ? OR teleport_two_id = ?)")) { + statement.setInt(1, this.currentTeleport.getId()); + statement.setInt(2, this.currentTeleport.getId()); + + try (ResultSet set = statement.executeQuery()) { + if (set.next()) { + if (set.getInt("a_id") != this.currentTeleport.getId()) { + ((InteractionTeleport) this.currentTeleport).setTargetId(set.getInt("a_id")); + ((InteractionTeleport) this.currentTeleport).setTargetRoomId(set.getInt("a_room_id")); + } else { + ((InteractionTeleport) this.currentTeleport).setTargetId(set.getInt("b_id")); + ((InteractionTeleport) this.currentTeleport).setTargetRoomId(set.getInt("b_room_id")); + } + } + } + } catch (SQLException e) { + log.error("Caught SQL exception", e); + } + } + + this.currentTeleport.setExtradata("0"); + this.room.updateItem(this.currentTeleport); + + if (((InteractionTeleport) this.currentTeleport).getTargetRoomId() == 0) { + //Emulator.getThreading().run(new HabboItemNewState(this.currentTeleport, room, "1"), 0); + Emulator.getThreading().run(new TeleportActionFive(this.currentTeleport, this.room, this.client), 0); + return; + } + + Emulator.getThreading().run(new HabboItemNewState(this.currentTeleport, this.room, "2"), delayOffset); + Emulator.getThreading().run(new HabboItemNewState(this.currentTeleport, this.room, "0"), delayOffset + 1000); + Emulator.getThreading().run(new TeleportActionThree(this.currentTeleport, this.room, this.client), delayOffset); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/util/ANSI.java b/Emulator/src/main/java/com/eu/habbo/util/ANSI.java new file mode 100644 index 0000000..4c59761 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/util/ANSI.java @@ -0,0 +1,16 @@ +package com.eu.habbo.util; + +import ch.qos.logback.core.pattern.color.ANSIConstants; + +public class ANSI { + + public static final String RED = "\u001B[" + ANSIConstants.RED_FG + "m"; + public static final String GREEN = "\u001B[" + ANSIConstants.GREEN_FG + "m"; + public static final String YELLOW = "\u001B[" + ANSIConstants.YELLOW_FG + "m"; + public static final String BLUE = "\u001B[" + ANSIConstants.BLUE_FG + "m"; + public static final String MAGENTA = "\u001B[" + ANSIConstants.MAGENTA_FG + "m"; + public static final String CYAN = "\u001B[" + ANSIConstants.CYAN_FG + "m"; + public static final String WHITE = "\u001B[" + ANSIConstants.WHITE_FG + "m"; + public static final String DEFAULT = "\u001B[" + ANSIConstants.DEFAULT_FG + "m"; + +} diff --git a/Emulator/src/main/java/com/eu/habbo/util/DebugUtils.java b/Emulator/src/main/java/com/eu/habbo/util/DebugUtils.java new file mode 100644 index 0000000..d515b58 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/util/DebugUtils.java @@ -0,0 +1,22 @@ +package com.eu.habbo.util; + +public class DebugUtils { + + // Code from https://stackoverflow.com/a/11306854/11849181 + public static StackTraceElement getCallerCallerStacktrace() { + StackTraceElement[] stElements = Thread.currentThread().getStackTrace(); + String callerClassName = null; + for (int i = 1; i < stElements.length; i++) { + StackTraceElement ste = stElements[i]; + if (!ste.getClassName().equals(DebugUtils.class.getName()) && ste.getClassName().indexOf("java.lang.Thread") != 0) { + if (callerClassName == null) { + callerClassName = ste.getClassName(); + } else if (!callerClassName.equals(ste.getClassName())) { + return ste; + } + } + } + return null; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/util/HexUtils.java b/Emulator/src/main/java/com/eu/habbo/util/HexUtils.java new file mode 100644 index 0000000..2e5bccb --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/util/HexUtils.java @@ -0,0 +1,41 @@ +package com.eu.habbo.util; + +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; + +public class HexUtils { + + private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); + + public static String toHex(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2]; + for (int j = 0; j < bytes.length; j++) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = HEX_ARRAY[v >>> 4]; + hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; + } + return new String(hexChars); + } + + public static byte[] toBytes(String hexString) { + int len = hexString.length(); + byte[] data = new byte[len / 2]; + for (int i = 0; i < len; i += 2) { + data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + + Character.digit(hexString.charAt(i+1), 16)); + } + return data; + } + + public static String getRandom(int length){ + Random r = ThreadLocalRandom.current(); + StringBuilder sb = new StringBuilder(); + + while(sb.length() < length){ + sb.append(Integer.toHexString(r.nextInt())); + } + + return sb.toString().substring(0, length); + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/util/PacketUtils.java b/Emulator/src/main/java/com/eu/habbo/util/PacketUtils.java new file mode 100644 index 0000000..855ca9a --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/util/PacketUtils.java @@ -0,0 +1,19 @@ +package com.eu.habbo.util; + +import io.netty.buffer.ByteBuf; + +import java.nio.charset.Charset; + +public class PacketUtils { + + public static String formatPacket(ByteBuf buffer) { + String result = buffer.toString(Charset.defaultCharset()); + + for (int i = -1; i < 31; i++) { + result = result.replace(Character.toString((char) i), "[" + i + "]"); + } + + return result; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/util/callback/HTTPPostError.java b/Emulator/src/main/java/com/eu/habbo/util/callback/HTTPPostError.java new file mode 100644 index 0000000..2d1760f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/util/callback/HTTPPostError.java @@ -0,0 +1,55 @@ +package com.eu.habbo.util.callback; + +/* public class HTTPPostError implements Runnable +{ + public Throwable stackTrace; + + public HTTPPostError(Throwable stackTrace) + { + this.stackTrace = stackTrace; + } + + private void sendPost() + { + try + { + if (!Emulator.isReady) + return; + + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + this.stackTrace.printStackTrace(pw); + String url = "http://arcturus.pw/callback/error.php"; + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + con.setRequestMethod("POST"); + con.setRequestProperty("User-Agent", "arcturus"); + String urlParameters = "errors=1&version=" + Emulator.version + "&stacktrace=" + sw.toString() + "&users=" + Emulator.getGameEnvironment().getHabboManager().getOnlineCount() + "&rooms=" + Emulator.getGameEnvironment().getRoomManager().getActiveRooms().size() + "&username=" + Emulator.getConfig().getValue("username"); + con.setDoOutput(true); + DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + wr.writeBytes(urlParameters); + wr.flush(); + wr.close(); + pw.close(); + sw.close(); + + int responseCode = con.getResponseCode(); + con.disconnect(); + } + catch (Exception e) + { + } + } + + @Override + public void run() + { + try + { + this.sendPost(); + } + catch (Exception e) + { + } + } +} */ diff --git a/Emulator/src/main/java/com/eu/habbo/util/callback/HTTPPostStatus.java b/Emulator/src/main/java/com/eu/habbo/util/callback/HTTPPostStatus.java new file mode 100644 index 0000000..fec700e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/util/callback/HTTPPostStatus.java @@ -0,0 +1,40 @@ +/* package com.eu.habbo.util.callback; + +import com.eu.habbo.Emulator; + +import java.io.DataOutputStream; +import java.net.HttpURLConnection; +import java.net.URL; + + public class HTTPPostStatus implements Runnable +{ + private void sendPost() throws Exception + { + String url = "http://arcturus.pw/callback/status.php"; + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + con.setRequestMethod("POST"); + con.setRequestProperty("User-Agent", "arcturus"); + String urlParameters = "users=" + Emulator.getGameEnvironment().getHabboManager().getOnlineCount() + "&rooms=" + Emulator.getGameEnvironment().getRoomManager().getActiveRooms().size() + "&username=" + Emulator.getConfig().getValue("username") + "&version=" + Emulator.version; + con.setDoOutput(true); + DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + wr.writeBytes(urlParameters); + wr.flush(); + wr.close(); + int responseCode = con.getResponseCode(); + con.disconnect(); + } + + @Override + public void run() + { + try + { + this.sendPost(); + } + catch (Exception e) + { + } + } +} +*/ \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/util/callback/HTTPVersionCheck.java b/Emulator/src/main/java/com/eu/habbo/util/callback/HTTPVersionCheck.java new file mode 100644 index 0000000..8ac8ef3 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/util/callback/HTTPVersionCheck.java @@ -0,0 +1,68 @@ +package com.eu.habbo.util.callback; + +/* public class HTTPVersionCheck implements Runnable +{ + private void sendPost() + { + try + { + if (!Emulator.isReady) + return; + + String url = "http://arcturus.pw/callback/check.php"; + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + con.setRequestMethod("POST"); + con.setRequestProperty("User-Agent", "arcturus"); + String urlParameters = "&major=" + Emulator.MAJOR + "&minor=" + Emulator.MINOR + "&build=" + Emulator.BUILD + "&version=" + Emulator.version + "&users=" + Emulator.getGameEnvironment().getHabboManager().getOnlineCount() + "&rooms=" + Emulator.getGameEnvironment().getRoomManager().getActiveRooms().size() + "&username=" + Emulator.getConfig().getValue("username"); + con.setDoOutput(true); + DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + wr.writeBytes(urlParameters); + wr.flush(); + + int responseCode = con.getResponseCode(); + if (responseCode == 102) + { + StringBuilder text = new StringBuilder(); + InputStreamReader in = new InputStreamReader((InputStream) con.getContent()); + BufferedReader buff = new BufferedReader(in); + String line; + do { + line = buff.readLine(); + + if (line != null) + { + text.append(line).append("\n"); + } + } while (line != null); + buff.close(); + in.close(); + + logger.info(text.toString()); + Emulator.getGameServer().getGameClientManager().sendBroadcastResponse(new GenericAlertComposer(text.toString())); + } + wr.close(); + con.disconnect(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + @Override + public void run() + { + + + + + + + + + + } + +} + */ diff --git a/Emulator/src/main/java/com/eu/habbo/util/crypto/ZIP.java b/Emulator/src/main/java/com/eu/habbo/util/crypto/ZIP.java new file mode 100644 index 0000000..7346101 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/util/crypto/ZIP.java @@ -0,0 +1,27 @@ +package com.eu.habbo.util.crypto; + +import java.io.ByteArrayOutputStream; +import java.util.zip.Inflater; + +public class ZIP { + public static byte[] inflate(byte[] data) { + try { + byte[] buffer = new byte[data.length * 5]; + Inflater inflater = new Inflater(); + inflater.setInput(data); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length); + while (!inflater.finished()) { + int count = inflater.inflate(buffer); + outputStream.write(buffer, 0, count); + } + outputStream.close(); + byte[] output = outputStream.toByteArray(); + + inflater.end(); + return output; + } catch (Exception e) { + return new byte[0]; + } + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/util/figure/FigureUtil.java b/Emulator/src/main/java/com/eu/habbo/util/figure/FigureUtil.java new file mode 100644 index 0000000..efbb779 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/util/figure/FigureUtil.java @@ -0,0 +1,71 @@ +package com.eu.habbo.util.figure; + +import gnu.trove.map.hash.THashMap; +import org.apache.commons.lang3.ArrayUtils; + +import java.util.Map; +import java.util.Set; + +public class FigureUtil { + public static THashMap getFigureBits(String looks) { + THashMap bits = new THashMap<>(); + String[] sets = looks.split("\\."); + + for (String set : sets) { + String[] setBits = set.split("-", 2); + bits.put(setBits[0], setBits.length > 1 ? setBits[1] : ""); + } + + return bits; + } + + + public static String mergeFigures(String figure1, String figure2) { + return mergeFigures(figure1, figure2, null, null); + } + + public static String mergeFigures(String figure1, String figure2, String[] limitFigure1) { + return mergeFigures(figure1, figure2, limitFigure1, null); + } + + public static boolean hasBlacklistedClothing(String figure, Set blacklist) { + for (String set : figure.split("\\.")) { + String[] pieces = set.split("-"); + + try { + if (pieces.length >= 2 && blacklist.contains(Integer.valueOf(pieces[1]))) { + return true; + } + } catch (NumberFormatException ignored) { + + } + } + + return false; + } + + public static String mergeFigures(String figure1, String figure2, String[] limitFigure1, String[] limitFigure2) { + THashMap figureBits1 = getFigureBits(figure1); + THashMap figureBits2 = getFigureBits(figure2); + + StringBuilder finalLook = new StringBuilder(); + + for (Map.Entry keys : figureBits1.entrySet()) { + if (limitFigure1 == null || ArrayUtils.contains(limitFigure1, keys.getKey())) { + finalLook.append(keys.getKey()).append("-").append(keys.getValue()).append("."); + } + } + + for (Map.Entry keys : figureBits2.entrySet()) { + if (limitFigure2 == null || ArrayUtils.contains(limitFigure2, keys.getKey())) { + finalLook.append(keys.getKey()).append("-").append(keys.getValue()).append("."); + } + } + + if (finalLook.toString().endsWith(".")) { + finalLook = new StringBuilder(finalLook.substring(0, finalLook.length() - 1)); + } + + return finalLook.toString(); + } +} \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/util/imager/badges/BadgeImager.java b/Emulator/src/main/java/com/eu/habbo/util/imager/badges/BadgeImager.java new file mode 100644 index 0000000..a597e2f --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/util/imager/badges/BadgeImager.java @@ -0,0 +1,247 @@ +package com.eu.habbo.util.imager.badges; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.guilds.Guild; +import com.eu.habbo.habbohotel.guilds.GuildPart; +import com.eu.habbo.habbohotel.guilds.GuildPartType; +import gnu.trove.map.hash.THashMap; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.awt.image.ColorConvertOp; +import java.awt.image.ColorModel; +import java.awt.image.WritableRaster; +import java.io.File; +import java.util.Map; + +@Slf4j +public class BadgeImager { + + final THashMap cachedImages = new THashMap<>(); + + public BadgeImager() { + if (Emulator.getConfig().getBoolean("imager.internal.enabled")) { + if (this.reload()) { + log.info("Badge Imager -> Loaded!"); + } else { + log.warn("Badge Imager -> Disabled! Please check your configuration!"); + } + } + } + + public static BufferedImage deepCopy(BufferedImage bi) { + if (bi == null) + return null; + + ColorModel cm = bi.getColorModel(); + boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); + WritableRaster raster = bi.copyData(null); + return new BufferedImage(cm, raster, isAlphaPremultiplied, null); + } + + public static void recolor(BufferedImage image, Color maskColor) { + for (int x = 0; x < image.getWidth(); x++) { + for (int y = 0; y < image.getHeight(); y++) { + int pixel = image.getRGB(x, y); + + if ((pixel >> 24) == 0x00) + continue; + + Color color = new Color(pixel); + + float alpha = (color.getAlpha() / 255.0F) * (maskColor.getAlpha() / 255.0F); + float red = (color.getRed() / 255.0F) * (maskColor.getRed() / 255.0F); + float green = (color.getGreen() / 255.0F) * (maskColor.getGreen() / 255.0F); + float blue = (color.getBlue() / 255.0F) * (maskColor.getBlue() / 255.0F); + + color = new Color(red, green, blue, alpha); + + int rgb = color.getRGB(); + image.setRGB(x, y, rgb); + } + } + } + + public static Color colorFromHexString(String colorStr) { + try { + return new Color( + Integer.valueOf(colorStr, 16)); + } catch (Exception e) { + return new Color(0xffffff); + } + } + + public static Point getPoint(BufferedImage image, BufferedImage imagePart, int position) { + int x = 0; + int y = 0; + + if (position == 1) { + x = (image.getWidth() - imagePart.getWidth()) / 2; + y = 0; + } else if (position == 2) { + x = image.getWidth() - imagePart.getWidth(); + y = 0; + } else if (position == 3) { + x = 0; + y = (image.getHeight() / 2) - (imagePart.getHeight() / 2); + } else if (position == 4) { + x = (image.getWidth() / 2) - (imagePart.getWidth() / 2); + y = (image.getHeight() / 2) - (imagePart.getHeight() / 2); + } else if (position == 5) { + x = image.getWidth() - imagePart.getWidth(); + y = (image.getHeight() / 2) - (imagePart.getHeight() / 2); + } else if (position == 6) { + x = 0; + y = image.getHeight() - imagePart.getHeight(); + } else if (position == 7) { + x = ((image.getWidth() - imagePart.getWidth()) / 2); + y = image.getHeight() - imagePart.getHeight(); + } else if (position == 8) { + x = image.getWidth() - imagePart.getWidth(); + y = image.getHeight() - imagePart.getHeight(); + } + + return new Point(x, y); + } + + public static BufferedImage convert32(BufferedImage src) { + BufferedImage dest = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_ARGB); + ColorConvertOp cco = new ColorConvertOp(src.getColorModel().getColorSpace(), dest.getColorModel().getColorSpace(), null); + return cco.filter(src, dest); + } + + public synchronized boolean reload() { + File file = new File(Emulator.getConfig().getValue("imager.location.badgeparts")); + if (!file.exists()) { + log.error("BadgeImager output folder: {} does not exist!", Emulator.getConfig().getValue("imager.location.badgeparts")); + return false; + } + + this.cachedImages.clear(); + try { + for (Map.Entry> set : Emulator.getGameEnvironment().getGuildManager().getGuildParts().entrySet()) { + if (set.getKey() == GuildPartType.SYMBOL || set.getKey() == GuildPartType.BASE) { + for (Map.Entry map : set.getValue().entrySet()) { + if (!map.getValue().valueA.isEmpty()) { + try { + this.cachedImages.put(map.getValue().valueA, ImageIO.read(new File(Emulator.getConfig().getValue("imager.location.badgeparts"), "badgepart_" + map.getValue().valueA.replace(".gif", ".png")))); + } catch (Exception e) { + log.info(("[Badge Imager] Missing Badge Part: " + Emulator.getConfig().getValue("imager.location.badgeparts") + "/badgepart_" + map.getValue().valueA.replace(".gif", ".png"))); + } + } + + if (!map.getValue().valueB.isEmpty()) { + try { + this.cachedImages.put(map.getValue().valueB, ImageIO.read(new File(Emulator.getConfig().getValue("imager.location.badgeparts"), "badgepart_" + map.getValue().valueB.replace(".gif", ".png")))); + } catch (Exception e) { + log.info(("[Badge Imager] Missing Badge Part: " + Emulator.getConfig().getValue("imager.location.badgeparts") + "/badgepart_" + map.getValue().valueB.replace(".gif", ".png"))); + } + } + } + } + } + } catch (Exception e) { + log.error("Caught exception", e); + return false; + } + + return true; + } + + public void generate(Guild guild) { + String badge = guild.getBadge(); + File outputFile; + try { + outputFile = new File(Emulator.getConfig().getValue("imager.location.output.badges"), badge + ".png"); + + if (outputFile.exists()) + return; + } catch (Exception e) { + log.error("Caught exception", e); + return; + } + + String[] parts = new String[]{"", "", "", "", ""}; + + int count = 0; + + for (int i = 0; i < badge.length(); ) { + if (i > 0) { + if (i % 7 == 0) { + count++; + } + } + + for (int j = 0; j < 7; j++) { + parts[count] += badge.charAt(i); + i++; + } + } + + + BufferedImage image = new BufferedImage(39, 39, BufferedImage.TYPE_INT_ARGB); + Graphics graphics = image.getGraphics(); + + for (String s : parts) { + if (s.isEmpty()) + continue; + + String type = s.charAt(0) + ""; + int id = Integer.valueOf(s.substring(1, 4)); + int c = Integer.valueOf(s.substring(4, 6)); + int position = Integer.valueOf(s.substring(6)); + + GuildPart part; + GuildPart color = Emulator.getGameEnvironment().getGuildManager().getPart(GuildPartType.BASE_COLOR, c); + + if (type.equalsIgnoreCase("b")) { + part = Emulator.getGameEnvironment().getGuildManager().getPart(GuildPartType.BASE, id); + } else { + part = Emulator.getGameEnvironment().getGuildManager().getPart(GuildPartType.SYMBOL, id); + } + + if (part == null) continue; + + BufferedImage imagePart = BadgeImager.deepCopy(this.cachedImages.get(part.valueA)); + + Point point; + + if (imagePart != null) { + if (imagePart.getColorModel().getPixelSize() < 32) { + imagePart = convert32(imagePart); + } + + point = getPoint(image, imagePart, position); + + if(color != null) { + recolor(imagePart, colorFromHexString(color.valueA)); + } + + graphics.drawImage(imagePart, point.x, point.y, null); + } + + if (!part.valueB.isEmpty()) { + imagePart = BadgeImager.deepCopy(this.cachedImages.get(part.valueB)); + + if (imagePart != null) { + if (imagePart.getColorModel().getPixelSize() < 32) { + imagePart = convert32(imagePart); + } + + point = getPoint(image, imagePart, position); + graphics.drawImage(imagePart, point.x, point.y, null); + } + } + } + + try { + ImageIO.write(image, "PNG", outputFile); + } catch (Exception e) { + log.error("Failed to generate guild badge: {}.png Make sure the output folder exists and is writable!", outputFile); + } + + graphics.dispose(); + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/util/logback/SqlExceptionFilter.java b/Emulator/src/main/java/com/eu/habbo/util/logback/SqlExceptionFilter.java new file mode 100644 index 0000000..1026ad5 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/util/logback/SqlExceptionFilter.java @@ -0,0 +1,23 @@ +package com.eu.habbo.util.logback; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.classic.spi.ThrowableProxy; +import ch.qos.logback.core.filter.Filter; +import ch.qos.logback.core.spi.FilterReply; + +import java.sql.SQLException; + +public class SqlExceptionFilter extends Filter { + + @Override + public FilterReply decide(ILoggingEvent event) { + ThrowableProxy proxy = (ThrowableProxy) event.getThrowableProxy(); + + if (proxy.getThrowable() instanceof SQLException){ + return FilterReply.ACCEPT; + } + + return FilterReply.DENY; + } + +} diff --git a/Emulator/src/main/java/com/eu/habbo/util/pathfinding/Rotation.java b/Emulator/src/main/java/com/eu/habbo/util/pathfinding/Rotation.java new file mode 100644 index 0000000..51af541 --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/util/pathfinding/Rotation.java @@ -0,0 +1,25 @@ +package com.eu.habbo.util.pathfinding; + +public class Rotation { + public static int Calculate(int X1, int Y1, int X2, int Y2) { + int Rotation = 0; + if ((X1 > X2) && (Y1 > Y2)) { + Rotation = 7; + } else if ((X1 < X2) && (Y1 < Y2)) { + Rotation = 3; + } else if ((X1 > X2) && (Y1 < Y2)) { + Rotation = 5; + } else if ((X1 < X2) && (Y1 > Y2)) { + Rotation = 1; + } else if (X1 > X2) { + Rotation = 6; + } else if (X1 < X2) { + Rotation = 2; + } else if (Y1 < Y2) { + Rotation = 4; + } else if (Y1 > Y2) { + Rotation = 0; + } + return Rotation; + } +} diff --git a/Emulator/src/main/resources/logback.xml b/Emulator/src/main/resources/logback.xml new file mode 100644 index 0000000..6b298c1 --- /dev/null +++ b/Emulator/src/main/resources/logback.xml @@ -0,0 +1,71 @@ + + + + false + + %d{HH:mm:ss.SSS} [%-14thread] %highlight(%-5level) %cyan(%-36logger{36}) - %msg%n + + + + + logging/debug.txt + + DEBUG + ACCEPT + DENY + + + logging/debug.%d{yyyy-MM-dd}.%i.gz + 50MB + 7 + + + %d{HH:mm:ss.SSS} [%thread] %level %logger - %msg%n + + + + + logging/errors/runtime.txt + + ERROR + ACCEPT + DENY + + + logging/errors/runtime.%d{yyyy-MM-dd}.%i.gz + 50MB + 7 + + + %d{HH:mm:ss.SSS} [%thread] %level %logger - %msg%n + + + + + logging/errors/sql.txt + + + logging/errors/sql.%d{yyyy-MM-dd}.%i.gz + 50MB + 7 + + + %d{HH:mm:ss.SSS} [%thread] %level %logger - %msg%n + + + + + + + + + + + + + + + + + + \ No newline at end of file