Uploading Emulator

This commit is contained in:
duckietm 2024-03-13 11:28:48 +01:00
parent 9f061273ab
commit b017953b91
1824 changed files with 109921 additions and 0 deletions

17
Emulator/.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
logging/
compiled-builds/
*.iml
.idea/
target/**
TODO.txt
packet.pkt
plugins/**
src/test/
target/
config.ini
*.txt
*.jar
*.log
*.zip
.DS_Store

18
Emulator/.gitlab-ci.yml Normal file
View File

@ -0,0 +1,18 @@
image: maven:latest
stages:
- build
build:
stage: build
script:
- mvn package
only:
changes:
- src/**/*
- pom.xml
artifacts:
expire_in: 2 weeks
paths:
- target/Habbo-*.jar

3
Emulator/.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "morningstar-default-database"]
path = morningstar-default-database
url = https://git.krews.org/morningstar/morningstar-default-database

19
Emulator/Dockerfile Normal file
View File

@ -0,0 +1,19 @@
FROM maven:latest AS builder
# Copy the Emulator sources to the container
COPY . .
# Package it
RUN mvn package && mv /target/Habbo*-with-dependencies.jar /target/Habbo.jar
# Use Java 8 for running
FROM java:8 AS runner
# Copy the generated source
COPY --from=builder /target/Habbo.jar /
# Save the script to wait for the database, among running the Arcturus Emulator
RUN echo "#!/bin/bash \n java -Dfile.encoding=UTF-8 -jar /Habbo.jar" > /entrypoint.sh
RUN chmod +x /entrypoint.sh
# Run the Emulator with Java
ENTRYPOINT ["/entrypoint.sh"]

View File

@ -0,0 +1,2 @@
#!/bin/sh
java -Dfile.encoding=UTF8 -Xmx4096m -jar /PATH_TO_YOUR_EMULATOR/Habbo-3.5.3-jar-with-dependencies.jar

View File

@ -0,0 +1 @@
java -Dfile.encoding=UTF8 -Xmx4096m -jar /PATH_TO_YOUR_EMULATOR/Habbo-3.5.3-jar-with-dependencies.jar

165
Emulator/LICENSE Normal file
View File

@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

208
Emulator/featurelist.md Normal file
View File

@ -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
-

200
Emulator/pom.xml Normal file
View File

