You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-19 15:06:19 +00:00
🆙 Update Rare-Value page
This commit is contained in:
@@ -202,8 +202,8 @@ public class CatalogManager {
|
||||
public final Item ecotronItem;
|
||||
public final THashMap<Integer, CatalogLimitedConfiguration> limitedNumbers;
|
||||
private final List<Voucher> vouchers;
|
||||
// spriteId -> [credits, points, pointsType], derived from catalog_items (see loadFurnitureValues)
|
||||
public final TIntObjectMap<int[]> furnitureValues;
|
||||
private volatile byte[] rareValuesPayloadCache;
|
||||
|
||||
public CatalogManager() {
|
||||
long millis = System.currentTimeMillis();
|
||||
@@ -249,10 +249,6 @@ public class CatalogManager {
|
||||
this.loadFurnitureValues();
|
||||
}
|
||||
|
||||
// Builds spriteId -> [credits, points, pointsType] from catalog_items so the
|
||||
// client can show a furni's "value" (toolbar price guide + infostand line).
|
||||
// Only single-item, single-amount FLOOR/WALL sales are considered, so bundles
|
||||
// and multi-packs don't pollute the per-rare price. First clean entry wins.
|
||||
private synchronized void loadFurnitureValues() {
|
||||
this.furnitureValues.clear();
|
||||
final int diamondType = Emulator.getConfig().getInt("seasonal.currency.diamond", 5);
|
||||
@@ -266,8 +262,6 @@ public class CatalogManager {
|
||||
int points = catalogItem.getPoints();
|
||||
int pointsType = catalogItem.getPointsType();
|
||||
|
||||
// Only diamond-priced items — both the "Valore Rari" panel and the
|
||||
// infostand value line show diamonds only.
|
||||
if (points <= 0 || pointsType != diamondType)
|
||||
continue;
|
||||
|
||||
@@ -291,13 +285,39 @@ public class CatalogManager {
|
||||
}
|
||||
}
|
||||
|
||||
this.rebuildRareValuesPayloadCache();
|
||||
|
||||
LOGGER.info("Furniture Values -> Loaded! ({} entries)", this.furnitureValues.size());
|
||||
}
|
||||
|
||||
private void rebuildRareValuesPayloadCache() {
|
||||
try (java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream(this.furnitureValues.size() * 16 + 8);
|
||||
java.io.DataOutputStream out = new java.io.DataOutputStream(baos)) {
|
||||
out.writeInt(this.furnitureValues.size());
|
||||
TIntObjectIterator<int[]> iterator = this.furnitureValues.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
iterator.advance();
|
||||
int[] value = iterator.value();
|
||||
out.writeInt(iterator.key()); // spriteId
|
||||
out.writeInt(value[0]); // credits
|
||||
out.writeInt(value[1]); // points
|
||||
out.writeInt(value[2]); // pointsType
|
||||
}
|
||||
this.rareValuesPayloadCache = baos.toByteArray();
|
||||
} catch (java.io.IOException e) {
|
||||
LOGGER.error("Failed to build rare values payload cache", e);
|
||||
this.rareValuesPayloadCache = null;
|
||||
}
|
||||
}
|
||||
|
||||
public TIntObjectMap<int[]> getFurnitureValues() {
|
||||
return this.furnitureValues;
|
||||
}
|
||||
|
||||
public byte[] getRareValuesPayloadSnapshot() {
|
||||
return this.rareValuesPayloadCache;
|
||||
}
|
||||
|
||||
private synchronized void loadLimitedNumbers() {
|
||||
this.limitedNumbers.clear();
|
||||
|
||||
@@ -1104,9 +1124,6 @@ public class CatalogManager {
|
||||
type = type.replace("bot_", "");
|
||||
type = type.replace("visitor_logger", "visitor_log");
|
||||
|
||||
// Permission gate keyed on the canonical base-item name
|
||||
// (admin-controlled but stable), not the catalog page name
|
||||
// which can be renamed and bypass the check.
|
||||
if (("bot_" + com.eu.habbo.habbohotel.bots.FrankBot.BOT_TYPE).equals(baseName)
|
||||
|| ("rentable_bot_" + com.eu.habbo.habbohotel.bots.FrankBot.BOT_TYPE).equals(baseName)) {
|
||||
if (!habbo.getClient().getHabbo().hasPermission(com.eu.habbo.habbohotel.bots.FrankBot.PERMISSION_USE)) {
|
||||
|
||||
+11
-5
@@ -1,11 +1,10 @@
|
||||
package com.eu.habbo.messages.incoming.rarevalues;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.catalog.CatalogManager;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.rarevalues.RareValuesComposer;
|
||||
|
||||
// Client requests the furni value map once on load. Public info (catalog prices),
|
||||
// no permission gate. Rate limited since the payload is large.
|
||||
public class RequestRareValuesEvent extends MessageHandler {
|
||||
@Override
|
||||
public int getRatelimit() {
|
||||
@@ -14,8 +13,15 @@ public class RequestRareValuesEvent extends MessageHandler {
|
||||
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
this.client.sendResponse(new RareValuesComposer(
|
||||
Emulator.getGameEnvironment().getCatalogManager().getFurnitureValues()
|
||||
));
|
||||
if (this.client.getHabbo() == null) return;
|
||||
|
||||
CatalogManager catalog = Emulator.getGameEnvironment().getCatalogManager();
|
||||
byte[] snapshot = catalog.getRareValuesPayloadSnapshot();
|
||||
if (snapshot != null) {
|
||||
this.client.sendResponse(new RareValuesComposer(snapshot));
|
||||
return;
|
||||
}
|
||||
|
||||
this.client.sendResponse(new RareValuesComposer(catalog.getFurnitureValues()));
|
||||
}
|
||||
}
|
||||
|
||||
+13
-2
@@ -6,18 +6,29 @@ import com.eu.habbo.messages.outgoing.Outgoing;
|
||||
import gnu.trove.iterator.TIntObjectIterator;
|
||||
import gnu.trove.map.TIntObjectMap;
|
||||
|
||||
// Sends the full spriteId -> value map to the client. Consumed by the toolbar
|
||||
// price guide and the furni infostand "value" line. See CatalogManager#loadFurnitureValues.
|
||||
public class RareValuesComposer extends MessageComposer {
|
||||
private final TIntObjectMap<int[]> values;
|
||||
private final byte[] snapshot;
|
||||
|
||||
public RareValuesComposer(byte[] snapshot) {
|
||||
this.values = null;
|
||||
this.snapshot = snapshot;
|
||||
}
|
||||
|
||||
public RareValuesComposer(TIntObjectMap<int[]> values) {
|
||||
this.values = values;
|
||||
this.snapshot = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServerMessage composeInternal() {
|
||||
this.response.init(Outgoing.RareValuesComposer);
|
||||
|
||||
if (this.snapshot != null) {
|
||||
this.response.appendRawBytes(this.snapshot);
|
||||
return this.response;
|
||||
}
|
||||
|
||||
this.response.appendInt(this.values.size());
|
||||
|
||||
TIntObjectIterator<int[]> iterator = this.values.iterator();
|
||||
|
||||
+14
@@ -11,6 +11,7 @@ import io.netty.handler.codec.DecoderException;
|
||||
import io.netty.handler.codec.TooLongFrameException;
|
||||
import io.netty.handler.codec.UnsupportedMessageTypeException;
|
||||
import io.netty.handler.ssl.NotSslRecordException;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -39,6 +40,19 @@ public class GameMessageHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
if (!(msg instanceof ClientMessage)) {
|
||||
try {
|
||||
if (Emulator.getConfig().getBoolean("debug.mode")) {
|
||||
LOGGER.debug("Discarding non-game message {} from {}",
|
||||
msg.getClass().getSimpleName(), ctx.channel().remoteAddress());
|
||||
}
|
||||
} finally {
|
||||
ReferenceCountUtil.release(msg);
|
||||
ctx.channel().close();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ClientMessage message = (ClientMessage) msg;
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user