mirror of
https://git.krews.org/morningstar/Arcturus-Community.git
synced 2024-06-30 12:45:34 +02:00
434 lines
19 KiB
Java
434 lines
19 KiB
Java
package com.eu.habbo.habbohotel.users.subscriptions;
|
|
|
|
import com.eu.habbo.Emulator;
|
|
import com.eu.habbo.database.Database;
|
|
import com.eu.habbo.habbohotel.achievements.Achievement;
|
|
import com.eu.habbo.habbohotel.achievements.AchievementManager;
|
|
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.HabboStats;
|
|
import com.eu.habbo.habbohotel.users.clothingvalidation.ClothingValidationManager;
|
|
import com.eu.habbo.messages.outgoing.catalog.ClubCenterDataComposer;
|
|
import com.eu.habbo.messages.outgoing.generic.PickMonthlyClubGiftNotificationComposer;
|
|
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserDataComposer;
|
|
import com.eu.habbo.messages.outgoing.users.*;
|
|
import gnu.trove.map.hash.THashMap;
|
|
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.text.SimpleDateFormat;
|
|
import java.util.Date;
|
|
import java.util.Map;
|
|
import java.util.TreeMap;
|
|
|
|
/**
|
|
* @author Beny
|
|
*/
|
|
public class SubscriptionHabboClub extends Subscription {
|
|
private static final Logger LOGGER = LoggerFactory.getLogger(SubscriptionHabboClub.class);
|
|
|
|
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;
|
|
public static String ACHIEVEMENT_NAME = "";
|
|
public static boolean DISCOUNT_ENABLED = false;
|
|
public static int DISCOUNT_DAYS_BEFORE_END = 7;
|
|
|
|
/**
|
|
* 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();
|
|
|
|
HabboInfo habboInfo = Emulator.getGameEnvironment().getHabboManager().getHabboInfo(this.getUserId());
|
|
HabboStats stats = habboInfo.getHabboStats();
|
|
|
|
stats.maxFriends = Messenger.MAXIMUM_FRIENDS_HC;
|
|
stats.maxRooms = RoomManager.MAXIMUM_ROOMS_HC;
|
|
stats.lastHCPayday = HC_PAYDAY_COINSSPENT_RESET_ON_EXPIRE ? Emulator.getIntUnixTimestamp() : HC_PAYDAY_NEXT_DATE - Emulator.timeStringToSeconds(HC_PAYDAY_INTERVAL);
|
|
Emulator.getThreading().run(stats);
|
|
|
|
progressAchievement(habboInfo);
|
|
|
|
Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(this.getUserId());
|
|
if (habbo != null && habbo.getClient() != null) {
|
|
|
|
if (habbo.getHabboStats().getRemainingClubGifts() > 0) {
|
|
habbo.getClient().sendResponse(new PickMonthlyClubGiftNotificationComposer(habbo.getHabboStats().getRemainingClubGifts()));
|
|
}
|
|
|
|
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, SubscriptionHabboClub.HABBO_CLUB, UserClubComposer.RESPONSE_TYPE_NORMAL));
|
|
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, SubscriptionHabboClub.HABBO_CLUB, UserClubComposer.RESPONSE_TYPE_NORMAL));
|
|
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 != null && habbo.getClient() != null) {
|
|
habbo.getClient().sendResponse(new UserClubComposer(habbo, SubscriptionHabboClub.HABBO_CLUB, UserClubComposer.RESPONSE_TYPE_NORMAL));
|
|
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());
|
|
HabboInfo habboInfo = Emulator.getGameEnvironment().getHabboManager().getHabboInfo(this.getUserId());
|
|
HabboStats stats = habboInfo.getHabboStats();
|
|
|
|
stats.maxFriends = Messenger.MAXIMUM_FRIENDS;
|
|
stats.maxRooms = RoomManager.MAXIMUM_ROOMS_USER;
|
|
Emulator.getThreading().run(stats);
|
|
|
|
if (habbo != null && ClothingValidationManager.VALIDATE_ON_HC_EXPIRE) {
|
|
habboInfo.setLook(ClothingValidationManager.validateLook(habbo, habboInfo.getLook(), habboInfo.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 != null && habbo.getClient() != null) {
|
|
habbo.getClient().sendResponse(new UserClubComposer(habbo, SubscriptionHabboClub.HABBO_CLUB, UserClubComposer.RESPONSE_TYPE_NORMAL));
|
|
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);
|
|
HabboStats stats = habboInfo.getHabboStats();
|
|
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);
|
|
}
|
|
stats.lastHCPayday = timestampNow;
|
|
Emulator.getThreading().run(stats);
|
|
} 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) {
|
|
|
|
progressAchievement(habbo.getHabboInfo());
|
|
|
|
if (habbo.getHabboStats().getRemainingClubGifts() > 0) {
|
|
habbo.getClient().sendResponse(new PickMonthlyClubGiftNotificationComposer(habbo.getHabboStats().getRemainingClubGifts()));
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Seperated these because Beny shouldn't have tied them to Payday.
|
|
*/
|
|
public static void processClubBadge(Habbo habbo) {
|
|
progressAchievement(habbo.getHabboInfo());
|
|
}
|
|
|
|
/**
|
|
* 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().giveCredits(amount);
|
|
break;
|
|
|
|
case "diamonds":
|
|
case "diamond":
|
|
pointCurrency = 5;
|
|
habbo.getClient().getHabbo().givePoints(pointCurrency, amount);
|
|
break;
|
|
|
|
case "duckets":
|
|
case "ducket":
|
|
case "pixels":
|
|
case "pixel":
|
|
pointCurrency = 0;
|
|
habbo.getClient().getHabbo().givePoints(pointCurrency, amount);
|
|
break;
|
|
|
|
default:
|
|
pointCurrency = -1;
|
|
try {
|
|
pointCurrency = Integer.parseInt(currency);
|
|
}
|
|
catch (NumberFormatException ex) {
|
|
LOGGER.error("Couldn't convert the type point currency {} on HC PayDay. The number must be a integer and positive.", pointCurrency);
|
|
}
|
|
|
|
if (pointCurrency >= 0) {
|
|
habbo.getClient().getHabbo().givePoints(pointCurrency, amount);
|
|
}
|
|
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;
|
|
}
|
|
|
|
private static void progressAchievement(HabboInfo habboInfo) {
|
|
HabboStats stats = habboInfo.getHabboStats();
|
|
Achievement achievement = Emulator.getGameEnvironment().getAchievementManager().getAchievement(ACHIEVEMENT_NAME);
|
|
if(achievement != null) {
|
|
int currentProgress = stats.getAchievementProgress(achievement);
|
|
if(currentProgress == -1) {
|
|
currentProgress = 0;
|
|
}
|
|
|
|
int progressToSet = (int)Math.ceil(stats.getPastTimeAsClub() / 2678400.0);
|
|
int toIncrease = Math.max(progressToSet - currentProgress, 0);
|
|
|
|
if(toIncrease > 0) {
|
|
AchievementManager.progressAchievement(habboInfo.getId(), achievement, toIncrease);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|