@ -0,0 +1,200 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.eu.habbo</groupId>
<artifactId>Habbo</artifactId>
<version>3.6.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<additionalparam>-Xdoclint:none</additionalparam>
</properties>
<profiles>
<profile>
<id>java8-doclint-disabled</id>
<activation>
<jdk>[1.8,)</jdk>
</activation>
<properties>
<javadoc.opts>-Xdoclint:none</javadoc.opts>
</properties>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.12.1</version>
<configuration>
<source>16</source>
<target>16</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.eu.habbo.Emulator</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.6.3</version>
<configuration>
<additionalOptions>
<additionalOption>-Xdoclint:none</additionalOption>
</additionalOptions>
<show>public</show>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2/</url>
</repository>
<repository>
<id>mvnrepo</id>
<url>https://mvnrepository.com/</url>
</repository>
</repositories>
<dependencies>
<!-- Netty -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.106.Final</version>
</dependency>
<!-- GSON -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
<!-- MySQL Connector
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.1.4</version>
</dependency> -->
<!-- MySQL Connector -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.3.0</version>
<scope>runtime</scope>
</dependency>
<!-- Trove -->
<dependency>
<groupId>net.sf.trove4j</groupId>
<artifactId>trove4j</artifactId>
<version>3.0.3</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.zaxxer/HikariCP -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.1.0</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-jdk14 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>2.0.11</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.11</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.14.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.17.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.fusesource.jansi</groupId>
<artifactId>jansi</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.12.6</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,527 @@
package com.eu.habbo;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.ConsoleAppender;
import com.eu.habbo.core.*;
import com.eu.habbo.core.consolecommands.ConsoleCommand;
import com.eu.habbo.database.Database;
import com.eu.habbo.habbohotel.GameEnvironment;
import com.eu.habbo.networking.camera.CameraClient;
import com.eu.habbo.networking.gameserver.GameServer;
import com.eu.habbo.networking.rconserver.RCONServer;
import com.eu.habbo.networking.websockets.NetworkChannelInitializer;
import com.eu.habbo.plugin.PluginManager;
import com.eu.habbo.plugin.events.emulator.EmulatorConfigUpdatedEvent;
import com.eu.habbo.plugin.events.emulator.EmulatorLoadedEvent;
import com.eu.habbo.plugin.events.emulator.EmulatorStartShutdownEvent;
import com.eu.habbo.plugin.events.emulator.EmulatorStoppedEvent;
import com.eu.habbo.plugin.events.users.UserGetIPAddressEvent;
import com.eu.habbo.threading.ThreadPooling;
import com.eu.habbo.util.imager.badges.BadgeImager;
import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.security.MessageDigest;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.security.SecureRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
public final class Emulator {
private static final String OS_NAME = (System.getProperty("os.name") != null ? System.getProperty("os.name") : "Unknown");
private static final String CLASS_PATH = (System.getProperty("java.class.path") != null ? System.getProperty("java.class.path") : "Unknown");
private static final SecureRandom secureRandom = new SecureRandom();
public final static int MAJOR = 3;
public final static int MINOR = 6;
public final static int BUILD = 0;
public final static String PREVIEW = "";
public static final String version = "Arcturus Morningstar" + " " + MAJOR + "." + MINOR + "." + BUILD + " " + PREVIEW;
private static final String logo =
"\n" +
"███╗ ███╗ ██████╗ ██████╗ ███╗ ██╗██╗███╗ ██╗ ██████╗ ███████╗████████╗ █████╗ ██████╗ \n" +
"████╗ ████║██╔═══██╗██╔══██╗████╗ ██║██║████╗ ██║██╔════╝ ██╔════╝╚══██╔══╝██╔══██╗██╔══██╗\n" +
"██╔████╔██║██║ ██║██████╔╝██╔██╗ ██║██║██╔██╗ ██║██║ ███╗███████╗ ██║ ███████║██████╔╝\n" +
"██║╚██╔╝██║██║ ██║██╔══██╗██║╚██╗██║██║██║╚██╗██║██║ ██║╚════██║ ██║ ██╔══██║██╔══██╗\n" +
"██║ ╚═╝ ██║╚██████╔╝██║ ██║██║ ╚████║██║██║ ╚████║╚██████╔╝███████║ ██║ ██║ ██║██║ ██║\n" +
"╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝\n" +
" Extended version";
public static String build = "";
public static String debuglevel = "";
public static boolean isReady = false;
public static boolean isShuttingDown = false;
public static boolean stopped = false;
public static boolean debugging = false;
private static int timeStarted = 0;
private static Runtime runtime;
private static ConfigurationManager config;
private static CryptoConfig crypto;
private static TextsManager texts;
private static GameServer gameServer;
private static RCONServer rconServer;
private static CameraClient cameraClient;
private static Logging logging;
private static Database database;
private static DatabaseLogger databaseLogger;
private static ThreadPooling threading;
private static GameEnvironment gameEnvironment;
private static PluginManager pluginManager;
private static BadgeImager badgeImager;
public static final AttributeKey<String> WS_IP = AttributeKey.valueOf("WS_IP");
static {
Thread hook = new Thread(new Runnable() {
public synchronized void run() {
Emulator.dispose();
}
});
hook.setPriority(10);
Runtime.getRuntime().addShutdownHook(hook);
}
public static void main(String[] args) throws Exception {
try {
// Check if running on Windows and not in IntelliJ.
// If so, we need to reconfigure the console appender and enable Jansi for colors.
if (OS_NAME.startsWith("Windows") && !CLASS_PATH.contains("idea_rt.jar")) {
ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
ConsoleAppender<ILoggingEvent> appender = (ConsoleAppender<ILoggingEvent>) root.getAppender("Console");
appender.stop();
appender.setWithJansi(true);
appender.start();
}
Locale.setDefault(new Locale("en"));
setBuild();
Emulator.stopped = false;
ConsoleCommand.load();
Emulator.logging = new Logging();
System.out.println(logo);
log.info("Version: {}", version);
log.info("Build: {}", build);
long startTime = System.nanoTime();
Emulator.runtime = Runtime.getRuntime();
Emulator.config = new ConfigurationManager("config.ini");
Emulator.crypto = new CryptoConfig(
Emulator.getConfig().getBoolean("enc.enabled", false),
Emulator.getConfig().getValue("enc.e"),
Emulator.getConfig().getValue("enc.n"),
Emulator.getConfig().getValue("enc.d"));
Emulator.database = new Database(Emulator.getConfig());
Emulator.databaseLogger = new DatabaseLogger();
Emulator.config.loaded = true;
Emulator.config.loadFromDatabase();
Emulator.threading = new ThreadPooling(Emulator.getConfig().getInt("runtime.threads"));
Emulator.getDatabase().getDataSource().setMaximumPoolSize(Emulator.getConfig().getInt("runtime.threads") * 2);
Emulator.getDatabase().getDataSource().setMinimumIdle(10);
Emulator.pluginManager = new PluginManager();
Emulator.pluginManager.reload();
Emulator.getPluginManager().fireEvent(new EmulatorConfigUpdatedEvent());
Emulator.texts = new TextsManager();
new CleanerThread();
Emulator.gameServer = new GameServer(getConfig().getValue("game.host", "127.0.0.1"), getConfig().getInt("game.port", 30000));
Emulator.rconServer = new RCONServer(getConfig().getValue("rcon.host", "127.0.0.1"), getConfig().getInt("rcon.port", 30001));
Emulator.gameEnvironment = new GameEnvironment();
Emulator.gameEnvironment.load();
Emulator.gameServer.initializePipeline();
Emulator.gameServer.connect();
Emulator.rconServer.initializePipeline();
Emulator.rconServer.connect();
Emulator.badgeImager = new BadgeImager();
Emulator.getConfig().register("websockets.whitelist", "localhost");
Emulator.getConfig().register("ws.nitro.host", "0.0.0.0");
Emulator.getConfig().register("ws.nitro.port", "2096");
Emulator.getConfig().register("ws.nitro.ip.header", "");
NetworkChannelInitializer wsChannelHandler = new NetworkChannelInitializer();
Emulator.getGameServer().getServerBootstrap().childHandler(wsChannelHandler);
Emulator.getGameServer().getServerBootstrap().bind(Emulator.getConfig().getValue("ws.nitro.host", "0.0.0.0"), Emulator.getConfig().getInt("ws.nitro.port", 2096)).sync();
log.info("Websockets has started!");
log.info("Websockets Listening on " + (wsChannelHandler.isSSL() ? "wss://" : "ws://") + Emulator.getConfig().getValue("ws.nitro.host", "0.0.0.0") + ":" + Emulator.getConfig().getInt("ws.nitro.port", 2096));
log.info("Arcturus Morningstar has successfully loaded.");
log.info("System launched in: {}ms. Using {} threads!", (System.nanoTime() - startTime) / 1e6, Runtime.getRuntime().availableProcessors() * 2);
log.info("Memory: {}/{}MB", (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024), (runtime.freeMemory()) / (1024 * 1024));
Emulator.debugging = Emulator.getConfig().getBoolean("debug.mode");
Emulator.debuglevel = Emulator.getConfig().getValue("debug.level", "DEBUG");
/* Debug level can be : INFO WARN DEBUG TRACE*/
if (debugging) {
ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
root.setLevel(Level.DEBUG);
log.debug("Debugging enabled.");
Level logLevel = Level.toLevel(Emulator.debuglevel);
root.setLevel(logLevel);
log.info("Debugging enabled.");
log.info("The loaded debug mode is {}", Emulator.debuglevel);
}
Emulator.getPluginManager().fireEvent(new EmulatorLoadedEvent());
Emulator.isReady = true;
Emulator.timeStarted = getIntUnixTimestamp();
if (Emulator.getConfig().getInt("runtime.threads") < (Runtime.getRuntime().availableProcessors() * 2)) {
log.warn("Emulator settings runtime.threads ({}) can be increased to ({}) to possibly increase performance.",
Emulator.getConfig().getInt("runtime.threads"),
Runtime.getRuntime().availableProcessors() * 2);
}
Emulator.getThreading().run(() -> {
}, 1500);
// Check if console mode is true or false, default is true
if (Emulator.getConfig().getBoolean("console.mode", true)) {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (!isShuttingDown && isReady) {
try {
String line = reader.readLine();
if (line != null) {
ConsoleCommand.handle(line);
}
System.out.println("Waiting for command: ");
} catch (Exception e) {
if (!(e instanceof IOException && e.getMessage().equals("Bad file descriptor"))) {
log.error("Error while reading command", e);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void setBuild() {
if (Emulator.class.getProtectionDomain().getCodeSource() == null) {
build = "UNKNOWN";
return;
}
StringBuilder sb = new StringBuilder();
try {
String filepath = new File(Emulator.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getAbsolutePath();
MessageDigest md = MessageDigest.getInstance("MD5");// MD5
FileInputStream fis = new FileInputStream(filepath);
byte[] dataBytes = new byte[1024];
int nread = 0;
while ((nread = fis.read(dataBytes)) != -1)
md.update(dataBytes, 0, nread);
byte[] mdbytes = md.digest();
for (int i = 0; i < mdbytes.length; i++)
sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
} catch (Exception e) {
build = "UNKNOWN";
return;
}
build = sb.toString();
}
private static void dispose() {
Emulator.getThreading().setCanAdd(false);
Emulator.isShuttingDown = true;
Emulator.isReady = false;
log.info("Stopping Arcturus Morningstar {}", version);
try {
if (Emulator.getPluginManager() != null)
Emulator.getPluginManager().fireEvent(new EmulatorStartShutdownEvent());
} catch (Exception e) {
}
try {
if (Emulator.cameraClient != null)
Emulator.cameraClient.disconnect();
} catch (Exception e) {
}
try {
if (Emulator.rconServer != null)
Emulator.rconServer.stop();
} catch (Exception e) {
}
try {
if (Emulator.gameEnvironment != null)
Emulator.gameEnvironment.dispose();
} catch (Exception e) {
}
try {
if (Emulator.getPluginManager() != null)
Emulator.getPluginManager().fireEvent(new EmulatorStoppedEvent());
} catch (Exception e) {
}
try {
if (Emulator.pluginManager != null)
Emulator.pluginManager.dispose();
} catch (Exception e) {
}
try {
if (Emulator.config != null) {
Emulator.config.saveToDatabase();
}
} catch (Exception e) {
}
try {
if (Emulator.gameServer != null)
Emulator.gameServer.stop();
} catch (Exception e) {
}
log.info("Stopped Arcturus Morningstar {}", version);
if (Emulator.database != null) {
Emulator.getDatabase().dispose();
}
Emulator.stopped = true;
// if (osName.startsWith("Windows") && (!classPath.contains("idea_rt.jar"))) {
// AnsiConsole.systemUninstall();
// }
try {
if (Emulator.threading != null)
Emulator.threading.shutDown();
} catch (Exception e) {
}
}
public static ConfigurationManager getConfig() {
return config;
}
public static CryptoConfig getCrypto() {
return crypto;
}
public static TextsManager getTexts() {
return texts;
}
public static Database getDatabase() {
return database;
}
public static DatabaseLogger getDatabaseLogger() {
return databaseLogger;
}
public static Runtime getRuntime() {
return runtime;
}
public static GameServer getGameServer() {
return gameServer;
}
public static RCONServer getRconServer() {
return rconServer;
}
public void onUserGetIPEvent(UserGetIPAddressEvent e) {
Channel channel = e.habbo.getClient().getChannel();
if(channel != null && channel.hasAttr(Emulator.WS_IP)) {
String ip = channel.attr(Emulator.WS_IP).get();
if(!ip.isEmpty()) {
e.setUpdatedIp(ip);
}
}
}
/**
* @deprecated Do not use. Please use LoggerFactory.getLogger(YourClass.class) to log.
*/
@Deprecated
public static Logging getLogging() {
return logging;
}
public static ThreadPooling getThreading() {
return threading;
}
public static GameEnvironment getGameEnvironment() {
return gameEnvironment;
}
public static PluginManager getPluginManager() {
return pluginManager;
}
public static Random getRandom() {
return ThreadLocalRandom.current();
}
public static SecureRandom getRandomDice() {
return secureRandom;
}
public static BadgeImager getBadgeImager() {
return badgeImager;
}
public static CameraClient getCameraClient() {
return cameraClient;
}
public static synchronized void setCameraClient(CameraClient client) {
cameraClient = client;
}
public static int getTimeStarted() {
return timeStarted;
}
public static int getOnlineTime() {
return getIntUnixTimestamp() - timeStarted;
}
public static void prepareShutdown() {
System.exit(0);
}
public static int timeStringToSeconds(String timeString) {
int totalSeconds = 0;
Matcher m = Pattern.compile("(([0-9]*) (second|minute|hour|day|week|month|year))").matcher(timeString);
Map<String,Integer> map = new HashMap<String,Integer>() {
{
put("second", 1);
put("minute", 60);
put("hour", 3600);
put("day", 86400);
put("week", 604800);
put("month", 2628000);
put("year", 31536000);
}
};
while (m.find()) {
try {
int amount = Integer.parseInt(m.group(2));
String what = m.group(3);
totalSeconds += amount * map.get(what);
}
catch (Exception ignored) { }
}
return totalSeconds;
}
public static Date modifyDate(Date date, String timeString) {
int totalSeconds = 0;
Calendar c = Calendar.getInstance();
c.setTime(date);
Matcher m = Pattern.compile("(([0-9]*) (second|minute|hour|day|week|month|year))").matcher(timeString);
Map<String, Integer> map = new HashMap<String, Integer>() {
{
put("second", Calendar.SECOND);
put("minute", Calendar.MINUTE);
put("hour", Calendar.HOUR);
put("day", Calendar.DAY_OF_MONTH);
put("week", Calendar.WEEK_OF_MONTH);
put("month", Calendar.MONTH);
put("year", Calendar.YEAR);
}
};
while (m.find()) {
try {
int amount = Integer.parseInt(m.group(2));
String what = m.group(3);
c.add(map.get(what), amount);
}
catch (Exception ignored) { }
}
return c.getTime();
}
private static String dateToUnixTimestamp(Date date) {
String res = "";
Date aux = stringToDate("1970-01-01 00:00:00");
Timestamp aux1 = dateToTimeStamp(aux);
Timestamp aux2 = dateToTimeStamp(date);
long difference = aux2.getTime() - aux1.getTime();
long seconds = difference / 1000L;
return res + seconds;
}
public static Date stringToDate(String date) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date res = null;
try {
res = format.parse(date);
} catch (Exception e) {
log.error("Error parsing date", e);
}
return res;
}
public static Timestamp dateToTimeStamp(Date date) {
return new Timestamp(date.getTime());
}
public static Date getDate() {
return new Date(System.currentTimeMillis());
}
public static String getUnixTimestamp() {
return dateToUnixTimestamp(getDate());
}
public static int getIntUnixTimestamp() {
return (int) (System.currentTimeMillis() / 1000);
}
public static boolean isNumeric(String string)
throws IllegalArgumentException {
boolean isnumeric = false;
if ((string != null) && (!string.equals(""))) {
isnumeric = true;
char[] chars = string.toCharArray();
for (char aChar : chars) {
isnumeric = Character.isDigit(aChar);
if (!isnumeric) {
break;
}
}
}
return isnumeric;
}
public int getUserCount() {
return gameEnvironment.getHabboManager().getOnlineCount();
}
public int getRoomCount() {
return gameEnvironment.getRoomManager().getActiveRooms().size();
}
}

View File

@ -0,0 +1,160 @@
package com.eu.habbo.core;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.guilds.forums.ForumThread;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.messages.incoming.friends.SearchUserEvent;
import com.eu.habbo.messages.incoming.navigator.SearchRoomsEvent;
import com.eu.habbo.messages.outgoing.users.UserDataComposer;
import com.eu.habbo.threading.runnables.AchievementUpdater;
import lombok.extern.slf4j.Slf4j;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;
@Slf4j
public class CleanerThread implements Runnable {
private static final int DELAY = 10000;
private static final int RELOAD_HALL_OF_FAME = 1800;
private static final int RELOAD_NEWS_LIST = 3600;
private static final int REMOVE_INACTIVE_ROOMS = 120;
private static final int REMOVE_INACTIVE_GUILDS = 60;
private static final int REMOVE_INACTIVE_TOURS = 600;
private static final int CLEAR_CACHED_VALUES = 60 * 60;
private static final int CALLBACK_TIME = 60 * 15;
private static int LAST_HOF_RELOAD = Emulator.getIntUnixTimestamp();
private static int LAST_NL_RELOAD = Emulator.getIntUnixTimestamp();
private static int LAST_INACTIVE_ROOMS_CLEARED = Emulator.getIntUnixTimestamp();
private static int LAST_INACTIVE_GUILDS_CLEARED = Emulator.getIntUnixTimestamp();
private static int LAST_INACTIVE_TOURS_CLEARED = Emulator.getIntUnixTimestamp();
private static int LAST_DAILY_REFILL = Emulator.getIntUnixTimestamp();
private static int LAST_CALLBACK = Emulator.getIntUnixTimestamp();
private static int LAST_HABBO_CACHE_CLEARED = Emulator.getIntUnixTimestamp();
public CleanerThread() {
this.databaseCleanup();
Emulator.getThreading().run(this, DELAY);
Emulator.getThreading().run(new AchievementUpdater());
// Emulator.getThreading().run(new HTTPVersionCheck(), 10000);
}
@Override
public void run() {
Emulator.getThreading().run(this, DELAY);
int time = Emulator.getIntUnixTimestamp();
if (time - LAST_HOF_RELOAD > RELOAD_HALL_OF_FAME) {
Emulator.getGameEnvironment().getHotelViewManager().getHallOfFame().reload();
LAST_HOF_RELOAD = time;
}
if (time - LAST_NL_RELOAD > RELOAD_NEWS_LIST) {
Emulator.getGameEnvironment().getHotelViewManager().getNewsList().reload();
LAST_NL_RELOAD = time;
}
if (time - LAST_INACTIVE_ROOMS_CLEARED > REMOVE_INACTIVE_ROOMS) {
Emulator.getGameEnvironment().getRoomManager().clearInactiveRooms();
LAST_INACTIVE_ROOMS_CLEARED = time;
}
if (time - LAST_INACTIVE_GUILDS_CLEARED > REMOVE_INACTIVE_GUILDS) {
Emulator.getGameEnvironment().getGuildManager().clearInactiveGuilds();
ForumThread.clearCache();
LAST_INACTIVE_GUILDS_CLEARED = time;
}
if (time - LAST_INACTIVE_TOURS_CLEARED > REMOVE_INACTIVE_TOURS) {
Emulator.getGameEnvironment().getGuideManager().cleanup();
LAST_INACTIVE_TOURS_CLEARED = time;
}
if (time - LAST_CALLBACK > CALLBACK_TIME) {
// Emulator.getThreading().run(new HTTPPostStatus());
LAST_CALLBACK = time;
}
if (time - LAST_DAILY_REFILL > Emulator.getConfig().getInt("hotel.refill.daily")) {
this.refillDailyRespects();
LAST_DAILY_REFILL = time;
}
if (time - LAST_HABBO_CACHE_CLEARED > CLEAR_CACHED_VALUES) {
this.clearCachedValues();
LAST_HABBO_CACHE_CLEARED = time;
}
SearchRoomsEvent.cachedResults.clear();
SearchUserEvent.cachedResults.clear();
}
void databaseCleanup() {
this.refillDailyRespects();
int time = Emulator.getIntUnixTimestamp();
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) {
try (Statement statement = connection.createStatement()) {
statement.execute("UPDATE users SET online = '0' WHERE online = '1'");
statement.execute("UPDATE rooms SET users = '0' WHERE users > 0");
statement.execute("DELETE FROM room_mutes WHERE ends < " + time);
statement.execute("DELETE FROM room_bans WHERE ends < " + time);
statement.execute("DELETE users_favorite_rooms FROM users_favorite_rooms LEFT JOIN rooms ON room_id = rooms.id WHERE rooms.id IS NULL");
}
try (PreparedStatement statement = connection.prepareStatement("UPDATE users_effects SET total = total - 1 WHERE activation_timestamp + duration < ? AND activation_timestamp > 0 AND duration > 0")) {
statement.setInt(1, Emulator.getIntUnixTimestamp());
statement.execute();
}
try (Statement statement = connection.createStatement()) {
statement.execute("DELETE FROM users_effects WHERE total <= 0");
}
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
log.info("Database -> Cleaned!");
}
public void refillDailyRespects() {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users_settings SET daily_respect_points = ?, daily_pet_respect_points = ?")) {
statement.setInt(1, Emulator.getConfig().getInt("hotel.daily.respect"));
statement.setInt(2, Emulator.getConfig().getInt("hotel.daily.respect.pets"));
statement.executeUpdate();
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
if (Emulator.isReady) {
for (Habbo habbo : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().values()) {
habbo.getHabboStats().respectPointsToGive = Emulator.getConfig().getInt("hotel.daily.respect");
habbo.getHabboStats().petRespectPointsToGive = Emulator.getConfig().getInt("hotel.daily.respect.pets");
habbo.getClient().sendResponse(new UserDataComposer(habbo));
}
}
}
private void clearCachedValues() {
Habbo habbo;
for (Map.Entry<Integer, Habbo> map : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) {
habbo = map.getValue();
try {
if (habbo != null) {
habbo.clearCaches();
}
} catch (Exception e) {
log.error("Caught exception", e);
}
}
}
}

View File

@ -0,0 +1,41 @@
package com.eu.habbo.core;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.commands.Command;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class CommandLog implements DatabaseLoggable {
private static final String INSERT_QUERY = "INSERT INTO commandlogs (`user_id`, `timestamp`, `command`, `params`, `succes`) VALUES (?, ?, ?, ?, ?)";
private final int userId;
private final int timestamp = Emulator.getIntUnixTimestamp();
private final Command command;
private final String params;
private final boolean success;
public CommandLog(int userId, Command command, String params, boolean success) {
this.userId = userId;
this.command = command;
this.params = params;
this.success = success;
}
@Override
public String getQuery() {
return CommandLog.INSERT_QUERY;
}
@Override
public void log(PreparedStatement statement) throws SQLException {
statement.setInt(1, this.userId);
statement.setInt(2, this.timestamp);
statement.setString(3, this.command.getClass().getSimpleName());
statement.setString(4, this.params);
statement.setString(5, this.success ? "yes" : "no");
statement.addBatch();
}
}

View File

@ -0,0 +1,226 @@
package com.eu.habbo.core;
import com.eu.habbo.Emulator;
import com.eu.habbo.plugin.events.emulator.EmulatorConfigUpdatedEvent;
import gnu.trove.map.hash.THashMap;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Map;
import java.util.Properties;
@Slf4j
public class ConfigurationManager {
private final Properties properties;
private final String configurationPath;
public boolean loaded = false;
public boolean isLoading = false;
public ConfigurationManager(String configurationPath) {
this.properties = new Properties();
this.configurationPath = configurationPath;
this.reload();
}
public void reload() {
this.isLoading = true;
this.properties.clear();
InputStream input = null;
String envDbHostname = System.getenv("DB_HOSTNAME");
boolean useEnvVarsForDbConnection = false;
if(envDbHostname != null)
{
useEnvVarsForDbConnection = envDbHostname.length() > 1;
}
if (!useEnvVarsForDbConnection) {
try {
File f = new File(this.configurationPath);
input = new FileInputStream(f);
this.properties.load(input);
} catch (IOException ex) {
log.error("Failed to load config file.", ex);
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} else {
Map<String, String> envMapping = new THashMap<>();
// Database section
envMapping.put("db.hostname", "DB_HOSTNAME");
envMapping.put("db.port", "DB_PORT");
envMapping.put("db.database", "DB_DATABASE");
envMapping.put("db.username", "DB_USERNAME");
envMapping.put("db.password", "DB_PASSWORD");
envMapping.put("db.params", "DB_PARAMS");
// Game Configuration
envMapping.put("game.host", "EMU_HOST");
envMapping.put("game.port", "EMU_PORT");
// RCON
envMapping.put("rcon.host", "RCON_HOST");
envMapping.put("rcon.port", "RCON_PORT");
envMapping.put("rcon.allowed", "RCON_ALLOWED");
// Runtime
envMapping.put("runtime.threads", "RT_THREADS");
envMapping.put("logging.errors.runtime", "RT_LOG_ERRORS");
for (Map.Entry<String, String> entry : envMapping.entrySet()) {
String envValue = System.getenv(entry.getValue());
if (envValue == null || envValue.length() == 0) {
log.info("Cannot find environment-value for variable `" + entry.getValue() + "`");
} else {
this.properties.setProperty(entry.getKey(), envValue);
}
}
}
if (this.loaded) {
this.loadFromDatabase();
}
this.isLoading = false;
log.info("Configuration Manager -> Loaded!");
if (Emulator.getPluginManager() != null) {
Emulator.getPluginManager().fireEvent(new EmulatorConfigUpdatedEvent());
}
}
public void loadFromDatabase() {
log.info("Loading configuration from database...");
long millis = System.currentTimeMillis();
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement()) {
if (statement.execute("SELECT * FROM emulator_settings")) {
try (ResultSet set = statement.getResultSet()) {
while (set.next()) {
this.properties.put(set.getString("key"), set.getString("value"));
}
}
}
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
log.info("Configuration -> loaded! (" + (System.currentTimeMillis() - millis) + " MS)");
}
public void saveToDatabase() {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE emulator_settings SET `value` = ? WHERE `key` = ? LIMIT 1")) {
for (Map.Entry<Object, Object> entry : this.properties.entrySet()) {
statement.setString(1, entry.getValue().toString());
statement.setString(2, entry.getKey().toString());
statement.executeUpdate();
}
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
}
public String getValue(String key) {
return this.getValue(key, "");
}
public String getValue(String key, String defaultValue) {
if (this.isLoading)
return defaultValue;
if (!this.properties.containsKey(key)) {
log.error("Config key not found {}", key);
}
return this.properties.getProperty(key, defaultValue);
}
public boolean getBoolean(String key) {
return this.getBoolean(key, false);
}
public boolean getBoolean(String key, boolean defaultValue) {
if (this.isLoading)
return defaultValue;
try {
return (this.getValue(key, "0").equals("1")) || (this.getValue(key, "false").equals("true"));
} catch (Exception e) {
log.error("Failed to parse key {} with value '{}' to type boolean.", key, this.getValue(key));
}
return defaultValue;
}
public int getInt(String key) {
return this.getInt(key, 0);
}
public int getInt(String key, Integer defaultValue) {
if (this.isLoading)
return defaultValue;
try {
return Integer.parseInt(this.getValue(key, defaultValue.toString()));
} catch (Exception e) {
log.error("Failed to parse key {} with value '{}' to type integer.", key, this.getValue(key));
}
return defaultValue;
}
public double getDouble(String key) {
return this.getDouble(key, 0.0);
}
public double getDouble(String key, Double defaultValue) {
if (this.isLoading)
return defaultValue;
try {
return Double.parseDouble(this.getValue(key, defaultValue.toString()));
} catch (Exception e) {
log.error("Failed to parse key {} with value '{}' to type double.", key, this.getValue(key));
}
return defaultValue;
}
public void update(String key, String value) {
this.properties.setProperty(key, value);
}
public void register(String key, String value) {
if (this.properties.getProperty(key, null) != null)
return;
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO emulator_settings VALUES (?, ?)")) {
statement.setString(1, key);
statement.setString(2, value);
statement.execute();
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
this.update(key, value);
}
}

View File

@ -0,0 +1,66 @@
package com.eu.habbo.core;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.users.Habbo;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
@Slf4j
public class CreditsScheduler extends Scheduler {
public static boolean IGNORE_HOTEL_VIEW;
public static boolean IGNORE_IDLED;
public static double HC_MODIFIER;
public CreditsScheduler() {
super(Emulator.getConfig().getInt("hotel.auto.credits.interval"));
this.reloadConfig();
}
public void reloadConfig() {
if (Emulator.getConfig().getBoolean("hotel.auto.credits.enabled")) {
IGNORE_HOTEL_VIEW = Emulator.getConfig().getBoolean("hotel.auto.credits.ignore.hotelview");
IGNORE_IDLED = Emulator.getConfig().getBoolean("hotel.auto.credits.ignore.idled");
HC_MODIFIER = Emulator.getConfig().getDouble("hotel.auto.credits.hc_modifier", 1.0);
if (this.disposed) {
this.disposed = false;
this.run();
}
} else {
this.disposed = true;
}
}
@Override
public void run() {
super.run();
Habbo habbo;
for (Map.Entry<Integer, Habbo> map : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) {
habbo = map.getValue();
try {
if (habbo != null) {
if (habbo.getHabboInfo().getCurrentRoom() == null && IGNORE_HOTEL_VIEW)
continue;
if (habbo.getRoomUnit().isIdle() && IGNORE_IDLED)
continue;
habbo.giveCredits((int)(habbo.getHabboInfo().getRank().getCreditsTimerAmount() * (habbo.getHabboStats().hasActiveClub() ? HC_MODIFIER : 1.0)));
}
} catch (Exception e) {
log.error("Caught exception", e);
}
}
}
public boolean isDisposed() {
return this.disposed;
}
public void setDisposed(boolean disposed) {
this.disposed = disposed;
}
}

View File

@ -0,0 +1,33 @@
package com.eu.habbo.core;
public class CryptoConfig {
private final boolean enabled;
private final String exponent;
private final String modulus;
private final String privateExponent;
public CryptoConfig(boolean enabled, String exponent, String modulus, String privateExponent) {
this.enabled = enabled;
this.exponent = exponent;
this.modulus = modulus;
this.privateExponent = privateExponent;
}
public boolean isEnabled() {
return enabled;
}
public String getExponent() {
return exponent;
}
public String getModulus() {
return modulus;
}
public String getPrivateExponent() {
return privateExponent;
}
}

View File

@ -0,0 +1,12 @@
package com.eu.habbo.core;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public interface DatabaseLoggable {
String getQuery();
void log(PreparedStatement statement) throws SQLException;
}

View File

@ -0,0 +1,25 @@
package com.eu.habbo.core;
import com.eu.habbo.Emulator;
import lombok.extern.slf4j.Slf4j;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
@Slf4j
public class DatabaseLogger {
public void store(final DatabaseLoggable loggable) {
Emulator.getThreading().run(() -> {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) {
try (PreparedStatement statement = connection.prepareStatement(loggable.getQuery())) {
loggable.log(statement);
statement.executeBatch();
}
} catch (SQLException e) {
log.error("Exception caught while saving loggable to database.", e);
}
});
}
}

View File

@ -0,0 +1,7 @@
package com.eu.habbo.core;
public interface Disposable {
void dispose();
boolean disposed();
}

View File

@ -0,0 +1,25 @@
package com.eu.habbo.core;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomChatMessage;
import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles;
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserRemoveComposer;
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserWhisperComposer;
import com.eu.habbo.plugin.EventHandler;
import com.eu.habbo.plugin.events.users.UserSavedMottoEvent;
public class Easter {
@EventHandler
public static void onUserChangeMotto(UserSavedMottoEvent event) {
if (Emulator.getConfig().getBoolean("easter_eggs.enabled") && event.newMotto.equalsIgnoreCase("crickey!")) {
event.habbo.getClient().sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(event.newMotto, event.habbo, event.habbo, RoomChatMessageBubbles.ALERT)));
Room room = event.habbo.getHabboInfo().getCurrentRoom();
room.sendComposer(new RoomUserRemoveComposer(event.habbo.getRoomUnit()).compose());
room.sendComposer(new RoomUserPetComposer(2, 1, "FFFFFF", event.habbo).compose());
}
}
}

View File

@ -0,0 +1,63 @@
package com.eu.habbo.core;
import com.eu.habbo.Emulator;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.PreparedStatement;
import java.sql.SQLException;
@Slf4j
public class ErrorLog implements DatabaseLoggable {
private static final String QUERY = "INSERT INTO emulator_errors (timestamp, version, build_hash, type, stacktrace) VALUES (?, ?, ?, ?, ?)";
public final String version;
public final String buildHash;
public final int timeStamp;
public final String type;
public final String stackTrace;
public ErrorLog(String type, Throwable e) {
this.version = Emulator.version;
this.buildHash = Emulator.version;
this.timeStamp = Emulator.getIntUnixTimestamp();
this.type = type;
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
this.stackTrace = sw.toString();
try {
pw.close();
sw.close();
} catch (IOException e1) {
log.error("Exception caught", e1);
}
}
public ErrorLog(String type, String message) {
this.version = Emulator.version;
this.buildHash = Emulator.build;
this.timeStamp = Emulator.getIntUnixTimestamp();
this.type = type;
this.stackTrace = message;
}
@Override
public String getQuery() {
return QUERY;
}
@Override
public void log(PreparedStatement statement) throws SQLException {
statement.setInt(1, this.timeStamp);
statement.setString(2, this.version);
statement.setString(3, this.buildHash);
statement.setString(4, this.type);
statement.setString(5, this.stackTrace);
statement.addBatch();
}
}

View File

@ -0,0 +1,79 @@
package com.eu.habbo.core;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.users.Habbo;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
@Slf4j
public class GotwPointsScheduler extends Scheduler {
public static boolean IGNORE_HOTEL_VIEW;
public static boolean IGNORE_IDLED;
public static String GOTW_POINTS_NAME;
public static double HC_MODIFIER;
public GotwPointsScheduler() { //TODO MOVE TO A PLUGIN. IS NOT PART OF OFFICIAL HABBO.
super(Emulator.getConfig().getInt("hotel.auto.gotwpoints.interval"));
this.reloadConfig();
}
public void reloadConfig() {
if (Emulator.getConfig().getBoolean("hotel.auto.gotwpoints.enabled")) {
IGNORE_HOTEL_VIEW = Emulator.getConfig().getBoolean("hotel.auto.gotwpoints.ignore.hotelview");
IGNORE_IDLED = Emulator.getConfig().getBoolean("hotel.auto.gotwpoints.ignore.idled");
HC_MODIFIER = Emulator.getConfig().getDouble("hotel.auto.gotwpoints.hc_modifier", 1.0);
GOTW_POINTS_NAME = Emulator.getConfig().getValue("hotel.auto.gotwpoints.name");
if (this.disposed) {
this.disposed = false;
this.run();
}
} else {
this.disposed = true;
}
}
@Override
public void run() {
super.run();
Habbo habbo;
for (Map.Entry<Integer, Habbo> map : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) {
habbo = map.getValue();
try {
if (habbo != null) {
if (habbo.getHabboInfo().getCurrentRoom() == null && IGNORE_HOTEL_VIEW)
continue;
if (habbo.getRoomUnit().isIdle() && IGNORE_IDLED)
continue;
int type;
boolean found = false;
for (String s : Emulator.getConfig().getValue("seasonal.currency.names").split(";")) {
if (s.equalsIgnoreCase(GOTW_POINTS_NAME) || (GOTW_POINTS_NAME.startsWith(s) && Math.abs(s.length() - GOTW_POINTS_NAME.length()) < 3)) {
found = true;
break;
}
}
type = Emulator.getConfig().getInt("seasonal.currency." + GOTW_POINTS_NAME, -1);
if (found || type != -1) {
habbo.givePoints(type, (int)(habbo.getHabboInfo().getRank().getGotwTimerAmount() * (habbo.getHabboStats().hasActiveClub() ? HC_MODIFIER : 1.0)));
}
}
} catch (Exception e) {
log.error("Caught exception", e);
}
}
}
public boolean isDisposed() {
return this.disposed;
}
public void setDisposed(boolean disposed) {
this.disposed = disposed;
}
}

View File

@ -0,0 +1,63 @@
package com.eu.habbo.core;
import com.eu.habbo.Emulator;
import lombok.extern.slf4j.Slf4j;
import java.sql.SQLException;
@Slf4j
public class Logging {
@Deprecated
public void logStart(Object line) {
log.info("[LOADING] {}", line);
}
@Deprecated
public void logShutdownLine(Object line) {
log.info("[SHUTDOWN] {}", line);
}
@Deprecated
public void logUserLine(Object line) {
log.info("[USER] {}", line);
}
@Deprecated
public void logDebugLine(Object line) {
log.debug("[DEBUG] {}", line);
}
@Deprecated
public void logPacketLine(Object line) {
if (Emulator.getConfig().getBoolean("debug.show.packets")) {
log.debug("[PACKET] {}", line);
}
}
@Deprecated
public void logUndefinedPacketLine(Object line) {
if (Emulator.getConfig().getBoolean("debug.show.packets.undefined")) {
log.debug("[PACKET] [UNDEFINED] {}", line);
}
}
@Deprecated
public void logErrorLine(Object line) {
log.error("[ERROR] {}", line);
}
@Deprecated
public void logSQLException(SQLException e) {
log.error("[ERROR] SQLException", e);
}
@Deprecated
public void logPacketError(Object e) {
log.error("[ERROR] PacketError {}", e);
}
@Deprecated
public void handleException(Exception e) {
log.error("[ERROR] Exception", e);
}
}

View File

@ -0,0 +1,63 @@
package com.eu.habbo.core;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.users.Habbo;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
@Slf4j
public class PixelScheduler extends Scheduler {
public static boolean IGNORE_HOTEL_VIEW;
public static boolean IGNORE_IDLED;
public static double HC_MODIFIER;
public PixelScheduler() {
super(Emulator.getConfig().getInt("hotel.auto.pixels.interval"));
this.reloadConfig();
}
public void reloadConfig() {
if (Emulator.getConfig().getBoolean("hotel.auto.pixels.enabled")) {
IGNORE_HOTEL_VIEW = Emulator.getConfig().getBoolean("hotel.auto.pixels.ignore.hotelview");
IGNORE_IDLED = Emulator.getConfig().getBoolean("hotel.auto.pixels.ignore.idled");
HC_MODIFIER = Emulator.getConfig().getDouble("hotel.auto.pixels.hc_modifier", 1.0);
if (this.disposed) {
this.disposed = false;
this.run();
}
} else {
this.disposed = true;
}
}
@Override
public void run() {
super.run();
Habbo habbo;
for (Map.Entry<Integer, Habbo> map : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) {
habbo = map.getValue();
try {
if (habbo != null) {
if (habbo.getHabboInfo().getCurrentRoom() == null && IGNORE_HOTEL_VIEW)
continue;
if (habbo.getRoomUnit().isIdle() && IGNORE_IDLED)
continue;
habbo.givePixels((int)(habbo.getHabboInfo().getRank().getPixelsTimerAmount() * (habbo.getHabboStats().hasActiveClub() ? HC_MODIFIER : 1.0)));
}
} catch (Exception e) {
log.error("Caught exception", e);
}
}
}
public boolean isDisposed() {
return this.disposed;
}
public void setDisposed(boolean disposed) {
this.disposed = disposed;
}
}

View File

@ -0,0 +1,66 @@
package com.eu.habbo.core;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.users.Habbo;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
@Slf4j
public class PointsScheduler extends Scheduler {
public static boolean IGNORE_HOTEL_VIEW;
public static boolean IGNORE_IDLED;
public static double HC_MODIFIER;
public PointsScheduler() {
super(Emulator.getConfig().getInt("hotel.auto.points.interval"));
this.reloadConfig();
}
public void reloadConfig() {
if (Emulator.getConfig().getBoolean("hotel.auto.points.enabled")) {
IGNORE_HOTEL_VIEW = Emulator.getConfig().getBoolean("hotel.auto.points.ignore.hotelview");
IGNORE_IDLED = Emulator.getConfig().getBoolean("hotel.auto.points.ignore.idled");
HC_MODIFIER = Emulator.getConfig().getDouble("hotel.auto.points.hc_modifier", 1.0);
if (this.disposed) {
this.disposed = false;
this.run();
}
} else {
this.disposed = true;
}
}
@Override
public void run() {
super.run();
Habbo habbo;
for (Map.Entry<Integer, Habbo> map : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) {
habbo = map.getValue();
try {
if (habbo != null) {
if (habbo.getHabboInfo().getCurrentRoom() == null && IGNORE_HOTEL_VIEW)
continue;
if (habbo.getRoomUnit().isIdle() && IGNORE_IDLED)
continue;
//habbo.givePoints(POINTS);
habbo.givePoints((int)(habbo.getHabboInfo().getRank().getDiamondsTimerAmount() * (habbo.getHabboStats().hasActiveClub() ? HC_MODIFIER : 1.0)));
}
} catch (Exception e) {
log.error("Caught exception", e);
}
}
}
public boolean isDisposed() {
return this.disposed;
}
public void setDisposed(boolean disposed) {
this.disposed = disposed;
}
}

View File

@ -0,0 +1,49 @@
package com.eu.habbo.core;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.messages.ServerMessage;
import com.eu.habbo.messages.outgoing.MessageComposer;
import com.eu.habbo.messages.outgoing.Outgoing;
public class RoomUserPetComposer extends MessageComposer {
private final int petType;
private final int race;
private final String color;
private final Habbo habbo;
public RoomUserPetComposer(int petType, int race, String color, Habbo habbo) {
this.petType = petType;
this.race = race;
this.color = color;
this.habbo = habbo;
}
@Override
protected ServerMessage composeInternal() {
this.response.init(Outgoing.RoomUsersComposer);
this.response.appendInt(1);
this.response.appendInt(this.habbo.getHabboInfo().getId());
this.response.appendString(this.habbo.getHabboInfo().getUsername());
this.response.appendString("");
this.response.appendString(this.petType + " " + this.race + " " + this.color + " 2 2 -1 0 3 -1 0");
this.response.appendInt(this.habbo.getRoomUnit().getId());
this.response.appendInt(this.habbo.getRoomUnit().getX());
this.response.appendInt(this.habbo.getRoomUnit().getY());
this.response.appendString(this.habbo.getRoomUnit().getZ() + "");
this.response.appendInt(this.habbo.getRoomUnit().getBodyRotation().getValue());
this.response.appendInt(2);
this.response.appendInt(this.petType);
this.response.appendInt(this.habbo.getHabboInfo().getId());
this.response.appendString(this.habbo.getHabboInfo().getUsername());
this.response.appendInt(1);
this.response.appendBoolean(false);
this.response.appendBoolean(true);
this.response.appendBoolean(true); //Can toggle breeding permissions.
this.response.appendBoolean(true);
this.response.appendBoolean(true); //Can treat?
this.response.appendBoolean(true); //Can breed
this.response.appendInt(0);
this.response.appendString("");
return this.response;
}
}

View File

@ -0,0 +1,36 @@
package com.eu.habbo.core;
import com.eu.habbo.Emulator;
public class Scheduler implements Runnable {
protected boolean disposed;
protected int interval;
public Scheduler(int interval) {
this.interval = interval;
}
public boolean isDisposed() {
return this.disposed;
}
public void setDisposed(boolean disposed) {
this.disposed = disposed;
}
public int getInterval() {
return this.interval;
}
public void setInterval(int interval) {
this.interval = interval;
}
@Override
public void run() {
if (this.disposed)
return;
Emulator.getThreading().run(this, this.interval * 1000);
}
}

View File

@ -0,0 +1,97 @@
package com.eu.habbo.core;
import com.eu.habbo.Emulator;
import lombok.extern.slf4j.Slf4j;
import java.sql.*;
import java.util.Properties;
@Slf4j
public class TextsManager {
private final Properties texts;
public TextsManager() {
long millis = System.currentTimeMillis();
this.texts = new Properties();
try {
this.reload();
log.info("Texts Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)");
} catch (Exception e) {
e.printStackTrace();
}
}
public void reload() throws Exception {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM emulator_texts")) {
while (set.next()) {
if (this.texts.containsKey(set.getString("key"))) {
this.texts.setProperty(set.getString("key"), set.getString("value"));
} else {
this.texts.put(set.getString("key"), set.getString("value"));
}
}
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
}
public String getValue(String key) {
return this.getValue(key, "");
}
public String getValue(String key, String defaultValue) {
if (!this.texts.containsKey(key)) {
log.error("Text key not found: {}", key);
}
return this.texts.getProperty(key, defaultValue);
}
public boolean getBoolean(String key) {
return this.getBoolean(key, false);
}
public boolean getBoolean(String key, Boolean defaultValue) {
try {
return (this.getValue(key, "0").equals("1")) || (this.getValue(key, "false").equals("true"));
} catch (Exception e) {
log.error("Caught exception", e);
}
return defaultValue;
}
public int getInt(String key) {
return this.getInt(key, 0);
}
public int getInt(String key, Integer defaultValue) {
try {
return Integer.parseInt(this.getValue(key, defaultValue.toString()));
} catch (NumberFormatException e) {
log.error("Caught exception", e);
}
return defaultValue;
}
public void update(String key, String value) {
this.texts.setProperty(key, value);
}
public void register(String key, String value) {
if (this.texts.getProperty(key, null) != null)
return;
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO emulator_texts VALUES (?, ?)")) {
statement.setString(1, key);
statement.setString(2, value);
statement.execute();
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
this.update(key, value);
}
}

View File

@ -0,0 +1,62 @@
package com.eu.habbo.core.consolecommands;
import gnu.trove.map.hash.THashMap;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public abstract class ConsoleCommand {
private static final THashMap<String, ConsoleCommand> commands = new THashMap<>();
public final String key;
public final String usage;
public ConsoleCommand(String key, String usage) {
this.key = key;
this.usage = usage;
}
public static void load() {
addCommand(new ConsoleShutdownCommand());
addCommand(new ConsoleInfoCommand());
addCommand(new ConsoleTestCommand());
addCommand(new ConsoleReconnectCameraCommand());
addCommand(new ShowInteractionsCommand());
addCommand(new ShowRCONCommands());
addCommand(new ThankyouArcturusCommand());
}
public static void addCommand(ConsoleCommand command) {
commands.put(command.key, command);
}
public static ConsoleCommand findCommand(String key) {
return commands.get(key);
}
public static boolean handle(String line) {
String[] message = line.split(" ");
if (message.length > 0) {
ConsoleCommand command = ConsoleCommand.findCommand(message[0]);
if (command != null) {
try {
command.handle(message);
return true;
} catch (Exception e) {
log.error("Caught exception", e);
}
} else {
log.info("Unknown Console Command " + message[0]);
log.info("Commands Available (" + commands.size() + "): ");
for (ConsoleCommand c : commands.values()) {
log.info(c.key + " - " + c.usage);
}
}
}
return false;
}
public abstract void handle(String[] args) throws Exception;
}

View File

@ -0,0 +1,40 @@
package com.eu.habbo.core.consolecommands;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.catalog.CatalogManager;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@Slf4j
public class ConsoleInfoCommand extends ConsoleCommand {
public ConsoleInfoCommand() {
super("info", "Show current statistics.");
}
@Override
public void handle(String[] args) throws Exception {
int seconds = Emulator.getIntUnixTimestamp() - Emulator.getTimeStarted();
int day = (int) TimeUnit.SECONDS.toDays(seconds);
long hours = TimeUnit.SECONDS.toHours(seconds) - (day * 24);
long minute = TimeUnit.SECONDS.toMinutes(seconds) - (TimeUnit.SECONDS.toHours(seconds) * 60);
long second = TimeUnit.SECONDS.toSeconds(seconds) - (TimeUnit.SECONDS.toMinutes(seconds) * 60);
log.info("Emulator version: " + Emulator.version);
log.info("Emulator build: " + Emulator.build);
log.info("");
log.info("Hotel Statistics");
log.info("- Users: " + Emulator.getGameEnvironment().getHabboManager().getOnlineCount());
log.info("- Rooms: " + Emulator.getGameEnvironment().getRoomManager().getActiveRooms().size());
log.info("- Shop: " + Emulator.getGameEnvironment().getCatalogManager().catalogPages.size() + " pages and " + CatalogManager.catalogItemAmount + " items.");
log.info("- Furni: " + Emulator.getGameEnvironment().getItemManager().getItems().size() + " items.");
log.info("");
log.info("Server Statistics");
log.info("- Uptime: " + day + (day > 1 ? " days, " : " day, ") + hours + (hours > 1 ? " hours, " : " hour, ") + minute + (minute > 1 ? " minutes, " : " minute, ") + second + (second > 1 ? " seconds!" : " second!"));
log.info("- RAM Usage: " + (Emulator.getRuntime().totalMemory() - Emulator.getRuntime().freeMemory()) / (1024 * 1024) + "/" + (Emulator.getRuntime().freeMemory()) / (1024 * 1024) + "MB");
log.info("- CPU Cores: " + Emulator.getRuntime().availableProcessors());
log.info("- Total Memory: " + Emulator.getRuntime().maxMemory() / (1024 * 1024) + "MB");
}
}

View File

@ -0,0 +1,17 @@
package com.eu.habbo.core.consolecommands;
import com.eu.habbo.networking.camera.CameraClient;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ConsoleReconnectCameraCommand extends ConsoleCommand {
public ConsoleReconnectCameraCommand() {
super("camera", "Attempt to reconnect to the camera server.");
}
@Override
public void handle(String[] args) throws Exception {
log.info("Connecting to the camera...");
CameraClient.attemptReconnect = true;
}
}

View File

@ -0,0 +1,14 @@
package com.eu.habbo.core.consolecommands;
import com.eu.habbo.habbohotel.commands.ShutdownCommand;
public class ConsoleShutdownCommand extends ConsoleCommand {
public ConsoleShutdownCommand() {
super("stop", "Stop the emulator.");
}
@Override
public void handle(String[] args) throws Exception {
new ShutdownCommand().handle(null, args);
}
}

View File

@ -0,0 +1,22 @@
package com.eu.habbo.core.consolecommands;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.users.Habbo;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ConsoleTestCommand extends ConsoleCommand {
public ConsoleTestCommand() {
super("test", "This is just a test.");
}
@Override
public void handle(String[] args) throws Exception {
if (Emulator.debugging) {
log.info("This is a test command for live debugging.");
//AchievementManager.progressAchievement(4, Emulator.getGameEnvironment().getAchievementManager().getAchievement("AllTimeHotelPresence"), 30);
Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(1);
habbo.getHabboInfo().getMachineID();
}
}
}

View File

@ -0,0 +1,19 @@
package com.eu.habbo.core.consolecommands;
import com.eu.habbo.Emulator;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ShowInteractionsCommand extends ConsoleCommand {
public ShowInteractionsCommand() {
super("interactions", "Show a list of available furniture interactions.");
}
@Override
public void handle(String[] args) throws Exception {
for (String interaction : Emulator.getGameEnvironment().getItemManager().getInteractionList()) {
log.info(interaction);
}
}
}

View File

@ -0,0 +1,19 @@
package com.eu.habbo.core.consolecommands;
import com.eu.habbo.Emulator;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ShowRCONCommands extends ConsoleCommand {
public ShowRCONCommands() {
super("rconcommands", "Show a list of all RCON commands");
}
@Override
public void handle(String[] args) throws Exception {
for (String command : Emulator.getRconServer().getCommands()) {
log.info(command);
}
}
}

View File

@ -0,0 +1,42 @@
package com.eu.habbo.core.consolecommands;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ThankyouArcturusCommand extends ConsoleCommand {
public ThankyouArcturusCommand() {
super("thankyou", "A thankyou message.");
}
@Override
public void handle(String[] args) throws Exception {
log.info("Arcturus Morningstar is an opensource community fork of Arcturus Emulator by TheGeneral");
log.info("Thankyou to the following people who have helped with it's development:");
log.info("TheGeneral - For Creating Arcturus.");
log.info("Capheus - Decompilation");
log.info("Beny - Lead Developer");
log.info("Alejandro - Lead Developer");
log.info("Harmonic - Developer");
log.info("ArpyAge - Developer");
log.info("Mike - Developer");
log.info("Skeletor - Developer");
log.info("zGrav - Developer");
log.info("Swirny - Developer");
log.info("Quadral - Developer");
log.info("Dome - Developer");
log.info("Necmi - Developer");
log.info("Oliver - Support");
log.info("Rasmus - Support");
log.info("Layne - Support");
log.info("Bill - Support");
log.info("Harmony - Support");
log.info("Ridge - Catalogue");
log.info("Tenshie - Catalogue");
log.info("Wulles - Catalogue");
log.info("Gizmo - Catalogue");
log.info("TheJava - Motivation");
log.info("The Entire Krews.org Community.");
}
}

View File

@ -0,0 +1,108 @@
package com.eu.habbo.crypto;
import com.eu.habbo.crypto.exceptions.HabboCryptoException;
import com.eu.habbo.crypto.utils.BigIntegerUtils;
import com.eu.habbo.util.HexUtils;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ThreadLocalRandom;
public class HabboDiffieHellman {
private static final int DH_PRIMES_BIT_SIZE = 128;
private static final int DH_KEY_BIT_SIZE = 128;
private final HabboRSACrypto crypto;
private BigInteger DHPrime;
private BigInteger DHGenerator;
private BigInteger DHPrivate;
private BigInteger DHPublic;
public HabboDiffieHellman(HabboRSACrypto crypto) {
this.crypto = crypto;
this.generateDHPrimes();
this.generateDHKeys();
}
public BigInteger getDHPrime() {
return DHPrime;
}
public BigInteger getDHGenerator() {
return DHGenerator;
}
private void generateDHPrimes() {
this.DHPrime = BigInteger.probablePrime(DH_PRIMES_BIT_SIZE, ThreadLocalRandom.current());
this.DHGenerator = BigInteger.probablePrime(DH_PRIMES_BIT_SIZE, ThreadLocalRandom.current());
if (this.DHGenerator.compareTo(this.DHPrime) > 0) {
BigInteger temp = this.DHPrime;
this.DHPrime = this.DHGenerator;
this.DHGenerator = temp;
}
}
private void generateDHKeys() {
this.DHPrivate = BigInteger.probablePrime(DH_KEY_BIT_SIZE, ThreadLocalRandom.current());
this.DHPublic = this.DHGenerator.modPow(this.DHPrivate, this.DHPrime);
}
private String encryptBigInteger(BigInteger integer) throws HabboCryptoException {
String str = integer.toString(10);
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
byte[] encrypted = this.crypto.Sign(bytes);
return HexUtils.toHex(encrypted).toLowerCase();
}
private BigInteger decryptBigInteger(String str) throws HabboCryptoException {
byte[] bytes = HexUtils.toBytes(str);
byte[] decrypted = this.crypto.Decrypt(bytes);
String intStr = new String(decrypted, StandardCharsets.UTF_8);
return new BigInteger(intStr, 10);
}
public String getPublicKey() throws HabboCryptoException {
return encryptBigInteger(this.DHPublic);
}
public String getSignedPrime() throws HabboCryptoException {
return encryptBigInteger(this.DHPrime);
}
public String getSignedGenerator() throws HabboCryptoException {
return encryptBigInteger(this.DHGenerator);
}
public void doHandshake(String signedPrime, String signedGenerator) throws HabboCryptoException {
this.DHPrime = decryptBigInteger(signedPrime);
this.DHGenerator = decryptBigInteger(signedGenerator);
if (this.DHPrime == null || this.DHGenerator == null) {
throw new HabboCryptoException("DHPrime or DHGenerator was null.");
}
if (this.DHPrime.compareTo(BigInteger.valueOf(2)) < 1) {
throw new HabboCryptoException("Prime cannot be <= 2!\nPrime: " + this.DHPrime.toString());
}
if (this.DHGenerator.compareTo(this.DHPrime) > -1) {
throw new HabboCryptoException("Generator cannot be >= Prime!\nPrime: " + this.DHPrime.toString() + "\nGenerator: " + this.DHGenerator.toString());
}
generateDHKeys();
}
public byte[] getSharedKey(String publicKeyStr) throws HabboCryptoException {
BigInteger publicKey = this.decryptBigInteger(publicKeyStr);
BigInteger sharedKey = publicKey.modPow(this.DHPrivate, this.DHPrime);
return BigIntegerUtils.toUnsignedByteArray(sharedKey);
}
}

View File

@ -0,0 +1,21 @@
package com.eu.habbo.crypto;
public class HabboEncryption {
private final HabboRSACrypto crypto;
private final HabboDiffieHellman diffie;
public HabboEncryption(String e, String n, String d) {
this.crypto = new HabboRSACrypto(e, n, d);
this.diffie = new HabboDiffieHellman(this.crypto);
}
public HabboRSACrypto getCrypto() {
return crypto;
}
public HabboDiffieHellman getDiffie() {
return diffie;
}
}

View File

@ -0,0 +1,46 @@
package com.eu.habbo.crypto;
public class HabboRC4 {
private int i;
private int j;
private final int[] table = new int[256];
public HabboRC4(byte[] key) {
int length = key.length;
while (this.i < 256) {
table[this.i] = this.i;
this.i++;
}
this.i = 0;
this.j = 0;
while (this.i < 256) {
this.j = ((this.j + this.table[this.i]) + (key[this.i % length] & 0xff)) % 256;
this.swap(this.i, this.j);
this.i++;
}
this.i = 0;
this.j = 0;
}
private void swap(int a, int b) {
int num = table[a];
table[a] = table[b];
table[b] = num;
}
public void parse(byte[] bytes) {
for (int index1 = 0; index1 < bytes.length; index1++) {
this.i = (this.i + 1) % 256;
this.j = (this.j + this.table[this.i]) % 256;
this.swap(this.i, this.j);
bytes[index1] = (byte) ((bytes[index1] & 0xFF) ^ this.table[(this.table[this.i] + this.table[this.j]) % 256]);
}
}
}

View File

@ -0,0 +1,168 @@
package com.eu.habbo.crypto;
import com.eu.habbo.crypto.exceptions.HabboCryptoException;
import com.eu.habbo.crypto.utils.BigIntegerUtils;
import org.apache.commons.lang3.mutable.MutableInt;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.concurrent.ThreadLocalRandom;
public class HabboRSACrypto {
private final BigInteger e;
private final BigInteger n;
private final BigInteger d;
private final int blockSize;
public HabboRSACrypto(String e, String n) {
this.e = new BigInteger(e, 16);
this.n = new BigInteger(n, 16);
this.d = null;
this.blockSize = (this.n.bitLength() + 7) / 8;
}
public HabboRSACrypto(String e, String n, String d) {
this.e = new BigInteger(e, 16);
this.n = new BigInteger(n, 16);
this.d = new BigInteger(d, 16);
this.blockSize = (this.n.bitLength() + 7) / 8;
}
public byte[] Encrypt(byte[] data) throws HabboCryptoException {
return DoEncrypt(data, true, 2);
}
public byte[] Decrypt(byte[] data) throws HabboCryptoException {
return DoDecrypt(data, false, 2);
}
public byte[] Sign(byte[] data) throws HabboCryptoException {
return DoEncrypt(data, false, 1);
}
public byte[] Verify(byte[] data) throws HabboCryptoException {
return DoDecrypt(data, true, 1);
}
private BigInteger DoPublic(BigInteger x) {
return x.modPow(this.e, this.n);
}
private BigInteger DoPrivate(BigInteger x) {
return x.modPow(this.d, this.n);
}
private byte[] DoEncrypt(byte[] data, boolean isPublic, int padType) throws HabboCryptoException {
try (ByteArrayOutputStream dst = new ByteArrayOutputStream()) {
int bl = this.blockSize;
int end = data.length;
MutableInt pos = new MutableInt(0);
while (pos.intValue() < end) {
byte[] padded = Pkcs1Pad(data, pos, end, bl, padType);
BigInteger block = new BigInteger(padded);
BigInteger chunk = isPublic ? DoPublic(block) : DoPrivate(block);
for (int b = (int) (bl - Math.ceil(chunk.bitLength() / 8.0)); b > 0; --b) {
dst.write(0x00);
}
dst.write(BigIntegerUtils.toUnsignedByteArray(chunk));
}
return dst.toByteArray();
} catch (IOException e) {
throw new HabboCryptoException(e);
}
}
private byte[] DoDecrypt(byte[] data, boolean isPublic, int padType) throws HabboCryptoException {
if (data.length % this.blockSize != 0) {
throw new HabboCryptoException("Decryption data was not in blocks of " + this.blockSize + " bytes, total " + data.length + ".");
}
try (ByteArrayOutputStream dst = new ByteArrayOutputStream()) {
int end = data.length;
int pos = 0;
while (pos < end) {
byte[] blockData = new byte[this.blockSize];
System.arraycopy(data, pos, blockData, 0, this.blockSize);
BigInteger block = new BigInteger(1, blockData);
BigInteger chunk = isPublic ? DoPublic(block) : DoPrivate(block);
byte[] unpadded = Pkcs1Unpad(chunk.toByteArray(), this.blockSize, padType);
pos += this.blockSize;
dst.write(unpadded);
}
return dst.toByteArray();
} catch (IOException e) {
throw new HabboCryptoException(e);
}
}
private static byte[] Pkcs1Pad(byte[] src, MutableInt pos, int end, int n, int padType) {
byte[] result = new byte[n];
int p = pos.intValue();
end = Math.min(end, Math.min(src.length, p + n - 11));
pos.setValue(end);
int i = end - 1;
while (i >= p && n > 11) {
result[--n] = src[i--];
}
result[--n] = 0;
if (padType == 2) {
while (n > 2) {
result[--n] = (byte) ThreadLocalRandom.current().nextInt(1, 256);
}
} else {
while (n > 2) {
result[--n] = (byte) 0xFF;
}
}
result[--n] = (byte) padType;
result[--n] = 0;
return result;
}
private static byte[] Pkcs1Unpad(byte[] b, int n, int padType) throws HabboCryptoException {
byte[] result = new byte[n];
int resultPos = 0;
int i = 0;
while (i < b.length && b[i] == 0) {
++i;
}
if (b.length - i != n - 1 || b[i] != padType) {
throw new HabboCryptoException("PKCS#1 unpad: i=" + i + ", expected b[i]==" + padType + ", got b[i]=" + b[i]);
}
++i;
while (b[i] != 0) {
if (++i >= b.length) {
throw new HabboCryptoException("PKCS#1 unpad: i=" + i + ", b[i-1]!=0 (=" + b[i-1] + ")");
}
}
while (++i < b.length) {
result[resultPos++] = b[i];
}
byte[] resultCopy = new byte[resultPos];
System.arraycopy(result, 0, resultCopy, 0, resultPos);
return resultCopy;
}
}

View File

@ -0,0 +1,17 @@
package com.eu.habbo.crypto.exceptions;
public class HabboCryptoException extends Exception {
public HabboCryptoException(String message) {
super(message);
}
public HabboCryptoException(String message, Throwable cause) {
super(message, cause);
}
public HabboCryptoException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,17 @@
package com.eu.habbo.crypto.utils;
import java.math.BigInteger;
import java.util.Arrays;
public class BigIntegerUtils {
public static byte[] toUnsignedByteArray(BigInteger bigInteger) {
byte[] bytes = bigInteger.toByteArray();
if (bytes[0] == 0) {
bytes = Arrays.copyOfRange(bytes, 1, bytes.length);
}
return bytes;
}
}

View File

@ -0,0 +1,109 @@
package com.eu.habbo.database;
import com.eu.habbo.Emulator;
import com.eu.habbo.core.ConfigurationManager;
import com.zaxxer.hikari.HikariDataSource;
import gnu.trove.map.hash.THashMap;
import gnu.trove.set.hash.THashSet;
import lombok.extern.slf4j.Slf4j;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
public class Database {
private HikariDataSource dataSource;
private DatabasePool databasePool;
public Database(ConfigurationManager config) {
long millis = System.currentTimeMillis();
boolean SQLException = false;
try {
this.databasePool = new DatabasePool();
if (!this.databasePool.getStoragePooling(config)) {
log.info("Failed to connect to the database. Please check config.ini and make sure the MySQL process is running. Shutting down...");
SQLException = true;
return;
}
this.dataSource = this.databasePool.getDatabase();
} catch (Exception e) {
SQLException = true;
log.error("Failed to connect to your database.", e);
} finally {
if (SQLException) {
Emulator.prepareShutdown();
}
}
log.info("Database -> Connected! ({} MS)", System.currentTimeMillis() - millis);
}
public void dispose() {
if (this.databasePool != null) {
this.databasePool.getDatabase().close();
}
this.dataSource.close();
}
public HikariDataSource getDataSource() {
return this.dataSource;
}
public DatabasePool getDatabasePool() {
return this.databasePool;
}
public static PreparedStatement preparedStatementWithParams(Connection connection, String query, THashMap<String, Object> queryParams) throws SQLException {
THashMap<Integer, Object> params = new THashMap<Integer, Object>();
THashSet<String> quotedParams = new THashSet<>();
for(String key : queryParams.keySet()) {
quotedParams.add(Pattern.quote(key));
}
String regex = "(" + String.join("|", quotedParams) + ")";
Matcher m = Pattern.compile(regex).matcher(query);
int i = 1;
while (m.find()) {
try {
params.put(i, queryParams.get(m.group(1)));
i++;
}
catch (Exception ignored) { }
}
PreparedStatement statement = connection.prepareStatement(query.replaceAll(regex, "?"));
for(Map.Entry<Integer, Object> set : params.entrySet()) {
if(set.getValue().getClass() == String.class) {
statement.setString(set.getKey(), (String)set.getValue());
}
else if(set.getValue().getClass() == Integer.class) {
statement.setInt(set.getKey(), (Integer)set.getValue());
}
else if(set.getValue().getClass() == Double.class) {
statement.setDouble(set.getKey(), (Double)set.getValue());
}
else if(set.getValue().getClass() == Float.class) {
statement.setFloat(set.getKey(), (Float)set.getValue());
}
else if(set.getValue().getClass() == Long.class) {
statement.setLong(set.getKey(), (Long)set.getValue());
}
else {
statement.setObject(set.getKey(), set.getValue());
}
}
return statement;
}
}

View File

@ -0,0 +1,60 @@
package com.eu.habbo.database;
import com.eu.habbo.core.ConfigurationManager;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
@Slf4j
class DatabasePool {
private static final String DB_POOL_MAX_SIZE = "db.pool.maxsize";
private static final String DB_POOL_MIN_SIZE = "db.pool.minsize";
private static final String DB_HOSTNAME_KEY = "db.hostname";
private static final String DB_PORT_KEY = "db.port";
private static final String DB_PASSWORD_KEY = "db.password";
private static final String DB_NAME_KEY = "db.database";
private static final String DB_USER_KEY = "db.username";
private static final String DB_PARAMS_KEY = "db.params";
private HikariDataSource database;
private static DatabasePool instance;
DatabasePool() {
// Private constructor for singleton pattern
}
public static synchronized DatabasePool getInstance() {
if (instance == null) {
instance = new DatabasePool();
}
return instance;
}
public boolean getStoragePooling(ConfigurationManager config) {
try {
HikariConfig databaseConfiguration = new HikariConfig();
databaseConfiguration.setMaximumPoolSize(config.getInt(DB_POOL_MAX_SIZE, 50));
databaseConfiguration.setMinimumIdle(config.getInt(DB_POOL_MIN_SIZE, 10));
databaseConfiguration.setJdbcUrl("jdbc:mysql://" + config.getValue(DB_HOSTNAME_KEY, "localhost") + ":" + config.getValue(DB_PORT_KEY, "3306") + "/" + config.getValue(DB_NAME_KEY) + config.getValue(DB_PARAMS_KEY));
databaseConfiguration.addDataSourceProperty("serverName", config.getValue(DB_HOSTNAME_KEY, "localhost"));
databaseConfiguration.addDataSourceProperty("port", config.getValue(DB_PORT_KEY, "3306"));
databaseConfiguration.addDataSourceProperty("databaseName", config.getValue(DB_NAME_KEY));
databaseConfiguration.addDataSourceProperty("user", config.getValue(DB_USER_KEY));
databaseConfiguration.addDataSourceProperty("password", config.getValue(DB_PASSWORD_KEY));
log.info("INITIALIZING DATABASE SERVER: " + config.getValue(DB_HOSTNAME_KEY));
log.info("ON PORT: " + config.getValue(DB_PORT_KEY));
log.info("HABBO DATABASE: " + config.getValue(DB_NAME_KEY));
this.database = new HikariDataSource(databaseConfiguration);
} catch (Exception e) {
log.error("Error initializing database connection pool: {}", e.getMessage());
return false;
}
return true;
}
public HikariDataSource getDatabase() {
if (database == null) {
throw new IllegalStateException("Database connection pool is not initialized.");
}
return database;
}
}

View File

@ -0,0 +1,212 @@
package com.eu.habbo.habbohotel;
import com.eu.habbo.Emulator;
import com.eu.habbo.core.*;
import com.eu.habbo.habbohotel.achievements.AchievementManager;
import com.eu.habbo.habbohotel.bots.BotManager;
import com.eu.habbo.habbohotel.campaign.calendar.CalendarManager;
import com.eu.habbo.habbohotel.catalog.CatalogManager;
import com.eu.habbo.habbohotel.commands.CommandHandler;
import com.eu.habbo.habbohotel.crafting.CraftingManager;
import com.eu.habbo.habbohotel.guides.GuideManager;
import com.eu.habbo.habbohotel.guilds.GuildManager;
import com.eu.habbo.habbohotel.hotelview.HotelViewManager;
import com.eu.habbo.habbohotel.items.ItemManager;
import com.eu.habbo.habbohotel.modtool.ModToolManager;
import com.eu.habbo.habbohotel.modtool.ModToolSanctions;
import com.eu.habbo.habbohotel.modtool.WordFilter;
import com.eu.habbo.habbohotel.navigation.NavigatorManager;
import com.eu.habbo.habbohotel.permissions.PermissionsManager;
import com.eu.habbo.habbohotel.pets.PetManager;
import com.eu.habbo.habbohotel.polls.PollManager;
import com.eu.habbo.habbohotel.rooms.RoomManager;
import com.eu.habbo.habbohotel.users.HabboManager;
import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionManager;
import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionScheduler;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class GameEnvironment {
public CreditsScheduler creditsScheduler;
public PixelScheduler pixelScheduler;
public PointsScheduler pointsScheduler;
public GotwPointsScheduler gotwPointsScheduler;
public SubscriptionScheduler subscriptionScheduler;
private HabboManager habboManager;
private NavigatorManager navigatorManager;
private GuildManager guildManager;
private ItemManager itemManager;
private CatalogManager catalogManager;
private HotelViewManager hotelViewManager;
private RoomManager roomManager;
private CommandHandler commandHandler;
private PermissionsManager permissionsManager;
private BotManager botManager;
private ModToolManager modToolManager;
private ModToolSanctions modToolSanctions;
private PetManager petManager;
private AchievementManager achievementManager;
private GuideManager guideManager;
private WordFilter wordFilter;
private CraftingManager craftingManager;
private PollManager pollManager;
private SubscriptionManager subscriptionManager;
private CalendarManager calendarManager;
public void load() throws Exception {
log.info("GameEnvironment -> Loading...");
this.permissionsManager = new PermissionsManager();
this.habboManager = new HabboManager();
this.hotelViewManager = new HotelViewManager();
this.itemManager = new ItemManager();
this.itemManager.load();
this.botManager = new BotManager();
this.petManager = new PetManager();
this.guildManager = new GuildManager();
this.catalogManager = new CatalogManager();
this.roomManager = new RoomManager();
this.navigatorManager = new NavigatorManager();
this.commandHandler = new CommandHandler();
this.modToolManager = new ModToolManager();
this.modToolSanctions = new ModToolSanctions();
this.achievementManager = new AchievementManager();
this.achievementManager.reload();
this.guideManager = new GuideManager();
this.wordFilter = new WordFilter();
this.craftingManager = new CraftingManager();
this.pollManager = new PollManager();
this.calendarManager = new CalendarManager();
this.roomManager.loadPublicRooms();
this.navigatorManager.loadNavigator();
this.creditsScheduler = new CreditsScheduler();
Emulator.getThreading().run(this.creditsScheduler);
this.pixelScheduler = new PixelScheduler();
Emulator.getThreading().run(this.pixelScheduler);
this.pointsScheduler = new PointsScheduler();
Emulator.getThreading().run(this.pointsScheduler);
this.gotwPointsScheduler = new GotwPointsScheduler();
Emulator.getThreading().run(this.gotwPointsScheduler);
this.subscriptionManager = new SubscriptionManager();
this.subscriptionManager.init();
this.subscriptionScheduler = new SubscriptionScheduler();
Emulator.getThreading().run(this.subscriptionScheduler);
log.info("GameEnvironment -> Loaded!");
}
public void dispose() {
this.pointsScheduler.setDisposed(true);
this.pixelScheduler.setDisposed(true);
this.creditsScheduler.setDisposed(true);
this.gotwPointsScheduler.setDisposed(true);
this.craftingManager.dispose();
this.habboManager.dispose();
this.commandHandler.dispose();
this.guildManager.dispose();
this.catalogManager.dispose();
this.roomManager.dispose();
this.itemManager.dispose();
this.hotelViewManager.dispose();
this.subscriptionManager.dispose();
this.calendarManager.dispose();
log.info("GameEnvironment -> Disposed!");
}
public HabboManager getHabboManager() {
return this.habboManager;
}
public NavigatorManager getNavigatorManager() {
return this.navigatorManager;
}
public GuildManager getGuildManager() {
return this.guildManager;
}
public ItemManager getItemManager() {
return this.itemManager;
}
public CatalogManager getCatalogManager() {
return this.catalogManager;
}
public HotelViewManager getHotelViewManager() {
return this.hotelViewManager;
}
public RoomManager getRoomManager() {
return this.roomManager;
}
public CommandHandler getCommandHandler() {
return this.commandHandler;
}
public PermissionsManager getPermissionsManager() {
return this.permissionsManager;
}
public BotManager getBotManager() {
return this.botManager;
}
public ModToolManager getModToolManager() {
return this.modToolManager;
}
public ModToolSanctions getModToolSanctions() {
return this.modToolSanctions;
}
public PetManager getPetManager() {
return this.petManager;
}
public AchievementManager getAchievementManager() {
return this.achievementManager;
}
public GuideManager getGuideManager() {
return this.guideManager;
}
public WordFilter getWordFilter() {
return this.wordFilter;
}
public CraftingManager getCraftingManager() {
return this.craftingManager;
}
public PollManager getPollManager() {
return this.pollManager;
}
public CreditsScheduler getCreditsScheduler() {
return this.creditsScheduler;
}
public PixelScheduler getPixelScheduler() {
return this.pixelScheduler;
}
public PointsScheduler getPointsScheduler() { return this.pointsScheduler;
}
public GotwPointsScheduler getGotwPointsScheduler() { return this.gotwPointsScheduler;
}
public SubscriptionManager getSubscriptionManager() {
return this.subscriptionManager;
}
public CalendarManager getCalendarManager() { return this.calendarManager; }
}

View File

@ -0,0 +1,47 @@
package com.eu.habbo.habbohotel;
import com.eu.habbo.habbohotel.gameclients.GameClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
public class LatencyTracker {
private static final Logger LOGGER = LoggerFactory.getLogger(GameClient.class);
private boolean initialPing;
private long last;
private long average;
public LatencyTracker() {
this.initialPing = true;
this.average = 0;
}
public void update(long latencyInNano) {
this.last = latencyInNano;
if (this.initialPing) {
this.initialPing = false;
this.average = latencyInNano;
return;
}
this.average = (long) (this.average * .7f + latencyInNano * .3f);
}
public boolean hasInitialized() {
return !this.initialPing;
}
public long getLastMs() {
return TimeUnit.NANOSECONDS.toMillis(this.last);
}
public long getAverageMs() {
return TimeUnit.NANOSECONDS.toMillis(this.average);
}
}

View File

@ -0,0 +1,77 @@
package com.eu.habbo.habbohotel.achievements;
import gnu.trove.map.hash.THashMap;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Achievement {
public final int id;
public final String name;
public final AchievementCategories category;
public final THashMap<Integer, AchievementLevel> levels;
public Achievement(ResultSet set) throws SQLException {
this.levels = new THashMap<>();
this.id = set.getInt("id");
this.name = set.getString("name");
this.category = AchievementCategories.valueOf(set.getString("category").toUpperCase());
this.addLevel(new AchievementLevel(set));
}
public void addLevel(AchievementLevel level) {
synchronized (this.levels) {
this.levels.put(level.level, level);
}
}
public AchievementLevel getLevelForProgress(int progress) {
AchievementLevel l = null;
if (progress > 0) {
for (AchievementLevel level : this.levels.values()) {
if (progress >= level.progress) {
if (l != null) {
if (l.level > level.level) {
continue;
}
}
l = level;
}
}
}
return l;
}
public AchievementLevel getNextLevel(int currentLevel) {
AchievementLevel l = null;
for (AchievementLevel level : this.levels.values()) {
if (level.level == (currentLevel + 1))
return level;
}
return null;
}
public AchievementLevel firstLevel() {
return this.levels.get(1);
}
public void clearLevels() {
this.levels.clear();
}
}

View File

@ -0,0 +1,39 @@
package com.eu.habbo.habbohotel.achievements;
public enum AchievementCategories {
IDENTITY,
EXPLORE,
MUSIC,
SOCIAL,
GAMES,
ROOM_BUILDER,
PETS,
TOOLS,
OTHER,
TEST,
INVISIBLE,
EVENTS
}

View File

@ -0,0 +1,29 @@
package com.eu.habbo.habbohotel.achievements;
import java.sql.ResultSet;
import java.sql.SQLException;
public class AchievementLevel {
public final int level;
public final int rewardAmount;
public final int rewardType;
public final int points;
public final int progress;
public AchievementLevel(ResultSet set) throws SQLException {
this.level = set.getInt("level");
this.rewardAmount = set.getInt("reward_amount");
this.rewardType = set.getInt("reward_type");
this.points = set.getInt("points");
this.progress = set.getInt("progress_needed");
}
}

View File

@ -0,0 +1,394 @@
package com.eu.habbo.habbohotel.achievements;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.habbohotel.users.HabboBadge;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.messages.outgoing.achievements.AchievementProgressComposer;
import com.eu.habbo.messages.outgoing.achievements.AchievementUnlockedComposer;
import com.eu.habbo.messages.outgoing.achievements.talenttrack.TalentLevelUpdateComposer;
import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer;
import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer;
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer;
import com.eu.habbo.messages.outgoing.users.AddUserBadgeComposer;
import com.eu.habbo.messages.outgoing.users.UserBadgesComposer;
import com.eu.habbo.plugin.Event;
import com.eu.habbo.plugin.events.users.achievements.UserAchievementLeveledEvent;
import com.eu.habbo.plugin.events.users.achievements.UserAchievementProgressEvent;
import gnu.trove.map.hash.THashMap;
import gnu.trove.procedure.TObjectIntProcedure;
import lombok.extern.slf4j.Slf4j;
import java.sql.*;
import java.util.LinkedHashMap;
import java.util.Map;
@Slf4j
public class AchievementManager {
public static boolean TALENTTRACK_ENABLED = false;
private final THashMap<String, Achievement> achievements;
private final THashMap<TalentTrackType, LinkedHashMap<Integer, TalentTrackLevel>> talentTrackLevels;
public AchievementManager() {
this.achievements = new THashMap<>();
this.talentTrackLevels = new THashMap<>();
}
public static void progressAchievement(int habboId, Achievement achievement) {
progressAchievement(habboId, achievement, 1);
}
public static void progressAchievement(int habboId, Achievement achievement, int amount) {
if (achievement != null) {
Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(habboId);
if (habbo != null) {
progressAchievement(habbo, achievement, amount);
} else {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
PreparedStatement statement = connection.prepareStatement("" +
"INSERT INTO users_achievements_queue (user_id, achievement_id, amount) VALUES (?, ?, ?) " +
"ON DUPLICATE KEY UPDATE amount = amount + ?")) {
statement.setInt(1, habboId);
statement.setInt(2, achievement.id);
statement.setInt(3, amount);
statement.setInt(4, amount);
statement.execute();
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
}
}
}
public static void progressAchievement(Habbo habbo, Achievement achievement) {
progressAchievement(habbo, achievement, 1);
}
public static void progressAchievement(Habbo habbo, Achievement achievement, int amount) {
if (achievement == null)
return;
if (habbo == null)
return;
if (!habbo.isOnline())
return;
int currentProgress = habbo.getHabboStats().getAchievementProgress(achievement);
if (currentProgress == -1) {
currentProgress = 0;
createUserEntry(habbo, achievement);
habbo.getHabboStats().setProgress(achievement, 0);
}
if (Emulator.getPluginManager().isRegistered(UserAchievementProgressEvent.class, true)) {
Event userAchievementProgressedEvent = new UserAchievementProgressEvent(habbo, achievement, amount);
Emulator.getPluginManager().fireEvent(userAchievementProgressedEvent);
if (userAchievementProgressedEvent.isCancelled())
return;
}
AchievementLevel oldLevel = achievement.getLevelForProgress(currentProgress);
if (oldLevel != null && (oldLevel.level == achievement.levels.size() && currentProgress >= oldLevel.progress)) //Maximum achievement gotten.
return;
habbo.getHabboStats().setProgress(achievement, currentProgress + amount);
AchievementLevel newLevel = achievement.getLevelForProgress(currentProgress + amount);
if (AchievementManager.TALENTTRACK_ENABLED) {
for (TalentTrackType type : TalentTrackType.values()) {
if (Emulator.getGameEnvironment().getAchievementManager().talentTrackLevels.containsKey(type)) {
for (Map.Entry<Integer, TalentTrackLevel> entry : Emulator.getGameEnvironment().getAchievementManager().talentTrackLevels.get(type).entrySet()) {
if (entry.getValue().achievements.containsKey(achievement)) {
Emulator.getGameEnvironment().getAchievementManager().handleTalentTrackAchievement(habbo, type, achievement);
break;
}
}
}
}
}
if (newLevel == null ||
(oldLevel != null && (oldLevel.level == newLevel.level && newLevel.level < achievement.levels.size()))) {
habbo.getClient().sendResponse(new AchievementProgressComposer(habbo, achievement));
} else {
if (Emulator.getPluginManager().isRegistered(UserAchievementLeveledEvent.class, true)) {
Event userAchievementLeveledEvent = new UserAchievementLeveledEvent(habbo, achievement, oldLevel, newLevel);
Emulator.getPluginManager().fireEvent(userAchievementLeveledEvent);
if (userAchievementLeveledEvent.isCancelled())
return;
}
habbo.getClient().sendResponse(new AchievementProgressComposer(habbo, achievement));
habbo.getClient().sendResponse(new AchievementUnlockedComposer(habbo, achievement));
//Exception could possibly arise when the user disconnects while being in tour.
//The achievement is then progressed but the user is already disposed so fetching
//the badge would result in an nullpointer exception. This is normal behaviour.
HabboBadge badge = null;
if (oldLevel != null) {
try {
badge = habbo.getInventory().getBadgesComponent().getBadge(("ACH_" + achievement.name + oldLevel.level).toLowerCase());
} catch (Exception e) {
log.error("Caught exception", e);
return;
}
}
String newBadgCode = "ACH_" + achievement.name + newLevel.level;
if (badge != null) {
badge.setCode(newBadgCode);
badge.needsInsert(false);
badge.needsUpdate(true);
} else {
if (habbo.getInventory().getBadgesComponent().hasBadge(newBadgCode))
return;
badge = new HabboBadge(0, newBadgCode, 0, habbo);
habbo.getClient().sendResponse(new AddUserBadgeComposer(badge));
badge.needsInsert(true);
badge.needsUpdate(true);
habbo.getInventory().getBadgesComponent().addBadge(badge);
}
Emulator.getThreading().run(badge);
if (badge.getSlot() > 0) {
if (habbo.getHabboInfo().getCurrentRoom() != null) {
habbo.getHabboInfo().getCurrentRoom().sendComposer(new UserBadgesComposer(habbo.getInventory().getBadgesComponent().getWearingBadges(), habbo.getHabboInfo().getId()).compose());
}
}
habbo.getClient().sendResponse(new AddHabboItemComposer(badge.getId(), AddHabboItemComposer.AddHabboItemCategory.BADGE));
habbo.getHabboStats().addAchievementScore(newLevel.points);
if (newLevel.rewardAmount > 0) {
habbo.givePoints(newLevel.rewardType, newLevel.rewardAmount);
}
if (habbo.getHabboInfo().getCurrentRoom() != null) {
habbo.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserDataComposer(habbo).compose());
}
}
}
public static boolean hasAchieved(Habbo habbo, Achievement achievement) {
int currentProgress = habbo.getHabboStats().getAchievementProgress(achievement);
if (currentProgress == -1) {
return false;
}
AchievementLevel level = achievement.getLevelForProgress(currentProgress);
if (level == null)
return false;
AchievementLevel nextLevel = achievement.levels.get(level.level + 1);
return nextLevel == null && currentProgress >= level.progress;
}
public static void createUserEntry(Habbo habbo, Achievement achievement) {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO users_achievements (user_id, achievement_name, progress) VALUES (?, ?, ?)")) {
statement.setInt(1, habbo.getHabboInfo().getId());
statement.setString(2, achievement.name);
statement.setInt(3, 1);
statement.execute();
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
}
public static void saveAchievements(Habbo habbo) {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users_achievements SET progress = ? WHERE achievement_name = ? AND user_id = ? LIMIT 1")) {
statement.setInt(3, habbo.getHabboInfo().getId());
for (Map.Entry<Achievement, Integer> map : habbo.getHabboStats().getAchievementProgress().entrySet()) {
statement.setInt(1, map.getValue());
statement.setString(2, map.getKey().name);
statement.addBatch();
}
statement.executeBatch();
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
}
public static int getAchievementProgressForHabbo(int userId, Achievement achievement) {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT progress FROM users_achievements WHERE user_id = ? AND achievement_name = ? LIMIT 1")) {
statement.setInt(1, userId);
statement.setString(2, achievement.name);
try (ResultSet set = statement.executeQuery()) {
if (set.next()) {
return set.getInt("progress");
}
}
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
return 0;
}
public void reload() {
long millis = System.currentTimeMillis();
synchronized (this.achievements) {
for (Achievement achievement : this.achievements.values()) {
achievement.clearLevels();
}
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) {
try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM achievements")) {
while (set.next()) {
if (!this.achievements.containsKey(set.getString("name"))) {
this.achievements.put(set.getString("name"), new Achievement(set));
} else {
this.achievements.get(set.getString("name")).addLevel(new AchievementLevel(set));
}
}
} catch (SQLException e) {
log.error("Caught SQL exception", e);
} catch (Exception e) {
log.error("Caught exception", e);
}
synchronized (this.talentTrackLevels) {
this.talentTrackLevels.clear();
try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM achievements_talents ORDER BY level ASC")) {
while (set.next()) {
TalentTrackLevel level = new TalentTrackLevel(set);
if (!this.talentTrackLevels.containsKey(level.type)) {
this.talentTrackLevels.put(level.type, new LinkedHashMap<>());
}
this.talentTrackLevels.get(level.type).put(level.level, level);
}
}
}
} catch (SQLException e) {
log.error("Caught SQL exception", e);
log.error("Achievement Manager -> Failed to load!");
return;
}
}
log.info("Achievement Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)");
}
public Achievement getAchievement(String name) {
return this.achievements.get(name);
}
public Achievement getAchievement(int id) {
synchronized (this.achievements) {
for (Map.Entry<String, Achievement> set : this.achievements.entrySet()) {
if (set.getValue().id == id) {
return set.getValue();
}
}
}
return null;
}
public THashMap<String, Achievement> getAchievements() {
return this.achievements;
}
public LinkedHashMap<Integer, TalentTrackLevel> getTalenTrackLevels(TalentTrackType type) {
return this.talentTrackLevels.get(type);
}
public TalentTrackLevel calculateTalenTrackLevel(Habbo habbo, TalentTrackType type) {
TalentTrackLevel level = null;
for (Map.Entry<Integer, TalentTrackLevel> entry : this.talentTrackLevels.get(type).entrySet()) {
final boolean[] allCompleted = {true};
entry.getValue().achievements.forEachEntry(new TObjectIntProcedure<Achievement>() {
@Override
public boolean execute(Achievement a, int b) {
if (habbo.getHabboStats().getAchievementProgress(a) < b) {
allCompleted[0] = false;
}
return allCompleted[0];
}
});
if (allCompleted[0]) {
if (level == null || level.level < entry.getValue().level) {
level = entry.getValue();
}
} else {
break;
}
}
return level;
}
public void handleTalentTrackAchievement(Habbo habbo, TalentTrackType type, Achievement achievement) {
TalentTrackLevel currentLevel = this.calculateTalenTrackLevel(habbo, type);
if (currentLevel != null) {
if (currentLevel.level > habbo.getHabboStats().talentTrackLevel(type)) {
for (int i = habbo.getHabboStats().talentTrackLevel(type); i <= currentLevel.level; i++) {
TalentTrackLevel level = this.getTalentTrackLevel(type, i);
if (level != null) {
if (level.items != null && !level.items.isEmpty()) {
for (Item item : level.items) {
HabboItem rewardItem = Emulator.getGameEnvironment().getItemManager().createItem(habbo.getHabboInfo().getId(), item, 0, 0, "");
habbo.getInventory().getItemsComponent().addItem(rewardItem);
habbo.getClient().sendResponse(new AddHabboItemComposer(rewardItem));
habbo.getClient().sendResponse(new InventoryRefreshComposer());
}
}
if (level.badges != null && level.badges.length > 0) {
for (String badge : level.badges) {
if (!badge.isEmpty()) {
if (!habbo.getInventory().getBadgesComponent().hasBadge(badge)) {
HabboBadge b = new HabboBadge(0, badge, 0, habbo);
Emulator.getThreading().run(b);
habbo.getInventory().getBadgesComponent().addBadge(b);
habbo.getClient().sendResponse(new AddUserBadgeComposer(b));
}
}
}
}
if (level.perks != null && level.perks.length > 0) {
for (String perk : level.perks) {
if (perk.equalsIgnoreCase("TRADE")) {
habbo.getHabboStats().perkTrade = true;
}
}
}
habbo.getClient().sendResponse(new TalentLevelUpdateComposer(type, level));
}
}
}
habbo.getHabboStats().setTalentLevel(type, currentLevel.level);
}
}
public TalentTrackLevel getTalentTrackLevel(TalentTrackType type, int level) {
return this.talentTrackLevels.get(type).get(level);
}
}

View File

@ -0,0 +1,64 @@
package com.eu.habbo.habbohotel.achievements;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.items.Item;
import gnu.trove.map.TObjectIntMap;
import gnu.trove.map.hash.TObjectIntHashMap;
import gnu.trove.set.hash.THashSet;
import lombok.extern.slf4j.Slf4j;
import java.sql.ResultSet;
import java.sql.SQLException;
@Slf4j
public class TalentTrackLevel {
public TalentTrackType type;
public int level;
public TObjectIntMap<Achievement> achievements;
public THashSet<Item> items;
public String[] perks;
public String[] badges;
public TalentTrackLevel(ResultSet set) throws SQLException {
this.type = TalentTrackType.valueOf(set.getString("type").toUpperCase());
this.level = set.getInt("level");
this.achievements = new TObjectIntHashMap<>();
this.items = new THashSet<>();
String[] achievements = set.getString("achievement_ids").split(",");
String[] achievementLevels = set.getString("achievement_levels").split(",");
if (achievementLevels.length == achievements.length) {
for (int i = 0; i < achievements.length; i++) {
if (achievements[i].isEmpty() || achievementLevels[i].isEmpty())
continue;
Achievement achievement = Emulator.getGameEnvironment().getAchievementManager().getAchievement(Integer.valueOf(achievements[i]));
if (achievement != null) {
this.achievements.put(achievement, Integer.valueOf(achievementLevels[i]));
} else {
log.error("Could not find achievement with ID " + achievements[i] + " for talenttrack level " + this.level + " of type " + this.type);
}
}
}
for (String s : set.getString("reward_furni").split(",")) {
Item item = Emulator.getGameEnvironment().getItemManager().getItem(Integer.valueOf(s));
if (item != null) {
this.items.add(item);
} else {
log.error("Incorrect reward furni (ID: " + s + ") for talent track level " + this.level);
}
}
if (!set.getString("reward_perks").isEmpty()) {
this.perks = set.getString("reward_perks").split(",");
}
if (!set.getString("reward_badges").isEmpty()) {
this.badges = set.getString("reward_badges").split(",");
}
}
}

View File

@ -0,0 +1,9 @@
package com.eu.habbo.habbohotel.achievements;
public enum TalentTrackType {
CITIZENSHIP,
HELPER
}

View File

@ -0,0 +1,485 @@
package com.eu.habbo.habbohotel.bots;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.rooms.*;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.habbohotel.users.HabboGender;
import com.eu.habbo.habbohotel.wired.WiredHandler;
import com.eu.habbo.habbohotel.wired.WiredTriggerType;
import com.eu.habbo.messages.outgoing.rooms.users.*;
import com.eu.habbo.plugin.events.bots.BotChatEvent;
import com.eu.habbo.plugin.events.bots.BotShoutEvent;
import com.eu.habbo.plugin.events.bots.BotTalkEvent;
import com.eu.habbo.plugin.events.bots.BotWhisperEvent;
import com.eu.habbo.threading.runnables.BotFollowHabbo;
import lombok.extern.slf4j.Slf4j;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
@Slf4j
public class Bot implements Runnable {
public static final String NO_CHAT_SET = "${bot.skill.chatter.configuration.text.placeholder}";
public static String[] PLACEMENT_MESSAGES = "Yo!;Hello I'm a real party animal!;Hello!".split(";");
private final ArrayList<String> chatLines;
private transient int id;
private String name;
private String motto;
private String figure;
private HabboGender gender;
private int ownerId;
private String ownerName;
private Room room;
private RoomUnit roomUnit;
private boolean chatAuto;
private boolean chatRandom;
private short chatDelay;
private int chatTimeOut;
private int chatTimestamp;
private short lastChatIndex;
private int bubble;
private String type;
private int effect;
private transient boolean canWalk = true;
private boolean needsUpdate;
private transient int followingHabboId;
public Bot(int id, String name, String motto, String figure, HabboGender gender, int ownerId, String ownerName) {
this.id = id;
this.name = name;
this.motto = motto;
this.figure = figure;
this.gender = gender;
this.ownerId = ownerId;
this.ownerName = ownerName;
this.chatAuto = false;
this.chatRandom = false;
this.chatDelay = 1000;
this.chatLines = new ArrayList<>();
this.type = "generic_bot";
this.room = null;
this.bubble = RoomChatMessageBubbles.BOT_RENTABLE.getType();
}
public Bot(ResultSet set) throws SQLException {
this.id = set.getInt("id");
this.name = set.getString("name");
this.motto = set.getString("motto");
this.figure = set.getString("figure");
this.gender = HabboGender.valueOf(set.getString("gender"));
this.ownerId = set.getInt("user_id");
this.ownerName = set.getString("owner_name");
this.chatAuto = set.getString("chat_auto").equals("1");
this.chatRandom = set.getString("chat_random").equals("1");
this.chatDelay = set.getShort("chat_delay");
this.chatLines = new ArrayList<>(Arrays.asList(set.getString("chat_lines").split("\r")));
this.type = set.getString("type");
this.effect = set.getInt("effect");
this.canWalk = set.getString("freeroam").equals("1");
this.room = null;
this.roomUnit = null;
this.chatTimeOut = Emulator.getIntUnixTimestamp() + this.chatDelay;
this.needsUpdate = false;
this.bubble = set.getInt("bubble_id");
}
public Bot(Bot bot) {
this.name = bot.getName();
this.motto = bot.getMotto();
this.figure = bot.getFigure();
this.gender = bot.getGender();
this.ownerId = bot.getOwnerId();
this.ownerName = bot.getOwnerName();
this.chatAuto = true;
this.chatRandom = false;
this.chatDelay = 10;
this.chatTimeOut = Emulator.getIntUnixTimestamp() + this.chatDelay;
this.chatLines = new ArrayList<>(Arrays.asList("Default Message :D"));
this.type = bot.getType();
this.effect = bot.getEffect();
this.bubble = bot.getBubbleId();
this.needsUpdate = false;
}
public static void initialise() {
}
public static void dispose() {
}
public void needsUpdate(boolean needsUpdate) {
this.needsUpdate = needsUpdate;
}
public boolean needsUpdate() {
return this.needsUpdate;
}
@Override
public void run() {
if (this.needsUpdate) {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE bots SET name = ?, motto = ?, figure = ?, gender = ?, user_id = ?, room_id = ?, x = ?, y = ?, z = ?, rot = ?, dance = ?, freeroam = ?, chat_lines = ?, chat_auto = ?, chat_random = ?, chat_delay = ?, effect = ?, bubble_id = ? WHERE id = ?")) {
statement.setString(1, this.name);
statement.setString(2, this.motto);
statement.setString(3, this.figure);
statement.setString(4, this.gender.toString());
statement.setInt(5, this.ownerId);
statement.setInt(6, this.room == null ? 0 : this.room.getId());
statement.setInt(7, this.roomUnit == null ? 0 : this.roomUnit.getX());
statement.setInt(8, this.roomUnit == null ? 0 : this.roomUnit.getY());
statement.setDouble(9, this.roomUnit == null ? 0 : this.roomUnit.getZ());
statement.setInt(10, this.roomUnit == null ? 0 : this.roomUnit.getBodyRotation().getValue());
statement.setInt(11, this.roomUnit == null ? 0 : this.roomUnit.getDanceType().getType());
statement.setString(12, this.canWalk ? "1" : "0");
StringBuilder text = new StringBuilder();
for (String s : this.chatLines) {
text.append(s).append("\r");
}
statement.setString(13, text.toString());
statement.setString(14, this.chatAuto ? "1" : "0");
statement.setString(15, this.chatRandom ? "1" : "0");
statement.setInt(16, this.chatDelay);
statement.setInt(17, this.effect);
statement.setInt(18, this.bubble);
statement.setInt(19, this.id);
statement.execute();
this.needsUpdate = false;
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
}
}
public void cycle(boolean allowBotsWalk) {
if (this.roomUnit != null) {
if (allowBotsWalk && this.canWalk) {
if (!this.roomUnit.isWalking()) {
if (this.roomUnit.getWalkTimeOut() < Emulator.getIntUnixTimestamp() && this.followingHabboId == 0) {
this.roomUnit.setGoalLocation(this.room.getRandomWalkableTile());
int timeOut = Emulator.getRandom().nextInt(20) * 2;
this.roomUnit.setWalkTimeOut((timeOut < 10 ? 5 : timeOut) + Emulator.getIntUnixTimestamp());
}
}/* else {
for (RoomTile t : this.room.getLayout().getTilesAround(this.room.getLayout().getTile(this.getRoomUnit().getX(), this.getRoomUnit().getY()))) {
WiredHandler.handle(WiredTriggerType.BOT_REACHED_STF, this.roomUnit, this.room, this.room.getItemsAt(t).toArray());
}
}*/
}
if (!this.chatLines.isEmpty() && this.chatTimeOut <= Emulator.getIntUnixTimestamp() && this.chatAuto) {
if (this.room != null) {
this.lastChatIndex = (this.chatRandom ? (short) Emulator.getRandom().nextInt(this.chatLines.size()) : (this.lastChatIndex == (this.chatLines.size() - 1) ? 0 : this.lastChatIndex++));
if (this.lastChatIndex >= this.chatLines.size()) {
this.lastChatIndex = 0;
}
String message = this.chatLines.get(this.lastChatIndex)
.replace(Emulator.getTexts().getValue("wired.variable.owner", "%owner%"), this.room.getOwnerName())
.replace(Emulator.getTexts().getValue("wired.variable.item_count", "%item_count%"), this.room.itemCount() + "")
.replace(Emulator.getTexts().getValue("wired.variable.name", "%name%"), this.name)
.replace(Emulator.getTexts().getValue("wired.variable.roomname", "%roomname%"), this.room.getName())
.replace(Emulator.getTexts().getValue("wired.variable.user_count", "%user_count%"), this.room.getUserCount() + ""); // TODO: Should getUserCount be replaced with getUsersWithoutInvisibleHabbos?
if(!WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, this.getRoomUnit(), room, new Object[]{ message })) {
this.talk(message);
}
this.chatTimeOut = Emulator.getIntUnixTimestamp() + this.chatDelay;
}
}
}
}
public void talk(String message) {
if (this.room != null) {
BotChatEvent event = new BotTalkEvent(this, message);
if (Emulator.getPluginManager().fireEvent(event).isCancelled())
return;
this.chatTimestamp = Emulator.getIntUnixTimestamp();
this.room.botChat(new RoomUserTalkComposer(new RoomChatMessage(event.message, this.roomUnit, RoomChatMessageBubbles.getBubble(this.getBubbleId()))).compose());
if (message.equals("o/") || message.equals("_o/")) {
this.room.sendComposer(new RoomUserActionComposer(this.roomUnit, RoomUserAction.WAVE).compose());
}
}
}
public void shout(String message) {
if (this.room != null) {
BotChatEvent event = new BotShoutEvent(this, message);
if (Emulator.getPluginManager().fireEvent(event).isCancelled())
return;
this.chatTimestamp = Emulator.getIntUnixTimestamp();
this.room.botChat(new RoomUserShoutComposer(new RoomChatMessage(event.message, this.roomUnit, RoomChatMessageBubbles.getBubble(this.getBubbleId()))).compose());
if (message.equals("o/") || message.equals("_o/")) {
this.room.sendComposer(new RoomUserActionComposer(this.roomUnit, RoomUserAction.WAVE).compose());
}
}
}
public void whisper(String message, Habbo habbo) {
if (this.room != null && habbo != null) {
BotWhisperEvent event = new BotWhisperEvent(this, message, habbo);
if (Emulator.getPluginManager().fireEvent(event).isCancelled())
return;
this.chatTimestamp = Emulator.getIntUnixTimestamp();
event.target.getClient().sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(event.message, this.roomUnit, RoomChatMessageBubbles.getBubble(this.getBubbleId()))));
}
}
public void onPlace(Habbo habbo, Room room) {
if (this.roomUnit != null) {
room.giveEffect(this.roomUnit, this.effect, -1);
}
if(PLACEMENT_MESSAGES.length > 0) {
String message = PLACEMENT_MESSAGES[Emulator.getRandom().nextInt(PLACEMENT_MESSAGES.length)];
if (!WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, this.getRoomUnit(), room, new Object[]{message})) {
this.talk(message);
}
}
}
public void onPickUp(Habbo habbo, Room room) {
}
public void onUserSay(final RoomChatMessage message) {
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return this.name;
}
public int getBubbleId() {
return bubble;
}
public void setName(String name) {
this.name = name;
this.needsUpdate = true;
//if(this.room != null)
//this.room.sendComposer(new ChangeNameUpdatedComposer(this.getRoomUnit(), this.getName()).compose());
}
public String getMotto() {
return this.motto;
}
public void setMotto(String motto) {
this.motto = motto;
this.needsUpdate = true;
}
public String getFigure() {
return this.figure;
}
public void setFigure(String figure) {
this.figure = figure;
this.needsUpdate = true;
if (this.room != null)
this.room.sendComposer(new RoomUsersComposer(this).compose());
}
public HabboGender getGender() {
return this.gender;
}
public void setGender(HabboGender gender) {
this.gender = gender;
this.needsUpdate = true;
if (this.room != null)
this.room.sendComposer(new RoomUsersComposer(this).compose());
}
public int getOwnerId() {
return this.ownerId;
}
public void setOwnerId(int ownerId) {
this.ownerId = ownerId;
this.needsUpdate = true;
if (this.room != null)
this.room.sendComposer(new RoomUsersComposer(this).compose());
}
public String getOwnerName() {
return this.ownerName;
}
public void setOwnerName(String ownerName) {
this.ownerName = ownerName;
this.needsUpdate = true;
if (this.room != null)
this.room.sendComposer(new RoomUsersComposer(this).compose());
}
public Room getRoom() {
return this.room;
}
public void setRoom(Room room) {
this.room = room;
}
public RoomUnit getRoomUnit() {
return this.roomUnit;
}
public void setRoomUnit(RoomUnit roomUnit) {
this.roomUnit = roomUnit;
}
public boolean isChatAuto() {
return this.chatAuto;
}
public void setChatAuto(boolean chatAuto) {
this.chatAuto = chatAuto;
this.needsUpdate = true;
}
public boolean isChatRandom() {
return this.chatRandom;
}
public void setChatRandom(boolean chatRandom) {
this.chatRandom = chatRandom;
this.needsUpdate = true;
}
public boolean hasChat() {
return !this.chatLines.isEmpty();
}
public int getChatDelay() {
return this.chatDelay;
}
public void setChatDelay(short chatDelay) {
this.chatDelay = (short) Math.min(Math.max(chatDelay, BotManager.MINIMUM_CHAT_SPEED), BotManager.MAXIMUM_CHAT_SPEED);
this.needsUpdate = true;
this.chatTimeOut = Emulator.getIntUnixTimestamp() + this.chatDelay;
}
public int getChatTimestamp() {
return this.chatTimestamp;
}
public void clearChat() {
synchronized (this.chatLines) {
this.chatLines.clear();
this.needsUpdate = true;
}
}
public String getType() {
return this.type;
}
public int getEffect() {
return this.effect;
}
public void setEffect(int effect, int duration) {
this.effect = effect;
this.needsUpdate = true;
if (this.roomUnit != null) {
if (this.room != null) {
this.room.giveEffect(this.roomUnit, this.effect, duration);
}
}
}
public void addChatLines(ArrayList<String> chatLines) {
synchronized (this.chatLines) {
this.chatLines.addAll(chatLines);
this.needsUpdate = true;
}
}
public void addChatLine(String chatLine) {
synchronized (this.chatLines) {
this.chatLines.add(chatLine);
this.needsUpdate = true;
}
}
public ArrayList<String> getChatLines() {
return this.chatLines;
}
public int getFollowingHabboId() {
return this.followingHabboId;
}
public void startFollowingHabbo(Habbo habbo) {
this.followingHabboId = habbo.getHabboInfo().getId();
Emulator.getThreading().run(new BotFollowHabbo(this, habbo, habbo.getHabboInfo().getCurrentRoom()));
}
public void stopFollowingHabbo() {
this.followingHabboId = 0;
}
public boolean canWalk() {
return this.canWalk;
}
public void setCanWalk(boolean canWalk) {
this.canWalk = canWalk;
}
public void lookAt(Habbo habbo) {
this.lookAt(habbo.getRoomUnit().getCurrentLocation());
}
public void lookAt(RoomUnit roomUnit) {
this.lookAt(roomUnit.getCurrentLocation());
}
public void lookAt(RoomTile tile) {
this.roomUnit.lookAtPoint(tile);
this.roomUnit.statusUpdate(true);
}
}

