From dfd12bd56aa08bfb08c8306e15eb66d2f4f687c6 Mon Sep 17 00:00:00 2001 From: brenoepics Date: Mon, 21 Mar 2022 18:51:52 +0000 Subject: [PATCH] New campaign calendar system --- sqlupdates/3_0_0 to 3_0_1.sql | 54 +++++- .../eu/habbo/habbohotel/GameEnvironment.java | 6 + .../campaign/calendar/CalendarCampaign.java | 64 ++++++++ .../campaign/calendar/CalendarManager.java | 154 ++++++++++++++++++ .../calendar/CalendarRewardClaimed.java | 50 ++++++ .../calendar}/CalendarRewardObject.java | 45 ++++- .../habbohotel/catalog/CatalogManager.java | 43 +---- .../habbohotel/commands/CalendarCommand.java | 20 ++- .../habbohotel/commands/CommandHandler.java | 1 + .../commands/UpdateCalendarCommand.java | 21 +++ .../eu/habbo/habbohotel/users/HabboStats.java | 7 +- .../AdventCalendarForceOpenEvent.java | 4 +- .../calendar/AdventCalendarOpenDayEvent.java | 4 +- .../incoming/handshake/UsernameEvent.java | 18 +- .../calendar/AdventCalendarDataComposer.java | 22 ++- .../AdventCalendarProductComposer.java | 32 +++- .../users/calendar/UserClaimRewardEvent.java | 23 +++ 17 files changed, 498 insertions(+), 70 deletions(-) create mode 100644 src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarCampaign.java create mode 100644 src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarManager.java create mode 100644 src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardClaimed.java rename src/main/java/com/eu/habbo/habbohotel/{catalog => campaign/calendar}/CalendarRewardObject.java (59%) create mode 100644 src/main/java/com/eu/habbo/habbohotel/commands/UpdateCalendarCommand.java create mode 100644 src/main/java/com/eu/habbo/plugin/events/users/calendar/UserClaimRewardEvent.java diff --git a/sqlupdates/3_0_0 to 3_0_1.sql b/sqlupdates/3_0_0 to 3_0_1.sql index 8ae563e1..7fc77aed 100644 --- a/sqlupdates/3_0_0 to 3_0_1.sql +++ b/sqlupdates/3_0_0 to 3_0_1.sql @@ -20,4 +20,56 @@ CREATE TABLE `messenger_categories` ( ); -- Set an ID (int) from category list items -ALTER TABLE messenger_friendships ADD category int NOT NULL DEFAULT '0' AFTER friends_since; \ No newline at end of file +ALTER TABLE messenger_friendships ADD category int NOT NULL DEFAULT '0' AFTER friends_since; + +-- ---------------------------- +-- Table structure for calendar_campaigns +-- ---------------------------- +DROP TABLE IF EXISTS `calendar_campaigns`; +CREATE TABLE `calendar_campaigns` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL DEFAULT '', + `image` varchar(255) NOT NULL DEFAULT '', + `start_timestamp` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `total_days` int NOT NULL DEFAULT '30', + `lock_expired` enum('1','0') NOT NULL DEFAULT '1', + `enabled` enum('1','0') NOT NULL DEFAULT '1', + UNIQUE KEY `id` (`id`) +); + +-- ---------------------------- +-- Records of calendar_campaigns +-- ---------------------------- +INSERT INTO `calendar_campaigns` VALUES ('1', 'test', '', '2022-02-09 16:49:13', '31', '1', '1'); + +-- ---------------------------- +-- Table structure for calendar_rewards +-- ---------------------------- +DROP TABLE IF EXISTS `calendar_rewards`; +CREATE TABLE `calendar_rewards` ( + `id` int NOT NULL AUTO_INCREMENT, + `campaign_id` int NOT NULL DEFAULT '0', + `product_name` varchar(128) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '', + `custom_image` varchar(128) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '', + `credits` int NOT NULL DEFAULT '0', + `pixels` int NOT NULL DEFAULT '0', + `points` int NOT NULL DEFAULT '0', + `points_type` int NOT NULL DEFAULT '0', + `badge` varchar(25) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '', + `item_id` int NOT NULL DEFAULT '0', + `subscription_type` enum('HABBO_CLUB') CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL, + `subscription_type` varchar(128) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT '', + `subscription_days` int NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) USING BTREE +); + +INSERT INTO `emulator_settings` (`key`, `value`) VALUES ('hotel.calendar.default', 'test'); +INSERT INTO `emulator_settings` (`key`, `value`) VALUES ('hotel.calendar.pixels.hc_modifier', '2.0'); + +-- Calendar force open +ALTER TABLE `permissions` ADD COLUMN `acc_calendar_force` enum('0','1') NULL DEFAULT '0'; + +-- UpdateCalendar command. +ALTER TABLE `permissions` ADD `cmd_update_calendar` ENUM('0', '1') NOT NULL DEFAULT '0'; +INSERT INTO `emulator_texts` (`key`, `value`) VALUES ('commands.description.cmd_update_calendar', ':update_calendar'), ('commands.keys.cmd_update_calendar', 'update_calendar'); +INSERT INTO `emulator_texts` (`key`, `value`) VALUES ('commands.success.cmd_update_calendar', 'Calendar updated successfully!'); \ No newline at end of file diff --git a/src/main/java/com/eu/habbo/habbohotel/GameEnvironment.java b/src/main/java/com/eu/habbo/habbohotel/GameEnvironment.java index a614cb05..7944ae8c 100644 --- a/src/main/java/com/eu/habbo/habbohotel/GameEnvironment.java +++ b/src/main/java/com/eu/habbo/habbohotel/GameEnvironment.java @@ -4,6 +4,7 @@ import com.eu.habbo.Emulator; import com.eu.habbo.core.*; import com.eu.habbo.habbohotel.achievements.AchievementManager; import com.eu.habbo.habbohotel.bots.BotManager; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarManager; import com.eu.habbo.habbohotel.catalog.CatalogManager; import com.eu.habbo.habbohotel.commands.CommandHandler; import com.eu.habbo.habbohotel.crafting.CraftingManager; @@ -54,6 +55,7 @@ public class GameEnvironment { private CraftingManager craftingManager; private PollManager pollManager; private SubscriptionManager subscriptionManager; + private CalendarManager calendarManager; public void load() throws Exception { LOGGER.info("GameEnvironment -> Loading..."); @@ -78,6 +80,7 @@ public class GameEnvironment { this.wordFilter = new WordFilter(); this.craftingManager = new CraftingManager(); this.pollManager = new PollManager(); + this.calendarManager = new CalendarManager(); this.roomManager.loadPublicRooms(); this.navigatorManager.loadNavigator(); @@ -114,6 +117,7 @@ public class GameEnvironment { this.itemManager.dispose(); this.hotelViewManager.dispose(); this.subscriptionManager.dispose(); + this.calendarManager.dispose(); LOGGER.info("GameEnvironment -> Disposed!"); } @@ -206,4 +210,6 @@ public class GameEnvironment { public SubscriptionManager getSubscriptionManager() { return this.subscriptionManager; } + + public CalendarManager getCalendarManager() { return this.calendarManager; } } diff --git a/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarCampaign.java b/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarCampaign.java new file mode 100644 index 00000000..b00cf7fc --- /dev/null +++ b/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarCampaign.java @@ -0,0 +1,64 @@ +package com.eu.habbo.habbohotel.campaign.calendar; + +import gnu.trove.map.hash.THashMap; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.Map; + +public class CalendarCampaign { + private int id; + private final String name; + private final String image; + private Map rewards = new THashMap<>(); + private final Timestamp start_timestamp; + private final int total_days; + private final boolean lock_expired; + + public CalendarCampaign(ResultSet set) throws SQLException { + this.id = set.getInt("id"); + this.name = set.getString("name"); + this.image = set.getString("image"); + this.start_timestamp = set.getTimestamp("start_timestamp"); + this.total_days = set.getInt("total_days"); + this.lock_expired = set.getInt("lock_expired") == 1; + } + + public CalendarCampaign(int id, String name, String image, Timestamp start_timestamp, int total_days, boolean lock_expired) { + this.id = id; + this.name = name; + this.image = image; + this.start_timestamp = start_timestamp; + this.total_days = total_days; + this.lock_expired = lock_expired; + } + + public int getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public String getImage() { + return this.image; + } + + public Timestamp getStartTimestamp() { + return this.start_timestamp; + } + + public int getTotalDays() { return this.total_days; } + + public boolean getLockExpired() { return this.lock_expired; } + + public Map getRewards() { return rewards; } + + public void setId(int id) { this.id = id; } + + public void setRewards(Map rewards) { this.rewards = rewards; } + + public void addReward(CalendarRewardObject reward) { this.rewards.put(reward.getId(), reward); } +} diff --git a/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarManager.java b/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarManager.java new file mode 100644 index 00000000..4e2720e8 --- /dev/null +++ b/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarManager.java @@ -0,0 +1,154 @@ +package com.eu.habbo.habbohotel.campaign.calendar; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.messages.outgoing.events.calendar.AdventCalendarProductComposer; +import com.eu.habbo.plugin.events.users.calendar.UserClaimRewardEvent; +import gnu.trove.map.hash.THashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.*; +import java.util.*; +import java.util.Date; + +import static java.time.temporal.ChronoUnit.DAYS; + + +public class CalendarManager { + private static final Logger LOGGER = LoggerFactory.getLogger(CalendarCampaign.class); + + final private static Map calendarCampaigns = new THashMap<>(); + public static double HC_MODIFIER; + + public CalendarManager() { + long millis = System.currentTimeMillis(); + this.reload(); + LOGGER.info("Calendar Manager -> Loaded! ({} MS)", (System.currentTimeMillis() - millis)); + } + + public void dispose(){ + calendarCampaigns.clear(); + } + + public boolean reload() { + this.dispose(); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM calendar_campaigns WHERE enabled = 1")) { + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + calendarCampaigns.put(set.getInt("id"), new CalendarCampaign(set)); + } + } + } catch (SQLException e) { + LOGGER.error("Caught SQL exception", e); + return false; + } + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM calendar_rewards")) { + try (ResultSet set = statement.executeQuery()) { + while (set.next()) { + CalendarCampaign campaign = calendarCampaigns.get(set.getInt("campaign_id")); + if(campaign != null){ + campaign.addReward(new CalendarRewardObject(set)); + } + } + } + } catch (SQLException e) { + LOGGER.error("Caught SQL exception", e); + return false; + } + + HC_MODIFIER = Emulator.getConfig().getDouble("hotel.calendar.pixels.hc_modifier", 2.0); + + return true; + } + + public void addCampaign(CalendarCampaign campaign) { + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO calendar_campaigns ( name, image, start_timestamp, total_days, lock_expired) VALUES (?, ?, ?, ? , ?)", Statement.RETURN_GENERATED_KEYS)) { + statement.setString(1, campaign.getName()); + statement.setString(2, campaign.getImage()); + statement.setTimestamp(3, campaign.getStartTimestamp()); + statement.setInt(4, campaign.getTotalDays()); + statement.setBoolean(5, campaign.getLockExpired()); + int affectedRows = statement.executeUpdate(); + + if (affectedRows == 0) { + throw new SQLException("Creating calendar campaign failed, no rows affected."); + } + + try (ResultSet generatedKeys = statement.getGeneratedKeys()) { + if (generatedKeys.next()) { + campaign.setId(generatedKeys.getInt(1)); + } else { + throw new SQLException("Creating calendar campaign failed, no ID found."); + } + } + } catch (SQLException e) { + LOGGER.error("Caught SQL exception", e); + } + + calendarCampaigns.put(campaign.getId(), campaign); + } + + public boolean deleteCampaign(CalendarCampaign campaign) { + calendarCampaigns.remove(campaign.getId()); + + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM calendar_campaigns WHERE id = ? LIMIT 1")) { + statement.setInt(1, campaign.getId()); + return statement.execute(); + } catch (SQLException e) { + LOGGER.error("Caught SQL exception", e); + } + + return false; + } + + public CalendarCampaign getCalendarCampaign(String campaignName) { + return calendarCampaigns.values().stream().filter(cc -> Objects.equals(cc.getName(), campaignName)).findFirst().orElse(null); + } + public Map getCalendarCampaigns() { + return calendarCampaigns; + } + + public void claimCalendarReward(Habbo habbo, String campaignName, int day, boolean force) { + CalendarCampaign campaign = calendarCampaigns.values().stream().filter(cc -> Objects.equals(cc.getName(), campaignName)).findFirst().orElse(null); + if(campaign == null) return; + if (habbo.getHabboStats().calendarRewardsClaimed.stream().noneMatch(claimed -> claimed.getCampaignId() == campaign.getId() && claimed.getDay() == day)) { + + Set keys = campaign.getRewards().keySet(); + Map rewards = new THashMap<>(); + if(keys.isEmpty()) return; + keys.forEach(key -> rewards.put(rewards.size() + 1, key)); + int rand = Emulator.getRandom().nextInt(rewards.size() - 1 + 1) + 1; + int random = rewards.get(rand); + CalendarRewardObject object = campaign.getRewards().get(random); + if (object == null) return; + int daysBetween = (int) DAYS.between(campaign.getStartTimestamp().toInstant(), new Date().toInstant()); + if(daysBetween >= 0 && daysBetween <= campaign.getTotalDays()) { + int diff = (daysBetween - day); + if ((((diff <= 2 || !campaign.getLockExpired()) && diff >= 0) || (force && habbo.hasPermission("acc_calendar_force")))) { + + if (Emulator.getPluginManager().fireEvent(new UserClaimRewardEvent(habbo, campaign, day, object, force)).isCancelled()) { + return; + } + + habbo.getHabboStats().calendarRewardsClaimed.add(new CalendarRewardClaimed(habbo.getHabboInfo().getId(), campaign.getId(), day, object.getId(), new Timestamp(System.currentTimeMillis()))); + habbo.getClient().sendResponse(new AdventCalendarProductComposer(true, object, habbo)); + object.give(habbo); + try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO calendar_rewards_claimed (user_id, campaign_id, day, reward_id, timestamp) VALUES (?, ?, ?, ?, ?)")) { + statement.setInt(1, habbo.getHabboInfo().getId()); + statement.setInt(2, campaign.getId()); + statement.setInt(3, day); + statement.setInt(4, object.getId()); + statement.setTimestamp(5, new Timestamp(System.currentTimeMillis())); + statement.execute(); + } catch (SQLException e) { + LOGGER.error("Caught SQL exception", e); + } + } + } + } + } +} + diff --git a/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardClaimed.java b/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardClaimed.java new file mode 100644 index 00000000..3cc0c56d --- /dev/null +++ b/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardClaimed.java @@ -0,0 +1,50 @@ +package com.eu.habbo.habbohotel.campaign.calendar; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; + +public class CalendarRewardClaimed { + private final int user_id; + private final int campaign; + private final int day; + private final int reward_id; + private final Timestamp timestamp; + + public CalendarRewardClaimed(ResultSet set) throws SQLException { + this.user_id = set.getInt("user_id"); + this.campaign = set.getInt("campaign_id"); + this.day = set.getInt("day"); + this.reward_id = set.getInt("reward_id"); + this.timestamp = set.getTimestamp("timestamp"); + } + + public CalendarRewardClaimed(int user_id, int campaign, int day, int reward_id, Timestamp timestamp) { + this.user_id = user_id; + this.campaign = campaign; + this.day = day; + this.reward_id = reward_id; + this.timestamp = timestamp; + } + + public int getUserId() { + return this.user_id; + } + + public int getCampaignId() { + return this.campaign; + } + + public int getDay() { + return this.day; + } + + public int getRewardId() { + return this.reward_id; + } + + public Timestamp getTimestamp() { + return this.timestamp; + } + +} diff --git a/src/main/java/com/eu/habbo/habbohotel/catalog/CalendarRewardObject.java b/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardObject.java similarity index 59% rename from src/main/java/com/eu/habbo/habbohotel/catalog/CalendarRewardObject.java rename to src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardObject.java index f2b135b5..efe8f91d 100644 --- a/src/main/java/com/eu/habbo/habbohotel/catalog/CalendarRewardObject.java +++ b/src/main/java/com/eu/habbo/habbohotel/campaign/calendar/CalendarRewardObject.java @@ -1,32 +1,47 @@ -package com.eu.habbo.habbohotel.catalog; +package com.eu.habbo.habbohotel.campaign.calendar; import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; import com.eu.habbo.habbohotel.users.Habbo; import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.users.subscriptions.Subscription; +import com.eu.habbo.habbohotel.users.subscriptions.SubscriptionHabboClub; import com.eu.habbo.messages.outgoing.inventory.AddHabboItemComposer; import com.eu.habbo.messages.outgoing.inventory.InventoryRefreshComposer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.sql.ResultSet; import java.sql.SQLException; public class CalendarRewardObject { + private static final Logger LOGGER = LoggerFactory.getLogger(CalendarRewardObject.class); + private final int id; + private final String productName; private final String customImage; private final int credits; + private final int pixels; private final int points; private final int pointsType; private final String badge; private final int itemId; + private final String subscription_type; + private final int subscription_days; public CalendarRewardObject(ResultSet set) throws SQLException { this.id = set.getInt("id"); + this.productName = set.getString("product_name"); this.customImage = set.getString("custom_image"); this.credits = set.getInt("credits"); + this.pixels = set.getInt("pixels"); this.points = set.getInt("points"); this.pointsType = set.getInt("points_type"); this.badge = set.getString("badge"); this.itemId = set.getInt("item_id"); + this.subscription_type = set.getString("subscription_type"); + this.subscription_days = set.getInt("subscription_days"); } public void give(Habbo habbo) { @@ -34,6 +49,10 @@ public class CalendarRewardObject { habbo.giveCredits(this.credits); } + if (this.pixels > 0) { + habbo.givePixels((int)(this.pixels * (habbo.getHabboStats().hasActiveClub() ? CalendarManager.HC_MODIFIER : 1.0))); + } + if (this.points > 0) { habbo.givePoints(this.pointsType, this.points); } @@ -42,6 +61,14 @@ public class CalendarRewardObject { habbo.addBadge(this.badge); } + if(this.subscription_type != null && !this.subscription_type.isEmpty()) { + if ("HABBO_CLUB".equals(this.subscription_type)) { + habbo.getHabboStats().createSubscription(SubscriptionHabboClub.HABBO_CLUB, this.subscription_days * 86400); + } else { + habbo.getHabboStats().createSubscription(this.subscription_type, this.subscription_days * 86400); + } + } + if (this.itemId > 0) { Item item = getItem(); @@ -71,6 +98,9 @@ public class CalendarRewardObject { return this.credits; } + public int getPixels() { + return this.pixels; + } public int getPoints() { return this.points; } @@ -79,6 +109,18 @@ public class CalendarRewardObject { return this.pointsType; } + public String getProductName() { + return productName; + } + + public String getSubscriptionType() { + return subscription_type; + } + + public int getSubscriptionDays() { + return subscription_days; + } + public String getBadge() { return this.badge; } @@ -86,4 +128,5 @@ public class CalendarRewardObject { public Item getItem() { return Emulator.getGameEnvironment().getItemManager().getItem(this.itemId); } + } diff --git a/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java b/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java index 6eb01a77..3e543e0c 100644 --- a/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java +++ b/src/main/java/com/eu/habbo/habbohotel/catalog/CatalogManager.java @@ -3,6 +3,7 @@ package com.eu.habbo.habbohotel.catalog; import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.achievements.AchievementManager; import com.eu.habbo.habbohotel.bots.Bot; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarRewardObject; import com.eu.habbo.habbohotel.catalog.layouts.*; import com.eu.habbo.habbohotel.gameclients.GameClient; import com.eu.habbo.habbohotel.guilds.Guild; @@ -190,7 +191,6 @@ public class CatalogManager { public final TIntIntHashMap offerDefs; public final Item ecotronItem; public final THashMap limitedNumbers; - public final THashMap calendarRewards; private final List vouchers; public CatalogManager() { @@ -207,7 +207,6 @@ public class CatalogManager { this.offerDefs = new TIntIntHashMap(); this.vouchers = new ArrayList<>(); this.limitedNumbers = new THashMap<>(); - this.calendarRewards = new THashMap<>(); this.initialize(); @@ -230,7 +229,6 @@ public class CatalogManager { this.loadClothing(); this.loadRecycler(); this.loadGiftWrappers(); - this.loadCalendarRewards(); } private synchronized void loadLimitedNumbers() { @@ -482,23 +480,6 @@ public class CatalogManager { } } - private void loadCalendarRewards() { - synchronized (this.calendarRewards) { - this.calendarRewards.clear(); - - try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM calendar_rewards")) { - try (ResultSet set = statement.executeQuery()) { - while (set.next()) { - this.calendarRewards.put(set.getInt("id"), new CalendarRewardObject(set)); - } - } - } catch (SQLException e) { - LOGGER.error("Caught SQL exception", e); - } - } - } - - private void loadClothing() { synchronized (this.clothing) { this.clothing.clear(); @@ -1167,28 +1148,6 @@ public class CatalogManager { return offers; } - public void claimCalendarReward(Habbo habbo, int day, boolean force) { - if (!habbo.getHabboStats().calendarRewardsClaimed.contains(day)) { - CalendarRewardObject object = this.calendarRewards.get((day+1)); - int actualDay = (int) Math.floor((Emulator.getIntUnixTimestamp() - Emulator.getConfig().getInt("hotel.calendar.starttimestamp")) / 86400); - int diff = (actualDay - day); - if (((diff <= 2 && diff >= 0) || force) && object != null) { - habbo.getHabboStats().calendarRewardsClaimed.add(day); - habbo.getClient().sendResponse(new AdventCalendarProductComposer(true, object)); - object.give(habbo); - - try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO calendar_rewards_claimed (user_id, reward_id, timestamp) VALUES (?, ?, ?)")) { - statement.setInt(1, habbo.getHabboInfo().getId()); - statement.setInt(2, day); - statement.setInt(3, Emulator.getIntUnixTimestamp()); - statement.execute(); - } catch (SQLException e) { - LOGGER.error("Caught SQL exception", e); - } - } - } - } - public TargetOffer getTargetOffer(int offerId) { return this.targetOffers.get(offerId); } diff --git a/src/main/java/com/eu/habbo/habbohotel/commands/CalendarCommand.java b/src/main/java/com/eu/habbo/habbohotel/commands/CalendarCommand.java index 5d996740..ea9d3c69 100644 --- a/src/main/java/com/eu/habbo/habbohotel/commands/CalendarCommand.java +++ b/src/main/java/com/eu/habbo/habbohotel/commands/CalendarCommand.java @@ -1,10 +1,17 @@ package com.eu.habbo.habbohotel.commands; import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarCampaign; import com.eu.habbo.habbohotel.gameclients.GameClient; import com.eu.habbo.messages.outgoing.events.calendar.AdventCalendarDataComposer; import com.eu.habbo.messages.outgoing.habboway.nux.NuxAlertComposer; +import java.sql.Timestamp; +import java.time.Duration; +import java.util.Date; + +import static java.time.temporal.ChronoUnit.DAYS; + public class CalendarCommand extends Command { public CalendarCommand() { super("cmd_calendar", Emulator.getTexts().getValue("commands.keys.cmd_calendar").split(";")); @@ -13,8 +20,17 @@ public class CalendarCommand extends Command { @Override public boolean handle(GameClient gameClient, String[] params) throws Exception { if (Emulator.getConfig().getBoolean("hotel.calendar.enabled")) { - gameClient.sendResponse(new AdventCalendarDataComposer("xmas11", Emulator.getGameEnvironment().getCatalogManager().calendarRewards.size(), (int) Math.floor((Emulator.getIntUnixTimestamp() - Emulator.getConfig().getInt("hotel.calendar.starttimestamp")) / 86400), gameClient.getHabbo().getHabboStats().calendarRewardsClaimed, true)); - gameClient.sendResponse(new NuxAlertComposer("openView/calendar")); + String campaignName = Emulator.getConfig().getValue("hotel.calendar.default"); + + if(params.length > 1 && gameClient.getHabbo().hasPermission("cmd_calendar_staff")) { + campaignName = params[1]; + } + CalendarCampaign campaign = Emulator.getGameEnvironment().getCalendarManager().getCalendarCampaign(campaignName); + if(campaign == null) return false; + int daysBetween = (int) DAYS.between(campaign.getStartTimestamp().toInstant(), new Date().toInstant()); + if(daysBetween >= 0) { + gameClient.sendResponse(new AdventCalendarDataComposer(campaign.getName(), campaign.getImage(), campaign.getTotalDays(), daysBetween, gameClient.getHabbo().getHabboStats().calendarRewardsClaimed, campaign.getLockExpired())); + } } return true; diff --git a/src/main/java/com/eu/habbo/habbohotel/commands/CommandHandler.java b/src/main/java/com/eu/habbo/habbohotel/commands/CommandHandler.java index a37d9482..64dd09d8 100644 --- a/src/main/java/com/eu/habbo/habbohotel/commands/CommandHandler.java +++ b/src/main/java/com/eu/habbo/habbohotel/commands/CommandHandler.java @@ -275,6 +275,7 @@ public class CommandHandler { addCommand(new UnmuteCommand()); addCommand(new UpdateAchievements()); addCommand(new UpdateBotsCommand()); + addCommand(new UpdateCalendarCommand()); addCommand(new UpdateCatalogCommand()); addCommand(new UpdateConfigCommand()); addCommand(new UpdateGuildPartsCommand()); diff --git a/src/main/java/com/eu/habbo/habbohotel/commands/UpdateCalendarCommand.java b/src/main/java/com/eu/habbo/habbohotel/commands/UpdateCalendarCommand.java new file mode 100644 index 00000000..a110c20b --- /dev/null +++ b/src/main/java/com/eu/habbo/habbohotel/commands/UpdateCalendarCommand.java @@ -0,0 +1,21 @@ +package com.eu.habbo.habbohotel.commands; + +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; +import com.eu.habbo.habbohotel.rooms.RoomChatMessageBubbles; +import com.eu.habbo.messages.outgoing.catalog.*; +import com.eu.habbo.messages.outgoing.catalog.marketplace.MarketplaceConfigComposer; + +public class UpdateCalendarCommand extends Command { + + public UpdateCalendarCommand() { + super("cmd_update_calendar", Emulator.getTexts().getValue("commands.keys.cmd_update_calendar").split(";")); + } + + @Override + public boolean handle(GameClient gameClient, String[] params) { + Emulator.getGameEnvironment().getCalendarManager().reload(); + gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.success.cmd_update_calendar"), RoomChatMessageBubbles.ALERT); + return true; + } +} diff --git a/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java b/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java index 75808977..462af849 100644 --- a/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java +++ b/src/main/java/com/eu/habbo/habbohotel/users/HabboStats.java @@ -1,6 +1,7 @@ package com.eu.habbo.habbohotel.users; import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarRewardClaimed; import com.eu.habbo.habbohotel.gameclients.GameClient; import com.eu.habbo.habbohotel.achievements.Achievement; import com.eu.habbo.habbohotel.achievements.AchievementManager; @@ -33,7 +34,7 @@ public class HabboStats implements Runnable { public final TIntArrayList secretRecipes; public final HabboNavigatorWindowSettings navigatorWindowSettings; public final THashMap cache; - public final TIntArrayList calendarRewardsClaimed; + public final ArrayList calendarRewardsClaimed; public final TIntObjectMap offerCache = new TIntObjectHashMap<>(); private final AtomicInteger lastOnlineTime = new AtomicInteger(Emulator.getIntUnixTimestamp()); private final THashMap achievementProgress; @@ -109,7 +110,7 @@ public class HabboStats implements Runnable { this.ignoredUsers = new TIntArrayList(0); this.roomsVists = new TIntArrayList(0); this.secretRecipes = new TIntArrayList(0); - this.calendarRewardsClaimed = new TIntArrayList(0); + this.calendarRewardsClaimed = new ArrayList<>(); this.habboInfo = habboInfo; @@ -206,7 +207,7 @@ public class HabboStats implements Runnable { calendarRewardsStatement.setInt(1, this.habboInfo.getId()); try (ResultSet rewardSet = calendarRewardsStatement.executeQuery()) { while (rewardSet.next()) { - this.calendarRewardsClaimed.add(rewardSet.getInt("reward_id")); + this.calendarRewardsClaimed.add(new CalendarRewardClaimed(rewardSet)); } } } diff --git a/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarForceOpenEvent.java b/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarForceOpenEvent.java index 1ab77c2c..bca8c1de 100644 --- a/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarForceOpenEvent.java +++ b/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarForceOpenEvent.java @@ -6,9 +6,9 @@ import com.eu.habbo.messages.incoming.MessageHandler; public class AdventCalendarForceOpenEvent extends MessageHandler { @Override public void handle() throws Exception { - String campaign = this.packet.readString(); + String campaignName = this.packet.readString(); int day = this.packet.readInt(); - Emulator.getGameEnvironment().getCatalogManager().claimCalendarReward(this.client.getHabbo(), day, true); + Emulator.getGameEnvironment().getCalendarManager().claimCalendarReward(this.client.getHabbo(), campaignName, day, true); } } \ No newline at end of file diff --git a/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarOpenDayEvent.java b/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarOpenDayEvent.java index 9c68cfd0..58970271 100644 --- a/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarOpenDayEvent.java +++ b/src/main/java/com/eu/habbo/messages/incoming/events/calendar/AdventCalendarOpenDayEvent.java @@ -6,9 +6,9 @@ import com.eu.habbo.messages.incoming.MessageHandler; public class AdventCalendarOpenDayEvent extends MessageHandler { @Override public void handle() throws Exception { - String campaign = this.packet.readString(); + String campaignName = this.packet.readString(); int day = this.packet.readInt(); - Emulator.getGameEnvironment().getCatalogManager().claimCalendarReward(this.client.getHabbo(), day, false); + Emulator.getGameEnvironment().getCalendarManager().claimCalendarReward(this.client.getHabbo(), campaignName, day, false); } } \ No newline at end of file diff --git a/src/main/java/com/eu/habbo/messages/incoming/handshake/UsernameEvent.java b/src/main/java/com/eu/habbo/messages/incoming/handshake/UsernameEvent.java index aa4d946f..3636c6c0 100644 --- a/src/main/java/com/eu/habbo/messages/incoming/handshake/UsernameEvent.java +++ b/src/main/java/com/eu/habbo/messages/incoming/handshake/UsernameEvent.java @@ -2,6 +2,7 @@ package com.eu.habbo.messages.incoming.handshake; import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.achievements.AchievementManager; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarCampaign; import com.eu.habbo.habbohotel.catalog.TargetOffer; import com.eu.habbo.messages.incoming.MessageHandler; import com.eu.habbo.messages.outgoing.catalog.TargetedOfferComposer; @@ -11,9 +12,14 @@ import com.eu.habbo.messages.outgoing.habboway.nux.NuxAlertComposer; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.Timestamp; +import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.Calendar; import java.util.Date; +import java.util.concurrent.TimeUnit; + +import static java.time.temporal.ChronoUnit.DAYS; public class UsernameEvent extends MessageHandler { @Override @@ -24,7 +30,7 @@ public class UsernameEvent extends MessageHandler { calendar = true; } else { - long daysBetween = ChronoUnit.DAYS.between(new Date((long) this.client.getHabbo().getHabboInfo().getLastOnline() * 1000L).toInstant(), new Date().toInstant()); + long daysBetween = DAYS.between(new Date((long) this.client.getHabbo().getHabboInfo().getLastOnline() * 1000L).toInstant(), new Date().toInstant()); Date lastLogin = new Date(this.client.getHabbo().getHabboInfo().getLastOnline()); @@ -84,8 +90,14 @@ public class UsernameEvent extends MessageHandler { } if (Emulator.getConfig().getBoolean("hotel.calendar.enabled")) { - this.client.sendResponse(new AdventCalendarDataComposer("xmas15", Emulator.getGameEnvironment().getCatalogManager().calendarRewards.size(), (int) Math.floor((Emulator.getIntUnixTimestamp() - Emulator.getConfig().getInt("hotel.calendar.starttimestamp")) / 86400), this.client.getHabbo().getHabboStats().calendarRewardsClaimed, true)); - this.client.sendResponse(new NuxAlertComposer("openView/calendar")); + CalendarCampaign campaign = Emulator.getGameEnvironment().getCalendarManager().getCalendarCampaign(Emulator.getConfig().getValue("hotel.calendar.default")); + if(campaign != null){ + long daysBetween = DAYS.between(campaign.getStartTimestamp().toInstant(), new Date().toInstant()); + if(daysBetween >= 0) { + this.client.sendResponse(new AdventCalendarDataComposer(campaign.getName(), campaign.getImage(), campaign.getTotalDays(), (int) daysBetween, this.client.getHabbo().getHabboStats().calendarRewardsClaimed, campaign.getLockExpired())); + this.client.sendResponse(new NuxAlertComposer("openView/calendar")); + } + }; } if (TargetOffer.ACTIVE_TARGET_OFFER_ID > 0) { diff --git a/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarDataComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarDataComposer.java index 82c512f2..abf20a7a 100644 --- a/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarDataComposer.java +++ b/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarDataComposer.java @@ -1,20 +1,24 @@ package com.eu.habbo.messages.outgoing.events.calendar; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarRewardClaimed; import com.eu.habbo.messages.ServerMessage; import com.eu.habbo.messages.outgoing.MessageComposer; import com.eu.habbo.messages.outgoing.Outgoing; import gnu.trove.list.array.TIntArrayList; -import gnu.trove.procedure.TIntProcedure; + +import java.util.ArrayList; public class AdventCalendarDataComposer extends MessageComposer { private final String eventName; + private final String campaignImage; private final int totalDays; private final int currentDay; - private final TIntArrayList unlocked; + private final ArrayList unlocked; private final boolean lockExpired; - public AdventCalendarDataComposer(String eventName, int totalDays, int currentDay, TIntArrayList unlocked, boolean lockExpired) { + public AdventCalendarDataComposer(String eventName, String campaignImage, int totalDays, int currentDay, ArrayList unlocked, boolean lockExpired) { this.eventName = eventName; + this.campaignImage = campaignImage; this.totalDays = totalDays; this.currentDay = currentDay; this.unlocked = unlocked; @@ -25,23 +29,23 @@ public class AdventCalendarDataComposer extends MessageComposer { protected ServerMessage composeInternal() { this.response.init(Outgoing.AdventCalendarDataComposer); this.response.appendString(this.eventName); - this.response.appendString(""); + this.response.appendString(this.campaignImage); this.response.appendInt(this.currentDay); this.response.appendInt(this.totalDays); this.response.appendInt(this.unlocked.size()); TIntArrayList expired = new TIntArrayList(); - for (int i = 0; i < this.totalDays; i++) { + if (this.lockExpired) { for (int i = 0; i < this.totalDays; i++) { expired.add(i); } + } expired.remove(this.currentDay); if(this.currentDay > 1) expired.remove(this.currentDay - 2); if(this.currentDay > 0) expired.remove(this.currentDay - 1); - this.unlocked.forEach(value -> { - AdventCalendarDataComposer.this.response.appendInt(value); - expired.remove(value); - return true; + this.unlocked.forEach(claimed -> { + AdventCalendarDataComposer.this.response.appendInt(claimed.getDay()); + expired.remove(claimed.getDay()); }); diff --git a/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarProductComposer.java b/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarProductComposer.java index 999eefbb..fb23b318 100644 --- a/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarProductComposer.java +++ b/src/main/java/com/eu/habbo/messages/outgoing/events/calendar/AdventCalendarProductComposer.java @@ -1,7 +1,9 @@ package com.eu.habbo.messages.outgoing.events.calendar; -import com.eu.habbo.habbohotel.catalog.CalendarRewardObject; -import com.eu.habbo.habbohotel.items.Item; +import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarManager; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarRewardObject; +import com.eu.habbo.habbohotel.users.Habbo; import com.eu.habbo.messages.ServerMessage; import com.eu.habbo.messages.outgoing.MessageComposer; import com.eu.habbo.messages.outgoing.Outgoing; @@ -9,19 +11,39 @@ import com.eu.habbo.messages.outgoing.Outgoing; public class AdventCalendarProductComposer extends MessageComposer { public final boolean visible; public final CalendarRewardObject rewardObject; + public final Habbo habbo; - public AdventCalendarProductComposer(boolean visible, CalendarRewardObject rewardObject) { + public AdventCalendarProductComposer(boolean visible, CalendarRewardObject rewardObject, Habbo habbo) { this.visible = visible; this.rewardObject = rewardObject; + this.habbo = habbo; } @Override protected ServerMessage composeInternal() { this.response.init(Outgoing.AdventCalendarProductComposer); this.response.appendBoolean(this.visible); - this.response.appendString(this.rewardObject.getItem().getName()); + + String className = ""; + String productName = this.rewardObject.getProductName() + .replace("%credits%", String.valueOf(this.rewardObject.getCredits())) + .replace("%pixels%", String.valueOf((int) (this.rewardObject.getPixels() * (habbo.getHabboStats().hasActiveClub() ? CalendarManager.HC_MODIFIER : 1.0)))) + .replace("%points%", String.valueOf(this.rewardObject.getPoints())) + .replace("%points_type%", String.valueOf(this.rewardObject.getPointsType())) + .replace("%badge%", this.rewardObject.getBadge()); + if(this.rewardObject.getSubscriptionType() != null){ + productName = productName.replace("%subscription_type%", this.rewardObject.getSubscriptionType()).replace("%subscription_days%", String.valueOf(this.rewardObject.getSubscriptionDays())); + } + + if(this.rewardObject.getItem() != null){ + productName = productName.replace("%item%", this.rewardObject.getItem().getName()); + className = this.rewardObject.getItem().getName(); + } + + this.response.appendString(productName); this.response.appendString(this.rewardObject.getCustomImage()); - this.response.appendString(this.rewardObject.getItem().getName()); + this.response.appendString(className); + return this.response; } } \ No newline at end of file diff --git a/src/main/java/com/eu/habbo/plugin/events/users/calendar/UserClaimRewardEvent.java b/src/main/java/com/eu/habbo/plugin/events/users/calendar/UserClaimRewardEvent.java new file mode 100644 index 00000000..c57f60db --- /dev/null +++ b/src/main/java/com/eu/habbo/plugin/events/users/calendar/UserClaimRewardEvent.java @@ -0,0 +1,23 @@ +package com.eu.habbo.plugin.events.users.calendar; + +import com.eu.habbo.habbohotel.campaign.calendar.CalendarCampaign; +import com.eu.habbo.habbohotel.campaign.calendar.CalendarRewardObject; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.plugin.events.users.UserEvent; + +public class UserClaimRewardEvent extends UserEvent { + + public CalendarCampaign campaign; + public int day; + public CalendarRewardObject reward; + public boolean force; + + public UserClaimRewardEvent(Habbo habbo, CalendarCampaign campaign, int day, CalendarRewardObject reward, boolean force) { + super(habbo); + + this.campaign = campaign; + this.day = day; + this.reward = reward; + this.force = force; + } +}