diff --git a/README.md b/README.md
index bff62d04..1f0a1c0f 100644
--- a/README.md
+++ b/README.md
@@ -1,84 +1,59 @@
# Arcturus Morningstar #
-## What is Arcturus Morningstar? ##
-Arcturus Morningstar is the community project for the Arcturus Emulator by TheGeneral.
-
-The community project was made because the Arcturus Emulator has been abandoned by TheGeneral with lack of updates, an intent to monetize the project, and make the project private.
-
-TheGeneral's own words were "dont like it then dont use it". We did not like what he was doing, so we made our own version.
-
-## License ##
-Arcturus Morningstar is released under the [GNU General Public License v3](https://www.gnu.org/licenses/gpl-3.0.txt).
-
-## Versions ##
-[![image](https://img.shields.io/badge/VERSION-3.0.0-success.svg?style=for-the-badge&logo=appveyor)](#)
-[![image](https://img.shields.io/badge/STATUS-STABLE-blue.svg?style=for-the-badge&logo=appveyor)](#)
-[![image](https://img.shields.io/discord/557240155040251905?style=for-the-badge&logo=discord&color=7289DA&label=DISCORD&logoColor=fff)](https://discord.gg/BzfFsTp)
-
-Compiled Download: https://git.krews.org/morningstar/Arcturus-Community/-/releases
-
-Client build: **PRODUCTION-201611291003-338511768**
-
-## Reporting problems ##
-You can report problems via the Issue Tracker at https://git.krews.org/morningstar/Arcturus-Community/issues
-When making an bug report or a feature request use the template we provide so that it can be categorized correctly and we have more information to replicate a bug or implement a feature correctly.
-
-## Credits ##
-- TheGeneral
-- Beny
-- Alejandro
-- Capheus
-- Skeletor
-- Harmonic
-- Mike
-- Remco
-- zGrav
-- Quadral
-- Harmony
-- Swirny
-- ArpyAge
-- Mikkel
-- Rodolfo
-- Rasmus
-- Kitt Mustang
-- Snaiker
-- nttzx
-- necmi
-- Dome
-- Jose Flores
-- Cam
-- Oliver
-- Narzo
-- Tenshie
-- MartenM
-- Ridge
-- SenpaiDipper
-- Snaiker
-- Thijmen
+Arcturus Morningstar is as a fork of Arcturus Emulator by TheGeneral. Arcturus Morningstar is released under the [GNU General Public License v3](https://www.gnu.org/licenses/gpl-3.0.txt) and is developed for free by talented developers at Krews.org and is compatible with the following client revision/community projects:
-## Discord ##
-Join us on Discord at https://discord.gg/BzfFsTp
+| Flash | Community Clients |
+| ------------- | ------------- |
+| [PRODUCTION-201611291003-338511768](https://git.krews.org/morningstar/apollyon/uploads/dc669a26613bf2356e48eb653734ab29/patched-habbo.swf) | [Nitro (Recommended)*](https://git.krews.org/nitro) |
+
+###### *Note to use Nitro you will need to use the following [plugin](https://git.krews.org/nitro/ms-websockets/-/releases) with Arcturus Morningstar #######
-## Contributing ##
-Anyone is allowed to fork the project and make pull requests. We make no guarantee that pull requests will be approved into the project.
-## Branches ##
-There will be 2 branches of the Arcturus Morningstar emulator:
-`master` - The master branch will be the stable branch. Everything here has been tested on a live hotel and contains no known problems.
-`dev` - The dev branch will be the unstable branch. This one is the most up to date, but things may not work as intended.
-There is no set timeframe on when new versions will be released or when the stable branch will be updated.
+[![image](https://img.shields.io/discord/557240155040251905?style=for-the-badge&logo=discord&color=7289DA&label=KREWS&logoColor=fff)](https://discord.gg/BzfFsTp)
-## Custom features ##
-Do not implement custom features into the source.
-A custom feature will be defined as a feature or ability which is not possible in Habbo.com
-Use plugins for custom features, and if a plugin is not possible, you should adapt the source to enable plugins to do that.
+## Download ##
+[![image](https://img.shields.io/badge/STABLE%20RELEASES-3.0.0-success.svg?style=for-the-badge&logo=appveyor)](https://git.krews.org/morningstar/Arcturus-Community/-/releases)
-## Why always make things as plugins? ##
-Why always make things as plugins?
+[![image](https://img.shields.io/badge/DEVELOPER%20BUILDS-3.1.0-red.svg?style=for-the-badge&logo=appveyor)](https://git.krews.org/morningstar/Arcturus-Community/-/jobs) *
+
+[![image](https://img.shields.io/badge/RECOMMENDED%20PLUGINS-blue.svg?style=for-the-badge&logo=)](https://git.krews.org/official-plugins)
+
+###### * Note to use these builds you will need to run any database updates from [here](https://git.krews.org/morningstar/Arcturus-Community/-/tree/dev/sqlupdates) #######
+
+
+### Branches ###
+There are two main branches in use on the Arcturus Morningstar git. Below the pros an
+
+| master | Tested on a production hotel and is stable for every day use with no known serious exploits. |
+| ------------- | ------------- |
+
+| dev | The most up-to-date, but features may not work as intended. |
+| ------------- | ------------- |
+
+
+
+
+There is no set timeframe on when new versions will be released or when the stable branch will be updated
+
+
+## Can I Help!? ##
+#### Reporting Bugs: ####
+You can report problems via the [Issue Tracker](https://git.krews.org/morningstar/Arcturus-Community/issues)*
+###### * When making an bug report or a feature request use the template we provide so that it can be categorized correctly and we have more information to replicate a bug or implement a feature correctly. ######
+#### Can I contribute code to this project? ####
+Of Course! if you have fixed a bug from the git please feel free to do a [merge request](https://git.krews.org/morningstar/Arcturus-Community/issues)*
+###### * Anyone is allowed to fork the project and make pull requests, we make no guarantee that pull requests will be approved into the project. Please Do NOT push code which does not replicate behaviour on habbo.com, instead make the behaviour configurable or as a plugin. ######
+
+
+
+## Plugin System ##
+The robust Plugin System included in the original Arcturus release is also included in Arcturus Morningstar, if you're interested in making your own plugins, feel free to ask around on our discord and we'll point you in the right direction!
+
+A lot of the community aren't used to modifying things in this way, so we've written a few pros:
1. Other people will see that plugins are the normal way of adding custom features
2. Plugins can be added and removed at the hotel owner's choice, it makes customizing the hotel easier
3. Developers will be able to read plugin source code to learn how to make their own plugins, without the need to look in complicated source code
@@ -91,8 +66,48 @@ Sale of a special edition of a *source code* will not be permitted. You may use
If we ever are to make paid features or plugins, we will not prevent or discourage developers from creating alternative options for users.
-## Plugins - Official Plugins ##
-You can find official plugins to add custom features to Arcturus Morningstar at the following URL:
-[View the respository here.](https://git.krews.org/official-plugins)
+
+
+
+### Credits ###
+
+ - TheGeneral (Arcturus Emulator)
+ - Beny
+ - Alejandro
+ - Capheus
+ - Skeletor
+ - Harmonic
+ - Mike
+ - Remco
+ - zGrav
+ - Quadral
+ - Harmony
+ - Swirny
+ - ArpyAge
+ - Mikkel
+ - Rodolfo
+ - Rasmus
+ - Kitt Mustang
+ - Snaiker
+ - nttzx
+ - necmi
+ - Dome
+ - Jose Flores
+ - Cam
+ - Oliver
+ - Narzo
+ - Tenshie
+ - MartenM
+ - Ridge
+ - SenpaiDipper
+ - Thijmen
+ - Brenoepic
+ - Stankman
+ - Laynester
+
+
+
+
+
diff --git a/featurelist.md b/featurelist.md
new file mode 100644
index 00000000..7f494997
--- /dev/null
+++ b/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/pom.xml b/pom.xml
index 419c9bea..ec802d30 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.eu.habbo
Habbo
- 3.0.0
+ 3.5.0
UTF-8
@@ -106,7 +106,7 @@
mysql
mysql-connector-java
- 5.1.49
+ 8.0.22
runtime
diff --git a/sqlupdates/3_0_0 to 3_5_0.sql b/sqlupdates/3_0_0 to 3_5_0.sql
new file mode 100644
index 00000000..c937d10f
--- /dev/null
+++ b/sqlupdates/3_0_0 to 3_5_0.sql
@@ -0,0 +1,96 @@
+INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('wired.place.under', '0');
+INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('wired.custom.enabled', '0');
+
+INSERT INTO `emulator_texts` (`key`, `value`) VALUES ('commands.error.cmd_stalk.forgot_username', 'Specify the username of the Habbo you want to follow!');
+
+-- Enable or Disable TTY in console (Default is enabled)
+INSERT INTO `emulator_settings` (`key`, `value`) VALUES ('console.mode', '1');
+
+-- Youtube Api v3 key to YoutubeManager
+INSERT INTO `emulator_settings` (`key`, `value`) VALUES ('youtube.apikey', '');
+
+INSERT INTO `emulator_settings` (`key`, `value`) VALUES ('hotel.gifts.length.max', '300');
+
+INSERT INTO `emulator_settings` (`key`, `value`) VALUES ('hotel.trophies.length.max', '300');
+
+-- Add friendship categories table
+CREATE TABLE `messenger_categories` (
+ `id` int NOT NULL AUTO_INCREMENT,
+ `name` varchar(25) NOT NULL,
+ `user_id` int NOT NULL,
+ UNIQUE KEY `identifier` (`id`)
+);
+
+-- Set an ID (int) from category list items
+ALTER TABLE messenger_friendships ADD category int NOT NULL DEFAULT '0' AFTER friends_since;
+
+
+-- ----------------------------
+-- Table structure for calendar_campaigns
+-- ----------------------------
+DROP TABLE IF EXISTS `calendar_campaigns`;
+CREATE TABLE `calendar_campaigns` (
+ `id` int NOT NULL AUTO_INCREMENT,
+ `name` varchar(255) NOT NULL DEFAULT '',
+ `image` varchar(255) NOT NULL DEFAULT '',
+ `start_timestamp` int NOT NULL DEFAULT '0',
+ `total_days` int NOT NULL DEFAULT '30',
+ `lock_expired` enum('1','0') NOT NULL DEFAULT '1',
+ `enabled` enum('1','0') NOT NULL DEFAULT '1',
+ UNIQUE KEY `id` (`id`)
+);
+
+-- ----------------------------
+-- Table structure for calendar_rewards
+-- ----------------------------
+DROP TABLE IF EXISTS `calendar_rewards`;
+CREATE TABLE `calendar_rewards` (
+ `id` int NOT NULL AUTO_INCREMENT,
+ `campaign_id` int NOT NULL DEFAULT '0',
+ `product_name` varchar(128) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '',
+ `custom_image` varchar(128) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '',
+ `credits` int NOT NULL DEFAULT '0',
+ `pixels` int NOT NULL DEFAULT '0',
+ `points` int NOT NULL DEFAULT '0',
+ `points_type` int NOT NULL DEFAULT '0',
+ `badge` varchar(25) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '',
+ `item_id` int NOT NULL DEFAULT '0',
+ `subscription_type` varchar(128) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT '',
+ `subscription_days` int NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`) USING BTREE
+);
+
+-- ----------------------------
+-- Table structure for calendar_rewards_claimed
+-- ----------------------------
+DROP TABLE IF EXISTS `calendar_rewards_claimed`;
+CREATE TABLE `calendar_rewards_claimed` (
+ `user_id` int NOT NULL,
+ `campaign_id` int NOT NULL DEFAULT '0',
+ `day` int NOT NULL,
+ `reward_id` int NOT NULL,
+ `timestamp` int NOT NULL
+);
+
+INSERT INTO `emulator_settings` (`key`, `value`) VALUES ('hotel.calendar.default', 'test');
+INSERT INTO `emulator_settings` (`key`, `value`) VALUES ('hotel.calendar.pixels.hc_modifier', '2.0');
+
+-- Calendar force open
+ALTER TABLE `permissions` ADD COLUMN `acc_calendar_force` enum('0','1') NULL DEFAULT '0';
+
+-- UpdateCalendar command.
+ALTER TABLE `permissions` ADD `cmd_update_calendar` ENUM('0', '1') NOT NULL DEFAULT '0';
+INSERT INTO `emulator_texts` (`key`, `value`) VALUES ('commands.description.cmd_update_calendar', ':update_calendar'), ('commands.keys.cmd_update_calendar', 'update_calendar');
+INSERT INTO `emulator_texts` (`key`, `value`) VALUES ('commands.success.cmd_update_calendar', 'Calendar updated successfully!');
+
+-- add moodlight configuration
+INSERT INTO `emulator_settings` (`key`, `value`) VALUES ('moodlight.color_check.enabled', '1');
+
+-- Mannequin name
+INSERT INTO `emulator_texts` (`key`, `value`) VALUES ('hotel.mannequin.name.default', 'My look');
+
+-- RCON: Change Username
+INSERT INTO `emulator_texts` (`key`, `value`) VALUES ('rcon.alert.user.change_username', 'You can change your username. Click on yourself to change it.');
+
+-- Custom Stacking Setting
+INSERT INTO `emulator_texts` (`key`, `value`) VALUES ('custom.stacking.enabled', '0');
diff --git a/src/main/java/com/eu/habbo/Emulator.java b/src/main/java/com/eu/habbo/Emulator.java
index 33a46886..f156150e 100644
--- a/src/main/java/com/eu/habbo/Emulator.java
+++ b/src/main/java/com/eu/habbo/Emulator.java
@@ -32,11 +32,11 @@ import java.util.regex.Pattern;
public final class Emulator {
private static final Logger LOGGER = LoggerFactory.getLogger(Emulator.class);
- private static final String OS_NAME = System.getProperty("os.name");
- private static final String CLASS_PATH = System.getProperty("java.class.path");
+ 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");
public final static int MAJOR = 3;
- public final static int MINOR = 0;
+ public final static int MINOR = 5;
public final static int BUILD = 0;
public final static String PREVIEW = "";
@@ -115,12 +115,11 @@ public final class Emulator {
System.out.println("Warning, this is a beta build, this means that there may be unintended consequences so make sure you take regular backups while using this build. If you notice any issues you should make an issue on the Krews Git.");
promptEnterKey();
}
-
+ LOGGER.info("eek. Has it really been a year?");
LOGGER.info("This project is for educational purposes only. This Emulator is an open-source fork of Arcturus created by TheGeneral.");
LOGGER.info("Version: {}", version);
LOGGER.info("Build: {}", build);
- LOGGER.info("Remember to sign up your hotel to join our toplist beta at https://bit.ly/2NN0rxq");
- LOGGER.info("Join our discord at https://discord.gg/syuqgN");
+ LOGGER.info("Follow our development at https://git.krews.org/morningstar/Arcturus-Community");
long startTime = System.nanoTime();
@@ -170,31 +169,35 @@ public final class Emulator {
Emulator.timeStarted = getIntUnixTimestamp();
if (Emulator.getConfig().getInt("runtime.threads") < (Runtime.getRuntime().availableProcessors() * 2)) {
- LOGGER.warn("Emulator settings runtime.threads ({}) can be increased to {} to possibly increase performance.",
+ LOGGER.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);
- BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+ // Check if console mode is true or false, default is true
+ if (Emulator.getConfig().getBoolean("console.mode", true)) {
- while (!isShuttingDown && isReady) {
- try {
- String line = reader.readLine();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
- 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"))) {
- LOGGER.error("Error while reading command", e);
+ 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"))) {
+ LOGGER.error("Error while reading command", e);
+ }
}
}
}
+
} catch (Exception e) {
e.printStackTrace();
}
@@ -499,4 +502,4 @@ public final class Emulator {
public int getRoomCount() {
return gameEnvironment.getRoomManager().getActiveRooms().size();
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/eu/habbo/core/CleanerThread.java b/src/main/java/com/eu/habbo/core/CleanerThread.java
index 10dcc784..e9e2f122 100644
--- a/src/main/java/com/eu/habbo/core/CleanerThread.java
+++ b/src/main/java/com/eu/habbo/core/CleanerThread.java
@@ -5,6 +5,7 @@ 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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -146,6 +147,7 @@ public class CleanerThread implements Runnable {
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));
}
}
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/GameEnvironment.java b/src/main/java/com/eu/habbo/habbohotel/GameEnvironment.java
index a614cb05..7944ae8c 100644
--- a/src/main/java/com/eu/habbo/habbohotel/GameEnvironment.java
+++ b/src/main/java/com/eu/habbo/habbohotel/GameEnvironment.java
@@ -4,6 +4,7 @@ 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;
@@ -54,6 +55,7 @@ public class GameEnvironment {
private CraftingManager craftingManager;
private PollManager pollManager;
private SubscriptionManager subscriptionManager;
+ private CalendarManager calendarManager;
public void load() throws Exception {
LOGGER.info("GameEnvironment -> Loading...");
@@ -78,6 +80,7 @@ public class GameEnvironment {
this.wordFilter = new WordFilter();
this.craftingManager = new CraftingManager();
this.pollManager = new PollManager();
+ this.calendarManager = new CalendarManager();
this.roomManager.loadPublicRooms();
this.navigatorManager.loadNavigator();
@@ -114,6 +117,7 @@ public class GameEnvironment {
this.itemManager.dispose();
this.hotelViewManager.dispose();
this.subscriptionManager.dispose();
+ this.calendarManager.dispose();
LOGGER.info("GameEnvironment -> Disposed!");
}
@@ -206,4 +210,6 @@ public class GameEnvironment {
public SubscriptionManager getSubscriptionManager() {
return this.subscriptionManager;
}
+
+ public CalendarManager getCalendarManager() { return this.calendarManager; }
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/achievements/AchievementManager.java b/src/main/java/com/eu/habbo/habbohotel/achievements/AchievementManager.java
index 9de60de5..78304cd3 100644
--- a/src/main/java/com/eu/habbo/habbohotel/achievements/AchievementManager.java
+++ b/src/main/java/com/eu/habbo/habbohotel/achievements/AchievementManager.java
@@ -146,12 +146,17 @@ public class AchievementManager {
}
}
+ String newBadgCode = "ACH_" + achievement.name + newLevel.level;
+
if (badge != null) {
- badge.setCode("ACH_" + achievement.name + newLevel.level);
+ badge.setCode(newBadgCode);
badge.needsInsert(false);
badge.needsUpdate(true);
} else {
- badge = new HabboBadge(0, "ACH_" + achievement.name + newLevel.level, 0, habbo);
+ 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);
@@ -359,10 +364,12 @@ public class AchievementManager {
if (level.badges != null && level.badges.length > 0) {
for (String badge : level.badges) {
if (!badge.isEmpty()) {
- HabboBadge b = new HabboBadge(0, badge, 0, habbo);
- Emulator.getThreading().run(b);
- habbo.getInventory().getBadgesComponent().addBadge(b);
- habbo.getClient().sendResponse(new AddUserBadgeComposer(b));
+ 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));
+ }
}
}
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/bots/BotManager.java b/src/main/java/com/eu/habbo/habbohotel/bots/BotManager.java
index 9a8129ae..2eebcc6f 100644
--- a/src/main/java/com/eu/habbo/habbohotel/bots/BotManager.java
+++ b/src/main/java/com/eu/habbo/habbohotel/bots/BotManager.java
@@ -127,7 +127,7 @@ public class BotManager {
roomUnit.setRotation(RoomUserRotation.SOUTH);
roomUnit.setLocation(location);
- double stackHeight = room.getStackHeight(location.x, location.y, false);
+ double stackHeight = location.getStackHeight();
roomUnit.setPreviousLocationZ(stackHeight);
roomUnit.setZ(stackHeight);
diff --git a/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarCampaign.java b/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarCampaign.java
new file mode 100644
index 00000000..29733ddb
--- /dev/null
+++ b/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/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarManager.java b/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarManager.java
new file mode 100644
index 00000000..1336f88f
--- /dev/null
+++ b/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarManager.java
@@ -0,0 +1,154 @@
+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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.*;
+import java.util.*;
+import java.util.Date;
+
+import static java.time.temporal.ChronoUnit.DAYS;
+
+
+public class CalendarManager {
+ private static final Logger LOGGER = LoggerFactory.getLogger(CalendarCampaign.class);
+
+ final private static Map calendarCampaigns = new THashMap<>();
+ public static double HC_MODIFIER;
+
+ public CalendarManager() {
+ long millis = System.currentTimeMillis();
+ this.reload();
+ LOGGER.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) {
+ LOGGER.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) {
+ LOGGER.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) {
+ LOGGER.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) {
+ LOGGER.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) {
+ LOGGER.error("Caught SQL exception", e);
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardClaimed.java b/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardClaimed.java
new file mode 100644
index 00000000..7b6a1837
--- /dev/null
+++ b/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/src/main/java/com/eu/habbo/habbohotel/catalog/CalendarRewardObject.java b/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardObject.java
similarity index 59%
rename from src/main/java/com/eu/habbo/habbohotel/catalog/CalendarRewardObject.java
rename to src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardObject.java
index f2b135b5..efe8f91d 100644
--- a/src/main/java/com/eu/habbo/habbohotel/catalog/CalendarRewardObject.java
+++ b/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardObject.java
@@ -1,32 +1,47 @@
-package com.eu.habbo.habbohotel.catalog;
+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) {
@@ -34,6 +49,10 @@ public class CalendarRewardObject {
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);
}
@@ -42,6 +61,14 @@ public class CalendarRewardObject {
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();
@@ -71,6 +98,9 @@ public class CalendarRewardObject {
return this.credits;
}
+ public int getPixels() {
+ return this.pixels;
+ }
public int getPoints() {
return this.points;
}
@@ -79,6 +109,18 @@ public class CalendarRewardObject {
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;
}
@@ -86,4 +128,5 @@ public class CalendarRewardObject {
public Item getItem() {
return Emulator.getGameEnvironment().getItemManager().getItem(this.itemId);
}
+
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java b/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java
index 6e7908c2..65d05d0d 100644
--- a/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java
+++ b/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java
@@ -3,6 +3,7 @@ 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;
@@ -167,6 +168,15 @@ public class CatalogManager {
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);
@@ -190,7 +200,6 @@ public class CatalogManager {
public final TIntIntHashMap offerDefs;
public final Item ecotronItem;
public final THashMap limitedNumbers;
- public final THashMap calendarRewards;
private final List vouchers;
public CatalogManager() {
@@ -207,7 +216,6 @@ public class CatalogManager {
this.offerDefs = new TIntIntHashMap();
this.vouchers = new ArrayList<>();
this.limitedNumbers = new THashMap<>();
- this.calendarRewards = new THashMap<>();
this.initialize();
@@ -230,7 +238,6 @@ public class CatalogManager {
this.loadClothing();
this.loadRecycler();
this.loadGiftWrappers();
- this.loadCalendarRewards();
}
private synchronized void loadLimitedNumbers() {
@@ -482,23 +489,6 @@ public class CatalogManager {
}
}
- private void loadCalendarRewards() {
- synchronized (this.calendarRewards) {
- this.calendarRewards.clear();
-
- try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM calendar_rewards")) {
- try (ResultSet set = statement.executeQuery()) {
- while (set.next()) {
- this.calendarRewards.put(set.getInt("id"), new CalendarRewardObject(set));
- }
- }
- } catch (SQLException e) {
- LOGGER.error("Caught SQL exception", e);
- }
- }
- }
-
-
private void loadClothing() {
synchronized (this.clothing) {
this.clothing.clear();
@@ -523,7 +513,6 @@ public class CatalogManager {
return null;
}
-
public Voucher getVoucher(String code) {
synchronized (this.vouchers) {
for (Voucher voucher : this.vouchers) {
@@ -535,22 +524,20 @@ public class CatalogManager {
return null;
}
-
public void redeemVoucher(GameClient client, String voucherCode) {
- Voucher voucher = Emulator.getGameEnvironment().getCatalogManager().getVoucher(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;
}
- Habbo habbo = client.getHabbo();
- if (habbo == null) return;
-
if (voucher.isExhausted()) {
- if (!Emulator.getGameEnvironment().getCatalogManager().deleteVoucher(voucher)) {
- client.sendResponse(new RedeemVoucherErrorComposer(RedeemVoucherErrorComposer.TECHNICAL_ERROR));
- }
+ client.sendResponse(new RedeemVoucherErrorComposer(Emulator.getGameEnvironment().getCatalogManager().deleteVoucher(voucher) ? RedeemVoucherErrorComposer.INVALID_CODE : RedeemVoucherErrorComposer.TECHNICAL_ERROR));
+ return;
}
if (voucher.hasUserExhausted(habbo.getHabboInfo().getId())) {
@@ -560,12 +547,6 @@ public class CatalogManager {
voucher.addHistoryEntry(habbo.getHabboInfo().getId());
- if (voucher.isExhausted()) {
- if (!Emulator.getGameEnvironment().getCatalogManager().deleteVoucher(voucher)) {
- client.sendResponse(new RedeemVoucherErrorComposer(RedeemVoucherErrorComposer.TECHNICAL_ERROR));
- }
- }
-
if (voucher.points > 0) {
client.getHabbo().getHabboInfo().addCurrencyAmount(voucher.pointsType, voucher.points);
client.sendResponse(new UserPointsComposer(client.getHabbo().getHabboInfo().getCurrencyAmount(voucher.pointsType), voucher.points, voucher.pointsType));
@@ -578,7 +559,6 @@ public class CatalogManager {
if (voucher.catalogItemId > 0) {
CatalogItem item = this.getCatalogItem(voucher.catalogItemId);
-
if (item != null) {
this.purchaseItem(null, item, client.getHabbo(), 1, "", true);
}
@@ -587,7 +567,6 @@ public class CatalogManager {
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);
@@ -1013,6 +992,10 @@ public class CatalogManager {
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);
}
@@ -1079,12 +1062,9 @@ public class CatalogManager {
}
}
- if (badgeFound) {
+ if (badgeFound && item.getBaseItems().size() == 1) {
habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.ALREADY_HAVE_BADGE));
-
- if (item.getBaseItems().size() == 1) {
return;
- }
}
UserCatalogItemPurchasedEvent purchasedEvent = new UserCatalogItemPurchasedEvent(habbo, item, itemsList, totalCredits, totalPoints, badges);
@@ -1181,28 +1161,6 @@ public class CatalogManager {
return offers;
}
- public void claimCalendarReward(Habbo habbo, int day, boolean force) {
- if (!habbo.getHabboStats().calendarRewardsClaimed.contains(day)) {
- CalendarRewardObject object = this.calendarRewards.get((day+1));
- int actualDay = (int) Math.floor((Emulator.getIntUnixTimestamp() - Emulator.getConfig().getInt("hotel.calendar.starttimestamp")) / 86400);
- int diff = (actualDay - day);
- if (((diff <= 2 && diff >= 0) || force) && object != null) {
- habbo.getHabboStats().calendarRewardsClaimed.add(day);
- habbo.getClient().sendResponse(new AdventCalendarProductComposer(true, object));
- object.give(habbo);
-
- try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO calendar_rewards_claimed (user_id, reward_id, timestamp) VALUES (?, ?, ?)")) {
- statement.setInt(1, habbo.getHabboInfo().getId());
- statement.setInt(2, day);
- statement.setInt(3, Emulator.getIntUnixTimestamp());
- statement.execute();
- } catch (SQLException e) {
- LOGGER.error("Caught SQL exception", e);
- }
- }
- }
- }
-
public TargetOffer getTargetOffer(int offerId) {
return this.targetOffers.get(offerId);
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPageLayouts.java b/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPageLayouts.java
index 9a8df100..ff6d01aa 100644
--- a/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPageLayouts.java
+++ b/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogPageLayouts.java
@@ -3,114 +3,45 @@ 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
+ builders_club_loyalty,
+ monkey,
+ niko,
+ mad_money
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/catalog/Voucher.java b/src/main/java/com/eu/habbo/habbohotel/catalog/Voucher.java
index b5e93b13..468e2a2b 100644
--- a/src/main/java/com/eu/habbo/habbohotel/catalog/Voucher.java
+++ b/src/main/java/com/eu/habbo/habbohotel/catalog/Voucher.java
@@ -38,7 +38,8 @@ public class Voucher {
}
private void loadHistory() {
- try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM voucher_history")) {
+ 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));
diff --git a/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoMonkeyLayout.java b/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoMonkeyLayout.java
new file mode 100644
index 00000000..1de28f58
--- /dev/null
+++ b/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/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoNikoLayout.java b/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/InfoNikoLayout.java
new file mode 100644
index 00000000..f6cd5160
--- /dev/null
+++ b/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/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/MadMoneyLayout.java b/src/main/java/com/eu/habbo/habbohotel/catalog/layouts/MadMoneyLayout.java
new file mode 100644
index 00000000..7e73ce19
--- /dev/null
+++ b/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/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlace.java b/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlace.java
index 031ff4f6..ec8dadfb 100644
--- a/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlace.java
+++ b/src/main/java/com/eu/habbo/habbohotel/catalog/marketplace/MarketPlace.java
@@ -67,7 +67,7 @@ public class MarketPlace {
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 = ?")) {
+ 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();
@@ -122,7 +122,7 @@ public class MarketPlace {
query += " AND CEIL(price + (price / 100)) <= " + maxPrice;
}
if (search.length() > 0) {
- query += " AND bi.public_name LIKE ? OR ci.catalog_name LIKE ?";
+ query += " AND ( bi.public_name LIKE ? OR ci.catalog_name LIKE ? ) ";
}
query += " GROUP BY base_item_id, ltd_data";
@@ -177,7 +177,7 @@ public class MarketPlace {
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))")) {
+ 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));
@@ -206,7 +206,7 @@ public class MarketPlace {
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 = ?")) {
+ 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()) {
@@ -223,7 +223,7 @@ public class MarketPlace {
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 = ?")) {
+ 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);
@@ -246,7 +246,7 @@ public class MarketPlace {
statement.setInt(1, offerId);
try (ResultSet set = statement.executeQuery()) {
if (set.next()) {
- try (PreparedStatement itemStatement = connection.prepareStatement("SELECT * FROM items WHERE id = ? LIMIT 1")) {
+ 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();
@@ -315,7 +315,7 @@ public class MarketPlace {
"FROM items_base\n" +
"WHERE items_base.id = ? LIMIT 1)\n" +
"ORDER BY price ASC\n" +
- "LIMIT 1")) {
+ "LIMIT 1", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) {
statement.setInt(1, baseItemId);
try (ResultSet countSet = statement.executeQuery()) {
countSet.last();
diff --git a/src/main/java/com/eu/habbo/habbohotel/commands/CalendarCommand.java b/src/main/java/com/eu/habbo/habbohotel/commands/CalendarCommand.java
index 5d996740..dd2a773f 100644
--- a/src/main/java/com/eu/habbo/habbohotel/commands/CalendarCommand.java
+++ b/src/main/java/com/eu/habbo/habbohotel/commands/CalendarCommand.java
@@ -1,10 +1,17 @@
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(";"));
@@ -13,8 +20,17 @@ public class CalendarCommand extends Command {
@Override
public boolean handle(GameClient gameClient, String[] params) throws Exception {
if (Emulator.getConfig().getBoolean("hotel.calendar.enabled")) {
- gameClient.sendResponse(new AdventCalendarDataComposer("xmas11", Emulator.getGameEnvironment().getCatalogManager().calendarRewards.size(), (int) Math.floor((Emulator.getIntUnixTimestamp() - Emulator.getConfig().getInt("hotel.calendar.starttimestamp")) / 86400), gameClient.getHabbo().getHabboStats().calendarRewardsClaimed, true));
- gameClient.sendResponse(new NuxAlertComposer("openView/calendar"));
+ 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/src/main/java/com/eu/habbo/habbohotel/commands/CommandHandler.java b/src/main/java/com/eu/habbo/habbohotel/commands/CommandHandler.java
index a37d9482..64dd09d8 100644
--- a/src/main/java/com/eu/habbo/habbohotel/commands/CommandHandler.java
+++ b/src/main/java/com/eu/habbo/habbohotel/commands/CommandHandler.java
@@ -275,6 +275,7 @@ public class CommandHandler {
addCommand(new UnmuteCommand());
addCommand(new UpdateAchievements());
addCommand(new UpdateBotsCommand());
+ addCommand(new UpdateCalendarCommand());
addCommand(new UpdateCatalogCommand());
addCommand(new UpdateConfigCommand());
addCommand(new UpdateGuildPartsCommand());
diff --git a/src/main/java/com/eu/habbo/habbohotel/commands/EmptyInventoryCommand.java b/src/main/java/com/eu/habbo/habbohotel/commands/EmptyInventoryCommand.java
index 779dd3e5..66af755a 100644
--- a/src/main/java/com/eu/habbo/habbohotel/commands/EmptyInventoryCommand.java
+++ b/src/main/java/com/eu/habbo/habbohotel/commands/EmptyInventoryCommand.java
@@ -43,6 +43,7 @@ public class EmptyInventoryCommand extends Command {
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 {
diff --git a/src/main/java/com/eu/habbo/habbohotel/commands/RedeemCommand.java b/src/main/java/com/eu/habbo/habbohotel/commands/RedeemCommand.java
index 21db5c7f..9d389474 100644
--- a/src/main/java/com/eu/habbo/habbohotel/commands/RedeemCommand.java
+++ b/src/main/java/com/eu/habbo/habbohotel/commands/RedeemCommand.java
@@ -51,6 +51,15 @@ public class RedeemCommand extends Command {
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);
}
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/commands/SoftKickCommand.java b/src/main/java/com/eu/habbo/habbohotel/commands/SoftKickCommand.java
index c89ab075..b841b945 100644
--- a/src/main/java/com/eu/habbo/habbohotel/commands/SoftKickCommand.java
+++ b/src/main/java/com/eu/habbo/habbohotel/commands/SoftKickCommand.java
@@ -2,6 +2,7 @@ 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;
@@ -30,7 +31,9 @@ public class SoftKickCommand extends Command {
final Room room = gameClient.getHabbo().getHabboInfo().getCurrentRoom();
if (room != null) {
- room.kickHabbo(habbo, false);
+ if (!(habbo.hasPermission(Permission.ACC_UNKICKABLE) || habbo.hasPermission(Permission.ACC_SUPPORTTOOL) || room.isOwner(habbo))) {
+ room.kickHabbo(habbo, false);
+ }
}
}
return true;
diff --git a/src/main/java/com/eu/habbo/habbohotel/commands/StalkCommand.java b/src/main/java/com/eu/habbo/habbohotel/commands/StalkCommand.java
index 31312dd7..de6bde54 100644
--- a/src/main/java/com/eu/habbo/habbohotel/commands/StalkCommand.java
+++ b/src/main/java/com/eu/habbo/habbohotel/commands/StalkCommand.java
@@ -43,7 +43,7 @@ public class StalkCommand extends Command {
//gameClient.sendResponse(new ForwardToRoomComposer(habbo.getHabboInfo().getCurrentRoom().getId()));
return true;
} else {
- gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_summon.forgot_username"), RoomChatMessageBubbles.ALERT);
+ gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_stalk.forgot_username"), RoomChatMessageBubbles.ALERT);
return true;
}
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/commands/SummonCommand.java b/src/main/java/com/eu/habbo/habbohotel/commands/SummonCommand.java
index 727d3fe2..b362f5a4 100644
--- a/src/main/java/com/eu/habbo/habbohotel/commands/SummonCommand.java
+++ b/src/main/java/com/eu/habbo/habbohotel/commands/SummonCommand.java
@@ -2,11 +2,10 @@ 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.rooms.RoomTile;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.messages.outgoing.rooms.ForwardToRoomComposer;
-import com.eu.habbo.messages.outgoing.rooms.HideDoorbellComposer;
public class SummonCommand extends Command {
public SummonCommand() {
@@ -36,22 +35,21 @@ public class SummonCommand extends Command {
return true;
}
- gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.generic.cmd_summon.summoning").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT);
+ Room room = habbo.getHabboInfo().getCurrentRoom();
+ if (room != null) {
+ Emulator.getGameEnvironment().getRoomManager().logExit(habbo);
- Emulator.getGameEnvironment().getRoomManager().leaveRoom(habbo, habbo.getHabboInfo().getCurrentRoom());
+ 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()));
- Emulator.getGameEnvironment().getRoomManager().enterRoom(habbo, gameClient.getHabbo().getHabboInfo().getCurrentRoom().getId(), "", true);
- habbo.getClient().sendResponse(new HideDoorbellComposer(""));
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_summon.summoned").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT);
- RoomTile t = gameClient.getHabbo().getHabboInfo().getCurrentRoom().getLayout().getTileInFront(gameClient.getHabbo().getRoomUnit().getCurrentLocation(), gameClient.getHabbo().getRoomUnit().getBodyRotation().getValue());
-
- if (t != null && gameClient.getHabbo().getHabboInfo().getCurrentRoom().tileWalkable(t)) {
- habbo.getRoomUnit().setGoalLocation(t);
- }
-
habbo.alert(Emulator.getTexts().getValue("commands.generic.cmd_summon.been_summoned").replace("%user%", gameClient.getHabbo().getHabboInfo().getUsername()));
return true;
diff --git a/src/main/java/com/eu/habbo/habbohotel/commands/SummonRankCommand.java b/src/main/java/com/eu/habbo/habbohotel/commands/SummonRankCommand.java
index 8dd8a070..16312bd5 100644
--- a/src/main/java/com/eu/habbo/habbohotel/commands/SummonRankCommand.java
+++ b/src/main/java/com/eu/habbo/habbohotel/commands/SummonRankCommand.java
@@ -2,6 +2,7 @@ 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;
@@ -19,7 +20,7 @@ public class SummonRankCommand extends Command {
if (params.length >= 2) {
try {
- minRank = Integer.valueOf(params[1]);
+ minRank = Integer.parseInt(params[1]);
} catch (Exception e) {
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.generic.cmd_summonrank.error"), RoomChatMessageBubbles.ALERT);
return true;
@@ -33,9 +34,19 @@ public class SummonRankCommand extends Command {
if (set.getValue().getHabboInfo().getCurrentRoom() == gameClient.getHabbo().getHabboInfo().getCurrentRoom())
continue;
- Emulator.getGameEnvironment().getRoomManager().leaveRoom(set.getValue(), set.getValue().getHabboInfo().getCurrentRoom());
- set.getValue().getClient().sendResponse(new ForwardToRoomComposer(gameClient.getHabbo().getHabboInfo().getCurrentRoom().getId()));
+ 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()));
+
}
}
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/commands/TakeBadgeCommand.java b/src/main/java/com/eu/habbo/habbohotel/commands/TakeBadgeCommand.java
index 8241d517..2afe3bb3 100644
--- a/src/main/java/com/eu/habbo/habbohotel/commands/TakeBadgeCommand.java
+++ b/src/main/java/com/eu/habbo/habbohotel/commands/TakeBadgeCommand.java
@@ -5,6 +5,8 @@ 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;
@@ -44,9 +46,21 @@ public class TakeBadgeCommand extends Command {
}
}
- gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_take_badge"), RoomChatMessageBubbles.ALERT);
+ int userId = 0;
- BadgesComponent.deleteBadge(username, badge);
+ 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;
diff --git a/src/main/java/com/eu/habbo/habbohotel/commands/UpdateCalendarCommand.java b/src/main/java/com/eu/habbo/habbohotel/commands/UpdateCalendarCommand.java
new file mode 100644
index 00000000..a110c20b
--- /dev/null
+++ b/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/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGame.java b/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGame.java
index b2ee6dcf..c14f6408 100644
--- a/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGame.java
+++ b/src/main/java/com/eu/habbo/habbohotel/games/battlebanzai/BattleBanzaiGame.java
@@ -203,8 +203,9 @@ public class BattleBanzaiGame extends Game {
item.setExtradata((6 + winningTeam.teamColor.type) + "");
this.room.updateItemState(item);
}
-
- Emulator.getThreading().run(new BattleBanzaiTilesFlicker(this.lockedTiles.get(winningTeam.teamColor), winningTeam.teamColor, this.room));
+ synchronized (this.lockedTiles) {
+ Emulator.getThreading().run(new BattleBanzaiTilesFlicker(this.lockedTiles.get(winningTeam.teamColor), winningTeam.teamColor, this.room));
+ }
}
super.onEnd();
@@ -222,7 +223,9 @@ public class BattleBanzaiGame extends Game {
this.room.updateItem(tile);
}
}
- this.lockedTiles.clear();
+ synchronized (this.lockedTiles) {
+ this.lockedTiles.clear();
+ }
}
@@ -249,52 +252,54 @@ public class BattleBanzaiGame extends Game {
}
public void tileLocked(GameTeamColors teamColor, HabboItem item, Habbo habbo, boolean doNotCheckFill) {
- 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);
- });
+ synchronized (this.lockedTiles) {
+ if (item instanceof InteractionBattleBanzaiTile) {
+ if (!this.lockedTiles.containsKey(teamColor)) {
+ this.lockedTiles.put(teamColor, new THashSet<>());
}
- this.refreshCounters(teamColor);
- if (habbo != null) {
- habbo.getHabboInfo().getGamePlayer().addScore(BattleBanzaiGame.POINTS_LOCK_TILE * largestAreaOfAll.get().size());
- }
+ 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) {
diff --git a/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumThreadState.java b/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumThreadState.java
index 4e044b98..2e57039e 100644
--- a/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumThreadState.java
+++ b/src/main/java/com/eu/habbo/habbohotel/guilds/forums/ForumThreadState.java
@@ -3,8 +3,8 @@ package com.eu.habbo.habbohotel.guilds.forums;
public enum ForumThreadState {
OPEN(0),
CLOSED(1),
- HIDDEN_BY_ADMIN(10),
- HIDDEN_BY_STAFF(20);
+ HIDDEN_BY_STAFF_MEMBER(10),
+ HIDDEN_BY_GUILD_ADMIN(20);
private int stateId;
diff --git a/src/main/java/com/eu/habbo/habbohotel/items/ItemManager.java b/src/main/java/com/eu/habbo/habbohotel/items/ItemManager.java
index f702d68c..16ec285d 100644
--- a/src/main/java/com/eu/habbo/habbohotel/items/ItemManager.java
+++ b/src/main/java/com/eu/habbo/habbohotel/items/ItemManager.java
@@ -161,6 +161,7 @@ public class ItemManager {
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));
@@ -179,6 +180,7 @@ public class ItemManager {
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));
diff --git a/src/main/java/com/eu/habbo/habbohotel/items/YoutubeManager.java b/src/main/java/com/eu/habbo/habbohotel/items/YoutubeManager.java
index 3be71726..a383541a 100644
--- a/src/main/java/com/eu/habbo/habbohotel/items/YoutubeManager.java
+++ b/src/main/java/com/eu/habbo/habbohotel/items/YoutubeManager.java
@@ -11,10 +11,12 @@ import org.slf4j.LoggerFactory;
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;
@@ -23,7 +25,7 @@ import java.util.concurrent.TimeUnit;
public class YoutubeManager {
private static final Logger LOGGER = LoggerFactory.getLogger(YoutubeManager.class);
- public class YoutubeVideo {
+ public static class YoutubeVideo {
private final String id;
private final int duration;
@@ -41,7 +43,7 @@ public class YoutubeManager {
}
}
- public class YoutubePlaylist {
+ public static class YoutubePlaylist {
private final String id;
private final String name;
private final String description;
@@ -71,8 +73,9 @@ public class YoutubeManager {
}
}
- private THashMap> playlists = new THashMap<>();
- private THashMap playlistCache = new THashMap<>();
+ 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();
@@ -94,11 +97,15 @@ public class YoutubeManager {
youtubeDataLoaderPool.submit(() -> {
ArrayList playlists = this.playlists.getOrDefault(itemId, new ArrayList<>());
- YoutubePlaylist playlist = this.getPlaylistDataById(playlistId);
- if (playlist != null) {
- playlists.add(playlist);
- } else {
- LOGGER.error("Failed to load YouTube playlist: " + playlistId);
+ YoutubePlaylist playlist;
+
+ try {
+ playlist = this.getPlaylistDataById(playlistId);
+ if (playlist != null) {
+ playlists.add(playlist);
+ }
+ } catch (IOException e) {
+ LOGGER.error("Failed to load YouTube playlist {} ERROR: {}", playlistId, e);
}
this.playlists.put(itemId, playlists);
@@ -120,56 +127,102 @@ public class YoutubeManager {
});
}
- public YoutubePlaylist getPlaylistDataById(String playlistId) {
+ public YoutubePlaylist getPlaylistDataById(String playlistId) throws IOException {
if (this.playlistCache.containsKey(playlistId)) return this.playlistCache.get(playlistId);
+ if(apiKey.isEmpty()) return null;
- try {
- URL myUrl = new URL("https://www.youtube.com/playlist?list=" + playlistId);
+ 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();
+ LOGGER.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);
- HttpsURLConnection conn = (HttpsURLConnection) myUrl.openConnection();
- conn.setRequestProperty("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
- conn.setRequestProperty("accept-language", "en-GB,en-US;q=0.9,en;q=0.8");
- conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3731.0 Safari/537.36");
+ JsonObject playlistData = JsonParser.parseReader(playlistBR).getAsJsonObject();
- InputStream is = conn.getInputStream();
- InputStreamReader isr = new InputStreamReader(is);
- YoutubePlaylist playlist;
- try (BufferedReader br = new BufferedReader(isr)) {
- playlist = null;
- String inputLine;
- while ((inputLine = br.readLine()) != null) {
- if (inputLine.contains("window[\"ytInitialData\"]")) {
- JsonObject obj = new JsonParser().parse(inputLine.substring(inputLine.indexOf("{")).replace(";", "")).getAsJsonObject();
-
- JsonObject meta = obj.get("microformat").getAsJsonObject().get("microformatDataRenderer").getAsJsonObject();
- String name = meta.get("title").getAsString();
- String description = meta.get("description").getAsString();
-
- ArrayList videos = new ArrayList<>();
-
- JsonArray rawVideos = obj.get("contents").getAsJsonObject().get("twoColumnBrowseResultsRenderer").getAsJsonObject().get("tabs").getAsJsonArray().get(0).getAsJsonObject().get("tabRenderer").getAsJsonObject().get("content").getAsJsonObject().get("sectionListRenderer").getAsJsonObject().get("contents").getAsJsonArray().get(0).getAsJsonObject().get("itemSectionRenderer").getAsJsonObject().get("contents").getAsJsonArray().get(0).getAsJsonObject().get("playlistVideoListRenderer").getAsJsonObject().get("contents").getAsJsonArray();
-
- for (JsonElement rawVideo : rawVideos) {
- JsonObject videoData = rawVideo.getAsJsonObject().get("playlistVideoRenderer").getAsJsonObject();
- if (!videoData.has("lengthSeconds")) continue; // removed videos
- videos.add(new YoutubeVideo(videoData.get("videoId").getAsString(), Integer.valueOf(videoData.get("lengthSeconds").getAsString())));
- }
-
- playlist = new YoutubePlaylist(playlistId, name, description, videos);
-
- break;
- }
- }
+ JsonArray playlists = playlistData.get("items").getAsJsonArray();
+ if (playlists.size() == 0) {
+ LOGGER.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);
}
- this.playlistCache.put(playlistId, playlist);
+ HttpsURLConnection con = (HttpsURLConnection) playlistItems.openConnection();
- return playlist;
- } catch (java.io.IOException e) {
- e.printStackTrace();
+ 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()) {
+ LOGGER.warn("Playlist {} has no videos!", playlistId);
+ return null;
}
+ playlist = new YoutubePlaylist(playlistId, name, description, videos);
+
+ this.playlistCache.put(playlistId, playlist);
+
+ return playlist;
- return null;
}
public ArrayList getPlaylistsForItemId(int itemId) {
diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBuildArea.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBuildArea.java
new file mode 100644
index 00000000..015ab451
--- /dev/null
+++ b/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/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionColorWheel.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionColorWheel.java
index 55c896fa..8105464c 100644
--- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionColorWheel.java
+++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionColorWheel.java
@@ -49,7 +49,7 @@ public class InteractionColorWheel extends HabboItem {
if (!room.hasRights(client.getHabbo()))
return;
- if (this.rollTaks == null) {
+ if (this.rollTaks == null && !this.getExtradata().equalsIgnoreCase("-1")) {
this.setExtradata("-1");
room.sendComposer(new WallItemUpdateComposer(this).compose());
Emulator.getThreading().run(this);
diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCrackable.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCrackable.java
index af65156c..1cc34bfc 100644
--- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCrackable.java
+++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCrackable.java
@@ -101,6 +101,11 @@ public class InteractionCrackable extends HabboItem {
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);
diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCustomValues.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCustomValues.java
index 9ef005bc..5a275c28 100644
--- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCustomValues.java
+++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCustomValues.java
@@ -80,7 +80,7 @@ public abstract class InteractionCustomValues extends HabboItem {
super.serializeExtradata(serverMessage);
}
- public void onCustomValuesSaved(Room room, GameClient client) {
+ public void onCustomValuesSaved(Room room, GameClient client, THashMap oldValues) {
}
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectVendingMachineNoSides.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionEffectVendingMachineNoSides.java
new file mode 100644
index 00000000..799c2116
--- /dev/null
+++ b/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/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMuteArea.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMuteArea.java
index 29a7c0ac..beed1131 100644
--- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMuteArea.java
+++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMuteArea.java
@@ -17,7 +17,6 @@ import gnu.trove.map.hash.THashMap;
import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.set.hash.THashSet;
-import java.awt.*;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -125,8 +124,8 @@ public class InteractionMuteArea extends InteractionCustomValues {
}
@Override
- public void onCustomValuesSaved(Room room, GameClient client) {
- super.onCustomValuesSaved(room, client);
+ public void onCustomValuesSaved(Room room, GameClient client, THashMap oldValues) {
+ super.onCustomValuesSaved(room, client, oldValues);
this.regenAffectedTiles(room);
diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPressurePlate.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPressurePlate.java
index 06d19289..b446e6f4 100644
--- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPressurePlate.java
+++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionPressurePlate.java
@@ -37,7 +37,7 @@ public class InteractionPressurePlate extends InteractionDefault {
@Override
public void onClick(GameClient client, Room room, Object[] objects) throws Exception {
- super.onClick(client, room, objects);
+
}
@Override
@@ -66,6 +66,11 @@ public class InteractionPressurePlate extends InteractionDefault {
updateState(room);
}
+ @Override
+ public void onPickUp(Room room) {
+ this.setExtradata("0");
+ }
+
public void updateState(Room room) {
boolean occupied = false;
diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTrap.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTrap.java
index 54b9baaa..cf740699 100644
--- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTrap.java
+++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionTrap.java
@@ -22,40 +22,40 @@ public class InteractionTrap extends InteractionDefault {
@Override
public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception {
- super.onWalkOn(roomUnit, room, objects);
+ if (!this.getExtradata().equals("0")) {
+ Habbo habbo = room.getHabbo(roomUnit);
+ 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 (!this.getExtradata().equals("1"))
- return;
+ if (roomUnit != null) {
+ if (this.getBaseItem().getEffectF() > 0 || this.getBaseItem().getEffectM() > 0) {
+ if (roomUnit.getRoomUnitType().equals(RoomUnitType.USER)) {
- int delay = Emulator.getConfig().getInt("hotel.item.trap." + this.getBaseItem().getName());
+ 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 (delay == 0) {
- Emulator.getConfig().register("hotel.item.trap." + this.getBaseItem().getName(), "3000");
- delay = 3000;
- }
+ 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;
+ }
- 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;
+ roomUnit.setCanWalk(false);
+ Emulator.getThreading().run(() -> {
+ room.giveEffect(roomUnit, 0, -1);
+ roomUnit.setCanWalk(true);
+ room.giveEffect(roomUnit, effect, -1);
+ }, delay);
}
-
- 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);
- }, delay);
}
}
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWired.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWired.java
index c19b1ec9..8a8f1e7f 100644
--- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWired.java
+++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWired.java
@@ -4,9 +4,9 @@ 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.HabboItem;
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;
@@ -18,6 +18,7 @@ import java.sql.SQLException;
public abstract class InteractionWired extends InteractionDefault {
private static final Logger LOGGER = LoggerFactory.getLogger(InteractionWired.class);
private long cooldown;
+ private TLongLongHashMap userExecutionCache = new TLongLongHashMap(3);
InteractionWired(ResultSet set, Item baseItem) throws SQLException {
super(set, baseItem);
@@ -69,10 +70,16 @@ public abstract class InteractionWired extends InteractionDefault {
public abstract void onPickUp();
public void activateBox(Room room) {
- this.setExtradata(this.getExtradata().equals("1") ? "0" : "1");
- room.sendComposer(new ItemStateComposer(this).compose());
+ this.activateBox(room, (RoomUnit)null, 0L);
}
+ public void activateBox(Room room, RoomUnit roomUnit, long millis) {
+ 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;
@@ -96,4 +103,27 @@ public abstract class InteractionWired extends InteractionDefault {
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 < 100L) {
+ 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/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredHighscore.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredHighscore.java
index 8fb95dd4..6c8be89c 100644
--- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredHighscore.java
+++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionWiredHighscore.java
@@ -110,15 +110,23 @@ public class InteractionWiredHighscore extends HabboItem {
serverMessage.appendInt(this.clearType.type);
if (this.data != null) {
- serverMessage.appendInt(this.data.size());
+ int size = this.data.size();
+ if(size > 50) {
+ size = 50;
+ }
+ serverMessage.appendInt(size);
+ int count = 0;
for (WiredHighscoreRow row : this.data) {
- serverMessage.appendInt(row.getValue());
+ if(count < 50) {
+ serverMessage.appendInt(row.getValue());
- serverMessage.appendInt(row.getUsers().size());
- for (String username : row.getUsers()) {
- serverMessage.appendString(username);
+ serverMessage.appendInt(row.getUsers().size());
+ for (String username : row.getUsers()) {
+ serverMessage.appendString(username);
+ }
}
+ count++;
}
} else {
serverMessage.appendInt(0);
diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionFootball.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionFootball.java
index f64b0ade..6bd21167 100644
--- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionFootball.java
+++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionFootball.java
@@ -12,6 +12,7 @@ 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;
@@ -151,7 +152,44 @@ public class InteractionFootball extends InteractionPushable {
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);
- return (topItem == null || topItem.getBaseItem().allowStack());
+
+ // 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
diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTriggerOnFurni.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTriggerOnFurni.java
index 250d4751..61e3fd70 100644
--- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTriggerOnFurni.java
+++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/conditions/WiredConditionTriggerOnFurni.java
@@ -46,28 +46,8 @@ public class WiredConditionTriggerOnFurni extends InteractionWiredCondition {
}
protected boolean triggerOnFurni(RoomUnit roomUnit, Room room) {
- /*
- * 1. If a Habbo IS NOT walking we only have to check if the Habbo is on one of the selected tiles.
- * 2. If a Habbo IS walking we have to check if the next tile in the walking path is one of the selected items
- * */
- if (!roomUnit.isWalking()) {
- THashSet itemsAtUser = room.getItemsAt(roomUnit.getCurrentLocation());
- return this.items.stream().anyMatch(itemsAtUser::contains);
- } else {
- RoomTile firstTileInPath = room.getLayout()
- .findPath(roomUnit.getCurrentLocation(), roomUnit.getGoal(), roomUnit.getGoal(), roomUnit)
- .peek();
-
- if (firstTileInPath == null)
- return false;
-
- return this.items
- .stream()
- .anyMatch(conditionItem -> conditionItem
- .getOccupyingTiles(room.getLayout())
- .contains(firstTileInPath)
- );
- }
+ THashSet itemsAtUser = room.getItemsAt(roomUnit.getCurrentLocation());
+ return this.items.stream().anyMatch(itemsAtUser::contains);
}
@Override
diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScore.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScore.java
index 5a326356..6632c2e4 100644
--- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScore.java
+++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectGiveScore.java
@@ -52,15 +52,19 @@ public class WiredEffectGiveScore extends InteractionWiredEffect {
if (game == null)
return false;
- TObjectIntIterator> iterator = this.data.iterator();
+ int gameStartTime = game.getStartTime();
- for (int i = this.data.size(); i-- > 0; ) {
+ 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() == game.getStartTime()) {
+ if (map.getKey() == gameStartTime) {
if (iterator.value() < this.count) {
iterator.setValue(iterator.value() + 1);
@@ -74,7 +78,13 @@ public class WiredEffectGiveScore extends InteractionWiredEffect {
}
}
- this.data.put(new AbstractMap.SimpleEntry<>(game.getStartTime(), habbo.getHabboInfo().getId()), 1);
+ 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);
diff --git a/src/main/java/com/eu/habbo/habbohotel/messenger/Messenger.java b/src/main/java/com/eu/habbo/habbohotel/messenger/Messenger.java
index db3c357c..fa4603cf 100644
--- a/src/main/java/com/eu/habbo/habbohotel/messenger/Messenger.java
+++ b/src/main/java/com/eu/habbo/habbohotel/messenger/Messenger.java
@@ -65,6 +65,11 @@ public class Messenger {
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;
@@ -297,7 +302,7 @@ public class Messenger {
buddy.setLook(owner.getHabboInfo().getLook());
buddy.setGender(owner.getHabboInfo().getGender());
buddy.setUsername(owner.getHabboInfo().getUsername());
- habbo.getClient().sendResponse(new UpdateFriendComposer(buddy));
+ habbo.getClient().sendResponse(new UpdateFriendComposer(habbo, buddy, 0));
}
}
}
@@ -363,12 +368,12 @@ public class Messenger {
return;
}
- habboTo.getClient().sendResponse(new UpdateFriendComposer(to));
- habboFrom.getClient().sendResponse(new UpdateFriendComposer(from));
+ 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(this.loadFriend(habboTo, userFrom)));
+ habboTo.getClient().sendResponse(new UpdateFriendComposer(habboTo, this.loadFriend(habboTo, userFrom), 1));
} else if (habboFrom != null) {
- habboFrom.getClient().sendResponse(new UpdateFriendComposer(this.loadFriend(habboFrom, userTo)));
+ habboFrom.getClient().sendResponse(new UpdateFriendComposer(habboFrom, this.loadFriend(habboFrom, userTo), 1));
}
}
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/messenger/MessengerBuddy.java b/src/main/java/com/eu/habbo/habbohotel/messenger/MessengerBuddy.java
index b48d7b9e..d879d004 100644
--- a/src/main/java/com/eu/habbo/habbohotel/messenger/MessengerBuddy.java
+++ b/src/main/java/com/eu/habbo/habbohotel/messenger/MessengerBuddy.java
@@ -25,6 +25,7 @@ public class MessengerBuddy implements Runnable, ISerialize {
private String look = "";
private String motto = "";
private short relation;
+ private int categoryId = 0;
private boolean inRoom;
private int userOne = 0;
@@ -33,10 +34,11 @@ public class MessengerBuddy implements Runnable, ISerialize {
this.id = set.getInt("id");
this.username = set.getString("username");
this.gender = HabboGender.valueOf(set.getString("gender"));
- this.online = Integer.valueOf(set.getString("online"));
+ 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) {
@@ -58,6 +60,7 @@ public class MessengerBuddy implements Runnable, ISerialize {
this.look = set.getString("look");
this.relation = 0;
this.userOne = 0;
+ this.online = set.getInt("online");
} catch (SQLException e) {
LOGGER.error("Caught SQL exception", e);
}
@@ -135,6 +138,8 @@ public class MessengerBuddy implements Runnable, ISerialize {
Emulator.getThreading().run(this);
}
+ public int getCategoryId() { return this.categoryId; }
+
public boolean inRoom() {
return this.inRoom;
}
@@ -180,7 +185,7 @@ public class MessengerBuddy implements Runnable, ISerialize {
message.appendBoolean(this.online == 1);
message.appendBoolean(this.inRoom); //IN ROOM
message.appendString(this.look);
- message.appendInt(0); // Friends category ID
+ message.appendInt(this.categoryId); // Friends category ID
message.appendString(this.motto);
message.appendString(""); //Last seen as DATETIMESTRING
message.appendString(""); // Realname or Facebookame as String
diff --git a/src/main/java/com/eu/habbo/habbohotel/messenger/MessengerCategory.java b/src/main/java/com/eu/habbo/habbohotel/messenger/MessengerCategory.java
new file mode 100644
index 00000000..b19a43b0
--- /dev/null
+++ b/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/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolIssue.java b/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolIssue.java
index 14a0b737..f9b008db 100644
--- a/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolIssue.java
+++ b/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolIssue.java
@@ -52,7 +52,7 @@ public class ModToolIssue implements ISerialize {
int photoItemId = set.getInt("photo_item_id");
if (photoItemId != -1) {
- this.photoItem = Emulator.getGameEnvironment().getItemManager().loadHabboItem(photoItemId);;
+ this.photoItem = Emulator.getGameEnvironment().getItemManager().loadHabboItem(photoItemId);
}
if (this.modId <= 0) {
diff --git a/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolManager.java b/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolManager.java
index 2a65ba4a..3b8e5b3b 100644
--- a/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolManager.java
+++ b/src/main/java/com/eu/habbo/habbohotel/modtool/ModToolManager.java
@@ -184,8 +184,6 @@ public class ModToolManager {
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);
- if (Emulator.getPluginManager().fireEvent(new SupportTicketEvent(null, issue)).isCancelled())
- return;
Emulator.getGameEnvironment().getModToolManager().addTicket(issue);
Emulator.getGameEnvironment().getModToolManager().updateTicketToMods(issue);
diff --git a/src/main/java/com/eu/habbo/habbohotel/modtool/WordFilter.java b/src/main/java/com/eu/habbo/habbohotel/modtool/WordFilter.java
index 791d12d5..8cd83a3c 100644
--- a/src/main/java/com/eu/habbo/habbohotel/modtool/WordFilter.java
+++ b/src/main/java/com/eu/habbo/habbohotel/modtool/WordFilter.java
@@ -79,7 +79,7 @@ public class WordFilter {
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")
+ .replaceAll("[^\\p{M}*$]", "").replaceAll("[1|]", "i")
.replace("2", "z").replace("3", "e")
.replace("4", "a").replace("5", "s")
.replace("8", "b").replace("0", "o")
diff --git a/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorManager.java b/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorManager.java
index 929456b9..5c16598e 100644
--- a/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorManager.java
+++ b/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorManager.java
@@ -46,7 +46,7 @@ public class NavigatorManager {
synchronized (this.publicCategories) {
this.publicCategories.clear();
- try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM navigator_publiccats WHERE visible = '1'")) {
+ 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));
}
@@ -80,7 +80,7 @@ public class NavigatorManager {
Class clazz = Room.class;
if (set.getString("field").contains(".")) {
- for (String s : (set.getString("field")).split(".")) {
+ for (String s : (set.getString("field")).split("\\.")) {
try {
field = clazz.getDeclaredMethod(s);
clazz = field.getReturnType();
diff --git a/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorPublicFilter.java b/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorPublicFilter.java
index 4ab8c3bd..40ae72b1 100644
--- a/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorPublicFilter.java
+++ b/src/main/java/com/eu/habbo/habbohotel/navigation/NavigatorPublicFilter.java
@@ -25,7 +25,7 @@ public class NavigatorPublicFilter extends NavigatorFilter {
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.ACTIVITY, category.order));
+ 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++;
}
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java b/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java
index 58321d7d..c408c069 100644
--- a/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java
+++ b/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java
@@ -1672,7 +1672,7 @@ public class Room implements Comparable, ISerialize, Runnable {
} else {
if (!unit.hasStatus(RoomUnitStatus.LAY)) {
unit.setStatus(RoomUnitStatus.LAY, Item.getCurrentHeight(topItem) * 1.0D + "");
- unit.setRotation(RoomUserRotation.values()[topItem.getRotation()]);
+ unit.setRotation(RoomUserRotation.values()[topItem.getRotation() % 4]);
if (topItem.getRotation() == 0 || topItem.getRotation() == 4) {
unit.setLocation(this.layout.getTile(unit.getX(), topItem.getY()));
@@ -2407,6 +2407,8 @@ public class Room implements Comparable, ISerialize, Runnable {
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) {
@@ -2671,6 +2673,10 @@ public class Room implements Comparable, ISerialize, Runnable {
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());
}
@@ -2687,10 +2693,6 @@ public class Room implements Comparable, ISerialize, Runnable {
}
}
- synchronized (this.roomUnitLock) {
- this.currentHabbos.remove(habbo.getHabboInfo().getId());
- }
-
if (habbo.getHabboInfo().getCurrentGame() != null) {
if (this.getGame(habbo.getHabboInfo().getCurrentGame()) != null) {
this.getGame(habbo.getHabboInfo().getCurrentGame()).removeHabbo(habbo);
@@ -3820,10 +3822,7 @@ public class Room implements Comparable, ISerialize, Runnable {
public void sendComposer(ServerMessage message) {
for (Habbo habbo : this.getHabbos()) {
- if (habbo.getClient() == null) {
- this.removeHabbo(habbo, true);
- continue;
- }
+ if (habbo.getClient() == null) continue;
habbo.getClient().sendResponse(message);
}
@@ -3965,7 +3964,7 @@ public class Room implements Comparable, ISerialize, Runnable {
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);
@@ -3977,6 +3976,7 @@ public class Room implements Comparable, ISerialize, Runnable {
}
if (habbo != null) {
+ this.ejectUserFurni(habbo.getHabboInfo().getId());
habbo.getRoomUnit().setRightsLevel(RoomRightLevels.NONE);
habbo.getRoomUnit().removeStatus(RoomUnitStatus.FLAT_CONTROL);
this.refreshRightsForHabbo(habbo);
@@ -3984,6 +3984,10 @@ public class Room implements Comparable, ISerialize, Runnable {
}
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 = ?")) {
@@ -4120,15 +4124,23 @@ public class Room implements Comparable, ISerialize, Runnable {
}
public void giveEffect(RoomUnit roomUnit, int effectId, int duration) {
- if (duration == -1 || duration == Integer.MAX_VALUE) {
- duration = Integer.MAX_VALUE;
- } else {
- duration += Emulator.getIntUnixTimestamp();
- }
+ if(roomUnit == null) return;
- if (this.allowEffects && roomUnit != null) {
- roomUnit.setEffectId(effectId, duration);
- this.sendComposer(new RoomUserEffectComposer(roomUnit).compose());
+ Habbo habbo = roomUnit.getRoom().getHabbo(roomUnit);
+
+ if(habbo == null) return;
+
+ if (!habbo.getHabboInfo().isInGame()) {
+ if (duration == -1 || duration == Integer.MAX_VALUE) {
+ duration = Integer.MAX_VALUE;
+ } else {
+ duration += Emulator.getIntUnixTimestamp();
+ }
+
+ if (this.allowEffects) {
+ roomUnit.setEffectId(effectId, duration);
+ this.sendComposer(new RoomUserEffectComposer(roomUnit).compose());
+ }
}
}
@@ -4468,6 +4480,10 @@ public class Room implements Comparable, ISerialize, Runnable {
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;
@@ -4485,6 +4501,12 @@ public class Room implements Comparable, ISerialize, Runnable {
}
}
+ 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;
}
@@ -4501,9 +4523,11 @@ public class Room implements Comparable, ISerialize, Runnable {
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 (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;
+ 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<>();
@@ -4610,10 +4634,14 @@ public class Room implements Comparable, ISerialize, Runnable {
}
public FurnitureMovementError moveFurniTo(HabboItem item, RoomTile tile, int rotation, Habbo actor) {
- return moveFurniTo(item, tile, rotation, actor, true);
+ 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;
@@ -4631,6 +4659,7 @@ public class Room implements Comparable, ISerialize, Runnable {
//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);
@@ -4640,9 +4669,14 @@ public class Room implements Comparable, ISerialize, Runnable {
HabboItem tileTopItem = this.getTopItemAt(t.x, t.y);
if (!magicTile && ((tileTopItem != null && tileTopItem != item ? (t.state.equals(RoomTileState.INVALID) || !t.getAllowStack() || !tileTopItem.getBaseItem().allowStack()) : this.calculateTileState(t, item).equals(RoomTileState.INVALID))))
return FurnitureMovementError.CANT_STACK;
- 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;
+
+ 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;
+ }
+ }
}
}
@@ -4698,6 +4732,9 @@ public class Room implements Comparable, ISerialize, Runnable {
}
}
+ 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()) {
@@ -4705,9 +4742,6 @@ public class Room implements Comparable, ISerialize, Runnable {
}
}
- 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
-
item.setX(tile.x);
item.setY(tile.y);
item.setZ(height);
@@ -4746,6 +4780,18 @@ public class Room implements Comparable, ISerialize, Runnable {
);
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;
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatMessage.java b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatMessage.java
index ba845ba4..294d2749 100644
--- a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatMessage.java
+++ b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomChatMessage.java
@@ -56,6 +56,7 @@ public class RoomChatMessage implements Runnable, ISerialize, DatabaseLoggable {
for (Integer i : RoomChatMessage.BANNED_BUBBLES) {
if (i == this.bubble.getType()) {
this.bubble = RoomChatMessageBubbles.NORMAL;
+ break;
}
}
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomManager.java b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomManager.java
index 05ddc66a..ab507719 100644
--- a/src/main/java/com/eu/habbo/habbohotel/rooms/RoomManager.java
+++ b/src/main/java/com/eu/habbo/habbohotel/rooms/RoomManager.java
@@ -42,11 +42,13 @@ import com.eu.habbo.messages.outgoing.rooms.promotions.RoomPromotionMessageCompo
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 com.eu.habbo.plugin.events.users.UsernameTalkEvent;
import gnu.trove.iterator.TIntObjectIterator;
import gnu.trove.map.hash.THashMap;
import gnu.trove.procedure.TIntProcedure;
@@ -788,7 +790,16 @@ public class RoomManager {
{
final THashSet floorItems = new THashSet<>();
- room.getFloorItems().forEach(new TObjectProcedure() {
+ 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)
@@ -1312,7 +1323,7 @@ public class RoomManager {
if (friend == null || friend.getHabboInfo() == null) continue;
Room room = friend.getHabboInfo().getCurrentRoom();
- if (room != null && !rooms.contains(room)) rooms.add(room);
+ if (room != null && !rooms.contains(room) && room.hasRights(habbo)) rooms.add(room);
if (rooms.size() >= limit) break;
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java b/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java
index dcc5a05e..f867a8a2 100644
--- a/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java
+++ b/src/main/java/com/eu/habbo/habbohotel/users/Habbo.java
@@ -380,7 +380,7 @@ public class Habbo implements Runnable {
public boolean addBadge(String code) {
- if (this.habboInventory.getBadgesComponent().getBadge(code) == null) {
+ if (!this.habboInventory.getBadgesComponent().hasBadge(code)) {
HabboBadge badge = BadgesComponent.createBadge(code, this);
this.habboInventory.getBadgesComponent().addBadge(badge);
this.client.sendResponse(new AddUserBadgeComposer(badge));
diff --git a/src/main/java/com/eu/habbo/habbohotel/users/HabboInfo.java b/src/main/java/com/eu/habbo/habbohotel/users/HabboInfo.java
index a7fd28a5..8c166631 100644
--- a/src/main/java/com/eu/habbo/habbohotel/users/HabboInfo.java
+++ b/src/main/java/com/eu/habbo/habbohotel/users/HabboInfo.java
@@ -4,6 +4,7 @@ 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;
@@ -55,6 +56,7 @@ public class HabboInfo implements Runnable {
private int webPublishTimestamp;
private String machineID;
private List savedSearches = new ArrayList<>();
+ private List messengerCategories = new ArrayList<>();
public HabboInfo(ResultSet set) {
try {
@@ -88,6 +90,7 @@ public class HabboInfo implements Runnable {
this.loadCurrencies();
this.loadSavedSearches();
+ this.loadMessengerCategories();
}
private void loadCurrencies() {
@@ -179,6 +182,56 @@ public class HabboInfo implements Runnable {
}
}
+ 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) {
+ LOGGER.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) {
+ LOGGER.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) {
+ LOGGER.error("Caught SQL exception", e);
+ }
+ }
+
public int getCurrencyAmount(int type) {
return this.currencies.get(type);
}
@@ -478,6 +531,8 @@ public class HabboInfo implements Runnable {
return this.savedSearches;
}
+ public List getMessengerCategories() { return this.messengerCategories; }
+
@Override
public void run() {
this.saveCurrencies();
diff --git a/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java b/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java
index 4463148f..462af849 100644
--- a/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java
+++ b/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java
@@ -1,6 +1,7 @@
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;
@@ -33,7 +34,7 @@ public class HabboStats implements Runnable {
public final TIntArrayList secretRecipes;
public final HabboNavigatorWindowSettings navigatorWindowSettings;
public final THashMap cache;
- public final TIntArrayList calendarRewardsClaimed;
+ public final ArrayList calendarRewardsClaimed;
public final TIntObjectMap offerCache = new TIntObjectHashMap<>();
private final AtomicInteger lastOnlineTime = new AtomicInteger(Emulator.getIntUnixTimestamp());
private final THashMap achievementProgress;
@@ -109,7 +110,7 @@ public class HabboStats implements Runnable {
this.ignoredUsers = new TIntArrayList(0);
this.roomsVists = new TIntArrayList(0);
this.secretRecipes = new TIntArrayList(0);
- this.calendarRewardsClaimed = new TIntArrayList(0);
+ this.calendarRewardsClaimed = new ArrayList<>();
this.habboInfo = habboInfo;
@@ -206,7 +207,7 @@ public class HabboStats implements Runnable {
calendarRewardsStatement.setInt(1, this.habboInfo.getId());
try (ResultSet rewardSet = calendarRewardsStatement.executeQuery()) {
while (rewardSet.next()) {
- this.calendarRewardsClaimed.add(rewardSet.getInt("reward_id"));
+ this.calendarRewardsClaimed.add(new CalendarRewardClaimed(rewardSet));
}
}
}
@@ -268,7 +269,7 @@ public class HabboStats implements Runnable {
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.first();
+ set.next();
if (set.getRow() != 0) {
stats = new HabboStats(set, habboInfo);
} else {
diff --git a/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java b/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java
index 02573ff4..49f30136 100644
--- a/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java
+++ b/src/main/java/com/eu/habbo/habbohotel/users/inventory/BadgesComponent.java
@@ -46,7 +46,7 @@ public class BadgesComponent {
}
if (delete) {
- deleteBadge(habbo.getHabboInfo().getUsername(), badge.getCode());
+ deleteBadge(habbo.getHabboInfo().getId(), badge.getCode());
continue;
}
}
@@ -94,22 +94,6 @@ public class BadgesComponent {
return badge;
}
- @Deprecated
- public static void deleteBadge(String username, HabboBadge badge) {
- deleteBadge(username, badge.getCode());
- }
-
- @Deprecated
- public static void deleteBadge(String username, String badge) {
- try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE users_badges FROM users_badges INNER JOIN users ON users_badges.user_id = users.id WHERE users.username LIKE ? AND badge_code LIKE ?")) {
- statement.setString(1, username);
- statement.setString(2, badge);
- statement.execute();
- } catch (SQLException e) {
- LOGGER.error("Caught SQL exception", e);
- }
- }
-
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);
diff --git a/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionHabboClub.java b/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionHabboClub.java
index 66c3d041..0c7fc193 100644
--- a/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionHabboClub.java
+++ b/src/main/java/com/eu/habbo/habbohotel/users/subscriptions/SubscriptionHabboClub.java
@@ -15,6 +15,8 @@ import com.eu.habbo.messages.outgoing.generic.PickMonthlyClubGiftNotificationCom
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer;
import com.eu.habbo.messages.outgoing.users.*;
import gnu.trove.map.hash.THashMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.PreparedStatement;
@@ -29,6 +31,7 @@ import java.util.TreeMap;
* @author Beny
*/
public class SubscriptionHabboClub extends Subscription {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SubscriptionHabboClub.class);
public static boolean HC_PAYDAY_ENABLED = false;
public static int HC_PAYDAY_NEXT_DATE = Integer.MAX_VALUE; // yyyy-MM-dd HH:mm:ss
@@ -393,9 +396,18 @@ public class SubscriptionHabboClub extends Subscription {
break;
default:
- pointCurrency = Integer.parseInt(currency);
- habbo.getClient().getHabbo().getHabboInfo().addCurrencyAmount(pointCurrency, amount);
- habbo.getClient().sendResponse(new UserPointsComposer(habbo.getClient().getHabbo().getHabboInfo().getCurrencyAmount(pointCurrency), amount, pointCurrency));
+ pointCurrency = -1;
+ try {
+ pointCurrency = Integer.parseInt(currency);
+ }
+ catch (NumberFormatException ex) {
+ LOGGER.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().getHabboInfo().addCurrencyAmount(pointCurrency, amount);
+ habbo.getClient().sendResponse(new UserPointsComposer(habbo.getClient().getHabbo().getHabboInfo().getCurrencyAmount(pointCurrency), amount, pointCurrency));
+ }
break;
}
diff --git a/src/main/java/com/eu/habbo/habbohotel/wired/WiredHandler.java b/src/main/java/com/eu/habbo/habbohotel/wired/WiredHandler.java
index 9f27ad78..1d2b20fc 100644
--- a/src/main/java/com/eu/habbo/habbohotel/wired/WiredHandler.java
+++ b/src/main/java/com/eu/habbo/habbohotel/wired/WiredHandler.java
@@ -160,8 +160,9 @@ public class WiredHandler {
public static boolean handle(InteractionWiredTrigger trigger, final RoomUnit roomUnit, final Room room, final Object[] stuff, final THashSet effectsToExecute) {
long millis = System.currentTimeMillis();
- if (Emulator.isReady && trigger.canExecute(millis) && trigger.execute(roomUnit, room, stuff)) {
- trigger.activateBox(room);
+ 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());
@@ -193,7 +194,7 @@ public class WiredHandler {
THashSet extras = room.getRoomSpecialTypes().getExtras(trigger.getX(), trigger.getY());
for (InteractionWiredExtra extra : extras) {
- extra.activateBox(room);
+ extra.activateBox(room, roomUnit, millis);
}
List effectList = new ArrayList<>(effects);
@@ -229,7 +230,7 @@ public class WiredHandler {
private static boolean triggerEffect(InteractionWiredEffect effect, RoomUnit roomUnit, Room room, Object[] stuff, long millis) {
boolean executed = false;
- if (effect != null && effect.canExecute(millis)) {
+ 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(() -> {
@@ -241,7 +242,7 @@ public class WiredHandler {
LOGGER.error("Caught exception", e);
}
- effect.activateBox(room);
+ effect.activateBox(room, roomUnit, millis);
}
}, effect.getDelay() * 500);
}
@@ -305,6 +306,9 @@ public class WiredHandler {
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);
@@ -373,7 +377,7 @@ public class WiredHandler {
}
}
- 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 ?")) {
+ 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());
diff --git a/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreManager.java b/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreManager.java
index 31431699..e7cf9cef 100644
--- a/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreManager.java
+++ b/src/main/java/com/eu/habbo/habbohotel/wired/highscores/WiredHighscoreManager.java
@@ -22,8 +22,11 @@ public class WiredHighscoreManager {
private static final Logger LOGGER = LoggerFactory.getLogger(WiredHighscoreManager.class);
private final HashMap> data = new HashMap<>();
+
+ 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(System.getProperty("user.language"), System.getProperty("user.country"))).getFirstDayOfWeek();
+ 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();
diff --git a/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyItemAsGiftEvent.java b/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyItemAsGiftEvent.java
index 13ffb72a..160f3e1a 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyItemAsGiftEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/catalog/CatalogBuyItemAsGiftEvent.java
@@ -80,6 +80,10 @@ public class CatalogBuyItemAsGiftEvent extends MessageHandler {
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)
@@ -164,15 +168,20 @@ public class CatalogBuyItemAsGiftEvent extends MessageHandler {
item.sellRare();
}
- int totalCredits = 0;
- int totalPoints = 0;
+ 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) {
+ if (Emulator.getGameEnvironment().getCatalogManager().getLimitedConfig(item).available() == 0 && habbo != null) {
habbo.getClient().sendResponse(new AlertLimitedSoldOutComposer());
return;
}
@@ -220,103 +229,87 @@ public class CatalogBuyItemAsGiftEvent extends MessageHandler {
return;
}
- for (int i = 0; i < count; i++) {
- if (item.getCredits() <= this.client.getHabbo().getHabboInfo().getCredits() - totalCredits) {
- if (
- item.getPoints() <= this.client.getHabbo().getHabboInfo().getCurrencyAmount(item.getPointsType()) - totalPoints)
- //item.getPointsType() == 0 && item.getPoints() <= this.client.getHabbo().getHabboInfo().getPixels() - totalPoints ||
+ if (item.getAmount() > 1 || item.getBaseItems().size() > 1) {
+ this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose());
+ return;
+ }
- {
- if (((i + 1) % 6 != 0 && CatalogItem.haveOffer(item)) || !CatalogItem.haveOffer(item)) {
- totalCredits += item.getCredits();
- totalPoints += item.getPoints();
- }
+ for (Item baseItem : item.getBaseItems()) {
+ if (item.getItemAmount(baseItem.getId()) > 1) {
+ this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose());
+ return;
+ }
- for (int j = 0; j < item.getAmount(); j++) {
- 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.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) {
- LOGGER.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;
+ 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) {
+ LOGGER.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;
}
}
}
diff --git a/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestCatalogPageEvent.java b/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestCatalogPageEvent.java
index 2e0f73c5..0198c01e 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestCatalogPageEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/catalog/RequestCatalogPageEvent.java
@@ -11,14 +11,14 @@ public class RequestCatalogPageEvent extends MessageHandler {
@Override
public void handle() throws Exception {
int catalogPageId = this.packet.readInt();
- int unknown = 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(), mode));
+ 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/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/OpenRecycleBoxEvent.java b/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/OpenRecycleBoxEvent.java
index 3662378b..f9508582 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/OpenRecycleBoxEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/catalog/recycler/OpenRecycleBoxEvent.java
@@ -3,9 +3,7 @@ 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.Room;
-import com.eu.habbo.habbohotel.rooms.RoomChatMessage;
-import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles;
+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;
@@ -58,7 +56,15 @@ public class OpenRecycleBoxEvent extends MessageHandler {
if (item.getRoomId() == 0) {
room.updateTile(room.getLayout().getTile(item.getX(), item.getY()));
- room.sendComposer(new UpdateStackHeightComposer(item.getX(), item.getY(), room.getStackHeight(item.getX(), item.getY(), true)).compose());
+ 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/src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingCraftItemEvent.java b/src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingCraftItemEvent.java
index 02936f01..3887c6a0 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingCraftItemEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/crafting/CraftingCraftItemEvent.java
@@ -54,17 +54,16 @@ public class CraftingCraftItemEvent extends MessageHandler {
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));
- toRemove.forEachValue(new TObjectProcedure() {
- @Override
- public boolean execute(HabboItem object) {
- CraftingCraftItemEvent.this.client.sendResponse(new RemoveHabboItemComposer(object.getGiftAdjustedId()));
- return true;
- }
+ 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());
diff --git a/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarForceOpenEvent.java b/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarForceOpenEvent.java
index 1ab77c2c..bca8c1de 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarForceOpenEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarForceOpenEvent.java
@@ -6,9 +6,9 @@ import com.eu.habbo.messages.incoming.MessageHandler;
public class AdventCalendarForceOpenEvent extends MessageHandler {
@Override
public void handle() throws Exception {
- String campaign = this.packet.readString();
+ String campaignName = this.packet.readString();
int day = this.packet.readInt();
- Emulator.getGameEnvironment().getCatalogManager().claimCalendarReward(this.client.getHabbo(), day, true);
+ Emulator.getGameEnvironment().getCalendarManager().claimCalendarReward(this.client.getHabbo(), campaignName, day, true);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarOpenDayEvent.java b/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarOpenDayEvent.java
index 9c68cfd0..58970271 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarOpenDayEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarOpenDayEvent.java
@@ -6,9 +6,9 @@ import com.eu.habbo.messages.incoming.MessageHandler;
public class AdventCalendarOpenDayEvent extends MessageHandler {
@Override
public void handle() throws Exception {
- String campaign = this.packet.readString();
+ String campaignName = this.packet.readString();
int day = this.packet.readInt();
- Emulator.getGameEnvironment().getCatalogManager().claimCalendarReward(this.client.getHabbo(), day, false);
+ Emulator.getGameEnvironment().getCalendarManager().claimCalendarReward(this.client.getHabbo(), campaignName, day, false);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorSaveEvent.java b/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorSaveEvent.java
index c819a940..b4d98206 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorSaveEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/floorplaneditor/FloorPlanEditorSaveEvent.java
@@ -2,9 +2,7 @@ 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.CustomRoomLayout;
-import com.eu.habbo.habbohotel.rooms.Room;
-import com.eu.habbo.habbohotel.rooms.RoomLayout;
+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;
@@ -12,6 +10,7 @@ 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.*;
@@ -85,7 +84,6 @@ public class FloorPlanEditorSaveEvent extends MessageHandler {
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}");
@@ -99,16 +97,44 @@ public class FloorPlanEditorSaveEvent extends MessageHandler {
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++) {
- if (mapRows[y].charAt(x) == "x".charAt(0) && room.getTopItemAt(x, y) != null) {
+
+ 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;
diff --git a/src/main/java/com/eu/habbo/messages/incoming/friends/AcceptFriendRequestEvent.java b/src/main/java/com/eu/habbo/messages/incoming/friends/AcceptFriendRequestEvent.java
index d5197131..d3f461bf 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/friends/AcceptFriendRequestEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/friends/AcceptFriendRequestEvent.java
@@ -3,11 +3,22 @@ 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 com.eu.habbo.plugin.PluginManager;
+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 static com.eu.habbo.habbohotel.users.HabboManager.getOfflineHabboInfo;
public class AcceptFriendRequestEvent extends MessageHandler {
+ private static final Logger LOGGER = LoggerFactory.getLogger(AcceptFriendRequestEvent.class);
+
@Override
public void handle() throws Exception {
int count = this.packet.readInt();
@@ -26,6 +37,28 @@ public class AcceptFriendRequestEvent extends MessageHandler {
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) {
+ LOGGER.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());
diff --git a/src/main/java/com/eu/habbo/messages/incoming/friends/ChangeRelationEvent.java b/src/main/java/com/eu/habbo/messages/incoming/friends/ChangeRelationEvent.java
index cb02842f..d2790194 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/friends/ChangeRelationEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/friends/ChangeRelationEvent.java
@@ -16,7 +16,7 @@ public class ChangeRelationEvent extends MessageHandler {
UserRelationShipEvent event = new UserRelationShipEvent(this.client.getHabbo(), buddy, relationId);
if (!event.isCancelled()) {
buddy.setRelation(event.relationShip);
- this.client.sendResponse(new UpdateFriendComposer(buddy));
+ this.client.sendResponse(new UpdateFriendComposer(this.client.getHabbo(), buddy, 0));
}
}
}
diff --git a/src/main/java/com/eu/habbo/messages/incoming/friends/FriendRequestEvent.java b/src/main/java/com/eu/habbo/messages/incoming/friends/FriendRequestEvent.java
index 758ca1b4..95b363d7 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/friends/FriendRequestEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/friends/FriendRequestEvent.java
@@ -23,70 +23,70 @@ public class FriendRequestEvent extends MessageHandler {
@Override
public void handle() throws Exception {
String username = this.packet.readString();
- Habbo habbo = Emulator.getGameServer().getGameClientManager().getHabbo(username);
- if (habbo.getHabboInfo().getId() == this.client.getHabbo().getHabboInfo().getId()) {
+ if (this.client == null || username == null || username.isEmpty())
return;
- }
- if (Emulator.getPluginManager().fireEvent(new UserRequestFriendshipEvent(this.client.getHabbo(), username, habbo)).isCancelled()) {
- this.client.sendResponse(new FriendRequestErrorComposer(2));
- 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);
- int id = 0;
- boolean allowFriendRequests = true;
-
- FriendRequest friendRequest = this.client.getHabbo().getMessenger().findFriendRequest(username);
- if (friendRequest != null) {
- this.client.getHabbo().getMessenger().acceptFriendRequest(friendRequest.getId(), this.client.getHabbo().getHabboInfo().getId());
- return;
- }
-
- if (!Messenger.canFriendRequest(this.client.getHabbo(), username)) {
- this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.TARGET_NOT_FOUND));
- return;
- }
-
- if (habbo == null) {
- try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT users_settings.block_friendrequests, users.id FROM users INNER JOIN users_settings ON users.id = users_settings.user_id WHERE username = ? LIMIT 1")) {
+ // 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()) {
- id = set.getInt("id");
- allowFriendRequests = set.getString("block_friendrequests").equalsIgnoreCase("0");
+ targetHabbo = new Habbo(set);
}
}
} catch (SQLException e) {
LOGGER.error("Caught SQL exception", e);
return;
}
- } else {
- id = habbo.getHabboInfo().getId();
- allowFriendRequests = !habbo.getHabboStats().blockFriendRequests;
- if (allowFriendRequests)
- habbo.getClient().sendResponse(new FriendRequestComposer(this.client.getHabbo()));
}
- if (id != 0) {
- if (!allowFriendRequests) {
- this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.TARGET_NOT_ACCEPTING_REQUESTS));
- return;
- }
-
- 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;
- }
-
- if (habbo.getMessenger().getFriends().values().size() >= habbo.getHabboStats().maxFriends && !habbo.hasPermission("acc_infinite_friends")) {
- this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.FRIEND_LIST_TARGET_FULL));
- return;
- }
-
- Messenger.makeFriendRequest(this.client.getHabbo().getHabboInfo().getId(), id);
- } else {
+ 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/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildAcceptMembershipEvent.java b/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildAcceptMembershipEvent.java
index 1f932ffb..068aba2e 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildAcceptMembershipEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildAcceptMembershipEvent.java
@@ -20,43 +20,44 @@ public class GuildAcceptMembershipEvent extends MessageHandler {
int userId = this.packet.readInt();
Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId);
-
- if (guild == null || (guild.getOwnerId() != this.client.getHabbo().getHabboInfo().getId() && !Emulator.getGameEnvironment().getGuildManager().getOnlyAdmins(guild).containsKey(this.client.getHabbo().getHabboInfo().getId()) && !this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)))
- return;
-
Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId);
- 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);
+ 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);
}
}
- } else {
- Emulator.getGameEnvironment().getGuildManager().joinGuild(guild, this.client, userId, true);
}
}
}
diff --git a/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeSettingsEvent.java b/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeSettingsEvent.java
index 2cb2d807..d21df54b 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeSettingsEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildChangeSettingsEvent.java
@@ -17,11 +17,6 @@ public class GuildChangeSettingsEvent extends MessageHandler {
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)
- return;
-
GuildChangedSettingsEvent settingsEvent = new GuildChangedSettingsEvent(guild, this.packet.readInt(), this.packet.readInt() == 0);
Emulator.getPluginManager().fireEvent(settingsEvent);
@@ -31,7 +26,10 @@ public class GuildChangeSettingsEvent extends MessageHandler {
guild.setState(GuildState.valueOf(settingsEvent.state));
guild.setRights(settingsEvent.rights);
- room.refreshGuild(guild);
+ Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(guild.getRoomId());
+ if(room != null) {
+ room.refreshGuild(guild);
+ }
guild.needsUpdate = true;
diff --git a/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildConfirmRemoveMemberEvent.java b/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildConfirmRemoveMemberEvent.java
index 0daebeab..ba569387 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildConfirmRemoveMemberEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildConfirmRemoveMemberEvent.java
@@ -19,7 +19,7 @@ public class GuildConfirmRemoveMemberEvent extends MessageHandler {
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)) || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) {
+ 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) {
diff --git a/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildDeclineMembershipEvent.java b/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildDeclineMembershipEvent.java
index d75a5ef1..885e771c 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildDeclineMembershipEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildDeclineMembershipEvent.java
@@ -23,7 +23,7 @@ public class GuildDeclineMembershipEvent extends MessageHandler {
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) || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) {
+ 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, "")));
diff --git a/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildRemoveMemberEvent.java b/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildRemoveMemberEvent.java
index 7ee21067..dcde989f 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildRemoveMemberEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/guilds/GuildRemoveMemberEvent.java
@@ -24,7 +24,7 @@ public class GuildRemoveMemberEvent extends MessageHandler {
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) || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) {
+ 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);
diff --git a/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateMessageEvent.java b/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateMessageEvent.java
index f7211d14..6febac46 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateMessageEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateMessageEvent.java
@@ -37,7 +37,7 @@ public class GuildForumModerateMessageEvent extends MessageHandler {
return;
}
- boolean isStaff = this.client.getHabbo().hasPermission(Permission.ACC_MODTOOL_TICKET_Q);
+ 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) {
@@ -45,14 +45,14 @@ public class GuildForumModerateMessageEvent extends MessageHandler {
return;
}
- boolean isAdmin = (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || member.getRank().type < GuildRank.MEMBER.type);
+ boolean isGuildAdministrator = (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || member.getRank().equals(GuildRank.ADMIN));
- if (!isAdmin && !isStaff) {
+ if (!isGuildAdministrator && !hasStaffPermissions) {
this.client.sendResponse(new ConnectionErrorComposer(403));
return;
}
- if (state == ForumThreadState.HIDDEN_BY_STAFF.getStateId() && !isStaff) {
+ if (state == ForumThreadState.HIDDEN_BY_GUILD_ADMIN.getStateId() && !hasStaffPermissions) {
this.client.sendResponse(new ConnectionErrorComposer(403));
return;
}
diff --git a/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateThreadEvent.java b/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateThreadEvent.java
index dfd1d31d..5a83d413 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateThreadEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumModerateThreadEvent.java
@@ -21,6 +21,8 @@ public class GuildForumModerateThreadEvent extends MessageHandler {
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);
@@ -30,29 +32,21 @@ public class GuildForumModerateThreadEvent extends MessageHandler {
return;
}
- boolean isStaff = this.client.getHabbo().hasPermission(Permission.ACC_MODTOOL_TICKET_Q);
-
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;
}
-
- boolean isAdmin = (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || member.getRank().type < GuildRank.MEMBER.type);
-
- if (!isAdmin && !isStaff) {
+ if (!isGuildAdmin && !hasStaffPerms) {
this.client.sendResponse(new ConnectionErrorComposer(403));
return;
}
- if (state == ForumThreadState.HIDDEN_BY_STAFF.getStateId() && !isStaff) {
- this.client.sendResponse(new ConnectionErrorComposer(403));
- return;
- }
-
- thread.setState(ForumThreadState.fromValue(state));
- thread.setAdminId(this.client.getHabbo().getHabboInfo().getId());
-
+ thread.setState(ForumThreadState.fromValue(state)); // sets state as defined in the packet
thread.run();
switch (state) {
diff --git a/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadsMessagesEvent.java b/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadsMessagesEvent.java
index c315fb1a..c4a3ffe0 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadsMessagesEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/guilds/forums/GuildForumThreadsMessagesEvent.java
@@ -2,14 +2,21 @@ 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 {
@@ -18,20 +25,23 @@ public class GuildForumThreadsMessagesEvent extends MessageHandler {
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_ADMIN || thread.getState() == ForumThreadState.HIDDEN_BY_STAFF) && guild.getOwnerId() != this.client.getHabbo().getHabboInfo().getId()) {
- this.client.sendResponse(new BubbleAlertComposer("oldforums.error.access_denied"));
- } else {
+ 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());
}
-
- this.client.sendResponse(new GuildForumDataComposer(guild, this.client.getHabbo()));
}
}
\ No newline at end of file
diff --git a/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java b/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java
index 82ab0bf1..2a47300f 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java
@@ -6,6 +6,7 @@ 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;
@@ -13,7 +14,6 @@ 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.achievements.AchievementListComposer;
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;
@@ -24,13 +24,13 @@ 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.InventoryRefreshComposer;
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.UserLoginEvent;
@@ -73,7 +73,7 @@ public class SecureLoginEvent extends MessageHandler {
if (sso.isEmpty()) {
Emulator.getGameServer().getGameClientManager().disposeClient(this.client);
- LOGGER.warn("Client is trying to connect without SSO ticket! Closed connection...");
+ LOGGER.debug("Client is trying to connect without SSO ticket! Closed connection...");
return;
}
@@ -115,7 +115,15 @@ public class SecureLoginEvent extends MessageHandler {
ArrayList messages = new ArrayList<>();
messages.add(new SecureLoginOKComposer().compose());
- messages.add(new UserHomeRoomComposer(this.client.getHabbo().getHabboInfo().getHomeRoom(), 0).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());
@@ -125,7 +133,7 @@ public class SecureLoginEvent extends MessageHandler {
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 UnknownComposer5().compose());
+ messages.add(new MysteryBoxKeysComposer().compose());
messages.add(new BuildersClubExpiredComposer().compose());
messages.add(new CfhTopicsMessageComposer().compose());
messages.add(new FavoriteRoomsCountComposer(this.client.getHabbo()).compose());
@@ -133,8 +141,6 @@ public class SecureLoginEvent extends MessageHandler {
messages.add(new GameCenterAccountInfoComposer(3, 100).compose());
messages.add(new GameCenterAccountInfoComposer(0, 100).compose());
- //messages.add(new MessengerInitComposer(this.client.getHabbo()).compose());
- //messages.add(new FriendsComposer(this.client.getHabbo()).compose());
messages.add(new UserClubComposer(this.client.getHabbo(), SubscriptionHabboClub.HABBO_CLUB, UserClubComposer.RESPONSE_TYPE_LOGIN).compose());
if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) {
@@ -144,16 +150,8 @@ public class SecureLoginEvent extends MessageHandler {
this.client.sendResponses(messages);
//Hardcoded
- 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());
- this.client.sendResponse(new InventoryRefreshComposer());
//this.client.sendResponse(new ForumsTestComposer());
this.client.sendResponse(new InventoryAchievementsComposer());
- this.client.sendResponse(new AchievementListComposer(this.client.getHabbo()));
ModToolSanctions modToolSanctions = Emulator.getGameEnvironment().getModToolSanctions();
diff --git a/src/main/java/com/eu/habbo/messages/incoming/handshake/UsernameEvent.java b/src/main/java/com/eu/habbo/messages/incoming/handshake/UsernameEvent.java
index aa4d946f..c217e946 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/handshake/UsernameEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/handshake/UsernameEvent.java
@@ -2,6 +2,7 @@ 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;
@@ -11,9 +12,14 @@ 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
@@ -24,7 +30,7 @@ public class UsernameEvent extends MessageHandler {
calendar = true;
} else {
- long daysBetween = ChronoUnit.DAYS.between(new Date((long) this.client.getHabbo().getHabboInfo().getLastOnline() * 1000L).toInstant(), new Date().toInstant());
+ 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());
@@ -82,10 +88,15 @@ public class UsernameEvent extends MessageHandler {
deleteStatement.execute();
}
}
-
if (Emulator.getConfig().getBoolean("hotel.calendar.enabled")) {
- this.client.sendResponse(new AdventCalendarDataComposer("xmas15", Emulator.getGameEnvironment().getCatalogManager().calendarRewards.size(), (int) Math.floor((Emulator.getIntUnixTimestamp() - Emulator.getConfig().getInt("hotel.calendar.starttimestamp")) / 86400), this.client.getHabbo().getHabboStats().calendarRewardsClaimed, true));
- this.client.sendResponse(new NuxAlertComposer("openView/calendar"));
+ 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) {
diff --git a/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewEvent.java b/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewEvent.java
index a1560542..67dddaa3 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/hotelview/HotelViewEvent.java
@@ -3,6 +3,7 @@ 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
@@ -21,6 +22,7 @@ public class HotelViewEvent extends MessageHandler {
} else {
this.client.getHabbo().getHabboInfo().setRoomQueueId(0);
}
+ this.client.sendResponse(new HotelViewComposer());
}
if (this.client.getHabbo().getRoomUnit() != null) {
diff --git a/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryItemsEvent.java b/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryItemsEvent.java
index 2b9641cb..7fa6a66b 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryItemsEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/inventory/RequestInventoryItemsEvent.java
@@ -17,20 +17,30 @@ public class RequestInventoryItemsEvent extends MessageHandler {
@Override
public void handle() throws Exception {
int totalItems = this.client.getHabbo().getInventory().getItemsComponent().getItems().size();
- int pages = (int) Math.ceil((double) totalItems / 1000.0);
- if (pages == 0) {
- pages = 1;
+ 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 page = 0;
+ int fragmentNumber = 0;
+
for (int i = this.client.getHabbo().getInventory().getItemsComponent().getItems().size(); i-- > 0; ) {
+
if (count == 0) {
- page++;
+ fragmentNumber++;
}
try {
@@ -43,13 +53,13 @@ public class RequestInventoryItemsEvent extends MessageHandler {
}
if (count == 1000) {
- this.client.sendResponse(new InventoryItemsComposer(page, pages, items));
+ this.client.sendResponse(new InventoryItemsComposer(fragmentNumber, totalFragments, items));
count = 0;
items.clear();
}
}
- this.client.sendResponse(new InventoryItemsComposer(page, pages, items));
+ if(count > 0 && items.size() > 0) this.client.sendResponse(new InventoryItemsComposer(fragmentNumber, totalFragments, items));
}
}
}
diff --git a/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestCanCreateRoomEvent.java b/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestCanCreateRoomEvent.java
index d1ed2bf0..b2b93714 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestCanCreateRoomEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestCanCreateRoomEvent.java
@@ -9,7 +9,7 @@ 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().maxRooms;
+ 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/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestCreateRoomEvent.java b/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestCreateRoomEvent.java
index d0f8f83a..c5e921f3 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestCreateRoomEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestCreateRoomEvent.java
@@ -48,7 +48,7 @@ public class RequestCreateRoomEvent extends MessageHandler {
return;
int count = Emulator.getGameEnvironment().getRoomManager().getRoomsForHabbo(this.client.getHabbo()).size();
- int max = this.client.getHabbo().getHabboStats().maxRooms;
+ 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));
diff --git a/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestNewNavigatorDataEvent.java b/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestNewNavigatorDataEvent.java
index 05442efe..6bc2a215 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestNewNavigatorDataEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/navigator/RequestNewNavigatorDataEvent.java
@@ -12,6 +12,5 @@ public class RequestNewNavigatorDataEvent extends MessageHandler {
this.client.sendResponse(new NewNavigatorCollapsedCategoriesComposer());
this.client.sendResponse(new NewNavigatorSavedSearchesComposer(this.client.getHabbo().getHabboInfo().getSavedSearches()));
this.client.sendResponse(new NewNavigatorEventCategoriesComposer());
- this.client.sendResponse(new NewNavigatorSettingsComposer(this.client.getHabbo().getHabboStats().navigatorWindowSettings));
}
}
diff --git a/src/main/java/com/eu/habbo/messages/incoming/polls/AnswerPollEvent.java b/src/main/java/com/eu/habbo/messages/incoming/polls/AnswerPollEvent.java
index 574e50ca..180b0a29 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/polls/AnswerPollEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/polls/AnswerPollEvent.java
@@ -21,12 +21,15 @@ public class AnswerPollEvent extends MessageHandler {
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(this.packet.readString());
+ 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;
@@ -49,7 +52,7 @@ public class AnswerPollEvent extends MessageHandler {
if (poll.lastQuestionId == questionId) {
if (poll.badgeReward.length() > 0) {
- if (this.client.getHabbo().getInventory().getBadgesComponent().getBadge(poll.badgeReward) == null) {
+ 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);
diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomLoadEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomLoadEvent.java
index 9bdaf28a..93c904be 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomLoadEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/RequestRoomLoadEvent.java
@@ -12,9 +12,6 @@ public class RequestRoomLoadEvent extends MessageHandler {
String password = this.packet.readString();
if (this.client.getHabbo().getHabboInfo().getLoadingRoom() == 0 && this.client.getHabbo().getHabboStats().roomEnterTimestamp + 1000 < System.currentTimeMillis()) {
- if (this.client.getHabbo().getRoomUnit() != null && this.client.getHabbo().getRoomUnit().isTeleporting) {
- return;
- }
Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom();
if (room != null) {
@@ -24,6 +21,11 @@ public class RequestRoomLoadEvent extends MessageHandler {
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/src/main/java/com/eu/habbo/messages/incoming/rooms/SetHomeRoomEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/SetHomeRoomEvent.java
index 3f8544e3..7a39e005 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/rooms/SetHomeRoomEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/SetHomeRoomEvent.java
@@ -10,7 +10,7 @@ public class SetHomeRoomEvent extends MessageHandler {
if (roomId != this.client.getHabbo().getHabboInfo().getHomeRoom()) {
this.client.getHabbo().getHabboInfo().setHomeRoom(roomId);
- this.client.sendResponse(new UserHomeRoomComposer(this.client.getHabbo().getHabboInfo().getHomeRoom(), this.client.getHabbo().getHabboInfo().getHomeRoom()));
+ this.client.sendResponse(new UserHomeRoomComposer(this.client.getHabbo().getHabboInfo().getHomeRoom(), 0));
}
}
}
diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotSaveSettingsEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotSaveSettingsEvent.java
index 2d217924..bb5da19d 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotSaveSettingsEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/bots/BotSaveSettingsEvent.java
@@ -152,7 +152,11 @@ public class BotSaveSettingsEvent extends MessageHandler {
}
break;
case 9:
- bot.setMotto(this.packet.readString());
+ 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;
diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/AdvertisingSaveEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/AdvertisingSaveEvent.java
index d705f8ff..b25f3792 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/AdvertisingSaveEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/AdvertisingSaveEvent.java
@@ -6,6 +6,9 @@ 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
@@ -26,6 +29,7 @@ public class AdvertisingSaveEvent extends MessageHandler {
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();
@@ -42,7 +46,7 @@ public class AdvertisingSaveEvent extends MessageHandler {
item.needsUpdate(true);
Emulator.getThreading().run(item);
room.updateItem(item);
- ((InteractionCustomValues) item).onCustomValuesSaved(room, this.client);
+ ((InteractionCustomValues) item).onCustomValuesSaved(room, this.client, oldValues);
}
}
}
diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MannequinSaveNameEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MannequinSaveNameEvent.java
index ad09fc3c..c5c94204 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MannequinSaveNameEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MannequinSaveNameEvent.java
@@ -18,6 +18,11 @@ public class MannequinSaveNameEvent extends MessageHandler {
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 {
diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoodLightSaveSettingsEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoodLightSaveSettingsEvent.java
index 731e6490..894e83c9 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoodLightSaveSettingsEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/MoodLightSaveSettingsEvent.java
@@ -30,7 +30,7 @@ public class MoodLightSaveSettingsEvent extends MessageHandler {
int brightness = this.packet.readInt();
boolean apply = this.packet.readBoolean();
- if (!MOODLIGHT_AVAILABLE_COLORS.contains(color)) {
+ 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;
}
diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItSaveDataEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItSaveDataEvent.java
index 2922fc94..a2bb5524 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItSaveDataEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/PostItSaveDataEvent.java
@@ -39,12 +39,12 @@ public class PostItSaveDataEvent extends MessageHandler {
if (!(item instanceof InteractionPostIt))
return;
- if (!color.equalsIgnoreCase(PostItColor.YELLOW.hexColor) && !room.hasRights(this.client.getHabbo()) && item.getUserId() != this.client.getHabbo().getHabboInfo().getId()) {
+ 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()) && item.getUserId() != this.client.getHabbo().getHabboInfo().getId())
+ if (!room.hasRights(this.client.getHabbo()))
return;
}
diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RedeemClothingEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RedeemClothingEvent.java
index 20f46659..2d489be7 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RedeemClothingEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RedeemClothingEvent.java
@@ -40,7 +40,7 @@ public class RedeemClothingEvent extends MessageHandler {
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.relativeHeight()).compose());
+ 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()));
diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RedeemItemEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RedeemItemEvent.java
index 3533ca6d..fa5ce66b 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RedeemItemEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RedeemItemEvent.java
@@ -102,7 +102,7 @@ public class RedeemItemEvent extends MessageHandler {
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.relativeHeight()).compose());
+ room.sendComposer(new UpdateStackHeightComposer(item.getX(), item.getY(), t.z, t.relativeHeight()).compose());
Emulator.getThreading().run(new QueryDeleteHabboItem(item.getId()));
switch (furniRedeemEvent.currencyID) {
diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPickupItemEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPickupItemEvent.java
index fe4ab2c9..c3585ecb 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPickupItemEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPickupItemEvent.java
@@ -9,7 +9,7 @@ import com.eu.habbo.messages.incoming.MessageHandler;
public class RoomPickupItemEvent extends MessageHandler {
@Override
public void handle() throws Exception {
- int unknown = this.packet.readInt();
+ int category = this.packet.readInt(); //10 = floorItem and 20 = wallItem
int itemId = this.packet.readInt();
Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom();
@@ -31,6 +31,8 @@ public class RoomPickupItemEvent extends MessageHandler {
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/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPlaceItemEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPlaceItemEvent.java
index bf3842ce..0f293184 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPlaceItemEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPlaceItemEvent.java
@@ -2,10 +2,8 @@ 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.rooms.FurnitureMovementError;
-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.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;
@@ -19,7 +17,7 @@ public class RoomPlaceItemEvent extends MessageHandler {
int itemId = -1;
- if (values.length != 0) itemId = Integer.valueOf(values[0]);
+ 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));
@@ -55,10 +53,28 @@ public class RoomPlaceItemEvent extends MessageHandler {
}
if (item.getBaseItem().getType() == FurnitureType.FLOOR) {
- short x = Short.valueOf(values[1]);
- short y = Short.valueOf(values[2]);
- int rotation = Integer.valueOf(values[3]);
- if (rentSpace != null && !room.hasRights(this.client.getHabbo())) {
+ 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 ||
@@ -70,14 +86,11 @@ public class RoomPlaceItemEvent extends MessageHandler {
this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, FurnitureMovementError.NO_RIGHTS.errorCode));
return;
}
-
- if (!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))) {
+ 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;
}
}
-
- RoomTile tile = room.getLayout().getTile(x, y);
FurnitureMovementError error = room.canPlaceFurnitureAt(item, this.client.getHabbo(), tile, rotation);
if (!error.equals(FurnitureMovementError.NONE)) {
diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestStateChange.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestStateChange.java
index f212e698..b9010e5a 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestStateChange.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/youtube/YoutubeRequestStateChange.java
@@ -64,10 +64,12 @@ public class YoutubeRequestStateChange extends MessageHandler {
HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId);
- if (item == null || !(item instanceof InteractionYoutubeTV)) return;
+ 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;
@@ -104,4 +106,4 @@ public class YoutubeRequestStateChange extends MessageHandler {
room.updateItem(tv);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetPackageNameEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetPackageNameEvent.java
index fd9617c1..9fa2f4cb 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetPackageNameEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/pets/PetPackageNameEvent.java
@@ -62,7 +62,7 @@ public class PetPackageNameEvent extends MessageHandler {
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.relativeHeight()).compose());
+ 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));
diff --git a/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserDataEvent.java b/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserDataEvent.java
index f4d37e90..aa55bd84 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserDataEvent.java
+++ b/src/main/java/com/eu/habbo/messages/incoming/users/RequestUserDataEvent.java
@@ -43,11 +43,6 @@ public class RequestUserDataEvent extends MessageHandler {
messages.add(new UserDataComposer(this.client.getHabbo()).compose());
messages.add(new UserPerksComposer(this.client.getHabbo()).compose());
- if (!this.client.getHabbo().getHabboStats().nux || Emulator.getConfig().getBoolean("retro.style.homeroom") && this.client.getHabbo().getHabboInfo().getHomeRoom() != 0)
- messages.add(new ForwardToRoomComposer(this.client.getHabbo().getHabboInfo().getHomeRoom()).compose());
- else if (!this.client.getHabbo().getHabboStats().nux || Emulator.getConfig().getBoolean("retro.style.homeroom") && RoomManager.HOME_ROOM_ID > 0)
- messages.add(new ForwardToRoomComposer(RoomManager.HOME_ROOM_ID).compose());
-
messages.add(new MeMenuSettingsComposer(this.client.getHabbo()).compose());
diff --git a/src/main/java/com/eu/habbo/messages/outgoing/Outgoing.java b/src/main/java/com/eu/habbo/messages/outgoing/Outgoing.java
index e38663e7..173ec13f 100644
--- a/src/main/java/com/eu/habbo/messages/outgoing/Outgoing.java
+++ b/src/main/java/com/eu/habbo/messages/outgoing/Outgoing.java
@@ -212,7 +212,7 @@ public class Outgoing {
//Uknown but work
public final static int IsFirstLoginOfDayComposer = 793; // PRODUCTION-201611291003-338511768 //Quest Engine
- public final static int UnknownComposer5 = 2833; // PRODUCTION-201611291003-338511768 //Mysterbox
+ 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
diff --git a/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogPageComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogPageComposer.java
index 9c0c682f..0f4d8bd5 100644
--- a/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogPageComposer.java
+++ b/src/main/java/com/eu/habbo/messages/outgoing/catalog/CatalogPageComposer.java
@@ -20,11 +20,13 @@ 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, String mode) {
+ public CatalogPageComposer(CatalogPage page, Habbo habbo, int offerId, String mode) {
this.page = page;
this.habbo = habbo;
+ this.offerId = offerId;
this.mode = mode;
}
@@ -49,7 +51,7 @@ public class CatalogPageComposer extends MessageComposer {
item.serialize(this.response);
}
}
- this.response.appendInt(0);
+ this.response.appendInt(this.offerId);
this.response.appendBoolean(false); //acceptSeasonCurrencyAsCredits
if (this.page instanceof FrontPageFeaturedLayout || this.page instanceof FrontpageLayout) {
diff --git a/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarDataComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarDataComposer.java
index 82c512f2..abf20a7a 100644
--- a/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarDataComposer.java
+++ b/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarDataComposer.java
@@ -1,20 +1,24 @@
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 gnu.trove.procedure.TIntProcedure;
+
+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 TIntArrayList unlocked;
+ private final ArrayList unlocked;
private final boolean lockExpired;
- public AdventCalendarDataComposer(String eventName, int totalDays, int currentDay, TIntArrayList unlocked, 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;
@@ -25,23 +29,23 @@ public class AdventCalendarDataComposer extends MessageComposer {
protected ServerMessage composeInternal() {
this.response.init(Outgoing.AdventCalendarDataComposer);
this.response.appendString(this.eventName);
- this.response.appendString("");
+ 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();
- for (int i = 0; i < this.totalDays; i++) {
+ 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(value -> {
- AdventCalendarDataComposer.this.response.appendInt(value);
- expired.remove(value);
- return true;
+ this.unlocked.forEach(claimed -> {
+ AdventCalendarDataComposer.this.response.appendInt(claimed.getDay());
+ expired.remove(claimed.getDay());
});
diff --git a/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarProductComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarProductComposer.java
index 999eefbb..fb23b318 100644
--- a/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarProductComposer.java
+++ b/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarProductComposer.java
@@ -1,7 +1,9 @@
package com.eu.habbo.messages.outgoing.events.calendar;
-import com.eu.habbo.habbohotel.catalog.CalendarRewardObject;
-import com.eu.habbo.habbohotel.items.Item;
+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;
@@ -9,19 +11,39 @@ 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) {
+ 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);
- this.response.appendString(this.rewardObject.getItem().getName());
+
+ 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(this.rewardObject.getItem().getName());
+ this.response.appendString(className);
+
return this.response;
}
}
\ No newline at end of file
diff --git a/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendsComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendsComposer.java
index 2fd69a9a..287e87cb 100644
--- a/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendsComposer.java
+++ b/src/main/java/com/eu/habbo/messages/outgoing/friends/FriendsComposer.java
@@ -41,10 +41,10 @@ public class FriendsComposer extends MessageComposer {
this.response.appendBoolean(row.getOnline() == 1);
this.response.appendBoolean(row.inRoom()); //IN ROOM
this.response.appendString(row.getOnline() == 1 ? row.getLook() : "");
- this.response.appendInt(0);
+ this.response.appendInt(row.getCategoryId()); //Friends category
this.response.appendString(row.getMotto());
- this.response.appendString("");
- this.response.appendString("");
+ 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);
diff --git a/src/main/java/com/eu/habbo/messages/outgoing/friends/MessengerInitComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/friends/MessengerInitComposer.java
index a48e6e65..de3b9206 100644
--- a/src/main/java/com/eu/habbo/messages/outgoing/friends/MessengerInitComposer.java
+++ b/src/main/java/com/eu/habbo/messages/outgoing/friends/MessengerInitComposer.java
@@ -1,11 +1,15 @@
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;
@@ -15,6 +19,7 @@ public class MessengerInitComposer extends MessageComposer {
@Override
protected ServerMessage composeInternal() {
+
this.response.init(Outgoing.MessengerInitComposer);
if (this.habbo.hasPermission("acc_infinite_friends")) {
this.response.appendInt(Integer.MAX_VALUE);
@@ -25,9 +30,19 @@ public class MessengerInitComposer extends MessageComposer {
this.response.appendInt(1337);
this.response.appendInt(Messenger.MAXIMUM_FRIENDS_HC);
}
+ if (!this.habbo.getHabboInfo().getMessengerCategories().isEmpty()) {
- //this.response.appendInt(1000);
- this.response.appendInt(0);
+ 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/src/main/java/com/eu/habbo/messages/outgoing/friends/UpdateFriendComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/friends/UpdateFriendComposer.java
index 907fa9a0..1be0b1ac 100644
--- a/src/main/java/com/eu/habbo/messages/outgoing/friends/UpdateFriendComposer.java
+++ b/src/main/java/com/eu/habbo/messages/outgoing/friends/UpdateFriendComposer.java
@@ -1,6 +1,11 @@
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;
@@ -8,60 +13,65 @@ import com.eu.habbo.messages.outgoing.MessageComposer;
import com.eu.habbo.messages.outgoing.Outgoing;
public class UpdateFriendComposer extends MessageComposer {
- private MessengerBuddy buddy;
+ private Collection buddies;
private Habbo habbo;
+ private int action;
- public UpdateFriendComposer(MessengerBuddy buddy) {
- this.buddy = buddy;
+ public UpdateFriendComposer(Habbo habbo, MessengerBuddy buddy, Integer action) {
+ this.habbo = habbo;
+ this.buddies = Collections.singletonList(buddy);
+ this.action = action;
}
-
- public UpdateFriendComposer(Habbo habbo) {
+ 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.buddy != null) {
- this.response.appendInt(0);
- this.response.appendInt(1);
- this.response.appendInt(0);
- this.response.appendInt(this.buddy.getId());
- this.response.appendString(this.buddy.getUsername());
- this.response.appendInt(this.buddy.getGender().equals(HabboGender.M) ? 0 : 1);
- this.response.appendBoolean(this.buddy.getOnline() == 1);
- this.response.appendBoolean(this.buddy.inRoom()); //In room
- this.response.appendString(this.buddy.getLook());
- this.response.appendInt(0);
- this.response.appendString(this.buddy.getMotto());
- this.response.appendString("");
- this.response.appendString("");
- this.response.appendBoolean(false);
- this.response.appendBoolean(false);
- this.response.appendBoolean(false);
- this.response.appendShort(this.buddy.getRelation());
+ 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(1);
- this.response.appendInt(0);
- this.response.appendInt(-1);
- this.response.appendString("Staff Chat");
- this.response.appendInt(0);
- this.response.appendBoolean(true);
- this.response.appendBoolean(false); //In room
- this.response.appendString(this.habbo.getHabboInfo().getLook());
- this.response.appendInt(0);
- this.response.appendString("");
- this.response.appendString("");
- this.response.appendString("");
- this.response.appendBoolean(false);
- this.response.appendBoolean(false);
- this.response.appendBoolean(false);
- this.response.appendShort(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/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/BubbleAlertKeys.java b/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/BubbleAlertKeys.java
index d3f30596..36ed0441 100644
--- a/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/BubbleAlertKeys.java
+++ b/src/main/java/com/eu/habbo/messages/outgoing/generic/alerts/BubbleAlertKeys.java
@@ -20,6 +20,7 @@ public enum BubbleAlertKeys {
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"),
diff --git a/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildInfoComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildInfoComposer.java
index 768e85ba..dab0c0e7 100644
--- a/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildInfoComposer.java
+++ b/src/main/java/com/eu/habbo/messages/outgoing/guilds/GuildInfoComposer.java
@@ -1,5 +1,6 @@
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;
@@ -28,28 +29,28 @@ public class GuildInfoComposer extends MessageComposer {
@Override
protected ServerMessage composeInternal() {
- boolean adminPermissions = this.client.getHabbo().getHabboStats().hasGuild(this.guild.getId()) && this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN);
- 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))));
+ 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;
+ 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/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumDataComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumDataComposer.java
index 8e03ebd3..555df4a9 100644
--- a/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumDataComposer.java
+++ b/src/main/java/com/eu/habbo/messages/outgoing/guilds/forums/GuildForumDataComposer.java
@@ -153,7 +153,12 @@ public class GuildForumDataComposer extends MessageComposer {
this.response.appendString(errorModerate);
this.response.appendString(""); //citizen
this.response.appendBoolean(guild.getOwnerId() == this.habbo.getHabboInfo().getId()); //Forum Settings
- this.response.appendBoolean(guild.getOwnerId() == this.habbo.getHabboInfo().getId() || isStaff); //Can Mod (staff)
+ 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();
diff --git a/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryItemsComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryItemsComposer.java
index 258ce1a9..a8a24ed0 100644
--- a/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryItemsComposer.java
+++ b/src/main/java/com/eu/habbo/messages/outgoing/inventory/InventoryItemsComposer.java
@@ -14,13 +14,13 @@ import org.slf4j.LoggerFactory;
public class InventoryItemsComposer extends MessageComposer implements TIntObjectProcedure {
private static final Logger LOGGER = LoggerFactory.getLogger(InventoryItemsComposer.class);
- private final int page;
- private final int out;
+ private final int fragmentNumber;
+ private final int totalFragments;
private final TIntObjectMap items;
- public InventoryItemsComposer(int page, int out, TIntObjectMap items) {
- this.page = page;
- this.out = out;
+ public InventoryItemsComposer(int fragmentNumber, int totalFragments, TIntObjectMap items) {
+ this.fragmentNumber = fragmentNumber;
+ this.totalFragments = totalFragments;
this.items = items;
}
@@ -28,8 +28,8 @@ public class InventoryItemsComposer extends MessageComposer implements TIntObjec
protected ServerMessage composeInternal() {
try {
this.response.init(Outgoing.InventoryItemsComposer);
- this.response.appendInt(this.out);
- this.response.appendInt(this.page - 1);
+ this.response.appendInt(this.totalFragments);
+ this.response.appendInt(this.fragmentNumber - 1);
this.response.appendInt(this.items.size());
this.items.forEachEntry(this);
diff --git a/src/main/java/com/eu/habbo/messages/incoming/handshake/UnknownComposer5.java b/src/main/java/com/eu/habbo/messages/outgoing/mysterybox/MysteryBoxKeysComposer.java
similarity index 66%
rename from src/main/java/com/eu/habbo/messages/incoming/handshake/UnknownComposer5.java
rename to src/main/java/com/eu/habbo/messages/outgoing/mysterybox/MysteryBoxKeysComposer.java
index 7cea96ee..8aa8d340 100644
--- a/src/main/java/com/eu/habbo/messages/incoming/handshake/UnknownComposer5.java
+++ b/src/main/java/com/eu/habbo/messages/outgoing/mysterybox/MysteryBoxKeysComposer.java
@@ -1,13 +1,13 @@
-package com.eu.habbo.messages.incoming.handshake;
+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 UnknownComposer5 extends MessageComposer {
+public class MysteryBoxKeysComposer extends MessageComposer {
@Override
protected ServerMessage composeInternal() {
- this.response.init(Outgoing.UnknownComposer5);
+ this.response.init(Outgoing.MysteryBoxKeysComposer);
this.response.appendString(""); //Box color
this.response.appendString(""); //Key color
return this.response;
diff --git a/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomDataComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomDataComposer.java
index 7dea5e9f..895cacc6 100644
--- a/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomDataComposer.java
+++ b/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomDataComposer.java
@@ -39,8 +39,8 @@ public class RoomDataComposer extends MessageComposer {
this.response.appendInt(this.room.getUsersMax());
this.response.appendString(this.room.getDescription());
this.response.appendInt(this.room.getTradeMode());
- this.response.appendInt(2);
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()) {
diff --git a/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRelativeMapComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRelativeMapComposer.java
index 1b31cb35..8236b453 100644
--- a/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRelativeMapComposer.java
+++ b/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomRelativeMapComposer.java
@@ -1,5 +1,6 @@
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;
@@ -22,10 +23,17 @@ public class RoomRelativeMapComposer extends MessageComposer {
for (short x = 0; x < this.room.getLayout().getMapSizeX(); x++) {
RoomTile t = this.room.getLayout().getTile(x, y);
- if (t != null)
- this.response.appendShort(t.relativeHeight());
- else
+ 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);
+ }
}
}
diff --git a/src/main/java/com/eu/habbo/messages/outgoing/rooms/UpdateStackHeightComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/rooms/UpdateStackHeightComposer.java
index 334581c6..a6d5d643 100644
--- a/src/main/java/com/eu/habbo/messages/outgoing/rooms/UpdateStackHeightComposer.java
+++ b/src/main/java/com/eu/habbo/messages/outgoing/rooms/UpdateStackHeightComposer.java
@@ -1,5 +1,6 @@
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;
@@ -10,14 +11,16 @@ 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, double height) {
+ public UpdateStackHeightComposer(int x, int y, short z, double height) {
this.x = x;
this.y = y;
+ this.z = z;
this.height = height;
}
@@ -40,7 +43,12 @@ public class UpdateStackHeightComposer extends MessageComposer {
updateTiles.remove(t); // remove it from the set
this.response.appendByte((int) t.x);
this.response.appendByte((int) t.y);
- this.response.appendShort(t.relativeHeight());
+ 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());
@@ -51,13 +59,23 @@ public class UpdateStackHeightComposer extends MessageComposer {
for (RoomTile t : this.updateTiles) {
this.response.appendByte((int) t.x);
this.response.appendByte((int) t.y);
- this.response.appendShort(t.relativeHeight());
+ 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);
- this.response.appendShort((int) (this.height));
+ 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/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownComposer5.java b/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownComposer5.java
deleted file mode 100644
index f9e18d7a..00000000
--- a/src/main/java/com/eu/habbo/messages/outgoing/unknown/UnknownComposer5.java
+++ /dev/null
@@ -1,14 +0,0 @@
-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 UnknownComposer5 extends MessageComposer {
- @Override
- protected ServerMessage composeInternal() {
- this.response.init(Outgoing.UnknownComposer5);
- this.response.appendInt(0);
- return this.response;
- }
-}
diff --git a/src/main/java/com/eu/habbo/messages/outgoing/users/UserHomeRoomComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/users/UserHomeRoomComposer.java
index 5ab9a8c3..4aeae0b3 100644
--- a/src/main/java/com/eu/habbo/messages/outgoing/users/UserHomeRoomComposer.java
+++ b/src/main/java/com/eu/habbo/messages/outgoing/users/UserHomeRoomComposer.java
@@ -6,18 +6,18 @@ import com.eu.habbo.messages.outgoing.Outgoing;
public class UserHomeRoomComposer extends MessageComposer {
private final int homeRoom;
- private final int newRoom;
+ private final int roomToEnter;
- public UserHomeRoomComposer(int homeRoom, int newRoom) {
+ public UserHomeRoomComposer(int homeRoom, int roomToEnter) {
this.homeRoom = homeRoom;
- this.newRoom = newRoom;
+ this.roomToEnter = roomToEnter;
}
@Override
protected ServerMessage composeInternal() {
this.response.init(Outgoing.UserHomeRoomComposer);
this.response.appendInt(this.homeRoom);
- this.response.appendInt(this.newRoom);
+ this.response.appendInt(this.roomToEnter);
return this.response;
}
}
diff --git a/src/main/java/com/eu/habbo/messages/rcon/ChangeUsername.java b/src/main/java/com/eu/habbo/messages/rcon/ChangeUsername.java
new file mode 100644
index 00000000..e7cb6c69
--- /dev/null
+++ b/src/main/java/com/eu/habbo/messages/rcon/ChangeUsername.java
@@ -0,0 +1,71 @@
+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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+public class ChangeUsername extends RCONMessage {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ChangeUsername.class);
+
+ 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";
+ LOGGER.error("Exception occurred", e);
+ }
+ }
+
+ static class JSON {
+ public int user_id;
+
+ public boolean canChange;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/eu/habbo/messages/rcon/GiveBadge.java b/src/main/java/com/eu/habbo/messages/rcon/GiveBadge.java
index 98d63c33..4cb93feb 100644
--- a/src/main/java/com/eu/habbo/messages/rcon/GiveBadge.java
+++ b/src/main/java/com/eu/habbo/messages/rcon/GiveBadge.java
@@ -55,16 +55,18 @@ public class GiveBadge extends RCONMessage {
} else {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) {
for (String badgeCode : json.badge.split(";")) {
- boolean found;
+ 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()) {
- found = set.next();
+ if (set.next()){
+ numberOfRows = set.getInt(1);
+ }
}
}
- if (found) {
+ 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 {
@@ -92,4 +94,4 @@ public class GiveBadge extends RCONMessage {
public String badge;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/eu/habbo/messages/rcon/GiveRespect.java b/src/main/java/com/eu/habbo/messages/rcon/GiveRespect.java
index 078f7143..3ffa2621 100644
--- a/src/main/java/com/eu/habbo/messages/rcon/GiveRespect.java
+++ b/src/main/java/com/eu/habbo/messages/rcon/GiveRespect.java
@@ -2,6 +2,7 @@ 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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -26,6 +27,7 @@ public class GiveRespect extends RCONMessage {
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);
diff --git a/src/main/java/com/eu/habbo/networking/rconserver/RCONServer.java b/src/main/java/com/eu/habbo/networking/rconserver/RCONServer.java
index 7bbd9f05..fed9aa56 100644
--- a/src/main/java/com/eu/habbo/networking/rconserver/RCONServer.java
+++ b/src/main/java/com/eu/habbo/networking/rconserver/RCONServer.java
@@ -62,6 +62,7 @@ public class RCONServer extends Server {
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(";"));
}
diff --git a/src/main/java/com/eu/habbo/plugin/events/rooms/RoomFloorItemsLoadEvent.java b/src/main/java/com/eu/habbo/plugin/events/rooms/RoomFloorItemsLoadEvent.java
new file mode 100644
index 00000000..01bea305
--- /dev/null
+++ b/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/src/main/java/com/eu/habbo/plugin/events/users/calendar/UserClaimRewardEvent.java b/src/main/java/com/eu/habbo/plugin/events/users/calendar/UserClaimRewardEvent.java
new file mode 100644
index 00000000..c57f60db
--- /dev/null
+++ b/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/src/main/java/com/eu/habbo/threading/runnables/CrackableExplode.java b/src/main/java/com/eu/habbo/threading/runnables/CrackableExplode.java
index d39b2f57..f5da2ca8 100644
--- a/src/main/java/com/eu/habbo/threading/runnables/CrackableExplode.java
+++ b/src/main/java/com/eu/habbo/threading/runnables/CrackableExplode.java
@@ -1,6 +1,7 @@
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;
@@ -34,7 +35,7 @@ public class CrackableExplode implements Runnable {
if (this.habboItem.getRoomId() == 0) {
return;
}
-//MAKING DINNER BRB
+
if (!this.habboItem.resetable()) {
this.room.removeHabboItem(this.habboItem);
this.room.sendComposer(new RemoveFloorItemComposer(this.habboItem, true).compose());
@@ -43,13 +44,15 @@ public class CrackableExplode implements Runnable {
} 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) {
- if (this.toInventory) {
+ //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());
@@ -66,7 +69,6 @@ public class CrackableExplode implements Runnable {
}
}
-
this.room.updateTile(this.room.getLayout().getTile(this.x, this.y));
}
}
diff --git a/src/main/java/com/eu/habbo/threading/runnables/HabboGiveHandItemToHabbo.java b/src/main/java/com/eu/habbo/threading/runnables/HabboGiveHandItemToHabbo.java
index 3c29ee52..16a59ec5 100644
--- a/src/main/java/com/eu/habbo/threading/runnables/HabboGiveHandItemToHabbo.java
+++ b/src/main/java/com/eu/habbo/threading/runnables/HabboGiveHandItemToHabbo.java
@@ -26,6 +26,8 @@ public class HabboGiveHandItemToHabbo implements Runnable {
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/src/main/java/com/eu/habbo/threading/runnables/RemoveFloorItemTask.java b/src/main/java/com/eu/habbo/threading/runnables/RemoveFloorItemTask.java
index f03b76d9..3a5b7aa7 100644
--- a/src/main/java/com/eu/habbo/threading/runnables/RemoveFloorItemTask.java
+++ b/src/main/java/com/eu/habbo/threading/runnables/RemoveFloorItemTask.java
@@ -24,6 +24,6 @@ class RemoveFloorItemTask implements Runnable {
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.relativeHeight()).compose());
+ this.room.sendComposer(new UpdateStackHeightComposer(this.item.getX(), this.item.getY(), tile.z, tile.relativeHeight()).compose());
}
}
diff --git a/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionThree.java b/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionThree.java
index 521c2f54..ad3cee43 100644
--- a/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionThree.java
+++ b/src/main/java/com/eu/habbo/threading/runnables/teleport/TeleportActionThree.java
@@ -51,6 +51,10 @@ class TeleportActionThree implements Runnable {
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);