View File

@ -0,0 +1,242 @@
package com.eu.habbo.habbohotel.bots;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.permissions.Permission;
import com.eu.habbo.habbohotel.rooms.*;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.habbohotel.users.HabboInfo;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.messages.outgoing.generic.alerts.BotErrorComposer;
import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer;
import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys;
import com.eu.habbo.messages.outgoing.inventory.AddBotComposer;
import com.eu.habbo.messages.outgoing.inventory.RemoveBotComposer;
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer;
import com.eu.habbo.messages.outgoing.rooms.users.RoomUsersComposer;
import com.eu.habbo.plugin.events.bots.BotPickUpEvent;
import com.eu.habbo.plugin.events.bots.BotPlacedEvent;
import gnu.trove.map.hash.THashMap;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.Map;
@Slf4j
public class BotManager {
final private static THashMap<String, Class<? extends Bot>> botDefenitions = new THashMap<>();
public static int MINIMUM_CHAT_SPEED = 7;
public static int MAXIMUM_CHAT_SPEED = 604800;
public static int MAXIMUM_CHAT_LENGTH = 120;
public static int MAXIMUM_NAME_LENGTH = 15;
public static int MAXIMUM_BOT_INVENTORY_SIZE = 25;
public BotManager() throws Exception {
long millis = System.currentTimeMillis();
addBotDefinition("generic", Bot.class);
addBotDefinition("bartender", ButlerBot.class);
addBotDefinition("visitor_log", VisitorBot.class);
this.reload();
log.info("Bot Manager -> Loaded! (" + (System.currentTimeMillis() - millis) + " MS)");
}
public static void addBotDefinition(String type, Class<? extends Bot> botClazz) throws Exception {
botClazz.getDeclaredConstructor(ResultSet.class).setAccessible(true);
botDefenitions.put(type, botClazz);
}
public boolean reload() {
for (Map.Entry<String, Class<? extends Bot>> set : botDefenitions.entrySet()) {
try {
Method m = set.getValue().getMethod("initialise");
m.setAccessible(true);
m.invoke(null);
} catch (NoSuchMethodException e) {
log.info("Bot Manager -> Failed to execute initialise method upon bot type '" + set.getKey() + "'. No Such Method!");
return false;
} catch (Exception e) {
log.info("Bot Manager -> Failed to execute initialise method upon bot type '" + set.getKey() + "'. Error: " + e.getMessage());
return false;
}
}
return true;
}
public Bot createBot(THashMap<String, String> data, String type) {
Bot bot = null;
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO bots (user_id, room_id, name, motto, figure, gender, type) VALUES (0, 0, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) {
statement.setString(1, data.get("name"));
statement.setString(2, data.get("motto"));
statement.setString(3, data.get("figure"));
statement.setString(4, data.get("gender").toUpperCase());
statement.setString(5, type);
statement.execute();
try (ResultSet set = statement.getGeneratedKeys()) {
if (set.next()) {
try (PreparedStatement stmt = connection.prepareStatement("SELECT users.username AS owner_name, bots.* FROM bots LEFT JOIN users ON bots.user_id = users.id WHERE bots.id = ? LIMIT 1")) {
stmt.setInt(1, set.getInt(1));
try (ResultSet resultSet = stmt.executeQuery()) {
if (resultSet.next()) {
bot = this.loadBot(resultSet);
}
}
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
}
}
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
return bot;
}
public void placeBot(Bot bot, Habbo habbo, Room room, RoomTile location) {
BotPlacedEvent event = new BotPlacedEvent(bot, location, habbo);
Emulator.getPluginManager().fireEvent(event);
if (event.isCancelled())
return;
if (room != null && bot != null && habbo != null) {
if (room.getOwnerId() == habbo.getHabboInfo().getId() || habbo.hasPermission(Permission.ACC_ANYROOMOWNER) || habbo.hasPermission(Permission.ACC_PLACEFURNI)) {
if (room.getCurrentBots().size() >= Room.MAXIMUM_BOTS && !habbo.hasPermission(Permission.ACC_UNLIMITED_BOTS)) {
habbo.getClient().sendResponse(new BotErrorComposer(BotErrorComposer.ROOM_ERROR_MAX_BOTS));
return;
}
if (room.hasHabbosAt(location.x, location.y) || (!location.isWalkable() && location.state != RoomTileState.SIT && location.state != RoomTileState.LAY))
return;
if (room.hasBotsAt(location.x, location.y)) {
habbo.getClient().sendResponse(new BotErrorComposer(BotErrorComposer.ROOM_ERROR_BOTS_SELECTED_TILE_NOT_FREE));
return;
}
RoomUnit roomUnit = new RoomUnit();
roomUnit.setRotation(RoomUserRotation.SOUTH);
roomUnit.setLocation(location);
double stackHeight = location.getStackHeight();
roomUnit.setPreviousLocationZ(stackHeight);
roomUnit.setZ(stackHeight);
roomUnit.setPathFinderRoom(room);
roomUnit.setRoomUnitType(RoomUnitType.BOT);
roomUnit.setCanWalk(room.isAllowBotsWalk());
bot.setRoomUnit(roomUnit);
bot.setRoom(room);
bot.needsUpdate(true);
room.addBot(bot);
Emulator.getThreading().run(bot);
room.sendComposer(new RoomUsersComposer(bot).compose());
room.sendComposer(new RoomUserStatusComposer(bot.getRoomUnit()).compose());
habbo.getInventory().getBotsComponent().removeBot(bot);
habbo.getClient().sendResponse(new RemoveBotComposer(bot));
bot.onPlace(habbo, room);
HabboItem topItem = room.getTopItemAt(location.x, location.y);
if (topItem != null) {
try {
topItem.onWalkOn(bot.getRoomUnit(), room, null);
} catch (Exception e) {
log.error("Caught exception", e);
}
}
bot.cycle(false);
} else {
habbo.getClient().sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, FurnitureMovementError.NO_RIGHTS.errorCode));
}
}
}
public void pickUpBot(int botId, Habbo habbo) {
if (habbo.getHabboInfo().getCurrentRoom() != null) {
this.pickUpBot(habbo.getHabboInfo().getCurrentRoom().getBot(Math.abs(botId)), habbo);
}
}
public void pickUpBot(Bot bot, Habbo habbo) {
HabboInfo receiverInfo = habbo == null ? Emulator.getGameEnvironment().getHabboManager().getHabboInfo(bot.getOwnerId()) : habbo.getHabboInfo();
if (bot != null) {
BotPickUpEvent pickedUpEvent = new BotPickUpEvent(bot, habbo);
Emulator.getPluginManager().fireEvent(pickedUpEvent);
if (pickedUpEvent.isCancelled())
return;
if (habbo == null || (bot.getOwnerId() == habbo.getHabboInfo().getId() || habbo.hasPermission(Permission.ACC_ANYROOMOWNER))) {
if (habbo != null && !habbo.hasPermission(Permission.ACC_UNLIMITED_BOTS) && habbo.getInventory().getBotsComponent().getBots().size() >= BotManager.MAXIMUM_BOT_INVENTORY_SIZE) {
habbo.alert(Emulator.getTexts().getValue("error.bots.max.inventory").replace("%amount%", BotManager.MAXIMUM_BOT_INVENTORY_SIZE + ""));
return;
}
bot.onPickUp(habbo, receiverInfo.getCurrentRoom());
receiverInfo.getCurrentRoom().removeBot(bot);
bot.stopFollowingHabbo();
bot.setOwnerId(receiverInfo.getId());
bot.setOwnerName(receiverInfo.getUsername());
bot.needsUpdate(true);
Emulator.getThreading().run(bot);
Habbo receiver = habbo == null ? Emulator.getGameEnvironment().getHabboManager().getHabbo(receiverInfo.getId()) : habbo;
if (receiver != null) {
receiver.getInventory().getBotsComponent().addBot(bot);
receiver.getClient().sendResponse(new AddBotComposer(bot));
}
}
}
}
public Bot loadBot(ResultSet set) {
try {
String type = set.getString("type");
Class<? extends Bot> botClazz = botDefenitions.get(type);
if (botClazz != null)
return botClazz.getDeclaredConstructor(ResultSet.class).newInstance(set);
else
log.error("Unknown Bot Type: " + type);
} catch (SQLException e) {
log.error("Caught SQL exception", e);
} catch (Exception e) {
log.error("Caught exception", e);
}
return null;
}
public boolean deleteBot(Bot bot) {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM bots WHERE id = ? LIMIT 1")) {
statement.setInt(1, bot.getId());
return statement.execute();
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
return false;
}
public void dispose() {
for (Map.Entry<String, Class<? extends Bot>> set : botDefenitions.entrySet()) {
try {
Method m = set.getValue().getMethod("dispose");
m.setAccessible(true);
m.invoke(null);
} catch (NoSuchMethodException e) {
log.info("Bot Manager -> Failed to execute dispose method upon bot type '" + set.getKey() + "'. No Such Method!");
} catch (Exception e) {
log.info("Bot Manager -> Failed to execute dispose method upon bot type '" + set.getKey() + "'. Error: " + e.getMessage());
}
}
}
}

