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 Item ecotronItem;
|
||||||
public final THashMap<Integer, CatalogLimitedConfiguration> limitedNumbers;
|
public final THashMap<Integer, CatalogLimitedConfiguration> limitedNumbers;
|
||||||
private final List<Voucher> vouchers;
|
private final List<Voucher> vouchers;
|
||||||
// spriteId -> [credits, points, pointsType], derived from catalog_items (see loadFurnitureValues)
|
|
||||||
public final TIntObjectMap<int[]> furnitureValues;
|
public final TIntObjectMap<int[]> furnitureValues;
|
||||||
|
private volatile byte[] rareValuesPayloadCache;
|
||||||
|
|
||||||
public CatalogManager() {
|
public CatalogManager() {
|
||||||
long millis = System.currentTimeMillis();
|
long millis = System.currentTimeMillis();
|
||||||
@@ -249,10 +249,6 @@ public class CatalogManager {
|
|||||||
this.loadFurnitureValues();
|
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() {
|
private synchronized void loadFurnitureValues() {
|
||||||
this.furnitureValues.clear();
|
this.furnitureValues.clear();
|
||||||
final int diamondType = Emulator.getConfig().getInt("seasonal.currency.diamond", 5);
|
final int diamondType = Emulator.getConfig().getInt("seasonal.currency.diamond", 5);
|
||||||
@@ -266,8 +262,6 @@ public class CatalogManager {
|
|||||||
int points = catalogItem.getPoints();
|
int points = catalogItem.getPoints();
|
||||||
int pointsType = catalogItem.getPointsType();
|
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)
|
if (points <= 0 || pointsType != diamondType)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -291,13 +285,39 @@ public class CatalogManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.rebuildRareValuesPayloadCache();
|
||||||
|
|
||||||
LOGGER.info("Furniture Values -> Loaded! ({} entries)", this.furnitureValues.size());
|
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() {
|
public TIntObjectMap<int[]> getFurnitureValues() {
|
||||||
return this.furnitureValues;
|
return this.furnitureValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] getRareValuesPayloadSnapshot() {
|
||||||
|
return this.rareValuesPayloadCache;
|
||||||
|
}
|
||||||
|
|
||||||
private synchronized void loadLimitedNumbers() {
|
private synchronized void loadLimitedNumbers() {
|
||||||
this.limitedNumbers.clear();
|
this.limitedNumbers.clear();
|
||||||
|
|
||||||
@@ -1104,9 +1124,6 @@ public class CatalogManager {
|
|||||||
type = type.replace("bot_", "");
|
type = type.replace("bot_", "");
|
||||||
type = type.replace("visitor_logger", "visitor_log");
|
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)
|
if (("bot_" + com.eu.habbo.habbohotel.bots.FrankBot.BOT_TYPE).equals(baseName)
|
||||||
|| ("rentable_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)) {
|
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;
|
package com.eu.habbo.messages.incoming.rarevalues;
|
||||||
|
|
||||||
import com.eu.habbo.Emulator;
|
import com.eu.habbo.Emulator;
|
||||||
|
import com.eu.habbo.habbohotel.catalog.CatalogManager;
|
||||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||||
import com.eu.habbo.messages.outgoing.rarevalues.RareValuesComposer;
|
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 {
|
public class RequestRareValuesEvent extends MessageHandler {
|
||||||
@Override
|
@Override
|
||||||
public int getRatelimit() {
|
public int getRatelimit() {
|
||||||
@@ -14,8 +13,15 @@ public class RequestRareValuesEvent extends MessageHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle() throws Exception {
|
public void handle() throws Exception {
|
||||||
this.client.sendResponse(new RareValuesComposer(
|
if (this.client.getHabbo() == null) return;
|
||||||
Emulator.getGameEnvironment().getCatalogManager().getFurnitureValues()
|
|
||||||
));
|
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.iterator.TIntObjectIterator;
|
||||||
import gnu.trove.map.TIntObjectMap;
|
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 {
|
public class RareValuesComposer extends MessageComposer {
|
||||||
private final TIntObjectMap<int[]> values;
|
private final TIntObjectMap<int[]> values;
|
||||||
|
private final byte[] snapshot;
|
||||||
|
|
||||||
|
public RareValuesComposer(byte[] snapshot) {
|
||||||
|
this.values = null;
|
||||||
|
this.snapshot = snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
public RareValuesComposer(TIntObjectMap<int[]> values) {
|
public RareValuesComposer(TIntObjectMap<int[]> values) {
|
||||||
this.values = values;
|
this.values = values;
|
||||||
|
this.snapshot = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ServerMessage composeInternal() {
|
protected ServerMessage composeInternal() {
|
||||||
this.response.init(Outgoing.RareValuesComposer);
|
this.response.init(Outgoing.RareValuesComposer);
|
||||||
|
|
||||||
|
if (this.snapshot != null) {
|
||||||
|
this.response.appendRawBytes(this.snapshot);
|
||||||
|
return this.response;
|
||||||
|
}
|
||||||
|
|
||||||
this.response.appendInt(this.values.size());
|
this.response.appendInt(this.values.size());
|
||||||
|
|
||||||
TIntObjectIterator<int[]> iterator = this.values.iterator();
|
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.TooLongFrameException;
|
||||||
import io.netty.handler.codec.UnsupportedMessageTypeException;
|
import io.netty.handler.codec.UnsupportedMessageTypeException;
|
||||||
import io.netty.handler.ssl.NotSslRecordException;
|
import io.netty.handler.ssl.NotSslRecordException;
|
||||||
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -39,6 +40,19 @@ public class GameMessageHandler extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
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;
|
ClientMessage message = (ClientMessage) msg;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user