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