View File

@ -0,0 +1,142 @@
package com.eu.habbo.habbohotel.bots;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.rooms.RoomChatMessage;
import com.eu.habbo.habbohotel.rooms.RoomUnitStatus;
import com.eu.habbo.habbohotel.wired.WiredHandler;
import com.eu.habbo.habbohotel.wired.WiredTriggerType;
import com.eu.habbo.plugin.events.bots.BotServerItemEvent;
import com.eu.habbo.threading.runnables.RoomUnitGiveHanditem;
import com.eu.habbo.threading.runnables.RoomUnitWalkToRoomUnit;
import gnu.trove.map.hash.THashMap;
import gnu.trove.set.hash.THashSet;
import lombok.extern.slf4j.Slf4j;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@Slf4j
public class ButlerBot extends Bot {
public static THashMap<THashSet<String>, Integer> serveItems = new THashMap<>();
public ButlerBot(ResultSet set) throws SQLException {
super(set);
}
public ButlerBot(Bot bot) {
super(bot);
}
public static void initialise() {
if (serveItems == null)
serveItems = new THashMap<>();
serveItems.clear();
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM bot_serves")) {
while (set.next()) {
String[] keys = set.getString("keys").split(";");
THashSet<String> ks = new THashSet<>();
Collections.addAll(ks, keys);
serveItems.put(ks, set.getInt("item"));
}
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
}
public static void dispose() {
serveItems.clear();
}
@Override
public void onUserSay(final RoomChatMessage message) {
if (this.getRoomUnit().hasStatus(RoomUnitStatus.MOVE) || this.getRoom() == null) {
return;
}
double distanceBetweenBotAndHabbo = this.getRoomUnit().getCurrentLocation().distance(message.getHabbo().getRoomUnit().getCurrentLocation());
if (distanceBetweenBotAndHabbo <= Emulator.getConfig().getInt("hotel.bot.butler.commanddistance")) {
if (message.getUnfilteredMessage() != null) {
for (Map.Entry<THashSet<String>, Integer> set : serveItems.entrySet()) {
for (String keyword : set.getKey()) {
// Check if the string contains a certain keyword using a regex.
// If keyword = tea, teapot wouldn't trigger it.
if (message.getUnfilteredMessage().toLowerCase().matches("\\b" + keyword + "\\b")) {
// Enable plugins to cancel this event
BotServerItemEvent serveEvent = new BotServerItemEvent(this, message.getHabbo(), set.getValue());
if (Emulator.getPluginManager().fireEvent(serveEvent).isCancelled()) {
return;
}
// Start give handitem process
if (this.getRoomUnit().canWalk()) {
final String key = keyword;
final Bot bot = this;
// Step 1: Look at Habbo
bot.lookAt(serveEvent.habbo);
// Step 2: Prepare tasks for when the Bot (carrying the handitem) reaches the Habbo
final List<Runnable> tasks = new ArrayList<>();
tasks.add(new RoomUnitGiveHanditem(serveEvent.habbo.getRoomUnit(), serveEvent.habbo.getHabboInfo().getCurrentRoom(), serveEvent.itemId));
tasks.add(new RoomUnitGiveHanditem(this.getRoomUnit(), serveEvent.habbo.getHabboInfo().getCurrentRoom(), 0));
tasks.add(() -> {
if(this.getRoom() != null) {
String botMessage = Emulator.getTexts()
.getValue("bots.butler.given")
.replace("%key%", key)
.replace("%username%", serveEvent.habbo.getHabboInfo().getUsername());
if (!WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, this.getRoomUnit(), this.getRoom(), new Object[]{ botMessage })) {
bot.talk(botMessage);
}
}
});
List<Runnable> failedReached = new ArrayList<>();
failedReached.add(() -> {
if (distanceBetweenBotAndHabbo <= Emulator.getConfig().getInt("hotel.bot.butler.servedistance", 8)) {
for (Runnable task : tasks) {
task.run();
}
}
});
// Give bot the handitem that it's going to give the Habbo
Emulator.getThreading().run(new RoomUnitGiveHanditem(this.getRoomUnit(), serveEvent.habbo.getHabboInfo().getCurrentRoom(), serveEvent.itemId));
if (distanceBetweenBotAndHabbo > Emulator.getConfig().getInt("hotel.bot.butler.reachdistance", 3)) {
Emulator.getThreading().run(new RoomUnitWalkToRoomUnit(this.getRoomUnit(), serveEvent.habbo.getRoomUnit(), serveEvent.habbo.getHabboInfo().getCurrentRoom(), tasks, failedReached, Emulator.getConfig().getInt("hotel.bot.butler.reachdistance", 3)));
} else {
Emulator.getThreading().run(failedReached.get(0), 1000);
}
} else {
if(this.getRoom() != null) {
this.getRoom().giveHandItem(serveEvent.habbo, serveEvent.itemId);
String msg = Emulator.getTexts().getValue("bots.butler.given").replace("%key%", keyword).replace("%username%", serveEvent.habbo.getHabboInfo().getUsername());
if (!WiredHandler.handle(WiredTriggerType.SAY_SOMETHING, this.getRoomUnit(), this.getRoom(), new Object[]{msg})) {
this.talk(msg);
}
}
}
return;
}
}
}
}
}
}
}

