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 { protected int id; protected int pageId; protected String itemId; protected String name; protected int credits; protected int points; protected short pointsType; protected int amount; protected boolean allowGift = false; protected int limitedStack; protected int limitedSells; protected String extradata; protected boolean clubOnly; protected boolean haveOffer; protected int offerId; protected boolean needsUpdate; protected HashMap bundle; public CatalogItem(ResultSet set) throws SQLException { this.load(set); this.needsUpdate = false; } 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.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; } 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 = Integer.parseInt(itemId); 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 " + itemId); e.printStackTrace(); } } 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.appendInt32(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) { return this.getId() - catalogItem.getId(); } private static boolean haveOffer(CatalogItem item) { if(!item.haveOffer) 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; } if(item.getName().toLowerCase().startsWith("cf_") || item.getName().toLowerCase().startsWith("cfc_")) return false; if(item.isLimited()) return false; if(item.getName().toLowerCase().startsWith("rentable_bot_")) return false; if(item.getAmount() != 1) return false; return item.bundle.size() <= 1; } }