package com.eu.habbo.habbohotel.catalog; import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.items.FurnitureType; import com.eu.habbo.habbohotel.items.Item; import com.eu.habbo.messages.ISerialize; import com.eu.habbo.messages.ServerMessage; import gnu.trove.set.hash.THashSet; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; public class CatalogItem implements ISerialize, Runnable, Comparable { int id; int limitedStack; private int pageId; private String itemId; private String name; private int credits; private int points; private short pointsType; private int amount; private boolean allowGift = false; private int limitedSells; private String extradata; private boolean clubOnly; private boolean haveOffer; private int offerId; private boolean needsUpdate; private int orderNumber; private HashMap bundle; public CatalogItem(ResultSet set) throws SQLException { this.load(set); this.needsUpdate = false; } public static boolean haveOffer(CatalogItem item) { if (!item.haveOffer) return false; if (item.getAmount() != 1) return false; if (item.isLimited()) return false; if (item.bundle.size() > 1) return false; if (item.getName().toLowerCase().startsWith("cf_") || item.getName().toLowerCase().startsWith("cfc_")) return false; for (Item i : item.getBaseItems()) { if (i.getName().toLowerCase().startsWith("cf_") || i.getName().toLowerCase().startsWith("cfc_") || i.getName().toLowerCase().startsWith("rentable_bot")) return false; } return !item.getName().toLowerCase().startsWith("rentable_bot_"); } public void update(ResultSet set) throws SQLException { this.load(set); } private void load(ResultSet set) throws SQLException { this.id = set.getInt("id"); this.pageId = set.getInt("page_id"); this.itemId = set.getString("item_Ids"); this.name = set.getString("catalog_name"); this.credits = set.getInt("cost_credits"); this.points = set.getInt("cost_points"); this.pointsType = set.getShort("points_type"); this.amount = set.getInt("amount"); this.limitedStack = set.getInt("limited_stack"); this.limitedSells = set.getInt("limited_sells"); this.extradata = set.getString("extradata"); this.clubOnly = set.getBoolean("club_only"); this.haveOffer = set.getBoolean("have_offer"); this.offerId = set.getInt("offer_id"); this.orderNumber = set.getInt("order_number"); this.bundle = new HashMap<>(); this.loadBundle(); } public int getId() { return this.id; } public int getPageId() { return this.pageId; } public void setPageId(int pageId) { this.pageId = pageId; } public String getItemId() { return this.itemId; } public void setItemId(String itemId) { this.itemId = itemId; } public String getName() { return this.name; } public int getCredits() { return this.credits; } public int getPoints() { return this.points; } public int getPointsType() { return this.pointsType; } public int getAmount() { return this.amount; } public int getLimitedStack() { return this.limitedStack; } public int getLimitedSells() { CatalogLimitedConfiguration ltdConfig = Emulator.getGameEnvironment().getCatalogManager().getLimitedConfig(this); if (ltdConfig != null) { return this.limitedStack - ltdConfig.available(); } return this.limitedStack; } public String getExtradata() { return this.extradata; } public boolean isClubOnly() { return this.clubOnly; } public boolean isHaveOffer() { return this.haveOffer; } public int getOfferId() { return this.offerId; } public boolean isLimited() { return this.limitedStack > 0; } private int getOrderNumber() { return this.orderNumber; } public synchronized void sellRare() { this.limitedSells++; this.needsUpdate = true; if (this.limitedSells == this.limitedStack) { Emulator.getGameEnvironment().getCatalogManager().moveCatalogItem(this, Emulator.getConfig().getInt("catalog.ltd.page.soldout")); } Emulator.getThreading().run(this); } public THashSet getBaseItems() { THashSet items = new THashSet<>(); if (!this.itemId.isEmpty()) { String[] itemIds = this.itemId.split(";"); for (String itemId : itemIds) { if (itemId.isEmpty()) continue; if (itemId.contains(":")) { itemId = itemId.split(":")[0]; } int identifier; try { identifier = Integer.parseInt(itemId); } catch (Exception e) { Emulator.getLogging().logStart("Invalid value (" + itemId + ") for items_base column for catalog_item id (" + this.id + "). Value must be integer or of the format of integer:amount;integer:amount"); continue; } if (identifier > 0) { Item item = Emulator.getGameEnvironment().getItemManager().getItem(identifier); if (item != null) items.add(item); } } } return items; } public int getItemAmount(int id) { if (this.bundle.containsKey(id)) return this.bundle.get(id); else return this.amount; } public HashMap getBundle() { return this.bundle; } public void loadBundle() { int intItemId; if (this.itemId.contains(";")) { try { String[] itemIds = this.itemId.split(";"); for (String itemId : itemIds) { if (itemId.contains(":")) { String[] data = itemId.split(":"); if (data.length > 1 && Integer.parseInt(data[0]) > 0 && Integer.parseInt(data[1]) > 0) { this.bundle.put(Integer.parseInt(data[0]), Integer.parseInt(data[1])); } } else { if (!itemId.isEmpty()) { intItemId = (Integer.parseInt(itemId)); this.bundle.put(intItemId, 1); } } } } catch (Exception e) { Emulator.getLogging().logDebugLine("Failed to load " + this.itemId); Emulator.getLogging().logErrorLine(e); } } else { try { Item item = Emulator.getGameEnvironment().getItemManager().getItem(Integer.valueOf(this.itemId)); if (item != null) { this.allowGift = item.allowGift(); } } catch (Exception e) { } } } @Override public void serialize(ServerMessage message) { message.appendInt(this.getId()); message.appendString(this.getName()); message.appendBoolean(false); message.appendInt(this.getCredits()); message.appendInt(this.getPoints()); message.appendInt(this.getPointsType()); message.appendBoolean(this.allowGift); //Can gift THashSet items = this.getBaseItems(); message.appendInt(items.size()); for (Item item : items) { message.appendString(item.getType().code.toLowerCase()); if (item.getType() == FurnitureType.BADGE) { message.appendString(item.getName()); } else { message.appendInt(item.getSpriteId()); if (this.getName().contains("wallpaper_single") || this.getName().contains("floor_single") || this.getName().contains("landscape_single")) { message.appendString(this.getName().split("_")[2]); } else if (item.getName().contains("bot") && item.getType() == FurnitureType.ROBOT) { boolean lookFound = false; for (String s : this.getExtradata().split(";")) { if (s.startsWith("figure:")) { lookFound = true; message.appendString(s.replace("figure:", "")); break; } } if (!lookFound) { message.appendString(this.getExtradata()); } } else if (item.getType() == FurnitureType.ROBOT) { message.appendString(this.getExtradata()); } else if (item.getName().equalsIgnoreCase("poster")) { message.appendString(this.getExtradata()); } else if (this.getName().startsWith("SONG ")) { message.appendString(this.getExtradata()); } else { message.appendString(""); } message.appendInt(this.getItemAmount(item.getId())); message.appendBoolean(this.isLimited()); if (this.isLimited()) { message.appendInt(this.getLimitedStack()); message.appendInt(this.getLimitedStack() - this.getLimitedSells()); } } } message.appendInt(this.clubOnly); message.appendBoolean(haveOffer(this)); message.appendBoolean(false); //unknown message.appendString(this.name + ".png"); } @Override public void run() { if (this.needsUpdate) { try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE catalog_items SET limited_sells = ?, page_id = ? WHERE id = ?")) { statement.setInt(1, this.getLimitedSells()); statement.setInt(2, this.pageId); statement.setInt(3, this.getId()); statement.execute(); } catch (SQLException e) { Emulator.getLogging().logSQLException(e); } this.needsUpdate = false; } } @SuppressWarnings("NullableProblems") @Override public int compareTo(CatalogItem catalogItem) { if (CatalogManager.SORT_USING_ORDERNUM) { return this.getOrderNumber() - catalogItem.getOrderNumber(); } else { return this.getId() - catalogItem.getId(); } } }