View File

@ -0,0 +1,70 @@
package com.eu.habbo.habbohotel.bots;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.modtool.ModToolRoomVisit;
import com.eu.habbo.habbohotel.rooms.RoomChatMessage;
import com.eu.habbo.habbohotel.users.Habbo;
import gnu.trove.set.hash.THashSet;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class VisitorBot extends Bot {
private static SimpleDateFormat DATE_FORMAT;
private boolean showedLog = false;
private THashSet<ModToolRoomVisit> visits = new THashSet<>(3);
public VisitorBot(ResultSet set) throws SQLException {
super(set);
}
public VisitorBot(Bot bot) {
super(bot);
}
public static void initialise() {
DATE_FORMAT = new SimpleDateFormat(Emulator.getConfig().getValue("bots.visitor.dateformat"));
}
@Override
public void onUserSay(final RoomChatMessage message) {
if (!this.showedLog) {
if (message.getMessage().equalsIgnoreCase(Emulator.getTexts().getValue("generic.yes"))) {
this.showedLog = true;
String visitMessage = Emulator.getTexts().getValue("bots.visitor.list").replace("%count%", this.visits.size() + "");
StringBuilder list = new StringBuilder();
for (ModToolRoomVisit visit : this.visits) {
list.append("\r");
list.append(visit.roomName).append(" ");
list.append(Emulator.getTexts().getValue("generic.time.at")).append(" ");
list.append(DATE_FORMAT.format(new Date((visit.timestamp * 1000L))));
}
visitMessage = visitMessage.replace("%list%", list.toString());
this.talk(visitMessage);
this.visits.clear();
}
}
}
public void onUserEnter(Habbo habbo) {
if (!this.showedLog) {
if (habbo.getHabboInfo().getCurrentRoom() != null) {
this.visits = Emulator.getGameEnvironment().getModToolManager().getVisitsForRoom(habbo.getHabboInfo().getCurrentRoom(), 10, true, habbo.getHabboInfo().getLastOnline(), Emulator.getIntUnixTimestamp(), habbo.getHabboInfo().getCurrentRoom().getOwnerName());
if (this.visits.isEmpty()) {
this.talk(Emulator.getTexts().getValue("bots.visitor.no_visits"));
} else {
this.talk(Emulator.getTexts().getValue("bots.visitor.visits").replace("%count%", this.visits.size() + "").replace("%positive%", Emulator.getTexts().getValue("generic.yes")));
}
}
}
}
}

