Added Plugins

This commit is contained in:
duckietm
2024-03-12 09:51:05 +01:00
parent a218dae3c1
commit a4595b85bd
27 changed files with 1708 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
+19
View File
@@ -0,0 +1,19 @@
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar
# Eclipse m2e generated files
# Eclipse Core
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath
.idea
Binary file not shown.
Binary file not shown.
Binary file not shown.
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 ThisAccountHasBeenSuspended, EntenKoeniq, habbo.sx
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+64
View File
@@ -0,0 +1,64 @@
# 📷 Camera
**New features compared to Apollyon**
- [x] Small and more efficient than Apollyon.
- [x] `*_small.png` are really small (original / 2) and not just copied.
- [x] Creates a folder structure if it doesn't exist.
- [x] Report failures to Habbo.
- [x] Added a cooldown time for taking photos to prevent your hard drive from filling up.
- [x] Prevent exploits on thumbnails, not just photos.
- [x] No more FTP (no one used that).
[Download the latest compiled version here!](https://git.krews.org/duckietm/habbocamera/-/blob/main/Compiled/Camera-1.6.jar)
## Informations
All missing settings in the database will be created with this plugin after the first launch of your emulator.
### emulator_settings
- `camera.url`
- - The URL from which you can access the image (default: http://localhost/camera/)
- `imager.location.output.camera`
- - The location where to save the photo (default: C:/inetpub/wwwroot/public/camera/)
- `imager.location.output.thumbnail`
- - The location to save the thumbnail (default: C:/inetpub/wwwroot/public/camera/thumbnails/)
- `camera.price.points.publish`
- - The price of points for publishing this photo (default: 1)
- `camera.price.points.publish.type`
- - The type of points to publish (default: 5 = diamonds)
- `camera.publish.delay`
- - The time, in seconds, how long the user should wait to post a new photo (default: 180)
- `camera.price.credits`
- - The credits required to purchase this photo (default: 2)
- `camera.price.points`
- - The price of points to purchase this photo (default: 0 = no points required)
- `camera.price.points.type`
- - The type of points to buy this photo (default: 5 = diamonds)
- `camera.render.delay`
- - The time, in seconds, how long the user should wait to take a new photo (default: 5)
### emulator_texts
- `camera.permission`
- - default: "You don't have permission to use the camera!"
- `camera.wait`
- - default: "Please wait %seconds% seconds before making another picture."
- `camera.error.creation`
- - default: "Failed to create your picture. \*sadpanda\*"
Since this plugin doesn't use FTP like “Apollyon”, you can delete these values in your database under `emulator_settings` if necessary.
## Comparison
Apollyon doesn't show you any errors like you don't have enough currency, this plugin doesn't have that bug as shown in the pictures.
### Apollyon
![first](https://cdn.discordapp.com/attachments/1098244829462405183/1154449248297963610/image.png)
![second](https://cdn.discordapp.com/attachments/1098244829462405183/1154448684063404104/image.png)
### Camera
![first](https://cdn.discordapp.com/attachments/1098244829462405183/1154446836917076070/image.png)
![second](https://cdn.discordapp.com/attachments/1098244829462405183/1154446698249199707/image.png)
# Credits
- EntenKoeniq for releaseing the fixes and rewritten the plugin. (This camera plugin was written for https://habbo.sx/ and is now available to the community for free.)
- John
- Beny (Packet Hijacking)
- Ovflowd (Original Implimentation)
- Alejandro (Error Handling Help)
+37
View File
@@ -0,0 +1,37 @@
<?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.camera</groupId>
<artifactId>Camera</artifactId>
<version>1.6</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.eu.habbo</groupId>
<artifactId>Habbo</artifactId>
<version>3.5.2</version>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,101 @@
package com.eu.camera;
import com.eu.camera.handlers.PublishPhotoEvent;
import com.eu.camera.handlers.PurchasePhotoEvent;
import com.eu.camera.handlers.RenderRoomEvent;
import com.eu.camera.handlers.RenderRoomThumbnailEvent;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.messages.PacketManager;
import com.eu.habbo.messages.incoming.Incoming;
import com.eu.habbo.messages.incoming.MessageHandler;
import com.eu.habbo.plugin.EventHandler;
import com.eu.habbo.plugin.EventListener;
import com.eu.habbo.plugin.HabboPlugin;
import com.eu.habbo.plugin.events.emulator.EmulatorLoadedEvent;
import gnu.trove.map.hash.THashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.lang.reflect.Field;
public class Main extends HabboPlugin implements EventListener {
private static final Logger LOGGER = LoggerFactory.getLogger(Emulator.class);
@Override
public void onEnable() throws Exception {
Emulator.getPluginManager().registerEvents(this, this);
if (Emulator.isReady && !Emulator.isShuttingDown) {
this.onEmulatorLoadedEvent(null);
}
}
@Override
public void onDisable() throws Exception {
PacketManager packetManager = Emulator.getGameServer().getPacketManager();
Field incomingField = PacketManager.class.getDeclaredField("incoming");
incomingField.setAccessible(true);
@SuppressWarnings("unchecked")
THashMap<Integer, Class<? extends MessageHandler>> incoming = (THashMap<Integer, Class<? extends MessageHandler>>)incomingField.get(packetManager);
// Removes the custom handlers for these packets.
incoming.remove(Incoming.CameraPublishToWebEvent, PublishPhotoEvent.class);
incoming.remove(Incoming.CameraPurchaseEvent, PurchasePhotoEvent.class);
incoming.remove(Incoming.CameraRoomPictureEvent, RenderRoomEvent.class);
incoming.remove(Incoming.CameraRoomThumbnailEvent, RenderRoomThumbnailEvent.class);
}
@Override
public boolean hasPermission(Habbo habbo, String string) {
return false;
}
@EventHandler
public void onEmulatorLoadedEvent(EmulatorLoadedEvent event) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException, Exception {
// Adds missing SQLs if they are not found.
Emulator.getConfig().register("camera.url", "http://localhost/camera/");
Emulator.getConfig().register("imager.location.output.camera", "C:/inetpub/wwwroot/public/camera/");
Emulator.getConfig().register("imager.location.output.thumbnail", "C:/inetpub/wwwroot/camera/thumbnails/");
Emulator.getConfig().register("camera.price.points.publish", "1");
Emulator.getConfig().register("camera.price.points.publish.type", "5");
Emulator.getConfig().register("camera.publish.delay", "180");
Emulator.getConfig().register("camera.price.credits", "2");
Emulator.getConfig().register("camera.price.points", "0");
Emulator.getConfig().register("camera.price.points.type", "5");
Emulator.getConfig().register("camera.render.delay", "5");
Emulator.getTexts().register("camera.permission", "You don't have permission to use the camera!");
Emulator.getTexts().register("camera.wait", "Please wait %seconds% seconds before making another picture.");
Emulator.getTexts().register("camera.error.creation", "Failed to create your picture. *sadpanda*");
PacketManager packetManager = Emulator.getGameServer().getPacketManager();
Field incomingField = PacketManager.class.getDeclaredField("incoming");
incomingField.setAccessible(true);
@SuppressWarnings("unchecked")
THashMap<Integer, Class<? extends MessageHandler>> incoming = (THashMap<Integer, Class<? extends MessageHandler>>)incomingField.get(packetManager);
// Removes the current handlers for these packets.
incoming.remove(Incoming.CameraPublishToWebEvent);
incoming.remove(Incoming.CameraPurchaseEvent);
incoming.remove(Incoming.CameraRoomPictureEvent);
incoming.remove(Incoming.CameraRoomThumbnailEvent);
// Adds the new handlers for these packets.
packetManager.registerHandler(Incoming.CameraPublishToWebEvent, PublishPhotoEvent.class);
packetManager.registerHandler(Incoming.CameraPurchaseEvent, PurchasePhotoEvent.class);
packetManager.registerHandler(Incoming.CameraRoomPictureEvent, RenderRoomEvent.class);
packetManager.registerHandler(Incoming.CameraRoomThumbnailEvent, RenderRoomThumbnailEvent.class);
// Create the output directories if they don't exist.
File outputDir = new File(Emulator.getConfig().getValue("imager.location.output.thumbnail"));
if (!outputDir.exists()) {
outputDir.mkdirs();
}
LOGGER.info("[Camera] Plugin has loaded!");
}
}
@@ -0,0 +1,71 @@
package com.eu.camera.handlers;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.habbohotel.users.HabboInfo;
import com.eu.habbo.messages.incoming.MessageHandler;
import com.eu.habbo.messages.outgoing.camera.CameraPublishWaitMessageComposer;
import com.eu.habbo.messages.outgoing.catalog.NotEnoughPointsTypeComposer;
import com.eu.habbo.plugin.events.users.UserPublishPictureEvent;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class PublishPhotoEvent extends MessageHandler {
public static final int CAMERA_PUBLISH_POINTS = Emulator.getConfig().getInt("camera.price.points.publish", 1);
public static final int CAMERA_PUBLISH_POINTS_TYPE = Emulator.getConfig().getInt("camera.price.points.publish.type", 5);
public static final int CAMERA_PUBLISH_DELAY = Emulator.getConfig().getInt("camera.publish.delay", 180);
@Override
public void handle() {
Habbo habbo = this.client.getHabbo();
HabboInfo habboInfo = habbo.getHabboInfo();
int points = habboInfo.getCurrencyAmount(CAMERA_PUBLISH_POINTS_TYPE);
if (points < CAMERA_PUBLISH_POINTS) {
String currencyName = Emulator.getTexts().getValue("seasonal.name." + Integer.toString(CAMERA_PUBLISH_POINTS_TYPE), "currency");
String alertMessage = "You don't have enough " + currencyName + "!";
habbo.alert(alertMessage);
this.client.sendResponse(new NotEnoughPointsTypeComposer(false, true, CAMERA_PUBLISH_POINTS_TYPE));
return;
}
int photoTimestamp = habboInfo.getPhotoTimestamp();
String photoJSON = habboInfo.getPhotoJSON();
if (photoTimestamp == 0 || photoJSON.isEmpty() || !photoJSON.contains(Integer.toString(photoTimestamp))) {
return;
}
int currentTimestamp = Emulator.getIntUnixTimestamp();
int timeSinceLastPublish = currentTimestamp - habboInfo.getWebPublishTimestamp();
if (timeSinceLastPublish < CAMERA_PUBLISH_DELAY) {
int wait = CAMERA_PUBLISH_DELAY - timeSinceLastPublish;
this.client.sendResponse(new CameraPublishWaitMessageComposer(false, wait, habboInfo.getPhotoURL()));
} else {
UserPublishPictureEvent publishPictureEvent = new UserPublishPictureEvent(habbo, habboInfo.getPhotoURL(), currentTimestamp, habboInfo.getPhotoRoomId());
if (!Emulator.getPluginManager().fireEvent(publishPictureEvent).isCancelled()) {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
PreparedStatement statement = connection.prepareStatement("INSERT INTO camera_web (user_id, room_id, timestamp, url) VALUES (?, ?, ?, ?)")) {
statement.setInt(1, habboInfo.getId());
statement.setInt(2, publishPictureEvent.roomId);
statement.setInt(3, publishPictureEvent.timestamp);
statement.setString(4, publishPictureEvent.URL);
statement.execute();
habboInfo.setWebPublishTimestamp(currentTimestamp);
habbo.givePoints(CAMERA_PUBLISH_POINTS_TYPE, -CAMERA_PUBLISH_POINTS);
} catch (SQLException throwable) {
throwable.printStackTrace();
}
}
this.client.sendResponse(new CameraPublishWaitMessageComposer(true, 0, ""));
}
}
}
@@ -0,0 +1,87 @@
package com.eu.camera.handlers;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.achievements.AchievementManager;
import com.eu.habbo.habbohotel.items.Item;
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.incoming.MessageHandler;
import com.eu.habbo.messages.outgoing.camera.CameraPurchaseSuccesfullComposer;
import com.eu.habbo.messages.outgoing.catalog.NotEnoughPointsTypeComposer;
import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer;
import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer;
import com.eu.habbo.plugin.events.users.UserPurchasePictureEvent;
public class PurchasePhotoEvent extends MessageHandler {
public static final int CAMERA_PURCHASE_CREDITS = Emulator.getConfig().getInt("camera.price.credits", 2);
public static final int CAMERA_PURCHASE_POINTS = Emulator.getConfig().getInt("camera.price.points", 0);
public static final int CAMERA_PURCHASE_POINTS_TYPE = Emulator.getConfig().getInt("camera.price.points.type", 5);
public static final int CAMERA_ITEM_ID = Emulator.getConfig().getInt("camera.item_id");
public static final String EXTERNAL_IMAGE_INTERACTION = "external_image";
@Override
public void handle() {
Habbo habbo = this.client.getHabbo();
HabboInfo habboInfo = habbo.getHabboInfo();
if (habboInfo.getCredits() < CAMERA_PURCHASE_CREDITS) {
handleInsufficientCredits(habbo);
return;
}
if (habboInfo.getCurrencyAmount(CAMERA_PURCHASE_POINTS_TYPE) < CAMERA_PURCHASE_POINTS) {
handleInsufficientPoints(habbo);
return;
}
if (!isValidPhoto(habboInfo)) {
return;
}
if (Emulator.getPluginManager().fireEvent(new UserPurchasePictureEvent(habbo, habboInfo.getPhotoURL(), habboInfo.getCurrentRoom().getId(), habboInfo.getPhotoTimestamp())).isCancelled()) {
return;
}
Item item = Emulator.getGameEnvironment().getItemManager().getItem(CAMERA_ITEM_ID);
if (item == null || !item.getInteractionType().getName().equals(EXTERNAL_IMAGE_INTERACTION)) {
return;
}
handlePurchasedPhoto(habbo, habboInfo, item);
}
private void handleInsufficientCredits(Habbo habbo) {
habbo.alert("You don't have enough credits!");
this.client.sendResponse(new NotEnoughPointsTypeComposer(true, false, 0));
}
private void handleInsufficientPoints(Habbo habbo) {
String alertMessage = "You don't have enough " + Emulator.getTexts().getValue("seasonal.name." + Integer.toString(CAMERA_PURCHASE_POINTS_TYPE), "currency") + "!";
habbo.alert(alertMessage);
this.client.sendResponse(new NotEnoughPointsTypeComposer(false, true, CAMERA_PURCHASE_POINTS_TYPE));
}
private boolean isValidPhoto(HabboInfo habboInfo) {
return habboInfo.getPhotoTimestamp() != 0 && !habboInfo.getPhotoJSON().isEmpty() && habboInfo.getPhotoJSON().contains(Integer.toString(habboInfo.getPhotoTimestamp()));
}
private void handlePurchasedPhoto(Habbo habbo, HabboInfo habboInfo, Item item) {
HabboItem photoItem = Emulator.getGameEnvironment().getItemManager().createItem(habboInfo.getId(), item, 0, 0, habboInfo.getPhotoJSON());
if (photoItem != null) {
photoItem.setExtradata(photoItem.getExtradata().replace("%id%", Integer.toString(photoItem.getId())));
photoItem.needsUpdate(true);
habbo.getInventory().getItemsComponent().addItem(photoItem);
this.client.sendResponse(new CameraPurchaseSuccesfullComposer());
this.client.sendResponse(new AddHabboItemComposer(photoItem));
this.client.sendResponse(new InventoryRefreshComposer());
habbo.giveCredits(-CAMERA_PURCHASE_CREDITS);
habbo.givePoints(CAMERA_PURCHASE_POINTS_TYPE, -CAMERA_PURCHASE_POINTS);
AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("CameraPhotoCount"));
}
}
}
@@ -0,0 +1,136 @@
package com.eu.camera.handlers;
import com.eu.habbo.Emulator;
import com.eu.habbo.messages.incoming.MessageHandler;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.habbohotel.users.HabboInfo;
import com.eu.habbo.habbohotel.users.HabboStats;
import com.eu.habbo.messages.outgoing.camera.CameraURLComposer;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufUtil;
import javax.imageio.ImageIO;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class RenderRoomEvent extends MessageHandler {
public static final int CAMERA_RENDER_DELAY = Emulator.getConfig().getInt("camera.render.delay", 5);
private ByteBuf image = null;
@Override
public void handle() {
try {
make();
} finally {
if (this.image != null) {
this.image.release();
}
}
}
private void make() {
Habbo habbo = this.client.getHabbo();
if (!habbo.hasPermission("acc_camera")) {
habbo.alert(Emulator.getTexts().getValue("camera.permission"));
return;
}
HabboInfo habboInfo = habbo.getHabboInfo();
HabboStats habboStats = habbo.getHabboStats();
int timestamp = Emulator.getIntUnixTimestamp();
if (habboStats.cache.containsKey("camera_render_cooldown")) {
int cameraTimestamp = (int) habboStats.cache.get("camera_render_cooldown");
if (timestamp - cameraTimestamp < CAMERA_RENDER_DELAY) {
String alertMessage = Emulator.getTexts().getValue("camera.wait")
.replace("%seconds%", Integer.toString(timestamp - cameraTimestamp));
habbo.alert(alertMessage);
// Show the correct last photo.
String[] splittedPhotoURL = habboInfo.getPhotoURL().split("/");
if (splittedPhotoURL.length > 0) {
this.client.sendResponse(new CameraURLComposer(splittedPhotoURL[splittedPhotoURL.length - 1]));
}
return;
}
}
habboStats.cache.put("camera_render_cooldown", (Object) timestamp);
Room room = habboInfo.getCurrentRoom();
if (room == null) {
return;
}
final int count = this.packet.readInt();
this.image = this.packet.getBuffer().readBytes(count);
if (this.image == null) {
return;
}
// Prevent possible exploits.
byte[] imageBytes = ByteBufUtil.getBytes(this.image, 0, 4, true);
if (imageBytes == null || imageBytes.length < 4 || !isPNG(imageBytes)) {
return;
}
BufferedImage theImage;
try (ByteBufInputStream in = new ByteBufInputStream(this.image)) {
theImage = ImageIO.read(in);
} catch (IOException e) {
handleImageProcessingError(habbo);
return;
}
String fileName = habboInfo.getId() + "_" + timestamp;
String URL = fileName + ".png";
String URLsmall = fileName + "_small.png";
String base = Emulator.getConfig().getValue("camera.url");
String json = Emulator.getConfig().getValue("camera.extradata")
.replace("%timestamp%", Integer.toString(timestamp))
.replace("%room_id%", Integer.toString(room.getId()))
.replace("%url%", base + URL);
habboInfo.setPhotoURL(base + URL);
habboInfo.setPhotoTimestamp(timestamp);
habboInfo.setPhotoRoomId(room.getId());
habboInfo.setPhotoJSON(json);
File imageFile = new File(Emulator.getConfig().getValue("imager.location.output.camera") + URL);
File smallImageFile = new File(Emulator.getConfig().getValue("imager.location.output.camera") + URLsmall);
try {
ImageIO.write(theImage, "png", imageFile);
Image smallImage = theImage.getScaledInstance(theImage.getWidth(null) / 2, theImage.getHeight(null) / 2, Image.SCALE_SMOOTH);
BufferedImage bi = new BufferedImage(smallImage.getWidth(null), smallImage.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics2D = bi.createGraphics();
graphics2D.drawImage(smallImage, 0, 0, null);
graphics2D.dispose();
ImageIO.write(bi, "png", smallImageFile);
} catch (IOException e) {
handleImageProcessingError(habbo);
return;
}
this.client.sendResponse(new CameraURLComposer(URL));
}
private boolean isPNG(byte[] bytes) {
return bytes[0] == -119 && bytes[1] == 80 && bytes[2] == 78 && bytes[3] == 71;
}
private void handleImageProcessingError(Habbo habbo) {
habbo.alert(Emulator.getTexts().getValue("camera.error.creation"));
}
}
@@ -0,0 +1,96 @@
package com.eu.camera.handlers;
import com.eu.habbo.Emulator;
import com.eu.habbo.messages.incoming.MessageHandler;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.habbohotel.users.HabboInfo;
import com.eu.habbo.habbohotel.users.HabboStats;
import com.eu.habbo.messages.outgoing.camera.CameraRoomThumbnailSavedComposer;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufUtil;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class RenderRoomThumbnailEvent extends MessageHandler {
public static final int CAMERA_RENDER_DELAY = Emulator.getConfig().getInt("camera.render.delay", 5);
private ByteBuf image = null;
@Override
public void handle() {
try {
make();
} finally {
if (this.image != null) {
this.image.release();
}
}
}
private void make() {
Habbo habbo = this.client.getHabbo();
if (!habbo.hasPermission("acc_camera")) {
habbo.alert(Emulator.getTexts().getValue("camera.permission"));
return;
}
HabboStats habboStats = habbo.getHabboStats();
int timestamp = Emulator.getIntUnixTimestamp();
if (habboStats.cache.containsKey("camera_render_cooldown")) {
int cameraTimestamp = (int) habboStats.cache.get("camera_render_cooldown");
if (timestamp - cameraTimestamp < CAMERA_RENDER_DELAY) {
String alertMessage = Emulator.getTexts().getValue("camera.wait")
.replace("%seconds%", Integer.toString(timestamp - cameraTimestamp));
habbo.alert(alertMessage);
return;
}
}
habboStats.cache.put("camera_render_cooldown", (Object) timestamp);
HabboInfo habboInfo = habbo.getHabboInfo();
Room room = habboInfo.getCurrentRoom();
if (room == null || !room.isOwner(habbo)) {
return;
}
final int count = this.packet.readInt();
this.image = this.packet.getBuffer().readBytes(count);
if (this.image == null || !isValidImage(this.image)) {
return;
}
BufferedImage theImage = null;
try (ByteBufInputStream in = new ByteBufInputStream(this.image)) {
theImage = ImageIO.read(in);
} catch (IOException e) {
e.printStackTrace();
habbo.alert(Emulator.getTexts().getValue("camera.error.creation"));
return;
}
File imageFile = new File(Emulator.getConfig().getValue("imager.location.output.thumbnail") + room.getId() + ".png");
try {
ImageIO.write(theImage, "png", imageFile);
} catch (IOException e) {
e.printStackTrace();
habbo.alert(Emulator.getTexts().getValue("camera.error.creation"));
return;
}
this.client.sendResponse(new CameraRoomThumbnailSavedComposer());
}
private boolean isValidImage(ByteBuf imageBuffer) {
byte[] imageBytes = ByteBufUtil.getBytes(imageBuffer, 0, 4, true);
return (imageBytes != null && imageBytes.length >= 4 &&
imageBytes[0] == -119 && imageBytes[1] == 80 && imageBytes[2] == 78 && imageBytes[3] == 71);
}
}
@@ -0,0 +1,6 @@
{
"main" : "com.eu.camera.Main",
"name" : "Camera",
"author" : "EntenKoeniq and habbo.sx"
}