mirror of
https://git.krews.org/morningstar/Arcturus-Community.git
synced 2024-11-26 16:30:52 +01:00
Subscription revamp, Habbo club, HC Pay day, Clothing validation and Catalog purchase logs
This commit is contained in:
parent
683ff1dd1d
commit
64b0f499d0
88
sqlupdates/DEV_TO_SUBSCRIPTION-REVAMP.sql
Normal file
88
sqlupdates/DEV_TO_SUBSCRIPTION-REVAMP.sql
Normal file
@ -0,0 +1,88 @@
|
||||
CREATE TABLE `users_subscriptions` (
|
||||
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(10) UNSIGNED NULL,
|
||||
`subscription_type` varchar(255) NULL,
|
||||
`timestamp_start` int(10) UNSIGNED NULL,
|
||||
`duration` int(10) UNSIGNED NULL,
|
||||
`active` tinyint(1) NULL DEFAULT 1,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `user_id`(`user_id`),
|
||||
INDEX `subscription_type`(`subscription_type`),
|
||||
INDEX `timestamp_start`(`timestamp_start`),
|
||||
INDEX `active`(`active`)
|
||||
);
|
||||
|
||||
CREATE TABLE `logs_shop_purchases` (
|
||||
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`timestamp` int(10) UNSIGNED NULL,
|
||||
`user_id` int(10) UNSIGNED NULL,
|
||||
`catalog_item_id` int(10) UNSIGNED NULL,
|
||||
`item_ids` text DEFAULT NULL,
|
||||
`catalog_name` varchar(255) NULL,
|
||||
`cost_credits` int(10) NULL,
|
||||
`cost_points` int(10) NULL,
|
||||
`points_type` int(10) NULL,
|
||||
`amount` int(10) NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `timestamp`(`timestamp`),
|
||||
INDEX `user_id`(`user_id`)
|
||||
);
|
||||
|
||||
CREATE TABLE `logs_hc_payday` (
|
||||
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`timestamp` int(10) UNSIGNED NULL,
|
||||
`user_id` int(10) UNSIGNED NULL,
|
||||
`hc_streak` int(10) UNSIGNED NULL,
|
||||
`total_coins_spent` int(10) UNSIGNED NULL,
|
||||
`reward_coins_spent` int(10) UNSIGNED NULL,
|
||||
`reward_streak` int(10) UNSIGNED NULL,
|
||||
`total_payout` int(10) UNSIGNED NULL,
|
||||
`currency` varchar(255) NULL,
|
||||
`claimed` tinyint(1) DEFAULT 0 NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `timestamp`(`timestamp`),
|
||||
INDEX `user_id`(`user_id`)
|
||||
);
|
||||
|
||||
ALTER TABLE `emulator_settings` MODIFY COLUMN `value` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL AFTER `key`;
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('subscriptions.hc.payday.enabled', '1');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('subscriptions.hc.payday.next_date', '2020-10-15 00:00:00');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('subscriptions.hc.payday.interval', '1 month');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('subscriptions.hc.payday.query', 'SELECT SUM(cost_credits) AS `amount_spent` FROM `logs_shop_purchases` WHERE `user_id` = @user_id AND `timestamp` > @timestamp_start AND `timestamp` <= @timestamp_end AND `catalog_name` NOT LIKE \'CF_%\' AND `catalog_name` NOT LIKE \'CFC_%\';');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('subscriptions.hc.payday.streak', '7=5;30=10;60=15;90=20;180=25;365=30');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('subscriptions.hc.payday.currency', 'credits');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('subscriptions.hc.payday.percentage', '10');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('subscriptions.hc.payday.creditsspent_reset_on_expire', '1');
|
||||
INSERT INTO `emulator_texts` (`key`, `value`) VALUES ('subscriptions.hc.payday.message', 'Woohoo HC Payday has arrived! You have received %amount% credits to your purse. Enjoy!')
|
||||
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('subscriptions.scheduler.enabled', '1');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('subscriptions.scheduler.interval', '10');
|
||||
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('hotel.users.clothingvalidation.onhcexpired', '0');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('hotel.users.clothingvalidation.onlogin', '0');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('hotel.users.clothingvalidation.onchangelooks', '0');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('hotel.users.clothingvalidation.onmimic', '0');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('hotel.users.clothingvalidation.onmannequin', '0');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('hotel.users.clothingvalidation.onfballgate', '0');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('gamedata.figuredata.url', 'https://habbo.com/gamedata/figuredata/0');
|
||||
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('hotel.users.max.friends', '300');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('hotel.users.max.friends.hc', '1100');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('hotel.users.max.rooms', '50');
|
||||
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('hotel.users.max.rooms.hc', '75');
|
||||
|
||||
DELETE FROM `emulator_settings` WHERE `key` = 'hotel.max.rooms.per.user';
|
||||
DELETE FROM `emulator_settings` WHERE `key` = 'hotel.max.rooms.user';
|
||||
DELETE FROM `emulator_settings` WHERE `key` = 'hotel.max.rooms.vip';
|
||||
|
||||
DELETE FROM `emulator_settings` WHERE `key` = 'max.friends';
|
||||
DELETE FROM `emulator_settings` WHERE `key` = 'max.friends';
|
||||
|
||||
ALTER TABLE `users_settings` ADD COLUMN `max_friends` int(10) NULL DEFAULT 300 AFTER `has_gotten_default_saved_searches`;
|
||||
ALTER TABLE `users_settings` ADD COLUMN `max_rooms` int(10) NULL DEFAULT 50 AFTER `has_gotten_default_saved_searches`;
|
||||
ALTER TABLE `users_settings` ADD COLUMN `last_hc_payday` int(10) NULL DEFAULT 0 AFTER `has_gotten_default_saved_searches`;
|
||||
|
||||
ALTER TABLE `permissions` ADD COLUMN `cmd_subscription` enum('0','1') NULL DEFAULT '0' AFTER `cmd_credits`;
|
||||
INSERT INTO `emulator_texts` (`key`, `value`) VALUES ('commands.keys.cmd_subscription', 'subscription;sub');
|
||||
|
||||
INSERT INTO users_subscriptions SELECT NULL, user_id, 'HABBO_CLUB' as `subscription_type`, UNIX_TIMESTAMP() AS `timestamp_start`, (club_expire_timestamp - UNIX_TIMESTAMP()) AS `duration`, 1 AS `active` FROM users_settings WHERE club_expire_timestamp > UNIX_TIMESTAMP();
|
@ -24,10 +24,10 @@ import java.io.*;
|
||||
import java.security.MessageDigest;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Random;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public final class Emulator {
|
||||
|
||||
@ -368,6 +368,65 @@ public final class Emulator {
|
||||
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");
|
||||
@ -378,7 +437,7 @@ public final class Emulator {
|
||||
return res + seconds;
|
||||
}
|
||||
|
||||
private static Date stringToDate(String date) {
|
||||
public static Date stringToDate(String date) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
Date res = null;
|
||||
try {
|
||||
|
@ -3,9 +3,18 @@ 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 org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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;
|
||||
|
||||
public class Database {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(Database.class);
|
||||
@ -53,4 +62,52 @@ public class Database {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ 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 org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -31,6 +33,8 @@ public class GameEnvironment {
|
||||
public PixelScheduler pixelScheduler;
|
||||
public PointsScheduler pointsScheduler;
|
||||
public GotwPointsScheduler gotwPointsScheduler;
|
||||
public SubscriptionScheduler subscriptionScheduler;
|
||||
|
||||
private HabboManager habboManager;
|
||||
private NavigatorManager navigatorManager;
|
||||
private GuildManager guildManager;
|
||||
@ -49,6 +53,7 @@ public class GameEnvironment {
|
||||
private WordFilter wordFilter;
|
||||
private CraftingManager craftingManager;
|
||||
private PollManager pollManager;
|
||||
private SubscriptionManager subscriptionManager;
|
||||
|
||||
public void load() throws Exception {
|
||||
LOGGER.info("GameEnvironment -> Loading...");
|
||||
@ -86,6 +91,11 @@ public class GameEnvironment {
|
||||
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);
|
||||
|
||||
LOGGER.info("GameEnvironment -> Loaded!");
|
||||
}
|
||||
@ -103,6 +113,7 @@ public class GameEnvironment {
|
||||
this.roomManager.dispose();
|
||||
this.itemManager.dispose();
|
||||
this.hotelViewManager.dispose();
|
||||
this.subscriptionManager.dispose();
|
||||
LOGGER.info("GameEnvironment -> Disposed!");
|
||||
}
|
||||
|
||||
@ -191,4 +202,8 @@ public class GameEnvironment {
|
||||
|
||||
public GotwPointsScheduler getGotwPointsScheduler() { return this.gotwPointsScheduler;
|
||||
}
|
||||
|
||||
public SubscriptionManager getSubscriptionManager() {
|
||||
return this.subscriptionManager;
|
||||
}
|
||||
}
|
||||
|
@ -1121,6 +1121,26 @@ public class CatalogManager {
|
||||
habbo.getClient().sendResponse(new PurchaseOKComposer(purchasedEvent.catalogItem));
|
||||
habbo.getClient().sendResponse(new InventoryRefreshComposer());
|
||||
|
||||
THashSet<String> itemIds = new THashSet<>();
|
||||
|
||||
for(HabboItem ix : purchasedEvent.itemsList) {
|
||||
itemIds.add(ix.getId() + "");
|
||||
}
|
||||
|
||||
if(!free) {
|
||||
Emulator.getThreading().run(new CatalogPurchaseLogEntry(
|
||||
Emulator.getIntUnixTimestamp(),
|
||||
purchasedEvent.habbo.getHabboInfo().getId(),
|
||||
purchasedEvent.catalogItem != null ? purchasedEvent.catalogItem.getId() : 0,
|
||||
String.join(";", itemIds),
|
||||
purchasedEvent.catalogItem != null ? purchasedEvent.catalogItem.getName() : "",
|
||||
purchasedEvent.totalCredits,
|
||||
purchasedEvent.totalPoints,
|
||||
item != null ? item.getPointsType() : 0,
|
||||
amount
|
||||
));
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Exception caught", e);
|
||||
habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR));
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -285,6 +285,7 @@ public class CommandHandler {
|
||||
addCommand(new UpdateYoutubePlaylistsCommand());
|
||||
addCommand(new AddYoutubePlaylistCommand());
|
||||
addCommand(new SoftKickCommand());
|
||||
addCommand(new SubscriptionCommand());
|
||||
|
||||
addCommand(new TestCommand());
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import com.eu.habbo.habbohotel.permissions.Permission;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles;
|
||||
import com.eu.habbo.habbohotel.users.Habbo;
|
||||
import com.eu.habbo.habbohotel.users.HabboGender;
|
||||
import com.eu.habbo.habbohotel.users.clothingvalidation.ClothingValidationManager;
|
||||
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer;
|
||||
import com.eu.habbo.messages.outgoing.users.UserDataComposer;
|
||||
import com.eu.habbo.util.figure.FigureUtil;
|
||||
@ -35,7 +36,7 @@ public class MimicCommand extends Command {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_mimic.forbidden_clothing"), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
} else {
|
||||
gameClient.getHabbo().getHabboInfo().setLook(habbo.getHabboInfo().getLook());
|
||||
gameClient.getHabbo().getHabboInfo().setLook(ClothingValidationManager.VALIDATE_ON_MIMIC ? ClothingValidationManager.validateLook(gameClient.getHabbo(), habbo.getHabboInfo().getLook(), habbo.getHabboInfo().getGender().name()) : habbo.getHabboInfo().getLook());
|
||||
gameClient.getHabbo().getHabboInfo().setGender(habbo.getHabboInfo().getGender());
|
||||
gameClient.sendResponse(new UserDataComposer(gameClient.getHabbo()));
|
||||
gameClient.getHabbo().getHabboInfo().getCurrentRoom().sendComposer(new RoomUserDataComposer(gameClient.getHabbo()).compose());
|
||||
|
@ -0,0 +1,107 @@
|
||||
package com.eu.habbo.habbohotel.commands;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.gameclients.GameClient;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles;
|
||||
import com.eu.habbo.habbohotel.users.Habbo;
|
||||
import com.eu.habbo.habbohotel.users.HabboInfo;
|
||||
import com.eu.habbo.habbohotel.users.HabboManager;
|
||||
import com.eu.habbo.habbohotel.users.subscriptions.Subscription;
|
||||
|
||||
/**
|
||||
* @author Beny
|
||||
*/
|
||||
public class SubscriptionCommand extends Command {
|
||||
public SubscriptionCommand() {
|
||||
super("cmd_subscription", Emulator.getTexts().getValue("commands.keys.cmd_subscription").split(";"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows you to give/extend/remove subscription on a given user.
|
||||
*
|
||||
* Parameters:
|
||||
* [username] = Username of user to execute command on
|
||||
* [type] = Subscription type (e.g. HABBO_CLUB)
|
||||
* [add|remove] = Use add or remove to increase/decrease sub duration
|
||||
* [time] = Time string e.g. "1 week", "18 days", "4 minutes". Can be complex e.g. "1 month 5 days 2 minutes"
|
||||
*
|
||||
* Examples:
|
||||
* :sub Beny habbo_club add 1 month - adds 1 month of HABBO_CLUB subscription duration on the user Beny
|
||||
* :sub Beny builders_club add 1 month - adds 1 month of BUILDERS_CLUB subscription duration on the user Beny
|
||||
* :sub Beny habbo_club remove 3 days - removes 3 days of HABBO_CLUB subscription duration on the user Beny
|
||||
* :sub Beny habbo_club remove - removes all remaining time from the HABBO_CLUB subscription (expires it) on the user Beny
|
||||
*
|
||||
* @param gameClient Client that executed the command
|
||||
* @param params Command parameters
|
||||
* @return Boolean indicating success
|
||||
* @throws Exception Exception
|
||||
*/
|
||||
@Override
|
||||
public boolean handle(GameClient gameClient, String[] params) throws Exception {
|
||||
if (params.length >= 4) {
|
||||
HabboInfo info = HabboManager.getOfflineHabboInfo(params[1]);
|
||||
|
||||
if (info != null) {
|
||||
Habbo habbo = Emulator.getGameServer().getGameClientManager().getHabbo(params[1]);
|
||||
|
||||
String subscription = params[2].toUpperCase();
|
||||
String action = params[3];
|
||||
|
||||
StringBuilder message = new StringBuilder();
|
||||
if (params.length > 4) {
|
||||
for (int i = 4; i < params.length; i++) {
|
||||
message.append(params[i]).append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
if(!Emulator.getGameEnvironment().getSubscriptionManager().types.containsKey(subscription)) {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.type_not_found", "%subscription% is not a valid subscription type").replace("%subscription%", subscription), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(action.equalsIgnoreCase("add") || action.equalsIgnoreCase("+") || action.equalsIgnoreCase("a")) {
|
||||
int timeToAdd = Emulator.timeStringToSeconds(message.toString());
|
||||
|
||||
if(timeToAdd < 1) {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.invalid_params", "Invalid time span, try: x minutes/days/weeks/months"), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
|
||||
habbo.getHabboStats().createSubscription(subscription, timeToAdd);
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.success_add_time", "Successfully added %time% seconds to %subscription% on %user%").replace("%time%", timeToAdd + "").replace("%user%", params[1]).replace("%subscription%", subscription), RoomChatMessageBubbles.ALERT);
|
||||
}
|
||||
|
||||
else if(action.equalsIgnoreCase("remove") || action.equalsIgnoreCase("-") || action.equalsIgnoreCase("r")) {
|
||||
Subscription s = habbo.getHabboStats().getSubscription(subscription);
|
||||
|
||||
if (s == null) {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.user_not_have", "%user% does not have the %subscription% subscription").replace("%user%", params[1]).replace("%subscription%", subscription), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(message.length() != 0) {
|
||||
int timeToRemove = Emulator.timeStringToSeconds(message.toString());
|
||||
|
||||
if (timeToRemove < 1) {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.invalid_params", "Invalid time span, try: x minutes/days/weeks/months"), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
|
||||
s.addDuration(timeToRemove);
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.success_remove_time", "Successfully removed %time% seconds from %subscription% on %user%").replace("%time%", timeToRemove + "").replace("%user%", params[1]).replace("%subscription%", subscription), RoomChatMessageBubbles.ALERT);
|
||||
}
|
||||
else {
|
||||
s.addDuration(-s.getRemaining());
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.success_remove_sub", "Successfully removed %subscription% sub from %user%").replace("%user%", params[1]).replace("%subscription%", subscription), RoomChatMessageBubbles.ALERT);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.user_not_found", "%user% was not found").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT);
|
||||
}
|
||||
} else {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_subscription.invalid_params", "Invalid command format"), RoomChatMessageBubbles.ALERT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import com.eu.habbo.habbohotel.items.Item;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomUnit;
|
||||
import com.eu.habbo.habbohotel.users.HabboItem;
|
||||
import com.eu.habbo.habbohotel.users.clothingvalidation.ClothingValidationManager;
|
||||
import com.eu.habbo.messages.ServerMessage;
|
||||
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer;
|
||||
import com.eu.habbo.messages.outgoing.users.UserDataComposer;
|
||||
@ -60,7 +61,17 @@ public class InteractionMannequin extends HabboItem {
|
||||
|
||||
@Override
|
||||
public void onClick(GameClient client, Room room, Object[] objects) throws Exception {
|
||||
String lookCode = this.getExtradata().split(":")[1];
|
||||
String[] data = this.getExtradata().split(":");
|
||||
|
||||
if(data.length < 2)
|
||||
return;
|
||||
|
||||
String gender = data[0];
|
||||
String figure = data[1];
|
||||
|
||||
if (gender.isEmpty() || figure.isEmpty() || (!gender.equalsIgnoreCase("m") && !gender.equalsIgnoreCase("f")) || !client.getHabbo().getHabboInfo().getGender().name().equalsIgnoreCase(gender))
|
||||
return;
|
||||
|
||||
String newFigure = "";
|
||||
|
||||
for (String playerFigurePart : client.getHabbo().getHabboInfo().getLook().split("\\.")) {
|
||||
@ -68,8 +79,7 @@ public class InteractionMannequin extends HabboItem {
|
||||
newFigure += playerFigurePart + ".";
|
||||
}
|
||||
|
||||
if (lookCode.isEmpty()) return;
|
||||
String newFigureParts = lookCode;
|
||||
String newFigureParts = figure;
|
||||
|
||||
for (String newFigurePart : newFigureParts.split("\\.")) {
|
||||
if (newFigurePart.startsWith("hd"))
|
||||
@ -78,12 +88,12 @@ public class InteractionMannequin extends HabboItem {
|
||||
|
||||
if (newFigureParts.equals("")) return;
|
||||
|
||||
final String figure = newFigure + newFigureParts;
|
||||
String newLook = newFigure + newFigureParts;
|
||||
|
||||
if (figure.length() > 512)
|
||||
if (newLook.length() > 512)
|
||||
return;
|
||||
|
||||
client.getHabbo().getHabboInfo().setLook(figure);
|
||||
client.getHabbo().getHabboInfo().setLook(ClothingValidationManager.VALIDATE_ON_MANNEQUIN ? ClothingValidationManager.validateLook(client.getHabbo(), newLook, client.getHabbo().getHabboInfo().getGender().name()) : newLook);
|
||||
room.sendComposer(new RoomUserDataComposer(client.getHabbo()).compose());
|
||||
client.sendResponse(new UserDataComposer(client.getHabbo()));
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import com.eu.habbo.habbohotel.rooms.RoomUnit;
|
||||
import com.eu.habbo.habbohotel.users.Habbo;
|
||||
import com.eu.habbo.habbohotel.users.HabboGender;
|
||||
import com.eu.habbo.habbohotel.users.HabboItem;
|
||||
import com.eu.habbo.habbohotel.users.clothingvalidation.ClothingValidationManager;
|
||||
import com.eu.habbo.messages.ServerMessage;
|
||||
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer;
|
||||
import com.eu.habbo.messages.outgoing.users.UpdateUserLookComposer;
|
||||
@ -120,7 +121,7 @@ public class InteractionFootballGate extends HabboItem {
|
||||
UserSavedLookEvent lookEvent = new UserSavedLookEvent(habbo, habbo.getHabboInfo().getGender(), oldlook);
|
||||
Emulator.getPluginManager().fireEvent(lookEvent);
|
||||
if (!lookEvent.isCancelled()) {
|
||||
habbo.getHabboInfo().setLook(lookEvent.newLook);
|
||||
habbo.getHabboInfo().setLook(ClothingValidationManager.VALIDATE_ON_FBALLGATE ? ClothingValidationManager.validateLook(habbo, lookEvent.newLook, lookEvent.gender.name()) : lookEvent.newLook);
|
||||
Emulator.getThreading().run(habbo.getHabboInfo());
|
||||
habbo.getClient().sendResponse(new UpdateUserLookComposer(habbo));
|
||||
room.sendComposer(new RoomUserDataComposer(habbo).compose());
|
||||
@ -134,7 +135,7 @@ public class InteractionFootballGate extends HabboItem {
|
||||
Emulator.getPluginManager().fireEvent(lookEvent);
|
||||
if (!lookEvent.isCancelled()) {
|
||||
habbo.getHabboStats().cache.put(CACHE_KEY, habbo.getHabboInfo().getLook());
|
||||
habbo.getHabboInfo().setLook(lookEvent.newLook);
|
||||
habbo.getHabboInfo().setLook(ClothingValidationManager.VALIDATE_ON_FBALLGATE ? ClothingValidationManager.validateLook(habbo, lookEvent.newLook, lookEvent.gender.name()) : lookEvent.newLook);
|
||||
Emulator.getThreading().run(habbo.getHabboInfo());
|
||||
habbo.getClient().sendResponse(new UpdateUserLookComposer(habbo));
|
||||
room.sendComposer(new RoomUserDataComposer(habbo).compose());
|
||||
|
@ -167,18 +167,6 @@ public class Messenger {
|
||||
return map;
|
||||
}
|
||||
|
||||
public static int friendLimit(Habbo habbo) {
|
||||
if (habbo.hasPermission("acc_infinite_friends")) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
if (habbo.getHabboStats().hasActiveClub()) {
|
||||
return MAXIMUM_FRIENDS_HC;
|
||||
}
|
||||
|
||||
return MAXIMUM_FRIENDS;
|
||||
}
|
||||
|
||||
public static void checkFriendSizeProgress(Habbo habbo) {
|
||||
int progress = habbo.getHabboStats().getAchievementProgress(Emulator.getGameEnvironment().getAchievementManager().getAchievement("FriendListSize"));
|
||||
|
||||
|
@ -66,7 +66,7 @@ public class RoomManager {
|
||||
private static final int page = 0;
|
||||
//Configuration. Loaded from database & updated accordingly.
|
||||
public static int MAXIMUM_ROOMS_USER = 25;
|
||||
public static int MAXIMUM_ROOMS_VIP = 35;
|
||||
public static int MAXIMUM_ROOMS_HC = 35;
|
||||
public static int HOME_ROOM_ID = 0;
|
||||
public static boolean SHOW_PUBLIC_IN_POPULAR_TAB = false;
|
||||
private final THashMap<Integer, RoomCategory> roomCategories;
|
||||
|
@ -9,22 +9,22 @@ import com.eu.habbo.habbohotel.catalog.CatalogItem;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomTrade;
|
||||
import com.eu.habbo.habbohotel.users.cache.HabboOfferPurchase;
|
||||
import com.eu.habbo.habbohotel.users.subscriptions.Subscription;
|
||||
import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionManager;
|
||||
import com.eu.habbo.plugin.events.users.subscriptions.UserSubscriptionCreatedEvent;
|
||||
import com.eu.habbo.plugin.events.users.subscriptions.UserSubscriptionExtendedEvent;
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
import gnu.trove.map.TIntObjectMap;
|
||||
import gnu.trove.map.hash.THashMap;
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
import gnu.trove.set.hash.THashSet;
|
||||
import gnu.trove.stack.array.TIntArrayStack;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class HabboStats implements Runnable {
|
||||
@ -93,6 +93,11 @@ public class HabboStats implements Runnable {
|
||||
private boolean allowTrade;
|
||||
private int clubExpireTimestamp;
|
||||
private int muteEndTime;
|
||||
public int maxFriends;
|
||||
public int maxRooms;
|
||||
public int lastHCPayday;
|
||||
public int hcMessageLastModified = Emulator.getIntUnixTimestamp();
|
||||
public THashSet<Subscription> subscriptions;
|
||||
|
||||
private HabboStats(ResultSet set, HabboInfo habboInfo) throws SQLException {
|
||||
this.cache = new THashMap<>(0);
|
||||
@ -142,9 +147,14 @@ public class HabboStats implements Runnable {
|
||||
this.forumPostsCount = set.getInt("forums_post_count");
|
||||
this.uiFlags = set.getInt("ui_flags");
|
||||
this.hasGottenDefaultSavedSearches = set.getInt("has_gotten_default_saved_searches") == 1;
|
||||
this.maxFriends = set.getInt("max_friends");
|
||||
this.maxRooms = set.getInt("max_rooms");
|
||||
this.lastHCPayday = set.getInt("last_hc_payday");
|
||||
|
||||
this.nuxReward = this.nux;
|
||||
|
||||
this.subscriptions = Emulator.getGameEnvironment().getSubscriptionManager().getSubscriptionsForUser(this.habboInfo.getId());
|
||||
|
||||
try (PreparedStatement statement = set.getStatement().getConnection().prepareStatement("SELECT * FROM user_window_settings WHERE user_id = ? LIMIT 1")) {
|
||||
statement.setInt(1, this.habboInfo.getId());
|
||||
try (ResultSet nSet = statement.executeQuery()) {
|
||||
@ -306,7 +316,7 @@ public class HabboStats implements Runnable {
|
||||
int onlineTime = Emulator.getIntUnixTimestamp() - onlineTimeLast;
|
||||
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) {
|
||||
try (PreparedStatement statement = connection.prepareStatement("UPDATE users_settings SET achievement_score = ?, respects_received = ?, respects_given = ?, daily_respect_points = ?, block_following = ?, block_friendrequests = ?, online_time = online_time + ?, guild_id = ?, daily_pet_respect_points = ?, club_expire_timestamp = ?, login_streak = ?, rent_space_id = ?, rent_space_endtime = ?, volume_system = ?, volume_furni = ?, volume_trax = ?, block_roominvites = ?, old_chat = ?, block_camera_follow = ?, chat_color = ?, hof_points = ?, block_alerts = ?, talent_track_citizenship_level = ?, talent_track_helpers_level = ?, ignore_bots = ?, ignore_pets = ?, nux = ?, mute_end_timestamp = ?, allow_name_change = ?, perk_trade = ?, can_trade = ?, `forums_post_count` = ?, ui_flags = ?, has_gotten_default_saved_searches = ? WHERE user_id = ? LIMIT 1")) {
|
||||
try (PreparedStatement statement = connection.prepareStatement("UPDATE users_settings SET achievement_score = ?, respects_received = ?, respects_given = ?, daily_respect_points = ?, block_following = ?, block_friendrequests = ?, online_time = online_time + ?, guild_id = ?, daily_pet_respect_points = ?, club_expire_timestamp = ?, login_streak = ?, rent_space_id = ?, rent_space_endtime = ?, volume_system = ?, volume_furni = ?, volume_trax = ?, block_roominvites = ?, old_chat = ?, block_camera_follow = ?, chat_color = ?, hof_points = ?, block_alerts = ?, talent_track_citizenship_level = ?, talent_track_helpers_level = ?, ignore_bots = ?, ignore_pets = ?, nux = ?, mute_end_timestamp = ?, allow_name_change = ?, perk_trade = ?, can_trade = ?, `forums_post_count` = ?, ui_flags = ?, has_gotten_default_saved_searches = ?, max_friends = ?, max_rooms = ?, last_hc_payday = ? WHERE user_id = ? LIMIT 1")) {
|
||||
statement.setInt(1, this.achievementScore);
|
||||
statement.setInt(2, this.respectPointsReceived);
|
||||
statement.setInt(3, this.respectPointsGiven);
|
||||
@ -341,7 +351,10 @@ public class HabboStats implements Runnable {
|
||||
statement.setInt(32, this.forumPostsCount);
|
||||
statement.setInt(33, this.uiFlags);
|
||||
statement.setInt(34, this.hasGottenDefaultSavedSearches ? 1 : 0);
|
||||
statement.setInt(35, this.habboInfo.getId());
|
||||
statement.setInt(35, this.maxFriends);
|
||||
statement.setInt(36, this.maxRooms);
|
||||
statement.setInt(37, this.lastHCPayday);
|
||||
statement.setInt(38, this.habboInfo.getId());
|
||||
|
||||
statement.executeUpdate();
|
||||
}
|
||||
@ -441,16 +454,92 @@ public class HabboStats implements Runnable {
|
||||
return this.rentedTimeEnd >= Emulator.getIntUnixTimestamp();
|
||||
}
|
||||
|
||||
public Subscription getSubscription(String subscriptionType) {
|
||||
for(Subscription subscription : subscriptions) {
|
||||
if(subscription.getSubscriptionType().equalsIgnoreCase(subscriptionType) && subscription.isActive() && subscription.getRemaining() > 0) {
|
||||
return subscription;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean hasSubscription(String subscriptionType) {
|
||||
Subscription subscription = getSubscription(subscriptionType);
|
||||
return subscription != null;
|
||||
}
|
||||
|
||||
public int getSubscriptionExpireTimestamp(String subscriptionType) {
|
||||
Subscription subscription = getSubscription(subscriptionType);
|
||||
|
||||
if(subscription == null)
|
||||
return 0;
|
||||
|
||||
return subscription.getTimestampEnd();
|
||||
}
|
||||
|
||||
public Subscription createSubscription(String subscriptionType, int duration) {
|
||||
Subscription subscription = getSubscription(subscriptionType);
|
||||
|
||||
if(subscription != null) {
|
||||
if (!Emulator.getPluginManager().fireEvent(new UserSubscriptionExtendedEvent(this.habboInfo.getId(), subscription, duration)).isCancelled()) {
|
||||
subscription.addDuration(duration);
|
||||
subscription.onExtended(duration);
|
||||
}
|
||||
return subscription;
|
||||
}
|
||||
|
||||
if (!Emulator.getPluginManager().fireEvent(new UserSubscriptionCreatedEvent(this.habboInfo.getId(), subscriptionType, duration)).isCancelled()) {
|
||||
int startTimestamp = Emulator.getIntUnixTimestamp();
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO `users_subscriptions` (`user_id`, `subscription_type`, `timestamp_start`, `duration`, `active`) VALUES (?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) {
|
||||
statement.setInt(1, this.habboInfo.getId());
|
||||
statement.setString(2, subscriptionType);
|
||||
statement.setInt(3, startTimestamp);
|
||||
statement.setInt(4, duration);
|
||||
statement.setInt(5, 1);
|
||||
statement.execute();
|
||||
try (ResultSet set = statement.getGeneratedKeys()) {
|
||||
if (set.next()) {
|
||||
Class<? extends Subscription> subClazz = Emulator.getGameEnvironment().getSubscriptionManager().getSubscriptionClass(subscriptionType);
|
||||
try {
|
||||
Constructor<? extends Subscription> c = subClazz.getConstructor(Integer.class, Integer.class, String.class, Integer.class, Integer.class, Boolean.class);
|
||||
c.setAccessible(true);
|
||||
Subscription sub = c.newInstance(set.getInt(1), this.habboInfo.getId(), subscriptionType, startTimestamp, duration, true);
|
||||
sub.onCreated();
|
||||
this.subscriptions.add(sub);
|
||||
return sub;
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOGGER.error("Caught exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Caught SQL exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getClubExpireTimestamp() {
|
||||
return this.clubExpireTimestamp;
|
||||
return getSubscriptionExpireTimestamp(Subscription.HABBO_CLUB);
|
||||
}
|
||||
|
||||
public void setClubExpireTimestamp(int clubExpireTimestamp) {
|
||||
this.clubExpireTimestamp = clubExpireTimestamp;
|
||||
Subscription subscription = getSubscription(Subscription.HABBO_CLUB);
|
||||
int duration = clubExpireTimestamp - Emulator.getIntUnixTimestamp();
|
||||
|
||||
if(subscription != null) {
|
||||
duration = clubExpireTimestamp - subscription.getTimestampStart();
|
||||
}
|
||||
|
||||
if(duration > 0) {
|
||||
createSubscription(Subscription.HABBO_CLUB, duration);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasActiveClub() {
|
||||
return this.clubExpireTimestamp > Emulator.getIntUnixTimestamp();
|
||||
return hasSubscription(Subscription.HABBO_CLUB);
|
||||
}
|
||||
|
||||
public THashMap<Achievement, Integer> getAchievementProgress() {
|
||||
|
@ -0,0 +1,184 @@
|
||||
package com.eu.habbo.habbohotel.users.clothingvalidation;
|
||||
|
||||
import com.eu.habbo.habbohotel.users.Habbo;
|
||||
import gnu.trove.TIntCollection;
|
||||
import gnu.trove.set.hash.TIntHashSet;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ClothingValidationManager {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ClothingValidationManager.class);
|
||||
|
||||
public static String FIGUREDATA_URL = "";
|
||||
public static boolean VALIDATE_ON_HC_EXPIRE = false;
|
||||
public static boolean VALIDATE_ON_LOGIN = false;
|
||||
public static boolean VALIDATE_ON_CHANGE_LOOKS = false;
|
||||
public static boolean VALIDATE_ON_MIMIC = false;
|
||||
public static boolean VALIDATE_ON_MANNEQUIN = false;
|
||||
public static boolean VALIDATE_ON_FBALLGATE = false;
|
||||
|
||||
private static final Figuredata FIGUREDATA = new Figuredata();
|
||||
|
||||
/**
|
||||
* Parses the new figuredata.xml file
|
||||
* @param newUrl URI of figuredata.xml file. Can be a file path or URL
|
||||
*/
|
||||
public static void reloadFiguredata(String newUrl) {
|
||||
try {
|
||||
FIGUREDATA.parseXML(newUrl);
|
||||
} catch (Exception e) {
|
||||
VALIDATE_ON_HC_EXPIRE = false;
|
||||
VALIDATE_ON_LOGIN = false;
|
||||
VALIDATE_ON_CHANGE_LOOKS = false;
|
||||
VALIDATE_ON_MIMIC = false;
|
||||
VALIDATE_ON_MANNEQUIN = false;
|
||||
VALIDATE_ON_FBALLGATE = false;
|
||||
LOGGER.error("Caught exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a figure string on a given user
|
||||
* @param habbo User to validate
|
||||
* @return Cleaned figure string
|
||||
*/
|
||||
public static String validateLook(Habbo habbo) {
|
||||
return validateLook(habbo.getHabboInfo().getLook(), habbo.getHabboInfo().getGender().name(), habbo.getHabboStats().hasActiveClub(), habbo.getInventory().getWardrobeComponent().getClothingSets());
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a given figure string and gender on a given user
|
||||
* @param habbo User to validate
|
||||
* @param look Figure string
|
||||
* @param gender Gender (M/F)
|
||||
* @return Cleaned figure string
|
||||
*/
|
||||
public static String validateLook(Habbo habbo, String look, String gender) {
|
||||
return validateLook(look, gender, habbo.getHabboStats().hasActiveClub(), habbo.getInventory().getWardrobeComponent().getClothingSets());
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a given figure string against a given gender
|
||||
* @param look Figure string
|
||||
* @param gender Gender (M/F)
|
||||
* @return Cleaned figure string
|
||||
*/
|
||||
public static String validateLook(String look, String gender) {
|
||||
return validateLook(look, gender, false, new TIntHashSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a given figure string against a given gender with club clothing option
|
||||
* @param look Figure string
|
||||
* @param gender Gender (M/F)
|
||||
* @param isHC Boolean indicating if club clothing is permitted
|
||||
* @return Cleaned figure string
|
||||
*/
|
||||
public static String validateLook(String look, String gender, boolean isHC) {
|
||||
return validateLook(look, gender, isHC, new TIntHashSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a figure string with all available options
|
||||
* @param look Figure string
|
||||
* @param gender Gender (M/F)
|
||||
* @param isHC Boolean indicating if club clothing is permitted
|
||||
* @param ownedClothing Array of owned clothing set IDs. If sellable and setId not in this array clothing will be removed
|
||||
* @return Cleaned figure string
|
||||
*/
|
||||
public static String validateLook(String look, String gender, boolean isHC, TIntCollection ownedClothing) {
|
||||
if(FIGUREDATA.palettes.size() == 0 || FIGUREDATA.settypes.size() == 0)
|
||||
return look;
|
||||
|
||||
String[] newLookParts = look.split(Pattern.quote("."));
|
||||
ArrayList<String> lookParts = new ArrayList<>();
|
||||
|
||||
for(String lookpart : newLookParts) {
|
||||
if(lookpart.contains("-")) {
|
||||
try {
|
||||
String[] data = lookpart.split(Pattern.quote("-"));
|
||||
if (data.length > 1) {
|
||||
FiguredataSettype settype = FIGUREDATA.settypes.get(data[0]);
|
||||
if (settype == null) {
|
||||
throw new Exception("Set type " + data[0] + " does not exist");
|
||||
}
|
||||
|
||||
FiguredataPalette palette = FIGUREDATA.palettes.get(settype.paletteId);
|
||||
if (palette == null) {
|
||||
throw new Exception("Palette " + settype.paletteId + " does not exist");
|
||||
}
|
||||
|
||||
int setId;
|
||||
FiguredataSettypeSet set;
|
||||
|
||||
setId = Integer.parseInt(data[1]);
|
||||
set = settype.getSet(setId);
|
||||
if (set == null)
|
||||
throw new Exception("Set " + setId + " does not exist in SetType");
|
||||
|
||||
if ((set.club && !isHC) || !set.selectable || (set.sellable && !ownedClothing.contains(set.id))) {
|
||||
if(gender.equalsIgnoreCase("M") && !isHC && !settype.mandatoryMale0)
|
||||
continue;
|
||||
|
||||
if(gender.equalsIgnoreCase("F") && !isHC && !settype.mandatoryFemale0)
|
||||
continue;
|
||||
|
||||
if(gender.equalsIgnoreCase("M") && isHC && !settype.mandatoryMale1)
|
||||
continue;
|
||||
|
||||
if(gender.equalsIgnoreCase("F") && isHC && !settype.mandatoryFemale1)
|
||||
continue;
|
||||
|
||||
set = settype.getFirstNonHCSetForGender(gender);
|
||||
setId = set.id;
|
||||
}
|
||||
|
||||
ArrayList<String> dataParts = new ArrayList<>();
|
||||
|
||||
int color1 = -1;
|
||||
int color2 = -1;
|
||||
|
||||
if (data.length > 2 && set.colorable) {
|
||||
color1 = Integer.parseInt(data[2]);
|
||||
FiguredataPaletteColor color = palette.getColor(color1);
|
||||
if (color == null || (color.club && !isHC)) {
|
||||
color1 = palette.getFirstNonHCColor().id;
|
||||
}
|
||||
}
|
||||
|
||||
if (data.length > 3 && set.colorable) {
|
||||
color2 = Integer.parseInt(data[3]);
|
||||
FiguredataPaletteColor color = palette.getColor(color2);
|
||||
if (color == null || (color.club && !isHC)) {
|
||||
color2 = palette.getFirstNonHCColor().id;
|
||||
}
|
||||
}
|
||||
|
||||
dataParts.add(settype.type);
|
||||
dataParts.add("" + setId);
|
||||
|
||||
if (color1 > -1) {
|
||||
dataParts.add("" + color1);
|
||||
}
|
||||
|
||||
if (color2 > -1) {
|
||||
dataParts.add("" + color2);
|
||||
}
|
||||
|
||||
lookParts.add(String.join("-", dataParts));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
//habbo.alert(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return String.join(".", lookParts);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
package com.eu.habbo.habbohotel.users.clothingvalidation;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class Figuredata {
|
||||
public Map<Integer, FiguredataPalette> palettes;
|
||||
public Map<String, FiguredataSettype> settypes;
|
||||
|
||||
public Figuredata() {
|
||||
palettes = new TreeMap<>();
|
||||
settypes = new TreeMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the figuredata.xml file
|
||||
* @param uri URI to the figuredata.xml file
|
||||
* @throws ParserConfigurationException
|
||||
* @throws IOException
|
||||
* @throws SAXException
|
||||
*/
|
||||
public void parseXML(String uri) throws ParserConfigurationException, IOException, SAXException {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
factory.setIgnoringElementContentWhitespace(true);
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
Document document = builder.parse(uri);
|
||||
|
||||
Element rootElement = document.getDocumentElement();
|
||||
NodeList palettesList = document.getElementsByTagName("colors").item(0).getChildNodes();
|
||||
NodeList settypesList = document.getElementsByTagName("sets").item(0).getChildNodes();
|
||||
|
||||
palettes.clear();
|
||||
settypes.clear();
|
||||
|
||||
for(int i = 0; i < palettesList.getLength(); i++) {
|
||||
Node nNode = palettesList.item(i);
|
||||
Element element = (Element)nNode;
|
||||
int paletteId = Integer.parseInt(element.getAttribute("id"));
|
||||
FiguredataPalette palette = new FiguredataPalette(paletteId);
|
||||
|
||||
NodeList colorsList = nNode.getChildNodes();
|
||||
for(int ii = 0; ii < colorsList.getLength(); ii++) {
|
||||
Element colorElement = (Element)colorsList.item(ii);
|
||||
FiguredataPaletteColor color = new FiguredataPaletteColor(
|
||||
Integer.parseInt(colorElement.getAttribute("id")),
|
||||
Integer.parseInt(colorElement.getAttribute("index")),
|
||||
!colorElement.getAttribute("club").equals("0"),
|
||||
colorElement.getAttribute("selectable").equals("1"),
|
||||
colorElement.getTextContent()
|
||||
);
|
||||
palette.addColor(color);
|
||||
}
|
||||
|
||||
palettes.put(palette.id, palette);
|
||||
}
|
||||
|
||||
for(int i = 0; i < settypesList.getLength(); i++) {
|
||||
Node nNode = settypesList.item(i);
|
||||
Element element = (Element)nNode;
|
||||
|
||||
String type = element.getAttribute("type");
|
||||
int paletteId = Integer.parseInt(element.getAttribute("paletteid"));
|
||||
boolean mandM0 = element.getAttribute("mand_m_0").equals("1");
|
||||
boolean mandF0 = element.getAttribute("mand_f_0").equals("1");
|
||||
boolean mandM1 = element.getAttribute("mand_m_1").equals("1");
|
||||
boolean mandF1 = element.getAttribute("mand_f_1").equals("1");
|
||||
|
||||
FiguredataSettype settype = new FiguredataSettype(type, paletteId, mandM0, mandF0, mandM1, mandF1);
|
||||
|
||||
NodeList setsList = nNode.getChildNodes();
|
||||
for(int ii = 0; ii < setsList.getLength(); ii++) {
|
||||
Element setElement = (Element)setsList.item(ii);
|
||||
FiguredataSettypeSet set = new FiguredataSettypeSet(
|
||||
Integer.parseInt(setElement.getAttribute("id")),
|
||||
setElement.getAttribute("gender"),
|
||||
!setElement.getAttribute("club").equals("0"),
|
||||
setElement.getAttribute("colorable").equals("1"),
|
||||
setElement.getAttribute("selectable").equals("1"),
|
||||
setElement.getAttribute("preselectable").equals("1"),
|
||||
setElement.getAttribute("sellable").equals("1")
|
||||
);
|
||||
settype.addSet(set);
|
||||
}
|
||||
|
||||
settypes.put(settype.type, settype);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.eu.habbo.habbohotel.users.clothingvalidation;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class FiguredataPalette {
|
||||
public int id;
|
||||
public Map<Integer, FiguredataPaletteColor> colors;
|
||||
|
||||
public FiguredataPalette(int id) {
|
||||
this.id = id;
|
||||
this.colors = new TreeMap<>();
|
||||
}
|
||||
|
||||
public void addColor(FiguredataPaletteColor color) {
|
||||
this.colors.put(color.id, color);
|
||||
}
|
||||
|
||||
public FiguredataPaletteColor getColor(int colorId) {
|
||||
return this.colors.get(colorId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return First non-club and selectable color
|
||||
*/
|
||||
public FiguredataPaletteColor getFirstNonHCColor() {
|
||||
for(FiguredataPaletteColor color : this.colors.values()) {
|
||||
if(!color.club && color.selectable)
|
||||
return color;
|
||||
}
|
||||
|
||||
return this.colors.size() > 0 ? this.colors.entrySet().iterator().next().getValue() : null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.eu.habbo.habbohotel.users.clothingvalidation;
|
||||
|
||||
public class FiguredataPaletteColor {
|
||||
public int id;
|
||||
public int index;
|
||||
public boolean club;
|
||||
public boolean selectable;
|
||||
public String colorHex;
|
||||
|
||||
public FiguredataPaletteColor(int id, int index, boolean club, boolean selectable, String colorHex) {
|
||||
this.id = id;
|
||||
this.index = index;
|
||||
this.club = club;
|
||||
this.selectable = selectable;
|
||||
this.colorHex = colorHex;
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package com.eu.habbo.habbohotel.users.clothingvalidation;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class FiguredataSettype {
|
||||
public String type;
|
||||
public int paletteId;
|
||||
public boolean mandatoryMale0;
|
||||
public boolean mandatoryFemale0;
|
||||
public boolean mandatoryMale1;
|
||||
public boolean mandatoryFemale1;
|
||||
public Map<Integer, FiguredataSettypeSet> sets;
|
||||
|
||||
public FiguredataSettype(String type, int paletteId, boolean mandatoryMale0, boolean mandatoryFemale0, boolean mandatoryMale1, boolean mandatoryFemale1) {
|
||||
this.type = type;
|
||||
this.paletteId = paletteId;
|
||||
this.mandatoryMale0 = mandatoryMale0;
|
||||
this.mandatoryFemale0 = mandatoryFemale0;
|
||||
this.mandatoryMale1 = mandatoryMale1;
|
||||
this.mandatoryFemale1 = mandatoryFemale1;
|
||||
this.sets = new TreeMap<>();
|
||||
}
|
||||
|
||||
public void addSet(FiguredataSettypeSet set) {
|
||||
this.sets.put(set.id, set);
|
||||
}
|
||||
|
||||
public FiguredataSettypeSet getSet(int id) {
|
||||
return this.sets.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param gender Gender (M/F)
|
||||
* @return First non-sellable and selectable set for given gender
|
||||
*/
|
||||
public FiguredataSettypeSet getFirstSetForGender(String gender) {
|
||||
for(FiguredataSettypeSet set : this.sets.values()) {
|
||||
if(set.gender.equalsIgnoreCase(gender) && !set.sellable && set.selectable) {
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
||||
return this.sets.size() > 0 ? this.sets.entrySet().iterator().next().getValue() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param gender Gender (M/F)
|
||||
* @return First non-club, non-sellable and selectable set for given gender
|
||||
*/
|
||||
public FiguredataSettypeSet getFirstNonHCSetForGender(String gender) {
|
||||
for(FiguredataSettypeSet set : this.sets.values()) {
|
||||
if(set.gender.equalsIgnoreCase(gender) && !set.club && !set.sellable && set.selectable) {
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
||||
return getFirstSetForGender(gender);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.eu.habbo.habbohotel.users.clothingvalidation;
|
||||
|
||||
public class FiguredataSettypeSet {
|
||||
public int id;
|
||||
public String gender;
|
||||
public boolean club;
|
||||
public boolean colorable;
|
||||
public boolean selectable;
|
||||
public boolean preselectable;
|
||||
public boolean sellable;
|
||||
|
||||
public FiguredataSettypeSet(int id, String gender, boolean club, boolean colorable, boolean selectable, boolean preselectable, boolean sellable) {
|
||||
this.id = id;
|
||||
this.gender = gender;
|
||||
this.club = club;
|
||||
this.colorable = colorable;
|
||||
this.selectable = selectable;
|
||||
this.preselectable = preselectable;
|
||||
this.sellable = sellable;
|
||||
}
|
||||
}
|
@ -14,15 +14,18 @@ import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class WardrobeComponent {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(WardrobeComponent.class);
|
||||
private final THashMap<Integer, WardrobeItem> looks;
|
||||
private final TIntSet clothing;
|
||||
private final TIntSet clothingSets;
|
||||
|
||||
public WardrobeComponent(Habbo habbo) {
|
||||
this.looks = new THashMap<>();
|
||||
this.clothing = new TIntHashSet();
|
||||
this.clothingSets = new TIntHashSet();
|
||||
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) {
|
||||
try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM users_wardrobe WHERE user_id = ?")) {
|
||||
@ -34,13 +37,19 @@ public class WardrobeComponent {
|
||||
}
|
||||
}
|
||||
|
||||
try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM users_clothing WHERE user_id = ?")) {
|
||||
try (PreparedStatement statement = connection.prepareStatement("SELECT users_clothing.*, catalog_clothing.setid FROM users_clothing LEFT JOIN catalog_clothing ON catalog_clothing.id = users_clothing.clothing_id WHERE users_clothing.user_id = ?")) {
|
||||
statement.setInt(1, habbo.getHabboInfo().getId());
|
||||
try (ResultSet set = statement.executeQuery()) {
|
||||
while (set.next()) {
|
||||
int value = set.getInt("clothing_id");
|
||||
|
||||
this.clothing.add(value);
|
||||
|
||||
for(String x : set.getString("setid").split(Pattern.quote(","))) {
|
||||
try {
|
||||
this.clothingSets.add(Integer.parseInt(x));
|
||||
}
|
||||
catch (Exception e) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -61,6 +70,10 @@ public class WardrobeComponent {
|
||||
return this.clothing;
|
||||
}
|
||||
|
||||
public TIntCollection getClothingSets() {
|
||||
return this.clothingSets;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
this.looks.values().stream().filter(item -> item.needsInsert || item.needsUpdate).forEach(item -> {
|
||||
Emulator.getThreading().run(item);
|
||||
|
@ -0,0 +1,64 @@
|
||||
package com.eu.habbo.habbohotel.users.subscriptions;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.core.DatabaseLoggable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* @author Beny
|
||||
*/
|
||||
public class HcPayDayLogEntry implements Runnable, DatabaseLoggable {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(HcPayDayLogEntry.class);
|
||||
private static final String QUERY = "INSERT INTO `logs_hc_payday` (`timestamp`, `user_id`, `hc_streak`, `total_coins_spent`, `reward_coins_spent`, `reward_streak`, `total_payout`, `currency`, `claimed`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
|
||||
public final int timestamp;
|
||||
public final int userId;
|
||||
public final int hcStreak;
|
||||
public final int totalCoinsSpent;
|
||||
public final int rewardCoinsSpent;
|
||||
public final int rewardStreak;
|
||||
public final int totalPayout;
|
||||
public final String currency;
|
||||
public final boolean claimed;
|
||||
|
||||
public HcPayDayLogEntry(int timestamp, int userId, int hcStreak, int totalCoinsSpent, int rewardCoinsSpent, int rewardStreak, int totalPayout, String currency, boolean claimed) {
|
||||
this.timestamp = timestamp;
|
||||
this.userId = userId;
|
||||
this.hcStreak = hcStreak;
|
||||
this.totalCoinsSpent = totalCoinsSpent;
|
||||
this.rewardCoinsSpent = rewardCoinsSpent;
|
||||
this.rewardStreak = rewardStreak;
|
||||
this.totalPayout = totalPayout;
|
||||
this.currency = currency;
|
||||
this.claimed = claimed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQuery() {
|
||||
return QUERY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(PreparedStatement statement) throws SQLException {
|
||||
statement.setInt(1, this.timestamp);
|
||||
statement.setInt(2, this.userId);
|
||||
statement.setInt(3, this.hcStreak);
|
||||
statement.setInt(4, this.totalCoinsSpent);
|
||||
statement.setInt(5, this.rewardCoinsSpent);
|
||||
statement.setInt(6, this.rewardStreak);
|
||||
statement.setInt(7, this.totalPayout);
|
||||
statement.setString(8, this.currency);
|
||||
statement.setInt(9, this.claimed ? 1 : 0);
|
||||
statement.addBatch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Emulator.getDatabaseLogger().store(this);
|
||||
}
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
package com.eu.habbo.habbohotel.users.subscriptions;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* @author Beny
|
||||
*/
|
||||
public class Subscription {
|
||||
public static final String HABBO_CLUB = "HABBO_CLUB";
|
||||
|
||||
private final int id;
|
||||
private final int userId;
|
||||
private final String subscriptionType;
|
||||
private final int timestampStart;
|
||||
private int duration;
|
||||
private boolean active;
|
||||
|
||||
/**
|
||||
* Subscription constructor
|
||||
* @param id ID of the subscription
|
||||
* @param userId ID of user who has the subscription
|
||||
* @param subscriptionType Subscription type name (e.g. HABBO_CLUB)
|
||||
* @param timestampStart Unix timestamp start of subscription
|
||||
* @param duration Length of subscription in seconds
|
||||
* @param active Boolean indicating if subscription is active
|
||||
*/
|
||||
public Subscription(Integer id, Integer userId, String subscriptionType, Integer timestampStart, Integer duration, Boolean active) {
|
||||
this.id = id;
|
||||
this.userId = userId;
|
||||
this.subscriptionType = subscriptionType;
|
||||
this.timestampStart = timestampStart;
|
||||
this.duration = duration;
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ID of the subscription
|
||||
*/
|
||||
public int getSubscriptionId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ID of user who has the subscription
|
||||
*/
|
||||
public int getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Subscription type name (e.g. HABBO_CLUB)
|
||||
*/
|
||||
public String getSubscriptionType() {
|
||||
return subscriptionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Length of subscription in seconds
|
||||
*/
|
||||
public int getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the Subscription record with new duration
|
||||
* @param amount Length of time to add in seconds
|
||||
*/
|
||||
public void addDuration(int amount) {
|
||||
this.duration += amount;
|
||||
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) {
|
||||
try (PreparedStatement statement = connection.prepareStatement("UPDATE `users_subscriptions` SET `duration` = ? WHERE `id` = ? LIMIT 1")) {
|
||||
statement.setInt(1, this.duration);
|
||||
statement.setInt(2, this.id);
|
||||
statement.executeUpdate();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
SubscriptionManager.LOGGER.error("Caught SQL exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the subscription as active or inactive. If active and remaining time <= 0 the SubscriptionScheduler will inactivate the subscription and call onExpired()
|
||||
* @param active Boolean indicating if the subscription is active
|
||||
*/
|
||||
public void setActive(boolean active) {
|
||||
this.active = active;
|
||||
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection()) {
|
||||
try (PreparedStatement statement = connection.prepareStatement("UPDATE `users_subscriptions` SET `active` = ? WHERE `id` = ? LIMIT 1")) {
|
||||
statement.setInt(1, this.active ? 1 : 0);
|
||||
statement.setInt(2, this.id);
|
||||
statement.executeUpdate();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
SubscriptionManager.LOGGER.error("Caught SQL exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Remaining duration of subscription in seconds
|
||||
*/
|
||||
public int getRemaining() {
|
||||
return (this.timestampStart + this.duration) - Emulator.getIntUnixTimestamp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Unix timestamp start of subscription
|
||||
*/
|
||||
public int getTimestampStart() {
|
||||
return this.timestampStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Unix timestamp end of subscription
|
||||
*/
|
||||
public int getTimestampEnd() {
|
||||
return (this.timestampStart + this.duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Boolean indicating if the subscription is active
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the subscription is first created
|
||||
*/
|
||||
public void onCreated() { }
|
||||
|
||||
/**
|
||||
* Called when the subscription is extended or bought again when already exists
|
||||
* @param duration Extended duration time in seconds
|
||||
*/
|
||||
public void onExtended(int duration) { }
|
||||
|
||||
/**
|
||||
* Called by SubscriptionScheduler when isActive() && getRemaining() < 0
|
||||
*/
|
||||
public void onExpired() { }
|
||||
}
|
@ -0,0 +1,371 @@
|
||||
package com.eu.habbo.habbohotel.users.subscriptions;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.database.Database;
|
||||
import com.eu.habbo.habbohotel.messenger.Messenger;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomManager;
|
||||
import com.eu.habbo.habbohotel.users.Habbo;
|
||||
import com.eu.habbo.habbohotel.users.HabboInfo;
|
||||
import com.eu.habbo.habbohotel.users.clothingvalidation.ClothingValidationManager;
|
||||
import com.eu.habbo.messages.outgoing.catalog.ClubCenterDataComposer;
|
||||
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer;
|
||||
import com.eu.habbo.messages.outgoing.users.*;
|
||||
import gnu.trove.map.hash.THashMap;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* @author Beny
|
||||
*/
|
||||
public class SubscriptionHabboClub extends Subscription {
|
||||
|
||||
public static boolean HC_PAYDAY_ENABLED = false;
|
||||
public static int HC_PAYDAY_NEXT_DATE = Integer.MAX_VALUE; // yyyy-MM-dd HH:mm:ss
|
||||
public static String HC_PAYDAY_INTERVAL = "";
|
||||
public static String HC_PAYDAY_QUERY = "";
|
||||
public static TreeMap<Integer, Integer> HC_PAYDAY_STREAK = new TreeMap<>();
|
||||
public static String HC_PAYDAY_CURRENCY = "";
|
||||
public static Double HC_PAYDAY_KICKBACK_PERCENTAGE = 0.1;
|
||||
|
||||
/**
|
||||
* When true "coins spent" will be calculated from the timestamp the user joins HC instead of from the last HC pay day execution timestamp
|
||||
*/
|
||||
public static boolean HC_PAYDAY_COINSSPENT_RESET_ON_EXPIRE = false;
|
||||
|
||||
/**
|
||||
* Boolean indicating if HC pay day currency executing. Prevents double execution
|
||||
*/
|
||||
public static boolean isExecuting = false;
|
||||
|
||||
public SubscriptionHabboClub(Integer id, Integer userId, String subscriptionType, Integer timestampStart, Integer duration, Boolean active) {
|
||||
super(id, userId, subscriptionType, timestampStart, duration, active);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the subscription is first created.
|
||||
* Actions:
|
||||
* - Set user's max_friends to MAXIMUM_FRIENDS_HC
|
||||
* - Set user's max_rooms to MAXIMUM_ROOMS_HC
|
||||
* - Reset the user's HC pay day timer (used in calculating the coins spent)
|
||||
* - Send associated HC packets to client
|
||||
*/
|
||||
@Override
|
||||
public void onCreated() {
|
||||
super.onCreated();
|
||||
|
||||
Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getUserId());
|
||||
habbo.getHabboStats().maxFriends = Messenger.MAXIMUM_FRIENDS_HC;
|
||||
habbo.getHabboStats().maxRooms = RoomManager.MAXIMUM_ROOMS_HC;
|
||||
habbo.getHabboStats().lastHCPayday = HC_PAYDAY_COINSSPENT_RESET_ON_EXPIRE ? Emulator.getIntUnixTimestamp() : HC_PAYDAY_NEXT_DATE - Emulator.timeStringToSeconds(HC_PAYDAY_INTERVAL);
|
||||
Emulator.getThreading().run(habbo.getHabboStats());
|
||||
|
||||
if(habbo.getClient() != null) {
|
||||
|
||||
if((Emulator.getIntUnixTimestamp() - habbo.getHabboStats().hcMessageLastModified) < 60) {
|
||||
Emulator.getThreading().run(() -> { habbo.getClient().sendResponse(new UserClubComposer(habbo)); habbo.getClient().sendResponse(new UserPermissionsComposer(habbo)); }, (Emulator.getIntUnixTimestamp() - habbo.getHabboStats().hcMessageLastModified));
|
||||
}
|
||||
else {
|
||||
habbo.getClient().sendResponse(new UserClubComposer(habbo));
|
||||
habbo.getClient().sendResponse(new UserPermissionsComposer(habbo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the subscription is extended by manual action (by admin command or RCON)
|
||||
* Actions:
|
||||
* - Extend duration of the subscription
|
||||
* - Send associated HC packets to client
|
||||
*/
|
||||
@Override
|
||||
public void addDuration(int amount) {
|
||||
super.addDuration(amount);
|
||||
|
||||
if(amount < 0) {
|
||||
Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getUserId());
|
||||
if(habbo != null && habbo.getClient() != null) {
|
||||
habbo.getClient().sendResponse(new UserClubComposer(habbo));
|
||||
habbo.getClient().sendResponse(new UserPermissionsComposer(habbo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the subscription is extended or bought again when already exists
|
||||
* Actions:
|
||||
* - Extend duration of the subscription
|
||||
* - Send associated HC packets to client
|
||||
*/
|
||||
@Override
|
||||
public void onExtended(int duration) {
|
||||
super.onExtended(duration);
|
||||
|
||||
Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getUserId());
|
||||
|
||||
if(habbo.getClient() != null) {
|
||||
habbo.getClient().sendResponse(new UserClubComposer(habbo));
|
||||
habbo.getClient().sendResponse(new UserPermissionsComposer(habbo));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by SubscriptionScheduler when isActive() && getRemaining() < 0
|
||||
* Actions:
|
||||
* - Set user's max_friends to MAXIMUM_FRIENDS
|
||||
* - Set user's max_rooms to MAXIMUM_ROOMS
|
||||
* - Remove HC clothing
|
||||
* - Send associated HC packets to client
|
||||
*/
|
||||
@Override
|
||||
public void onExpired() {
|
||||
super.onExpired();
|
||||
|
||||
Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getUserId());
|
||||
habbo.getHabboStats().maxFriends = Messenger.MAXIMUM_FRIENDS;
|
||||
habbo.getHabboStats().maxRooms = RoomManager.MAXIMUM_ROOMS_USER;
|
||||
Emulator.getThreading().run(habbo.getHabboStats());
|
||||
|
||||
if(ClothingValidationManager.VALIDATE_ON_HC_EXPIRE) {
|
||||
habbo.getHabboInfo().setLook(ClothingValidationManager.validateLook(habbo, habbo.getHabboInfo().getLook(), habbo.getHabboInfo().getGender().name()));
|
||||
Emulator.getThreading().run(habbo.getHabboInfo());
|
||||
|
||||
if(habbo.getClient() != null) {
|
||||
habbo.getClient().sendResponse(new UpdateUserLookComposer(habbo));
|
||||
}
|
||||
|
||||
if (habbo.getHabboInfo().getCurrentRoom() != null) {
|
||||
habbo.getHabboInfo().getCurrentRoom().sendComposer(new RoomUserDataComposer(habbo).compose());
|
||||
}
|
||||
}
|
||||
|
||||
if(habbo.getClient() != null) {
|
||||
habbo.getClient().sendResponse(new UserClubComposer(habbo));
|
||||
habbo.getClient().sendResponse(new UserPermissionsComposer(habbo));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate's a users upcoming HC Pay day rewards
|
||||
* @param habbo User to calculate for
|
||||
* @return ClubCenterDataComposer
|
||||
*/
|
||||
public static ClubCenterDataComposer calculatePayday(HabboInfo habbo) {
|
||||
Subscription activeSub = null;
|
||||
Subscription firstEverSub = null;
|
||||
int currentHcStreak = 0;
|
||||
int totalCreditsSpent = 0;
|
||||
int creditRewardForStreakBonus = 0;
|
||||
int creditRewardForMonthlySpent = 0;
|
||||
int timeUntilPayday = 0;
|
||||
|
||||
for(Subscription sub : habbo.getHabboStats().subscriptions) {
|
||||
if(sub.getSubscriptionType().equalsIgnoreCase(Subscription.HABBO_CLUB)) {
|
||||
|
||||
if(firstEverSub == null || sub.getTimestampStart() < firstEverSub.getTimestampStart()) {
|
||||
firstEverSub = sub;
|
||||
}
|
||||
|
||||
if(sub.isActive()) {
|
||||
activeSub = sub;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(HC_PAYDAY_ENABLED && activeSub != null) {
|
||||
currentHcStreak = (int)Math.floor((Emulator.getIntUnixTimestamp() - activeSub.getTimestampStart()) / (60 * 60 * 24.0));
|
||||
if(currentHcStreak < 1) {
|
||||
currentHcStreak = 0;
|
||||
}
|
||||
|
||||
for(Map.Entry<Integer, Integer> set : HC_PAYDAY_STREAK.entrySet()) {
|
||||
if(currentHcStreak >= set.getKey() && set.getValue() > creditRewardForStreakBonus) {
|
||||
creditRewardForStreakBonus = set.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
THashMap<String, Object> queryParams = new THashMap();
|
||||
queryParams.put("@user_id", habbo.getId());
|
||||
queryParams.put("@timestamp_start", habbo.getHabboStats().lastHCPayday);
|
||||
queryParams.put("@timestamp_end", HC_PAYDAY_NEXT_DATE);
|
||||
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||
PreparedStatement statement = Database.preparedStatementWithParams(connection, HC_PAYDAY_QUERY, queryParams)) {
|
||||
|
||||
try (ResultSet set = statement.executeQuery()) {
|
||||
while (set.next()) {
|
||||
totalCreditsSpent = set.getInt("amount_spent");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
SubscriptionManager.LOGGER.error("Caught SQL exception", e);
|
||||
}
|
||||
|
||||
creditRewardForMonthlySpent = (int)Math.floor(totalCreditsSpent * HC_PAYDAY_KICKBACK_PERCENTAGE);
|
||||
|
||||
timeUntilPayday = (HC_PAYDAY_NEXT_DATE - Emulator.getIntUnixTimestamp()) / 60;
|
||||
}
|
||||
|
||||
return new ClubCenterDataComposer(
|
||||
currentHcStreak,
|
||||
(firstEverSub != null ? new SimpleDateFormat("dd-MM-yyyy").format(new Date(firstEverSub.getTimestampStart() * 1000L)) : ""),
|
||||
HC_PAYDAY_KICKBACK_PERCENTAGE,
|
||||
0,
|
||||
0,
|
||||
totalCreditsSpent,
|
||||
creditRewardForStreakBonus,
|
||||
creditRewardForMonthlySpent,
|
||||
timeUntilPayday
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the HC Pay day, calculating reward for all active HABBO_CLUB subscribers and issuing rewards.
|
||||
*/
|
||||
public static void executePayDay() {
|
||||
isExecuting = true;
|
||||
int timestampNow = Emulator.getIntUnixTimestamp();
|
||||
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement("SELECT user_id FROM `users_subscriptions` WHERE subscription_type = '" + Subscription.HABBO_CLUB + "' AND `active` = 1 AND `timestamp_start` < ? AND (`timestamp_start` + `duration`) > ? GROUP BY user_id")) {
|
||||
statement.setInt(1, timestampNow);
|
||||
statement.setInt(2, timestampNow);
|
||||
|
||||
try (ResultSet set = statement.executeQuery()) {
|
||||
while (set.next()) {
|
||||
try {
|
||||
int userId = set.getInt("user_id");
|
||||
HabboInfo habboInfo = Emulator.getGameEnvironment().getHabboManager().getHabboInfo(userId);
|
||||
ClubCenterDataComposer calculated = calculatePayday(habboInfo);
|
||||
int totalReward = (calculated.creditRewardForMonthlySpent + calculated.creditRewardForStreakBonus);
|
||||
if(totalReward > 0) {
|
||||
boolean claimed = claimPayDay(Emulator.getGameEnvironment().getHabboManager().getHabbo(userId), totalReward, HC_PAYDAY_CURRENCY);
|
||||
HcPayDayLogEntry le = new HcPayDayLogEntry(timestampNow, userId, calculated.currentHcStreak, calculated.totalCreditsSpent, calculated.creditRewardForMonthlySpent, calculated.creditRewardForStreakBonus, totalReward, HC_PAYDAY_CURRENCY, claimed);
|
||||
Emulator.getThreading().run(le);
|
||||
}
|
||||
habboInfo.getHabboStats().lastHCPayday = timestampNow;
|
||||
}
|
||||
catch (Exception e) {
|
||||
SubscriptionManager.LOGGER.error("Exception processing HC payday for user #" + set.getInt("user_id"), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Date date = new java.util.Date(HC_PAYDAY_NEXT_DATE * 1000L);
|
||||
date = Emulator.modifyDate(date, HC_PAYDAY_INTERVAL);
|
||||
HC_PAYDAY_NEXT_DATE = (int)(date.getTime() / 1000L);
|
||||
|
||||
try(PreparedStatement stm2 = connection.prepareStatement("UPDATE `emulator_settings` SET `value` = ? WHERE `key` = ?")) {
|
||||
SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
stm2.setString(1, sdf.format(date));
|
||||
stm2.setString(2, "subscriptions.hc.payday.next_date");
|
||||
stm2.execute();
|
||||
}
|
||||
|
||||
try(PreparedStatement stm2 = connection.prepareStatement("UPDATE users_settings SET last_hc_payday = ? WHERE user_id IN (SELECT user_id FROM `users_subscriptions` WHERE subscription_type = '" + Subscription.HABBO_CLUB + "' AND `active` = 1 AND `timestamp_start` < ? AND (`timestamp_start` + `duration`) > ? GROUP BY user_id)")) {
|
||||
stm2.setInt(1, timestampNow);
|
||||
stm2.setInt(2, timestampNow);
|
||||
stm2.setInt(3, timestampNow);
|
||||
stm2.execute();
|
||||
}
|
||||
|
||||
}
|
||||
catch (SQLException e) {
|
||||
SubscriptionManager.LOGGER.error("Caught SQL exception", e);
|
||||
}
|
||||
isExecuting = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a user logs in. Checks for any unclaimed HC Pay day rewards and issues rewards.
|
||||
* @param habbo User to process
|
||||
*/
|
||||
public static void processUnclaimed(Habbo habbo) {
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement("SELECT * FROM `logs_hc_payday` WHERE user_id = ? AND claimed = 0")) {
|
||||
statement.setInt(1, habbo.getHabboInfo().getId());
|
||||
|
||||
try (ResultSet set = statement.executeQuery()) {
|
||||
while (set.next()) {
|
||||
try {
|
||||
int logId = set.getInt("id");
|
||||
int userId = set.getInt("user_id");
|
||||
int totalPayout = set.getInt("total_payout");
|
||||
String currency = set.getString("currency");
|
||||
|
||||
if(claimPayDay(habbo, totalPayout, currency)) {
|
||||
try(PreparedStatement stm2 = connection.prepareStatement("UPDATE logs_hc_payday SET claimed = 1 WHERE id = ?")) {
|
||||
stm2.setInt(1, logId);
|
||||
stm2.execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
SubscriptionManager.LOGGER.error("Exception processing HC payday for user #" + set.getInt("user_id"), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (SQLException e) {
|
||||
SubscriptionManager.LOGGER.error("Caught SQL exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Issues rewards to user.
|
||||
* @param habbo User to reward to
|
||||
* @param amount Amount of currency to reward
|
||||
* @param currency Currency string (Can be one of: credits, diamonds, duckets, pixels or a currency ID e.g. 5)
|
||||
* @return Boolean indicating success of the operation
|
||||
*/
|
||||
public static boolean claimPayDay(Habbo habbo, int amount, String currency) {
|
||||
if(habbo == null)
|
||||
return false;
|
||||
|
||||
int pointCurrency;
|
||||
switch(currency.toLowerCase()) {
|
||||
case "credits":
|
||||
case "coins":
|
||||
case "credit":
|
||||
case "coin":
|
||||
habbo.getClient().getHabbo().getHabboInfo().addCredits(amount);
|
||||
habbo.getClient().sendResponse(new UserCreditsComposer(habbo.getClient().getHabbo()));
|
||||
break;
|
||||
|
||||
case "diamonds":
|
||||
case "diamond":
|
||||
pointCurrency = 5;
|
||||
habbo.getClient().getHabbo().getHabboInfo().addCurrencyAmount(pointCurrency, amount);
|
||||
habbo.getClient().sendResponse(new UserPointsComposer(habbo.getClient().getHabbo().getHabboInfo().getCurrencyAmount(pointCurrency), amount, pointCurrency));
|
||||
break;
|
||||
|
||||
case "duckets":
|
||||
case "ducket":
|
||||
case "pixels":
|
||||
case "pixel":
|
||||
pointCurrency = 0;
|
||||
habbo.getClient().getHabbo().getHabboInfo().addCurrencyAmount(pointCurrency, amount);
|
||||
habbo.getClient().sendResponse(new UserPointsComposer(habbo.getClient().getHabbo().getHabboInfo().getCurrencyAmount(pointCurrency), amount, pointCurrency));
|
||||
break;
|
||||
|
||||
default:
|
||||
pointCurrency = Integer.parseInt(currency);
|
||||
habbo.getClient().getHabbo().getHabboInfo().addCurrencyAmount(pointCurrency, amount);
|
||||
habbo.getClient().sendResponse(new UserPointsComposer(habbo.getClient().getHabbo().getHabboInfo().getCurrencyAmount(pointCurrency), amount, pointCurrency));
|
||||
break;
|
||||
}
|
||||
|
||||
habbo.alert(Emulator.getTexts().getValue("subscriptions.hc.payday.message", "Woohoo HC Payday has arrived! You have received %amount% credits to your purse. Enjoy!").replace("%amount%", "" + amount));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package com.eu.habbo.habbohotel.users.subscriptions;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import gnu.trove.map.hash.THashMap;
|
||||
import gnu.trove.set.hash.THashSet;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* @author Beny
|
||||
*/
|
||||
public class SubscriptionManager {
|
||||
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(SubscriptionManager.class);
|
||||
|
||||
public THashMap<String, Class<? extends Subscription>> types;
|
||||
|
||||
public SubscriptionManager() {
|
||||
this.types = new THashMap<>();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
this.types.put(Subscription.HABBO_CLUB, SubscriptionHabboClub.class);
|
||||
}
|
||||
|
||||
public void addSubscriptionType(String type, Class<? extends Subscription> clazz) {
|
||||
if(this.types.containsKey(type) || this.types.containsValue(clazz)) {
|
||||
throw new RuntimeException("Subscription Type must be unique. An class with type: " + clazz.getName() + " was already added OR the key: " + type + " is already in use.");
|
||||
}
|
||||
|
||||
this.types.put(type, clazz);
|
||||
}
|
||||
|
||||
public void removeSubscriptionType(String type) {
|
||||
this.types.remove(type);
|
||||
}
|
||||
|
||||
public Class<? extends Subscription> getSubscriptionClass(String type) {
|
||||
if(!this.types.containsKey(type)) {
|
||||
LOGGER.debug("Can't find subscription class: {}", type);
|
||||
return Subscription.class;
|
||||
}
|
||||
|
||||
return this.types.get(type);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
this.types.clear();
|
||||
}
|
||||
|
||||
public THashSet<Subscription> getSubscriptionsForUser(int userId) {
|
||||
THashSet<Subscription> subscriptions = new THashSet<>();
|
||||
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement("SELECT * FROM users_subscriptions WHERE user_id = ?")) {
|
||||
statement.setInt(1, userId);
|
||||
|
||||
try (ResultSet set = statement.executeQuery()) {
|
||||
while (set.next()) {
|
||||
Class<? extends Subscription> subClazz = Emulator.getGameEnvironment().getSubscriptionManager().getSubscriptionClass(set.getString("subscription_type"));
|
||||
Constructor<? extends Subscription> c = subClazz.getConstructor(Integer.class, Integer.class, String.class, Integer.class, Integer.class, Boolean.class);
|
||||
c.setAccessible(true);
|
||||
Subscription subscription = c.newInstance(set.getInt("id"), set.getInt("user_id"), set.getString("subscription_type"), set.getInt("timestamp_start"), set.getInt("duration"), set.getInt("active") == 1);
|
||||
subscriptions.add(subscription);
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
LOGGER.error("IllegalAccessException", e);
|
||||
} catch (InstantiationException e) {
|
||||
LOGGER.error("InstantiationException", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
LOGGER.error("InvocationTargetException", e);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
LOGGER.error("Caught SQL exception", e);
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
LOGGER.error("Caught NoSuchMethodException", e);
|
||||
}
|
||||
|
||||
return subscriptions;
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package com.eu.habbo.habbohotel.users.subscriptions;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.core.Scheduler;
|
||||
import com.eu.habbo.habbohotel.users.Habbo;
|
||||
import com.eu.habbo.plugin.events.users.subscriptions.UserSubscriptionExpiredEvent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Beny
|
||||
*/
|
||||
public class SubscriptionScheduler extends Scheduler {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SubscriptionScheduler.class);
|
||||
|
||||
public SubscriptionScheduler() {
|
||||
super(Emulator.getConfig().getInt("subscriptions.scheduler.interval", 10));
|
||||
this.reloadConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when config is changed. Should end the scheduler if disabled.
|
||||
*/
|
||||
public void reloadConfig() {
|
||||
if (Emulator.getConfig().getBoolean("subscriptions.scheduler.enabled", true)) {
|
||||
if (this.disposed) {
|
||||
this.disposed = false;
|
||||
this.run();
|
||||
}
|
||||
} else {
|
||||
this.disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
super.run();
|
||||
|
||||
Habbo habbo;
|
||||
for (Map.Entry<Integer, Habbo> map : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().entrySet()) {
|
||||
habbo = map.getValue();
|
||||
|
||||
try {
|
||||
if (habbo != null) {
|
||||
for(Subscription subscription : habbo.getHabboStats().subscriptions) {
|
||||
if(subscription.isActive() && subscription.getRemaining() < 0) {
|
||||
if (!Emulator.getPluginManager().fireEvent(new UserSubscriptionExpiredEvent(habbo.getHabboInfo().getId(), subscription)).isCancelled()) {
|
||||
subscription.onExpired();
|
||||
subscription.setActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Caught exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
if(SubscriptionHabboClub.HC_PAYDAY_ENABLED && !SubscriptionHabboClub.isExecuting && SubscriptionHabboClub.HC_PAYDAY_NEXT_DATE < Emulator.getIntUnixTimestamp()) {
|
||||
SubscriptionHabboClub.executePayDay();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDisposed() {
|
||||
return this.disposed;
|
||||
}
|
||||
|
||||
public void setDisposed(boolean disposed) {
|
||||
this.disposed = disposed;
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ import com.eu.habbo.habbohotel.permissions.Permission;
|
||||
import com.eu.habbo.habbohotel.pets.PetManager;
|
||||
import com.eu.habbo.habbohotel.users.HabboBadge;
|
||||
import com.eu.habbo.habbohotel.users.HabboInventory;
|
||||
import com.eu.habbo.habbohotel.users.subscriptions.Subscription;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.catalog.AlertPurchaseFailedComposer;
|
||||
import com.eu.habbo.messages.outgoing.catalog.AlertPurchaseUnavailableComposer;
|
||||
@ -176,12 +177,19 @@ public class CatalogBuyItemEvent extends MessageHandler {
|
||||
if (!this.client.getHabbo().hasPermission(Permission.ACC_INFINITE_POINTS))
|
||||
this.client.getHabbo().getHabboInfo().addCurrencyAmount(item.getPointsType(), -totalDuckets);
|
||||
|
||||
if (this.client.getHabbo().getHabboStats().getClubExpireTimestamp() <= Emulator.getIntUnixTimestamp())
|
||||
|
||||
if(this.client.getHabbo().getHabboStats().createSubscription(Subscription.HABBO_CLUB, (totalDays * 86400)) == null) {
|
||||
this.client.sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR).compose());
|
||||
throw new Exception("Unable to create or extend subscription");
|
||||
}
|
||||
|
||||
/*if (this.client.getHabbo().getHabboStats().getClubExpireTimestamp() <= Emulator.getIntUnixTimestamp())
|
||||
this.client.getHabbo().getHabboStats().setClubExpireTimestamp(Emulator.getIntUnixTimestamp());
|
||||
|
||||
this.client.getHabbo().getHabboStats().setClubExpireTimestamp(this.client.getHabbo().getHabboStats().getClubExpireTimestamp() + (totalDays * 86400));
|
||||
|
||||
this.client.sendResponse(new UserPermissionsComposer(this.client.getHabbo()));
|
||||
this.client.sendResponse(new UserClubComposer(this.client.getHabbo()));
|
||||
this.client.sendResponse(new UserClubComposer(this.client.getHabbo()));*/
|
||||
|
||||
if (totalCredits > 0)
|
||||
this.client.sendResponse(new UserCreditsComposer(this.client.getHabbo()));
|
||||
|
@ -1,11 +1,14 @@
|
||||
package com.eu.habbo.messages.incoming.catalog;
|
||||
|
||||
import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionHabboClub;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.catalog.ClubCenterDataComposer;
|
||||
import com.eu.habbo.messages.outgoing.catalog.ClubDataComposer;
|
||||
|
||||
public class RequestClubDataEvent extends MessageHandler {
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
this.client.sendResponse(new ClubDataComposer(this.client.getHabbo(), this.packet.readInt()));
|
||||
this.client.sendResponse(SubscriptionHabboClub.calculatePayday(this.client.getHabbo().getHabboInfo()));
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.messenger.Messenger;
|
||||
import com.eu.habbo.habbohotel.users.Habbo;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.friends.FriendRequestErrorComposer;
|
||||
import com.eu.habbo.plugin.PluginManager;
|
||||
|
||||
public class AcceptFriendRequestEvent extends MessageHandler {
|
||||
@Override
|
||||
@ -17,18 +19,33 @@ public class AcceptFriendRequestEvent extends MessageHandler {
|
||||
if (userId == 0)
|
||||
return;
|
||||
|
||||
if (this.client.getHabbo().getMessenger().getFriends().containsKey(userId))
|
||||
if (this.client.getHabbo().getMessenger().getFriends().containsKey(userId)) {
|
||||
this.client.getHabbo().getMessenger().deleteFriendRequests(userId, this.client.getHabbo().getHabboInfo().getId());
|
||||
continue;
|
||||
}
|
||||
|
||||
Habbo target = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId);
|
||||
|
||||
if(target == null) {
|
||||
this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.TARGET_NOT_FOUND));
|
||||
this.client.getHabbo().getMessenger().deleteFriendRequests(userId, this.client.getHabbo().getHabboInfo().getId());
|
||||
continue;
|
||||
}
|
||||
|
||||
if(this.client.getHabbo().getMessenger().getFriends().size() >= this.client.getHabbo().getHabboStats().maxFriends && !this.client.getHabbo().hasPermission("acc_infinite_friends")) {
|
||||
this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.FRIEND_LIST_OWN_FULL));
|
||||
break;
|
||||
}
|
||||
|
||||
if(target.getMessenger().getFriends().size() >= target.getHabboStats().maxFriends && !target.hasPermission("acc_infinite_friends")) {
|
||||
this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.FRIEND_LIST_TARGET_FULL));
|
||||
continue;
|
||||
}
|
||||
|
||||
this.client.getHabbo().getMessenger().acceptFriendRequest(userId, this.client.getHabbo().getHabboInfo().getId());
|
||||
|
||||
Messenger.checkFriendSizeProgress(this.client.getHabbo());
|
||||
|
||||
Habbo target = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId);
|
||||
|
||||
if (target != null) {
|
||||
Messenger.checkFriendSizeProgress(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,10 +74,16 @@ public class FriendRequestEvent extends MessageHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.client.getHabbo().getMessenger().getFriends().values().size() >= Messenger.friendLimit(this.client.getHabbo()) && !this.client.getHabbo().hasPermission("acc_infinite_friends")) {
|
||||
if (this.client.getHabbo().getMessenger().getFriends().values().size() >= this.client.getHabbo().getHabboStats().maxFriends && !this.client.getHabbo().hasPermission("acc_infinite_friends")) {
|
||||
this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.FRIEND_LIST_OWN_FULL));
|
||||
return;
|
||||
}
|
||||
|
||||
if (habbo.getMessenger().getFriends().values().size() >= habbo.getHabboStats().maxFriends && !habbo.hasPermission("acc_infinite_friends")) {
|
||||
this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.FRIEND_LIST_TARGET_FULL));
|
||||
return;
|
||||
}
|
||||
|
||||
Messenger.makeFriendRequest(this.client.getHabbo().getHabboInfo().getId(), id);
|
||||
} else {
|
||||
this.client.sendResponse(new FriendRequestErrorComposer(FriendRequestErrorComposer.TARGET_NOT_FOUND));
|
||||
|
@ -8,6 +8,8 @@ import com.eu.habbo.habbohotel.navigation.NavigatorSavedSearch;
|
||||
import com.eu.habbo.habbohotel.permissions.Permission;
|
||||
import com.eu.habbo.habbohotel.users.Habbo;
|
||||
import com.eu.habbo.habbohotel.users.HabboManager;
|
||||
import com.eu.habbo.habbohotel.users.clothingvalidation.ClothingValidationManager;
|
||||
import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionHabboClub;
|
||||
import com.eu.habbo.messages.NoAuthMessage;
|
||||
import com.eu.habbo.messages.ServerMessage;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
@ -105,6 +107,14 @@ public class SecureLoginEvent extends MessageHandler {
|
||||
Emulator.getGameServer().getGameClientManager().disposeClient(this.client);
|
||||
return;
|
||||
}
|
||||
|
||||
if(ClothingValidationManager.VALIDATE_ON_LOGIN) {
|
||||
String validated = ClothingValidationManager.validateLook(this.client.getHabbo());
|
||||
if(!validated.equals(this.client.getHabbo().getHabboInfo().getLook())) {
|
||||
this.client.getHabbo().getHabboInfo().setLook(validated);
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<ServerMessage> messages = new ArrayList<>();
|
||||
|
||||
messages.add(new SecureLoginOKComposer().compose());
|
||||
@ -194,6 +204,10 @@ public class SecureLoginEvent extends MessageHandler {
|
||||
}, Emulator.getConfig().getInt("hotel.welcome.alert.delay", 5000));
|
||||
}
|
||||
|
||||
if(SubscriptionHabboClub.HC_PAYDAY_ENABLED) {
|
||||
SubscriptionHabboClub.processUnclaimed(habbo);
|
||||
}
|
||||
|
||||
Messenger.checkFriendSizeProgress(habbo);
|
||||
|
||||
if (!habbo.getHabboStats().hasGottenDefaultSavedSearches) {
|
||||
|
@ -9,7 +9,7 @@ public class RequestCanCreateRoomEvent extends MessageHandler {
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
int count = Emulator.getGameEnvironment().getRoomManager().getRoomsForHabbo(this.client.getHabbo()).size();
|
||||
int max = this.client.getHabbo().getHabboStats().hasActiveClub() ? RoomManager.MAXIMUM_ROOMS_VIP : RoomManager.MAXIMUM_ROOMS_USER;
|
||||
int max = this.client.getHabbo().getHabboStats().maxRooms;
|
||||
this.client.sendResponse(new CanCreateRoomComposer(count, max));
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public class RequestCreateRoomEvent extends MessageHandler {
|
||||
return;
|
||||
|
||||
int count = Emulator.getGameEnvironment().getRoomManager().getRoomsForHabbo(this.client.getHabbo()).size();
|
||||
int max = this.client.getHabbo().getHabboStats().hasActiveClub() ? RoomManager.MAXIMUM_ROOMS_VIP : RoomManager.MAXIMUM_ROOMS_USER;
|
||||
int max = this.client.getHabbo().getHabboStats().maxRooms;
|
||||
|
||||
if (count >= max) {
|
||||
this.client.sendResponse(new CanCreateRoomComposer(count, max));
|
||||
|
@ -53,6 +53,7 @@ public class RedeemClothingEvent extends MessageHandler {
|
||||
}
|
||||
|
||||
this.client.getHabbo().getInventory().getWardrobeComponent().getClothing().add(clothing.id);
|
||||
this.client.getHabbo().getInventory().getWardrobeComponent().getClothingSets().addAll(clothing.setId);
|
||||
this.client.sendResponse(new UserClothesComposer(this.client.getHabbo()));
|
||||
this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FIGURESET_REDEEMED.key));
|
||||
|
||||
|
@ -4,6 +4,7 @@ import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.achievements.AchievementManager;
|
||||
import com.eu.habbo.habbohotel.modtool.ScripterManager;
|
||||
import com.eu.habbo.habbohotel.users.HabboGender;
|
||||
import com.eu.habbo.habbohotel.users.clothingvalidation.ClothingValidationManager;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer;
|
||||
import com.eu.habbo.messages.outgoing.users.UpdateUserLookComposer;
|
||||
@ -35,7 +36,7 @@ public class UserSaveLookEvent extends MessageHandler {
|
||||
if (lookEvent.isCancelled())
|
||||
return;
|
||||
|
||||
this.client.getHabbo().getHabboInfo().setLook(lookEvent.newLook);
|
||||
this.client.getHabbo().getHabboInfo().setLook(ClothingValidationManager.VALIDATE_ON_CHANGE_LOOKS ? ClothingValidationManager.validateLook(this.client.getHabbo(), lookEvent.newLook, lookEvent.gender.name()) : lookEvent.newLook);
|
||||
this.client.getHabbo().getHabboInfo().setGender(lookEvent.gender);
|
||||
Emulator.getThreading().run(this.client.getHabbo().getHabboInfo());
|
||||
this.client.sendResponse(new UpdateUserLookComposer(this.client.getHabbo()));
|
||||
|
@ -1,40 +1,54 @@
|
||||
package com.eu.habbo.messages.outgoing.catalog;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.users.Habbo;
|
||||
import com.eu.habbo.habbohotel.users.subscriptions.Subscription;
|
||||
import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionHabboClub;
|
||||
import com.eu.habbo.messages.ServerMessage;
|
||||
import com.eu.habbo.messages.outgoing.MessageComposer;
|
||||
import com.eu.habbo.messages.outgoing.Outgoing;
|
||||
|
||||
public class ClubCenterDataComposer extends MessageComposer {
|
||||
private final int streakDuration;
|
||||
private final String joinDate;
|
||||
private final double percentage;
|
||||
private final int creditsSpend;
|
||||
private final int creditsBonus;
|
||||
private final int spendBonus;
|
||||
private final int delay;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
public ClubCenterDataComposer(int streakDuration, String joinDate, double percentage, int creditsSpend, int creditsBonus, int spendBonus, int delay) {
|
||||
this.streakDuration = streakDuration;
|
||||
this.joinDate = joinDate;
|
||||
this.percentage = percentage;
|
||||
this.creditsSpend = creditsSpend;
|
||||
this.creditsBonus = creditsBonus;
|
||||
this.spendBonus = spendBonus;
|
||||
this.delay = delay;
|
||||
public class ClubCenterDataComposer extends MessageComposer {
|
||||
public final int currentHcStreak;
|
||||
public final String firstSubDate;
|
||||
public final double kickbackPercentage;
|
||||
public final int totalCreditsMissed;
|
||||
public final int totalCreditsRewarded;
|
||||
public final int totalCreditsSpent;
|
||||
public final int creditRewardForStreakBonus;
|
||||
public final int creditRewardForMonthlySpent;
|
||||
public final int timeUntilPayday;
|
||||
|
||||
public ClubCenterDataComposer(int currentHcStreak, String firstSubDate, double kickbackPercentage, int totalCreditsMissed, int totalCreditsRewarded, int totalCreditsSpent, int creditRewardForStreakBonus, int creditRewardForMonthlySpent, int timeUntilPayday) {
|
||||
this.currentHcStreak = currentHcStreak;
|
||||
this.firstSubDate = firstSubDate;
|
||||
this.kickbackPercentage = kickbackPercentage;
|
||||
this.totalCreditsMissed = totalCreditsMissed;
|
||||
this.totalCreditsRewarded = totalCreditsRewarded;
|
||||
this.totalCreditsSpent = totalCreditsSpent;
|
||||
this.creditRewardForStreakBonus = creditRewardForStreakBonus;
|
||||
this.creditRewardForMonthlySpent = creditRewardForMonthlySpent;
|
||||
this.timeUntilPayday = timeUntilPayday;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServerMessage composeInternal() {
|
||||
this.response.init(Outgoing.ClubCenterDataComposer);
|
||||
this.response.appendInt(this.streakDuration); //streakduration in days
|
||||
this.response.appendString(this.joinDate); //joindate
|
||||
this.response.appendDouble(this.percentage); //percentage
|
||||
this.response.appendInt(0); //Unused
|
||||
this.response.appendInt(0); //unused
|
||||
this.response.appendInt(this.creditsSpend); //Amount credits spend
|
||||
this.response.appendInt(this.creditsBonus); //Credits bonus
|
||||
this.response.appendInt(this.spendBonus); //Spend bonus
|
||||
this.response.appendInt(this.delay); //next pay in minutes
|
||||
this.response.appendInt(this.currentHcStreak); // currentHcStreak (days)
|
||||
this.response.appendString(this.firstSubDate); // firstSubscriptionDate (dd-mm-yyyy)
|
||||
this.response.appendDouble(this.kickbackPercentage); // kickbackPercentage (e.g. 0.1 for 10%)
|
||||
this.response.appendInt(this.totalCreditsMissed); // (not used)
|
||||
this.response.appendInt(this.totalCreditsRewarded); // (not used)
|
||||
this.response.appendInt(this.totalCreditsSpent);
|
||||
this.response.appendInt(this.creditRewardForStreakBonus);
|
||||
this.response.appendInt(this.creditRewardForMonthlySpent);
|
||||
this.response.appendInt(this.timeUntilPayday); // timeUntilPayday (minutes)
|
||||
return this.response;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -6,6 +6,7 @@ import com.eu.habbo.messages.outgoing.Outgoing;
|
||||
|
||||
public class FriendRequestErrorComposer extends MessageComposer {
|
||||
public static final int FRIEND_LIST_OWN_FULL = 1;
|
||||
public static final int FRIEND_LIST_TARGET_FULL = 2;
|
||||
public static final int TARGET_NOT_ACCEPTING_REQUESTS = 3;
|
||||
public static final int TARGET_NOT_FOUND = 4;
|
||||
|
||||
|
@ -30,7 +30,7 @@ public class FriendsComposer extends MessageComposer {
|
||||
//this.response.appendInt(300);
|
||||
//this.response.appendInt(3); //Club level
|
||||
this.response.appendInt(this.habbo.hasPermission("acc_infinite_friends") ? Integer.MAX_VALUE : Messenger.MAXIMUM_FRIENDS);
|
||||
this.response.appendInt(this.habbo.hasPermission("acc_infinite_friends") ? Integer.MAX_VALUE : Messenger.MAXIMUM_FRIENDS);
|
||||
this.response.appendInt(this.habbo.hasPermission("acc_infinite_friends") ? Integer.MAX_VALUE : Messenger.MAXIMUM_FRIENDS_HC);
|
||||
this.response.appendInt(this.habbo.getMessenger().getFriends().size()/* + (this.habbo.hasPermission("acc_staff_chat") ? 1 : 0)*/);
|
||||
|
||||
for (Map.Entry<Integer, MessengerBuddy> row : this.habbo.getMessenger().getFriends().entrySet()) {
|
||||
|
@ -2,10 +2,15 @@ package com.eu.habbo.messages.outgoing.users;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.users.Habbo;
|
||||
import com.eu.habbo.habbohotel.users.subscriptions.Subscription;
|
||||
import com.eu.habbo.messages.ServerMessage;
|
||||
import com.eu.habbo.messages.outgoing.MessageComposer;
|
||||
import com.eu.habbo.messages.outgoing.Outgoing;
|
||||
|
||||
import java.time.Period;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class UserClubComposer extends MessageComposer {
|
||||
private final Habbo habbo;
|
||||
|
||||
@ -19,6 +24,47 @@ public class UserClubComposer extends MessageComposer {
|
||||
|
||||
this.response.appendString("club_habbo");
|
||||
|
||||
Subscription subscription = this.habbo.getHabboStats().getSubscription(Subscription.HABBO_CLUB);
|
||||
|
||||
int days = 0;
|
||||
int minutes = 0;
|
||||
int timeRemaining = 0;
|
||||
|
||||
if(subscription != null) {
|
||||
timeRemaining = subscription.getRemaining();
|
||||
days = (int) Math.floor(timeRemaining / 86400.0);
|
||||
minutes = (int) Math.ceil(timeRemaining / 60.0);
|
||||
|
||||
if(days < 1 && minutes > 0) {
|
||||
days = 1;
|
||||
}
|
||||
}
|
||||
|
||||
this.response.appendInt(days); // daysToPeriodEnd
|
||||
this.response.appendInt(0); // memberPeriods
|
||||
this.response.appendInt(0); // periodsSubscribedAhead
|
||||
this.response.appendInt(0); // responseType
|
||||
this.response.appendBoolean(true); // hasEverBeenMember
|
||||
this.response.appendBoolean(true); // isVIP
|
||||
this.response.appendInt(0); // pastClubDays
|
||||
this.response.appendInt(0); // pastVIPdays
|
||||
this.response.appendInt(minutes); // minutesTillExpiration
|
||||
this.response.appendInt((Emulator.getIntUnixTimestamp() - this.habbo.getHabboStats().hcMessageLastModified) / 60); // minutesSinceLastModified
|
||||
this.habbo.getHabboStats().hcMessageLastModified = Emulator.getIntUnixTimestamp();
|
||||
|
||||
// int - daysToPeriodEnd
|
||||
// int - memberPeriods
|
||||
// int - periodsSubscribedAhead
|
||||
// int - responseType
|
||||
// bool - hasEverBeenMember
|
||||
// bool - isVIP
|
||||
// int - pastClubDays
|
||||
// int - pastVIPdays
|
||||
// int - minutesTillExpiration
|
||||
// (optional) int - minutesSinceLastModified
|
||||
|
||||
|
||||
/*
|
||||
int endTimestamp = this.habbo.getHabboStats().getClubExpireTimestamp();
|
||||
int now = Emulator.getIntUnixTimestamp();
|
||||
|
||||
@ -48,6 +94,7 @@ public class UserClubComposer extends MessageComposer {
|
||||
this.response.appendInt(0);
|
||||
this.response.appendInt(1);
|
||||
}
|
||||
|
||||
this.response.appendBoolean(true);
|
||||
this.response.appendBoolean(true);
|
||||
this.response.appendInt(0);
|
||||
@ -60,6 +107,7 @@ public class UserClubComposer extends MessageComposer {
|
||||
} else {
|
||||
this.response.appendInt((int) remaining);
|
||||
}
|
||||
*/
|
||||
|
||||
return this.response;
|
||||
}
|
||||
|
@ -21,8 +21,11 @@ import com.eu.habbo.habbohotel.navigation.EventCategory;
|
||||
import com.eu.habbo.habbohotel.navigation.NavigatorManager;
|
||||
import com.eu.habbo.habbohotel.pets.PetManager;
|
||||
import com.eu.habbo.habbohotel.rooms.*;
|
||||
import com.eu.habbo.habbohotel.users.clothingvalidation.ClothingValidationManager;
|
||||
import com.eu.habbo.habbohotel.users.HabboInventory;
|
||||
import com.eu.habbo.habbohotel.users.HabboManager;
|
||||
import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionHabboClub;
|
||||
import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionManager;
|
||||
import com.eu.habbo.habbohotel.wired.WiredHandler;
|
||||
import com.eu.habbo.habbohotel.wired.highscores.WiredHighscoreManager;
|
||||
import com.eu.habbo.messages.PacketManager;
|
||||
@ -59,6 +62,7 @@ import java.net.URLClassLoader;
|
||||
import java.util.Arrays;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PluginManager {
|
||||
@ -97,8 +101,8 @@ public class PluginManager {
|
||||
Bot.PLACEMENT_MESSAGES = Emulator.getConfig().getValue("hotel.bot.placement.messages", "Yo!;Hello I'm a real party animal!;Hello!").split(";");
|
||||
|
||||
HabboInventory.MAXIMUM_ITEMS = Emulator.getConfig().getInt("hotel.inventory.max.items");
|
||||
Messenger.MAXIMUM_FRIENDS = Emulator.getConfig().getInt("hotel.max.friends");
|
||||
Messenger.MAXIMUM_FRIENDS_HC = Emulator.getConfig().getInt("hotel.max.friends.hc");
|
||||
Messenger.MAXIMUM_FRIENDS = Emulator.getConfig().getInt("hotel.users.max.friends", 300);
|
||||
Messenger.MAXIMUM_FRIENDS_HC = Emulator.getConfig().getInt("hotel.users.max.friends.hc", 1100);
|
||||
Room.MAXIMUM_BOTS = Emulator.getConfig().getInt("hotel.max.bots.room");
|
||||
Room.MAXIMUM_PETS = Emulator.getConfig().getInt("hotel.pets.max.room");
|
||||
Room.MAXIMUM_FURNI = Emulator.getConfig().getInt("hotel.room.furni.max", 2500);
|
||||
@ -107,8 +111,8 @@ public class PluginManager {
|
||||
Room.IDLE_CYCLES = Emulator.getConfig().getInt("hotel.roomuser.idle.cycles", 240);
|
||||
Room.IDLE_CYCLES_KICK = Emulator.getConfig().getInt("hotel.roomuser.idle.cycles.kick", 480);
|
||||
Room.ROLLERS_MAXIMUM_ROLL_AVATARS = Emulator.getConfig().getInt("hotel.room.rollers.roll_avatars.max", 1);
|
||||
RoomManager.MAXIMUM_ROOMS_VIP = Emulator.getConfig().getInt("hotel.max.rooms.vip");
|
||||
RoomManager.MAXIMUM_ROOMS_USER = Emulator.getConfig().getInt("hotel.max.rooms.user");
|
||||
RoomManager.MAXIMUM_ROOMS_USER = Emulator.getConfig().getInt("hotel.users.max.rooms", 50);
|
||||
RoomManager.MAXIMUM_ROOMS_HC = Emulator.getConfig().getInt("hotel.users.max.rooms.hc", 75);
|
||||
RoomManager.HOME_ROOM_ID = Emulator.getConfig().getInt("hotel.home.room");
|
||||
WiredHandler.MAXIMUM_FURNI_SELECTION = Emulator.getConfig().getInt("hotel.wired.furni.selection.count");
|
||||
WiredHandler.TELEPORT_DELAY = Emulator.getConfig().getInt("wired.effect.teleport.delay", 500);
|
||||
@ -162,6 +166,49 @@ public class PluginManager {
|
||||
PetManager.MAXIMUM_PET_INVENTORY_SIZE = Emulator.getConfig().getInt("hotel.pets.max.inventory");
|
||||
|
||||
|
||||
SubscriptionHabboClub.HC_PAYDAY_ENABLED = Emulator.getConfig().getBoolean("subscriptions.hc.payday.enabled", false);
|
||||
|
||||
try {
|
||||
SubscriptionHabboClub.HC_PAYDAY_NEXT_DATE = (int) (Emulator.stringToDate(Emulator.getConfig().getValue("subscriptions.hc.payday.next_date")).getTime() / 1000);
|
||||
}
|
||||
catch(Exception e) { SubscriptionHabboClub.HC_PAYDAY_NEXT_DATE = Integer.MAX_VALUE; }
|
||||
|
||||
SubscriptionHabboClub.HC_PAYDAY_INTERVAL = Emulator.getConfig().getValue("subscriptions.hc.payday.interval");
|
||||
SubscriptionHabboClub.HC_PAYDAY_QUERY = Emulator.getConfig().getValue("subscriptions.hc.payday.query");
|
||||
SubscriptionHabboClub.HC_PAYDAY_CURRENCY = Emulator.getConfig().getValue("subscriptions.hc.payday.currency");
|
||||
SubscriptionHabboClub.HC_PAYDAY_KICKBACK_PERCENTAGE = Emulator.getConfig().getInt("subscriptions.hc.payday.percentage", 10) / 100.0;
|
||||
SubscriptionHabboClub.HC_PAYDAY_COINSSPENT_RESET_ON_EXPIRE = Emulator.getConfig().getBoolean("subscriptions.hc.payday.creditsspent_reset_on_expire", false);
|
||||
|
||||
SubscriptionHabboClub.HC_PAYDAY_STREAK.clear();
|
||||
for (String streak : Emulator.getConfig().getValue("subscriptions.hc.payday.streak", "7=5;30=10;60=15;90=20;180=25;365=30").split(Pattern.quote(";"))) {
|
||||
if(streak.contains("=")) {
|
||||
SubscriptionHabboClub.HC_PAYDAY_STREAK.put(Integer.parseInt(streak.split(Pattern.quote("="))[0]), Integer.parseInt(streak.split(Pattern.quote("="))[1]));
|
||||
}
|
||||
}
|
||||
|
||||
ClothingValidationManager.VALIDATE_ON_HC_EXPIRE = Emulator.getConfig().getBoolean("hotel.users.clothingvalidation.onhcexpired", false);
|
||||
ClothingValidationManager.VALIDATE_ON_LOGIN = Emulator.getConfig().getBoolean("hotel.users.clothingvalidation.onlogin", false);
|
||||
ClothingValidationManager.VALIDATE_ON_CHANGE_LOOKS = Emulator.getConfig().getBoolean("hotel.users.clothingvalidation.onchangelooks", false);
|
||||
ClothingValidationManager.VALIDATE_ON_MIMIC = Emulator.getConfig().getBoolean("hotel.users.clothingvalidation.onmimic", false);
|
||||
ClothingValidationManager.VALIDATE_ON_MANNEQUIN = Emulator.getConfig().getBoolean("hotel.users.clothingvalidation.onmannequin", false);
|
||||
ClothingValidationManager.VALIDATE_ON_FBALLGATE = Emulator.getConfig().getBoolean("hotel.users.clothingvalidation.onfballgate", false);
|
||||
|
||||
String newUrl = Emulator.getConfig().getValue("gamedata.figuredata.url");
|
||||
if(!ClothingValidationManager.FIGUREDATA_URL.equals(newUrl)) {
|
||||
ClothingValidationManager.FIGUREDATA_URL = newUrl;
|
||||
ClothingValidationManager.reloadFiguredata(newUrl);
|
||||
}
|
||||
|
||||
if(newUrl.isEmpty()) {
|
||||
ClothingValidationManager.VALIDATE_ON_HC_EXPIRE = false;
|
||||
ClothingValidationManager.VALIDATE_ON_LOGIN = false;
|
||||
ClothingValidationManager.VALIDATE_ON_CHANGE_LOOKS = false;
|
||||
ClothingValidationManager.VALIDATE_ON_MIMIC = false;
|
||||
ClothingValidationManager.VALIDATE_ON_MANNEQUIN = false;
|
||||
ClothingValidationManager.VALIDATE_ON_FBALLGATE = false;
|
||||
}
|
||||
|
||||
|
||||
NewNavigatorEventCategoriesComposer.CATEGORIES.clear();
|
||||
for (String category : Emulator.getConfig().getValue("navigator.eventcategories", "").split(";")) {
|
||||
try {
|
||||
@ -179,6 +226,7 @@ public class PluginManager {
|
||||
Emulator.getGameEnvironment().getPointsScheduler().reloadConfig();
|
||||
Emulator.getGameEnvironment().getPixelScheduler().reloadConfig();
|
||||
Emulator.getGameEnvironment().getGotwPointsScheduler().reloadConfig();
|
||||
Emulator.getGameEnvironment().subscriptionScheduler.reloadConfig();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,17 @@
|
||||
package com.eu.habbo.plugin.events.users.subscriptions;
|
||||
|
||||
import com.eu.habbo.plugin.Event;
|
||||
|
||||
public class UserSubscriptionCreatedEvent extends Event {
|
||||
public final int userId;
|
||||
public final String subscriptionType;
|
||||
public final int duration;
|
||||
|
||||
public UserSubscriptionCreatedEvent(int userId, String subscriptionType, int duration) {
|
||||
super();
|
||||
|
||||
this.userId = userId;
|
||||
this.subscriptionType = subscriptionType;
|
||||
this.duration = duration;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.eu.habbo.plugin.events.users.subscriptions;
|
||||
|
||||
import com.eu.habbo.habbohotel.users.subscriptions.Subscription;
|
||||
import com.eu.habbo.plugin.Event;
|
||||
|
||||
public class UserSubscriptionExpiredEvent extends Event {
|
||||
public final int userId;
|
||||
public final Subscription subscription;
|
||||
|
||||
public UserSubscriptionExpiredEvent(int userId, Subscription subscription) {
|
||||
super();
|
||||
|
||||
this.userId = userId;
|
||||
this.subscription = subscription;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.eu.habbo.plugin.events.users.subscriptions;
|
||||
|
||||
import com.eu.habbo.habbohotel.users.subscriptions.Subscription;
|
||||
import com.eu.habbo.plugin.Event;
|
||||
|
||||
public class UserSubscriptionExtendedEvent extends Event {
|
||||
public final int userId;
|
||||
public final Subscription subscription;
|
||||
public final int duration;
|
||||
|
||||
public UserSubscriptionExtendedEvent(int userId, Subscription subscription, int duration) {
|
||||
super();
|
||||
this.userId = userId;
|
||||
this.subscription = subscription;
|
||||
this.duration = duration;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user