View File

@ -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<Integer , CalendarRewardObject> 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<Integer, CalendarRewardObject> getRewards() { return rewards; }
public void setId(int id) { this.id = id; }
public void setRewards(Map<Integer, CalendarRewardObject> rewards) { this.rewards = rewards; }
public void addReward(CalendarRewardObject reward) { this.rewards.put(reward.getId(), reward); }
}

View File

@ -0,0 +1,151 @@
package com.eu.habbo.habbohotel.campaign.calendar;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.messages.outgoing.events.calendar.AdventCalendarProductComposer;
import com.eu.habbo.plugin.events.users.calendar.UserClaimRewardEvent;
import gnu.trove.map.hash.THashMap;
import lombok.extern.slf4j.Slf4j;
import java.sql.*;
import java.util.*;
import java.util.Date;
import static java.time.temporal.ChronoUnit.DAYS;
@Slf4j
public class CalendarManager {
final private static Map<Integer, CalendarCampaign> calendarCampaigns = new THashMap<>();
public static double HC_MODIFIER;
public CalendarManager() {
long millis = System.currentTimeMillis();
this.reload();
log.info("Calendar Manager -> Loaded! ({} MS)", (System.currentTimeMillis() - millis));
}
public void dispose(){
calendarCampaigns.clear();
}
public boolean reload() {
this.dispose();
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM calendar_campaigns WHERE enabled = 1")) {
try (ResultSet set = statement.executeQuery()) {
while (set.next()) {
calendarCampaigns.put(set.getInt("id"), new CalendarCampaign(set));
}
}
} catch (SQLException e) {
log.error("Caught SQL exception", e);
return false;
}
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM calendar_rewards")) {
try (ResultSet set = statement.executeQuery()) {
while (set.next()) {
CalendarCampaign campaign = calendarCampaigns.get(set.getInt("campaign_id"));
if(campaign != null){
campaign.addReward(new CalendarRewardObject(set));
}
}
}
} catch (SQLException e) {
log.error("Caught SQL exception", e);
return false;
}
HC_MODIFIER = Emulator.getConfig().getDouble("hotel.calendar.pixels.hc_modifier", 2.0);
return true;
}
public void addCampaign(CalendarCampaign campaign) {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO calendar_campaigns ( name, image, start_timestamp, total_days, lock_expired) VALUES (?, ?, ?, ? , ?)", Statement.RETURN_GENERATED_KEYS)) {
statement.setString(1, campaign.getName());
statement.setString(2, campaign.getImage());
statement.setInt(3, campaign.getStartTimestamp());
statement.setInt(4, campaign.getTotalDays());
statement.setBoolean(5, campaign.getLockExpired());
int affectedRows = statement.executeUpdate();
if (affectedRows == 0) {
throw new SQLException("Creating calendar campaign failed, no rows affected.");
}
try (ResultSet generatedKeys = statement.getGeneratedKeys()) {
if (generatedKeys.next()) {
campaign.setId(generatedKeys.getInt(1));
} else {
throw new SQLException("Creating calendar campaign failed, no ID found.");
}
}
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
calendarCampaigns.put(campaign.getId(), campaign);
}
public boolean deleteCampaign(CalendarCampaign campaign) {
calendarCampaigns.remove(campaign.getId());
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM calendar_campaigns WHERE id = ? LIMIT 1")) {
statement.setInt(1, campaign.getId());
return statement.execute();
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
return false;
}
public CalendarCampaign getCalendarCampaign(String campaignName) {
return calendarCampaigns.values().stream().filter(cc -> Objects.equals(cc.getName(), campaignName)).findFirst().orElse(null);
}
public Map<Integer, CalendarCampaign> 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<Integer> keys = campaign.getRewards().keySet();
Map<Integer, Integer> rewards = new THashMap<>();
if(keys.isEmpty()) return;
keys.forEach(key -> rewards.put(rewards.size() + 1, key));
int rand = Emulator.getRandom().nextInt(rewards.size() - 1 + 1) + 1;
int random = rewards.get(rand);
CalendarRewardObject object = campaign.getRewards().get(random);
if (object == null) return;
int daysBetween = (int) DAYS.between(new Timestamp(campaign.getStartTimestamp() * 1000L).toInstant(), new Date().toInstant());
if(daysBetween >= 0 && daysBetween <= campaign.getTotalDays()) {
int diff = (daysBetween - day);
if ((((diff <= 2 || !campaign.getLockExpired()) && diff >= 0) || (force && habbo.hasPermission("acc_calendar_force")))) {
if (Emulator.getPluginManager().fireEvent(new UserClaimRewardEvent(habbo, campaign, day, object, force)).isCancelled()) {
return;
}
habbo.getHabboStats().calendarRewardsClaimed.add(new CalendarRewardClaimed(habbo.getHabboInfo().getId(), campaign.getId(), day, object.getId(), new Timestamp(System.currentTimeMillis())));
habbo.getClient().sendResponse(new AdventCalendarProductComposer(true, object, habbo));
object.give(habbo);
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO calendar_rewards_claimed (user_id, campaign_id, day, reward_id, timestamp) VALUES (?, ?, ?, ?, ?)")) {
statement.setInt(1, habbo.getHabboInfo().getId());
statement.setInt(2, campaign.getId());
statement.setInt(3, day);
statement.setInt(4, object.getId());
statement.setInt(5, Emulator.getIntUnixTimestamp());
statement.execute();
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
}
}
}
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,132 @@
package com.eu.habbo.habbohotel.campaign.calendar;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.habbohotel.users.subscriptions.Subscription;
import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionHabboClub;
import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer;
import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.ResultSet;
import java.sql.SQLException;
public class CalendarRewardObject {
private static final Logger LOGGER = LoggerFactory.getLogger(CalendarRewardObject.class);
private final int id;
private final String productName;
private final String customImage;
private final int credits;
private final int pixels;
private final int points;
private final int pointsType;
private final String badge;
private final int itemId;
private final String subscription_type;
private final int subscription_days;
public CalendarRewardObject(ResultSet set) throws SQLException {
this.id = set.getInt("id");
this.productName = set.getString("product_name");
this.customImage = set.getString("custom_image");
this.credits = set.getInt("credits");
this.pixels = set.getInt("pixels");
this.points = set.getInt("points");
this.pointsType = set.getInt("points_type");
this.badge = set.getString("badge");
this.itemId = set.getInt("item_id");
this.subscription_type = set.getString("subscription_type");
this.subscription_days = set.getInt("subscription_days");
}
public void give(Habbo habbo) {
if (this.credits > 0) {
habbo.giveCredits(this.credits);
}
if (this.pixels > 0) {
habbo.givePixels((int)(this.pixels * (habbo.getHabboStats().hasActiveClub() ? CalendarManager.HC_MODIFIER : 1.0)));
}
if (this.points > 0) {
habbo.givePoints(this.pointsType, this.points);
}
if (!this.badge.isEmpty()) {
habbo.addBadge(this.badge);
}
if(this.subscription_type != null && !this.subscription_type.isEmpty()) {
if ("HABBO_CLUB".equals(this.subscription_type)) {
habbo.getHabboStats().createSubscription(SubscriptionHabboClub.HABBO_CLUB, this.subscription_days * 86400);
} else {
habbo.getHabboStats().createSubscription(this.subscription_type, this.subscription_days * 86400);
}
}
if (this.itemId > 0) {
Item item = getItem();
if (item != null) {
HabboItem habboItem = Emulator.getGameEnvironment().getItemManager().createItem(
habbo.getHabboInfo().getId(),
item,
0,
0,
"");
habbo.getInventory().getItemsComponent().addItem(habboItem);
habbo.getClient().sendResponse(new AddHabboItemComposer(habboItem));
habbo.getClient().sendResponse(new InventoryRefreshComposer());
}
}
}
public int getId() {
return this.id;
}
public String getCustomImage() {
return this.customImage;
}
public int getCredits() {
return this.credits;
}
public int getPixels() {
return this.pixels;
}
public int getPoints() {
return this.points;
}
public int getPointsType() {
return this.pointsType;
}
public String getProductName() {
return productName;
}
public String getSubscriptionType() {
return subscription_type;
}
public int getSubscriptionDays() {
return subscription_days;
}
public String getBadge() {
return this.badge;
}
public Item getItem() {
return Emulator.getGameEnvironment().getItemManager().getItem(this.itemId);
}
}

View File

@ -0,0 +1,58 @@
package com.eu.habbo.habbohotel.catalog;
import com.eu.habbo.Emulator;
import com.eu.habbo.messages.ISerialize;
import com.eu.habbo.messages.ServerMessage;
public class CatalogFeaturedPage implements ISerialize {
private final int slotId;
private final String caption;
private final String image;
private final Type type;
private final int expireTimestamp;
private final String pageName;
private final int pageId;
private final String productName;
public CatalogFeaturedPage(int slotId, String caption, String image, Type type, int expireTimestamp, String pageName, int pageId, String productName) {
this.slotId = slotId;
this.caption = caption;
this.image = image;
this.type = type;
this.expireTimestamp = expireTimestamp;
this.pageName = pageName;
this.pageId = pageId;
this.productName = productName;
}
@Override
public void serialize(ServerMessage message) {
message.appendInt(this.slotId);
message.appendString(this.caption);
message.appendString(this.image);
message.appendInt(this.type.type);
switch (this.type) {
case PAGE_NAME:
message.appendString(this.pageName);
break;
case PAGE_ID:
message.appendInt(this.pageId);
break;
case PRODUCT_NAME:
message.appendString(this.productName);
break;
}
message.appendInt(Emulator.getIntUnixTimestamp() - this.expireTimestamp);
}
public enum Type {
PAGE_NAME(0),
PAGE_ID(1),
PRODUCT_NAME(2);
public final int type;
Type(int type) {
this.type = type;
}
}
}

View File

@ -0,0 +1,354 @@
package com.eu.habbo.habbohotel.catalog;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.items.FurnitureType;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.users.HabboBadge;
import com.eu.habbo.messages.ISerialize;
import com.eu.habbo.messages.ServerMessage;
import gnu.trove.set.hash.THashSet;
import lombok.extern.slf4j.Slf4j;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
@Slf4j
public class CatalogItem implements ISerialize, Runnable, Comparable<CatalogItem> {
int id;
int limitedStack;
private int pageId;
private String itemId;
private String name;
private int credits;
private int points;
private short pointsType;
private int amount;
private boolean allowGift = false;
private int limitedSells;
private String extradata;
private boolean clubOnly;
private boolean haveOffer;
private int offerId;
private boolean needsUpdate;
private int orderNumber;
private HashMap<Integer, Integer> bundle;
public CatalogItem(ResultSet set) throws SQLException {
this.load(set);
this.needsUpdate = false;
}
public static boolean haveOffer(CatalogItem item) {
if (!item.haveOffer)
return false;
if (item.getAmount() != 1)
return false;
if (item.isLimited())
return false;
if (item.bundle.size() > 1)
return false;
if (item.getName().toLowerCase().startsWith("cf_") || item.getName().toLowerCase().startsWith("cfc_"))
return false;
for (Item i : item.getBaseItems()) {
if (i.getName().toLowerCase().startsWith("cf_") || i.getName().toLowerCase().startsWith("cfc_") || i.getName().toLowerCase().startsWith("rentable_bot"))
return false;
}
return !item.getName().toLowerCase().startsWith("rentable_bot_");
}
public void update(ResultSet set) throws SQLException {
this.load(set);
}
private void load(ResultSet set) throws SQLException {
this.id = set.getInt("id");
this.pageId = set.getInt("page_id");
this.itemId = set.getString("item_Ids");
this.name = set.getString("catalog_name");
this.credits = set.getInt("cost_credits");
this.points = set.getInt("cost_points");
this.pointsType = set.getShort("points_type");
this.amount = set.getInt("amount");
this.limitedStack = set.getInt("limited_stack");
this.limitedSells = set.getInt("limited_sells");
this.extradata = set.getString("extradata");
this.clubOnly = set.getBoolean("club_only");
this.haveOffer = set.getBoolean("have_offer");
this.offerId = set.getInt("offer_id");
this.orderNumber = set.getInt("order_number");
this.bundle = new HashMap<>();
this.loadBundle();
}
public int getId() {
return this.id;
}
public int getPageId() {
return this.pageId;
}
public void setPageId(int pageId) {
this.pageId = pageId;
}
public String getItemId() {
return this.itemId;
}
public void setItemId(String itemId) {
this.itemId = itemId;
}
public String getName() {
return this.name;
}
public int getCredits() {
return this.credits;
}
public int getPoints() {
return this.points;
}
public int getPointsType() {
return this.pointsType;
}
public int getAmount() {
return this.amount;
}
public int getLimitedStack() {
return this.limitedStack;
}
public int getLimitedSells() {
CatalogLimitedConfiguration ltdConfig = Emulator.getGameEnvironment().getCatalogManager().getLimitedConfig(this);
if (ltdConfig != null) {
return this.limitedStack - ltdConfig.available();
}
return this.limitedStack;
}
public String getExtradata() {
return this.extradata;
}
public boolean isClubOnly() {
return this.clubOnly;
}
public boolean isHaveOffer() {
return this.haveOffer;
}
public int getOfferId() {
return this.offerId;
}
public boolean isLimited() {
return this.limitedStack > 0;
}
private int getOrderNumber() {
return this.orderNumber;
}
public void setNeedsUpdate(boolean needsUpdate) {
this.needsUpdate = needsUpdate;
}
public synchronized void sellRare() {
this.limitedSells++;
this.needsUpdate = true;
if (this.limitedSells == this.limitedStack) {
Emulator.getGameEnvironment().getCatalogManager().moveCatalogItem(this, Emulator.getConfig().getInt("catalog.ltd.page.soldout"));
}
Emulator.getThreading().run(this);
}
public THashSet<Item> getBaseItems() {
THashSet<Item> items = new THashSet<>();
if (!this.itemId.isEmpty()) {
String[] itemIds = this.itemId.split(";");
for (String itemId : itemIds) {
if (itemId.isEmpty())
continue;
if (itemId.contains(":")) {
itemId = itemId.split(":")[0];
}
int identifier;
try {
identifier = Integer.parseInt(itemId);
} catch (Exception e) {
log.info("Invalid value (" + itemId + ") for items_base column for catalog_item id (" + this.id + "). Value must be integer or of the format of integer:amount;integer:amount");
continue;
}
if (identifier > 0) {
Item item = Emulator.getGameEnvironment().getItemManager().getItem(identifier);
if (item != null)
items.add(item);
}
}
}
return items;
}
public int getItemAmount(int id) {
if (this.bundle.containsKey(id))
return this.bundle.get(id);
else
return this.amount;
}
public HashMap<Integer, Integer> getBundle() {
return this.bundle;
}
public void loadBundle() {
int intItemId;
if (this.itemId.contains(";")) {
try {
String[] itemIds = this.itemId.split(";");
for (String itemId : itemIds) {
if (itemId.contains(":")) {
String[] data = itemId.split(":");
if (data.length > 1 && Integer.parseInt(data[0]) > 0 && Integer.parseInt(data[1]) > 0) {
this.bundle.put(Integer.parseInt(data[0]), Integer.parseInt(data[1]));
}
} else {
if (!itemId.isEmpty()) {
intItemId = (Integer.parseInt(itemId));
this.bundle.put(intItemId, 1);
}
}
}
} catch (Exception e) {
log.debug("Failed to load " + this.itemId);
log.error("Caught exception", e);
}
} else {
try {
Item item = Emulator.getGameEnvironment().getItemManager().getItem(Integer.valueOf(this.itemId));
if (item != null) {
this.allowGift = item.allowGift();
}
} catch (Exception e) {
}
}
}
@Override
public void serialize(ServerMessage message) {
message.appendInt(this.getId());
message.appendString(this.getName());
message.appendBoolean(false);
message.appendInt(this.getCredits());
message.appendInt(this.getPoints());
message.appendInt(this.getPointsType());
message.appendBoolean(this.allowGift); //Can gift
THashSet<Item> items = this.getBaseItems();
message.appendInt(items.size());
for (Item item : items) {
message.appendString(item.getType().code.toLowerCase());
if (item.getType() == FurnitureType.BADGE) {
message.appendString(item.getName());
} else {
message.appendInt(item.getSpriteId());
if (this.getName().contains("wallpaper_single") || this.getName().contains("floor_single") || this.getName().contains("landscape_single")) {
message.appendString(this.getName().split("_")[2]);
} else if (item.getName().contains("bot") && item.getType() == FurnitureType.ROBOT) {
boolean lookFound = false;
for (String s : this.getExtradata().split(";")) {
if (s.startsWith("figure:")) {
lookFound = true;
message.appendString(s.replace("figure:", ""));
break;
}
}
if (!lookFound) {
message.appendString(this.getExtradata());
}
} else if (item.getType() == FurnitureType.ROBOT) {
message.appendString(this.getExtradata());
} else if (item.getName().equalsIgnoreCase("poster")) {
message.appendString(this.getExtradata());
} else if (this.getName().startsWith("SONG ")) {
message.appendString(this.getExtradata());
} else {
message.appendString("");
}
message.appendInt(this.getItemAmount(item.getId()));
message.appendBoolean(this.isLimited());
if (this.isLimited()) {
message.appendInt(this.getLimitedStack());
message.appendInt(this.getLimitedStack() - this.getLimitedSells());
}
}
}
message.appendInt(this.clubOnly);
message.appendBoolean(haveOffer(this));
message.appendBoolean(false); //unknown
message.appendString(this.name + ".png");
}
@Override
public void run() {
if (this.needsUpdate) {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE catalog_items SET limited_sells = ?, page_id = ? WHERE id = ?")) {
statement.setInt(1, this.getLimitedSells());
statement.setInt(2, this.pageId);
statement.setInt(3, this.getId());
statement.execute();
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
this.needsUpdate = false;
}
}
@SuppressWarnings("NullableProblems")
@Override
public int compareTo(CatalogItem catalogItem) {
if (CatalogManager.SORT_USING_ORDERNUM) {
return this.getOrderNumber() - catalogItem.getOrderNumber();
} else {
return this.getId() - catalogItem.getId();
}
}
}

View File

@ -0,0 +1,106 @@
package com.eu.habbo.habbohotel.catalog;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.habbohotel.users.HabboItem;
import lombok.extern.slf4j.Slf4j;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Collections;
import java.util.LinkedList;
@Slf4j
public class CatalogLimitedConfiguration implements Runnable {
private final int itemId;
private final LinkedList<Integer> limitedNumbers;
private int totalSet;
public CatalogLimitedConfiguration(int itemId, LinkedList<Integer> availableNumbers, int totalSet) {
this.itemId = itemId;
this.totalSet = totalSet;
this.limitedNumbers = availableNumbers;
if (Emulator.getConfig().getBoolean("catalog.ltd.random", true)) {
Collections.shuffle(this.limitedNumbers);
} else {
Collections.reverse(this.limitedNumbers);
}
}
public int getNumber() {
synchronized (this.limitedNumbers) {
int num = this.limitedNumbers.pop();
if (this.limitedNumbers.isEmpty()) {
Emulator.getGameEnvironment().getCatalogManager().moveCatalogItem(Emulator.getGameEnvironment().getCatalogManager().getCatalogItem(this.itemId), Emulator.getConfig().getInt("catalog.ltd.page.soldout"));
}
return num;
}
}
public void limitedSold(int catalogItemId, Habbo habbo, HabboItem item) {
synchronized (this.limitedNumbers) {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE catalog_items_limited SET user_id = ?, timestamp = ?, item_id = ? WHERE catalog_item_id = ? AND number = ? AND user_id = 0 LIMIT 1")) {
statement.setInt(1, habbo.getHabboInfo().getId());
statement.setInt(2, Emulator.getIntUnixTimestamp());
statement.setInt(3, item.getId());
statement.setInt(4, catalogItemId);
statement.setInt(5, item.getLimitedSells());
statement.execute();
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
}
}
public void generateNumbers(int starting, int amount) {
synchronized (this.limitedNumbers) {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO catalog_items_limited (catalog_item_id, number) VALUES (?, ?)")) {
statement.setInt(1, this.itemId);
for (int i = starting; i <= amount; i++) {
statement.setInt(2, i);
statement.addBatch();
this.limitedNumbers.push(i);
}
statement.executeBatch();
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
this.totalSet += amount;
if (Emulator.getConfig().getBoolean("catalog.ltd.random", true)) {
Collections.shuffle(this.limitedNumbers);
} else {
Collections.reverse(this.limitedNumbers);
}
}
}
public int available() {
return this.limitedNumbers.size();
}
public int getTotalSet() {
return this.totalSet;
}
public void setTotalSet(int totalSet) {
this.totalSet = totalSet;
}
@Override
public void run() {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE catalog_items SET limited_stack = ?, limited_sells = ? WHERE id = ?")) {
statement.setInt(1, this.totalSet);
statement.setInt(2, this.totalSet - this.available());
statement.setInt(3, this.itemId);
statement.execute();
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,206 @@
package com.eu.habbo.habbohotel.catalog;
import com.eu.habbo.messages.ISerialize;
import com.eu.habbo.messages.ServerMessage;
import gnu.trove.TCollections;
import gnu.trove.list.array.TIntArrayList;
import gnu.trove.map.TIntObjectMap;
import gnu.trove.map.hash.THashMap;
import gnu.trove.map.hash.TIntObjectHashMap;
import lombok.extern.slf4j.Slf4j;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
@Slf4j
public abstract class CatalogPage implements Comparable<CatalogPage>, ISerialize {
protected final TIntArrayList offerIds = new TIntArrayList();
protected final THashMap<Integer, CatalogPage> childPages = new THashMap<>();
private final TIntObjectMap<CatalogItem> catalogItems = TCollections.synchronizedMap(new TIntObjectHashMap<>());
private final ArrayList<Integer> included = new ArrayList<>();
protected int id;
protected int parentId;
protected int rank;
protected String caption;
protected String pageName;
protected int iconColor;
protected int iconImage;
protected int orderNum;
protected boolean visible;
protected boolean enabled;
protected boolean clubOnly;
protected String layout;
protected String headerImage;
protected String teaserImage;
protected String specialImage;
protected String textOne;
protected String textTwo;
protected String textDetails;
protected String textTeaser;
public CatalogPage() {
}
public CatalogPage(ResultSet set) throws SQLException {
if (set == null)
return;
this.id = set.getInt("id");
this.parentId = set.getInt("parent_id");
this.rank = set.getInt("min_rank");
this.caption = set.getString("caption");
this.pageName = set.getString("caption_save");
this.iconColor = set.getInt("icon_color");
this.iconImage = set.getInt("icon_image");
this.orderNum = set.getInt("order_num");
this.visible = set.getBoolean("visible");
this.enabled = set.getBoolean("enabled");
this.clubOnly = set.getBoolean("club_only");
this.layout = set.getString("page_layout");
this.headerImage = set.getString("page_headline");
this.teaserImage = set.getString("page_teaser");
this.specialImage = set.getString("page_special");
this.textOne = set.getString("page_text1");
this.textTwo = set.getString("page_text2");
this.textDetails = set.getString("page_text_details");
this.textTeaser = set.getString("page_text_teaser");
if (!set.getString("includes").isEmpty()) {
for (String id : set.getString("includes").split(";")) {
try {
this.included.add(Integer.valueOf(id));
} catch (Exception e) {
log.error("Caught exception", e);
log.error("Failed to parse includes column value of (" + id + ") for catalog page (" + this.id + ")");
}
}
}
}
public int getId() {
return this.id;
}
public int getParentId() {
return this.parentId;
}
public int getRank() {
return this.rank;
}
public void setRank(int rank) {
this.rank = rank;
}
public String getCaption() {
return this.caption;
}
public String getPageName() {
return this.pageName;
}
public int getIconColor() {
return this.iconColor;
}
public int getIconImage() {
return this.iconImage;
}
public int getOrderNum() {
return this.orderNum;
}
public boolean isVisible() {
return this.visible;
}
public boolean isEnabled() {
return this.enabled;
}
public boolean isClubOnly() {
return this.clubOnly;
}
public String getLayout() {
return this.layout;
}
public String getHeaderImage() {
return this.headerImage;
}
public String getTeaserImage() {
return this.teaserImage;
}
public String getSpecialImage() {
return this.specialImage;
}
public String getTextOne() {
return this.textOne;
}
public String getTextTwo() {
return this.textTwo;
}
public String getTextDetails() {
return this.textDetails;
}
public String getTextTeaser() {
return this.textTeaser;
}
public TIntArrayList getOfferIds() {
return this.offerIds;
}
public void addOfferId(int offerId) {
this.offerIds.add(offerId);
}
public void addItem(CatalogItem item) {
this.catalogItems.put(item.getId(), item);
}
public TIntObjectMap<CatalogItem> getCatalogItems() {
return this.catalogItems;
}
public CatalogItem getCatalogItem(int id) {
return this.catalogItems.get(id);
}
public ArrayList<Integer> getIncluded() {
return this.included;
}
public THashMap<Integer, CatalogPage> getChildPages() {
return this.childPages;
}
public void addChildPage(CatalogPage page) {
this.childPages.put(page.getId(), page);
if (page.getRank() < this.getRank()) {
page.setRank(this.getRank());
}
}
@SuppressWarnings("NullableProblems")
@Override
public int compareTo(CatalogPage page) {
return this.getOrderNum() - page.getOrderNum();
}
@Override
public abstract void serialize(ServerMessage message);
}

View File

@ -0,0 +1,47 @@
package com.eu.habbo.habbohotel.catalog;
public enum CatalogPageLayouts {
default_3x3,
guild_furni,
guilds,
guild_forum,
info_duckets,
info_rentables,
info_loyalty,
loyalty_vip_buy,
bots,
pets,
pets2,
pets3,
club_gift,
frontpage,
badge_display,
spaces_new,
soundmachine,
info_pets,
club_buy,
roomads,
trophies,
single_bundle,
marketplace,
marketplace_own_items,
recycler,
recycler_info,
recycler_prizes,
sold_ltd_items,
plasto,
default_3x3_color_grouping,
recent_purchases,
room_bundle,
petcustomization,
root,
vip_buy,
frontpage_featured,
builders_club_addons,
builders_club_frontpage,
builders_club_loyalty,
monkey,
niko,
mad_money
}

View File

@ -0,0 +1,9 @@
package com.eu.habbo.habbohotel.catalog;
public enum CatalogPageType {
NORMAL,
BUILDER
}

View File

@ -0,0 +1,61 @@
package com.eu.habbo.habbohotel.catalog;
import com.eu.habbo.Emulator;
import com.eu.habbo.core.DatabaseLoggable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class CatalogPurchaseLogEntry implements Runnable, DatabaseLoggable {
private static final Logger LOGGER = LoggerFactory.getLogger(CatalogPurchaseLogEntry.class);
private static final String QUERY = "INSERT INTO `logs_shop_purchases` (timestamp, user_id, catalog_item_id, item_ids, catalog_name, cost_credits, cost_points, points_type, amount) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
private final int timestamp;
private final int userId;
private final int catalogItemId;
private final String itemIds;
private final String catalogName;
private final int costCredits;
private final int costPoints;
private final int pointsType;
private final int amount;
public CatalogPurchaseLogEntry(int timestamp, int userId, int catalogItemId, String itemIds, String catalogName, int costCredits, int costPoints, int pointsType, int amount) {
this.timestamp = timestamp;
this.userId = userId;
this.catalogItemId = catalogItemId;
this.itemIds = itemIds;
this.catalogName = catalogName;
this.costCredits = costCredits;
this.costPoints = costPoints;
this.pointsType = pointsType;
this.amount = amount;
}
@Override
public String getQuery() {
return QUERY;
}
@Override
public void log(PreparedStatement statement) throws SQLException {
statement.setInt(1, this.timestamp);
statement.setInt(2, this.userId);
statement.setInt(3, this.catalogItemId);
statement.setString(4, this.itemIds);
statement.setString(5, this.catalogName);
statement.setInt(6, this.costCredits);
statement.setInt(7, this.costPoints);
statement.setInt(8, this.pointsType);
statement.setInt(9, this.amount);
statement.addBatch();
}
@Override
public void run() {
Emulator.getDatabaseLogger().store(this);
}
}

View File

@ -0,0 +1,26 @@
package com.eu.habbo.habbohotel.catalog;
import java.sql.ResultSet;
import java.sql.SQLException;
public class ClothItem {
public int id;
public String name;
public int[] setId;
public ClothItem(ResultSet set) throws SQLException {
this.id = set.getInt("id");
this.name = set.getString("name");
String[] parts = set.getString("setid").split(",");
this.setId = new int[parts.length];
for (int i = 0; i < this.setId.length; i++) {
this.setId[i] = Integer.valueOf(parts[i]);
}
}
}

View File

@ -0,0 +1,122 @@
package com.eu.habbo.habbohotel.catalog;
import com.eu.habbo.Emulator;
import com.eu.habbo.messages.ISerialize;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.TimeZone;
public class ClubOffer implements ISerialize {
private final int id;
private final String name;
private final int days;
private final int credits;
private final int points;
private final int pointsType;
private final boolean vip;
private final boolean deal;
public ClubOffer(ResultSet set) throws SQLException {
this.id = set.getInt("id");
this.name = set.getString("name");
this.days = set.getInt("days");
this.credits = set.getInt("credits");
this.points = set.getInt("points");
this.pointsType = set.getInt("points_type");
this.vip = set.getString("type").equalsIgnoreCase("vip");
this.deal = set.getString("deal").equals("1");
}
public int getId() {
return this.id;
}
public String getName() {
return this.name;
}
public int getDays() {
return this.days;
}
public int getCredits() {
return this.credits;
}
public int getPoints() {
return this.points;
}
public int getPointsType() {
return this.pointsType;
}
public boolean isVip() {
return this.vip;
}
public boolean isDeal() {
return this.deal;
}
@Override
public void serialize(ServerMessage message) {
serialize(message, Emulator.getIntUnixTimestamp());
}
public void serialize(ServerMessage message, int hcExpireTimestamp) {
hcExpireTimestamp = Math.max(Emulator.getIntUnixTimestamp(), hcExpireTimestamp);
message.appendInt(this.id);
message.appendString(this.name);
message.appendBoolean(false); //unused
message.appendInt(this.credits);
message.appendInt(this.points);
message.appendInt(this.pointsType);
message.appendBoolean(this.vip);
long seconds = this.days * 86400;
long secondsTotal = seconds;
int totalYears = (int) Math.floor((int) seconds / (86400.0 * 31 * 12));
seconds -= totalYears * (86400 * 31 * 12);
int totalMonths = (int) Math.floor((int) seconds / (86400.0 * 31));
seconds -= totalMonths * (86400 * 31);
int totalDays = (int) Math.floor((int) seconds / 86400.0);
seconds -= totalDays * 86400;
message.appendInt((int) secondsTotal / 86400 / 31);
message.appendInt((int) seconds);
message.appendBoolean(false); //giftable
message.appendInt((int) seconds);
hcExpireTimestamp += secondsTotal;
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
cal.setTimeInMillis(hcExpireTimestamp * 1000L);
message.appendInt(cal.get(Calendar.YEAR));
message.appendInt(cal.get(Calendar.MONTH) + 1);
message.appendInt(cal.get(Calendar.DAY_OF_MONTH));
}
}

View File

@ -0,0 +1,116 @@
package com.eu.habbo.habbohotel.catalog;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.users.cache.HabboOfferPurchase;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TargetOffer {
public static int ACTIVE_TARGET_OFFER_ID = 0;
private final int id;
private final int catalogItem;
private final String identifier;
private final int priceInCredits;
private final int priceInActivityPoints;
private final int activityPointsType;
private final int purchaseLimit;
private final int expirationTime;
private final String title;
private final String description;
private final String imageUrl;
private final String icon;
private final String[] vars;
public TargetOffer(ResultSet set) throws SQLException {
this.id = set.getInt("id");
this.identifier = set.getString("offer_code");
this.priceInCredits = set.getInt("credits");
this.priceInActivityPoints = set.getInt("points");
this.activityPointsType = set.getInt("points_type");
this.title = set.getString("title");
this.description = set.getString("description");
this.imageUrl = set.getString("image");
this.icon = set.getString("icon");
this.purchaseLimit = set.getInt("purchase_limit");
this.expirationTime = set.getInt("end_timestamp");
this.vars = set.getString("vars").split(";");
this.catalogItem = set.getInt("catalog_item");
}
public void serialize(ServerMessage message, HabboOfferPurchase purchase) {
message.appendInt(purchase.getState());
message.appendInt(this.id);
message.appendString(this.identifier);
message.appendString(this.identifier);
message.appendInt(this.priceInCredits);
message.appendInt(this.priceInActivityPoints);
message.appendInt(this.activityPointsType);
message.appendInt(Math.max(this.purchaseLimit - purchase.getAmount(), 0));
message.appendInt(Math.max(this.expirationTime - Emulator.getIntUnixTimestamp(), 0));
message.appendString(this.title);
message.appendString(this.description);
message.appendString(this.imageUrl);
message.appendString(this.icon);
message.appendInt(0);
message.appendInt(this.vars.length);
for (String variable : this.vars) {
message.appendString(variable);
}
}
public int getId() {
return this.id;
}
public String getIdentifier() {
return this.identifier;
}
public int getPriceInCredits() {
return this.priceInCredits;
}
public int getPriceInActivityPoints() {
return this.priceInActivityPoints;
}
public int getActivityPointsType() {
return this.activityPointsType;
}
public int getPurchaseLimit() {
return this.purchaseLimit;
}
public int getExpirationTime() {
return this.expirationTime;
}
public String getTitle() {
return this.title;
}
public String getDescription() {
return this.description;
}
public String getImageUrl() {
return this.imageUrl;
}
public String getIcon() {
return this.icon;
}
public String[] getVars() {
return this.vars;
}
public int getCatalogItem() {
return this.catalogItem;
}
}

View File

@ -0,0 +1,75 @@
package com.eu.habbo.habbohotel.catalog;
import com.eu.habbo.Emulator;
import lombok.extern.slf4j.Slf4j;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class Voucher {
public final int id;
public final String code;
public final int credits;
public final int points;
public final int pointsType;
public final int catalogItemId;
public final int amount;
public final int limit;
private final List<VoucherHistoryEntry> history = new ArrayList<>();
public Voucher(ResultSet set) throws SQLException {
this.id = set.getInt("id");
this.code = set.getString("code");
this.credits = set.getInt("credits");
this.points = set.getInt("points");
this.pointsType = set.getInt("points_type");
this.catalogItemId = set.getInt("catalog_item_id");
this.amount = set.getInt("amount");
this.limit = set.getInt("limit");
this.loadHistory();
}
private void loadHistory() {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM voucher_history WHERE voucher_id = ?")) {
statement.setInt(1, this.id);
try (ResultSet set = statement.executeQuery()) {
while (set.next()) {
this.history.add(new VoucherHistoryEntry(set));
}
}
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
}
public boolean hasUserExhausted(int userId) {
return this.limit > 0 && Math.toIntExact(this.history.stream().filter(h -> h.getUserId() == userId).count()) >= this.limit;
}
public boolean isExhausted() {
return this.amount > 0 && this.history.size() >= this.amount;
}
public void addHistoryEntry(int userId) {
int timestamp = Emulator.getIntUnixTimestamp();
this.history.add(new VoucherHistoryEntry(this.id, userId, timestamp));
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO voucher_history (`voucher_id`, `user_id`, `timestamp`) VALUES (?, ?, ?)")) {
statement.setInt(1, this.id);
statement.setInt(2, userId);
statement.setInt(3, timestamp);
statement.execute();
} catch (SQLException e) {
log.error("Caught SQL exception", e);
}
}
}

View File

@ -0,0 +1,34 @@
package com.eu.habbo.habbohotel.catalog;
import java.sql.ResultSet;
import java.sql.SQLException;
public class VoucherHistoryEntry {
private final int voucherId;
private final int userId;
private final int timestamp;
public VoucherHistoryEntry(ResultSet set) throws SQLException {
this.voucherId = set.getInt("voucher_id");
this.userId = set.getInt("user_id");
this.timestamp = set.getInt("timestamp");
}
public VoucherHistoryEntry(int voucherId, int userId, int timestamp) {
this.voucherId = voucherId;
this.userId = userId;
this.timestamp = timestamp;
}
public int getVoucherId() {
return voucherId;
}
public int getUserId() {
return userId;
}
public int getTimestamp() {
return timestamp;
}
}

View File

@ -0,0 +1,27 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class BadgeDisplayLayout extends CatalogPage {
public BadgeDisplayLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("badge_display");
message.appendInt(3);
message.appendString(super.getHeaderImage());
message.appendString(super.getTeaserImage());
message.appendString(super.getSpecialImage());
message.appendInt(3);
message.appendString(super.getTextOne());
message.appendString(super.getTextDetails());
message.appendString(super.getTextTeaser());
}
}

View File

@ -0,0 +1,26 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class BotsLayout extends CatalogPage {
public BotsLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("bots");
message.appendInt(2);
message.appendString(super.getHeaderImage());
message.appendString(super.getTeaserImage());
message.appendInt(3);
message.appendString(super.getTextOne());
message.appendString(super.getTextDetails());
message.appendString(super.getTextTwo());
}
}

View File

@ -0,0 +1,27 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class BuildersClubAddonsLayout extends CatalogPage {
public BuildersClubAddonsLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("builders_club_addons");
message.appendInt(3);
message.appendString(super.getHeaderImage());
message.appendString(super.getTeaserImage());
message.appendString(super.getSpecialImage());
message.appendInt(3);
message.appendString(super.getTextOne());
message.appendString(super.getTextDetails());
message.appendString(super.getTextTeaser());
}
}

View File

@ -0,0 +1,27 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class BuildersClubFrontPageLayout extends CatalogPage {
public BuildersClubFrontPageLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("builders_club_frontpage");
message.appendInt(3);
message.appendString(super.getHeaderImage());
message.appendString(super.getTeaserImage());
message.appendString(super.getSpecialImage());
message.appendInt(3);
message.appendString(super.getTextOne());
message.appendString(super.getTextDetails());
message.appendString(super.getTextTeaser());
}
}

View File

@ -0,0 +1,27 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class BuildersClubLoyaltyLayout extends CatalogPage {
public BuildersClubLoyaltyLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("builders_club_loyalty");
message.appendInt(3);
message.appendString(super.getHeaderImage());
message.appendString(super.getTeaserImage());
message.appendString(super.getSpecialImage());
message.appendInt(3);
message.appendString(super.getTextOne());
message.appendString(super.getTextDetails());
message.appendString(super.getTextTeaser());
}
}

View File

@ -0,0 +1,44 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class CatalogRootLayout extends CatalogPage {
public CatalogRootLayout() {
super();
this.id = -1;
this.parentId = -2;
this.rank = 0;
this.caption = "root";
this.pageName = "root";
this.iconColor = 0;
this.iconImage = 0;
this.orderNum = -10;
this.visible = true;
this.enabled = true;
}
public CatalogRootLayout(ResultSet set) throws SQLException {
super(null);
this.id = -1;
this.parentId = -2;
this.rank = 0;
this.caption = "root";
this.pageName = "root";
this.iconColor = 0;
this.iconImage = 0;
this.orderNum = -10;
this.visible = true;
this.enabled = true;
}
@Override
public void serialize(ServerMessage message) {
}
}

View File

@ -0,0 +1,22 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class ClubBuyLayout extends CatalogPage {
public ClubBuyLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("club_buy");
message.appendInt(2);
message.appendString(super.getHeaderImage());
message.appendString(super.getTeaserImage());
message.appendInt(0);
}
}

View File

@ -0,0 +1,22 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class ClubGiftsLayout extends CatalogPage {
public ClubGiftsLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("club_gifts");
message.appendInt(1);
message.appendString(super.getHeaderImage());
message.appendInt(1);
message.appendString(super.getTextOne());
}
}

View File

@ -0,0 +1,26 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class ColorGroupingLayout extends CatalogPage {
public ColorGroupingLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("default_3x3_color_grouping");
message.appendInt(3);
message.appendString(super.getHeaderImage());
message.appendString(super.getTeaserImage());
message.appendString(super.getSpecialImage());
message.appendInt(3);
message.appendString(super.getTextOne());
message.appendString(super.getTextDetails());
message.appendString(super.getTextTeaser());
}
}

View File

@ -0,0 +1,27 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Default_3x3Layout extends CatalogPage {
public Default_3x3Layout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("default_3x3");
message.appendInt(3);
message.appendString(super.getHeaderImage());
message.appendString(super.getTeaserImage());
message.appendString(super.getSpecialImage());
message.appendInt(3);
message.appendString(super.getTextOne());
message.appendString(super.getTextDetails());
message.appendString(super.getTextTeaser());
}
}

View File

@ -0,0 +1,75 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.catalog.CatalogFeaturedPage;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class FrontPageFeaturedLayout extends CatalogPage {
public FrontPageFeaturedLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("frontpage_featured");
String[] teaserImages = super.getTeaserImage().split(";");
String[] specialImages = super.getSpecialImage().split(";");
message.appendInt(1 + teaserImages.length + specialImages.length);
message.appendString(super.getHeaderImage());
for (String s : teaserImages) {
message.appendString(s);
}
for (String s : specialImages) {
message.appendString(s);
}
message.appendInt(3);
message.appendString(super.getTextOne());
message.appendString(super.getTextDetails());
message.appendString(super.getTextTeaser());
}
public void serializeExtra(ServerMessage message) {
message.appendInt(Emulator.getGameEnvironment().getCatalogManager().getCatalogFeaturedPages().size());
for (CatalogFeaturedPage page : Emulator.getGameEnvironment().getCatalogManager().getCatalogFeaturedPages().valueCollection()) {
page.serialize(message);
}
message.appendInt(1); //Position
message.appendString("NUOVO: Affare Stanza di Rilassamento");
message.appendString("catalogue/feature_cata_vert_oly16bundle4.png");
message.appendInt(0); //Type
//0 : String //Page Name
//1 : Int //Page ID
//2 : String //Productdata
message.appendString("");
message.appendInt(-1);
message.appendInt(2);
message.appendString("Il RITORNO di Habburgers! (TUTTI furni nuovi)");
message.appendString("catalogue/feature_cata_hort_habbergerbundle.png");
message.appendInt(0);
message.appendString("");
message.appendInt(-1);
message.appendInt(3);
message.appendString("Habbolympics");
message.appendString("catalogue/feature_cata_hort_olympic16.png");
message.appendInt(0);
message.appendString("");
message.appendInt(-1);
message.appendInt(4);
message.appendString("Diventa un Membro HC");
message.appendString("catalogue/feature_cata_hort_HC_b.png");
message.appendInt(0);
message.appendString("habbo_club");
message.appendInt(-1);
}
}

View File

@ -0,0 +1,26 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class FrontpageLayout extends CatalogPage {
public FrontpageLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("frontpage4");
message.appendInt(2);
message.appendString(super.getHeaderImage());
message.appendString(super.getTeaserImage());
message.appendInt(3);
message.appendString(super.getTextOne());
message.appendString(super.getTextTwo());
message.appendString(super.getTextTeaser());
}
}

View File

@ -0,0 +1,25 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class GuildForumLayout extends CatalogPage {
public GuildForumLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("guild_forum");
message.appendInt(2);
message.appendString(super.getHeaderImage());
message.appendString(super.getTeaserImage());
message.appendInt(3);
message.appendString(super.getTextOne());
message.appendString(super.getTextDetails());
message.appendString(super.getTextTeaser());
}
}

View File

@ -0,0 +1,25 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class GuildFrontpageLayout extends CatalogPage {
public GuildFrontpageLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("guild_frontpage");
message.appendInt(2);
message.appendString(super.getHeaderImage());
message.appendString(super.getTeaserImage());
message.appendInt(3);
message.appendString(super.getTextOne());
message.appendString(super.getTextDetails());
message.appendString(super.getTextTeaser());
}
}

View File

@ -0,0 +1,25 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class GuildFurnitureLayout extends CatalogPage {
public GuildFurnitureLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("guild_custom_furni");
message.appendInt(2);
message.appendString(super.getHeaderImage());
message.appendString(super.getTeaserImage());
message.appendInt(3);
message.appendString(super.getTextOne());
message.appendString(super.getTextDetails());
message.appendString(super.getTextTeaser());
}
}

View File

@ -0,0 +1,23 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class InfoDucketsLayout extends CatalogPage {
public InfoDucketsLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("info_duckets");
message.appendInt(1);
message.appendString(this.getHeaderImage());
message.appendInt(1);
message.appendString(this.getTextOne());
message.appendInt(0);
}
}

View File

@ -0,0 +1,23 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class InfoLoyaltyLayout extends CatalogPage {
public InfoLoyaltyLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("info_loyalty");
message.appendInt(1);
message.appendString(this.getHeaderImage());
message.appendInt(1);
message.appendString(this.getTextOne());
message.appendInt(0);
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -0,0 +1,26 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class InfoPetsLayout extends CatalogPage {
public InfoPetsLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("info_pets");
message.appendInt(2);
message.appendString(this.getHeaderImage());
message.appendString(this.getTeaserImage());
message.appendInt(3);
message.appendString(this.getTextOne());
message.appendString("");
message.appendString(this.getTextTeaser());
message.appendInt(0);
}
}

View File

@ -0,0 +1,26 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class InfoRentablesLayout extends CatalogPage {
public InfoRentablesLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
String[] data = this.getTextOne().split("\\|\\|");
message.appendString("info_rentables");
message.appendInt(1);
message.appendString(this.getHeaderImage());
message.appendInt(data.length);
for (String d : data) {
message.appendString(d);
}
message.appendInt(0);
}
}

View File

@ -0,0 +1,26 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class LoyaltyVipBuyLayout extends CatalogPage {
public LoyaltyVipBuyLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("loyalty_vip_buy");
message.appendInt(3);
message.appendString(super.getHeaderImage());
message.appendString(super.getTeaserImage());
message.appendString(super.getSpecialImage());
message.appendInt(3);
message.appendString(super.getTextOne());
message.appendString(super.getTextDetails());
message.appendString(super.getTextTeaser());
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,20 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class MarketplaceLayout extends CatalogPage {
public MarketplaceLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("marketplace");
message.appendInt(0);
message.appendInt(0);
}
}

View File

@ -0,0 +1,21 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class MarketplaceOwnItems extends CatalogPage {
public MarketplaceOwnItems(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("marketplace_own_items");
message.appendInt(0);
message.appendInt(0);
}
}

View File

@ -0,0 +1,26 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class PetCustomizationLayout extends CatalogPage {
public PetCustomizationLayout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("petcustomization");
message.appendInt(3);
message.appendString(super.getHeaderImage());
message.appendString(super.getTeaserImage());
message.appendString(super.getSpecialImage());
message.appendInt(3);
message.appendString(super.getTextOne());
message.appendString(super.getTextDetails());
message.appendString(super.getTextTeaser());
}
}

View File

@ -0,0 +1,26 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Pets2Layout extends CatalogPage {
public Pets2Layout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("pets2");
message.appendInt(2);
message.appendString(super.getHeaderImage());
message.appendString(super.getTeaserImage());
message.appendInt(4);
message.appendString(super.getTextOne());
message.appendString(super.getTextTwo());
message.appendString(super.getTextDetails());
message.appendString(super.getTextTeaser());
}
}

View File

@ -0,0 +1,26 @@
package com.eu.habbo.habbohotel.catalog.layouts;
import com.eu.habbo.habbohotel.catalog.CatalogPage;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Pets3Layout extends CatalogPage {
public Pets3Layout(ResultSet set) throws SQLException {
super(set);
}
@Override
public void serialize(ServerMessage message) {
message.appendString("pets3");
message.appendInt(2);
message.appendString(super.getHeaderImage());
message.appendString(super.getTeaserImage());
message.appendInt(4);
message.appendString(super.getTextOne());
message.appendString(super.getTextTwo());
message.appendString(super.getTextDetails());
message.appendString(super.getTextTeaser());
}
}

Some files were not shown because too many files have changed in this diff Show More