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
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 585f4dd3aa | |||
| afa114d511 | |||
| 0aadd01493 | |||
| 9d98fbf9ee | |||
| b38274e134 | |||
| 02ab30180c | |||
| da63439d53 |
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>com.eu.habbo</groupId>
|
<groupId>com.eu.habbo</groupId>
|
||||||
<artifactId>Habbo</artifactId>
|
<artifactId>Habbo</artifactId>
|
||||||
<version>4.2.26</version>
|
<version>4.2.27</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
|||||||
@@ -134,7 +134,18 @@ public class RoomChatMessageBubbles {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static RoomChatMessageBubbles getBubble(int id) {
|
public static RoomChatMessageBubbles getBubble(int id) {
|
||||||
return BUBBLES.getOrDefault(id, NORMAL);
|
RoomChatMessageBubbles bubble = BUBBLES.get(id);
|
||||||
|
if (bubble != null) return bubble;
|
||||||
|
|
||||||
|
// Custom chat bubbles (client-side only, e.g. ids 253+) are not registered
|
||||||
|
// above. Instead of falling back to NORMAL (which made them render as the
|
||||||
|
// default bubble), pass the id through so the server relays it as-is and
|
||||||
|
// the client renders its own .bubble-<id> style. Capped to avoid abuse.
|
||||||
|
if (id > 0 && id <= 1000) {
|
||||||
|
return new RoomChatMessageBubbles(id, "CUSTOM_" + id, "", true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void registerBubble(RoomChatMessageBubbles bubble) {
|
private static void registerBubble(RoomChatMessageBubbles bubble) {
|
||||||
|
|||||||
@@ -12,9 +12,11 @@ import java.sql.Connection;
|
|||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.StringJoiner;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
@@ -330,26 +332,88 @@ public class WheelManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void savePrize(int id, String type, String value, int amount, int pointsType, int weight, String label) {
|
/**
|
||||||
|
* Persists a single prize. An {@code id <= 0} inserts a brand-new prize and
|
||||||
|
* returns its generated id; a positive id updates the existing row (and
|
||||||
|
* re-enables it, so a previously soft-deleted prize can be brought back).
|
||||||
|
* {@code sortOrder} reflects the prize's position in the editor so the
|
||||||
|
* wheel layout matches what the admin sees. Returns the effective row id,
|
||||||
|
* or {@code 0} if the write failed.
|
||||||
|
*/
|
||||||
|
public int savePrize(int id, String type, String value, int amount, int pointsType, int weight, String label, int sortOrder) {
|
||||||
String safeType = (type != null && VALID_PRIZE_TYPES.contains(type)) ? type : "nothing";
|
String safeType = (type != null && VALID_PRIZE_TYPES.contains(type)) ? type : "nothing";
|
||||||
String safeValue = truncate(value, MAX_STRING_LEN);
|
String safeValue = truncate(value, MAX_STRING_LEN);
|
||||||
String safeLabel = truncate(label, MAX_STRING_LEN);
|
String safeLabel = truncate(label, MAX_STRING_LEN);
|
||||||
int safeAmount = clamp(amount, 0, MAX_PRIZE_AMOUNT);
|
int safeAmount = clamp(amount, 0, MAX_PRIZE_AMOUNT);
|
||||||
int safeWeight = clamp(weight, 0, MAX_WEIGHT);
|
int safeWeight = clamp(weight, 0, MAX_WEIGHT);
|
||||||
|
int safeSort = clamp(sortOrder, 0, MAX_PRIZES_PER_SAVE);
|
||||||
|
|
||||||
|
if (id > 0) {
|
||||||
|
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||||
|
PreparedStatement statement = connection.prepareStatement(
|
||||||
|
"UPDATE wheel_prizes SET type = ?, value = ?, amount = ?, points_type = ?, weight = ?, label = ?, sort_order = ?, enabled = 1 WHERE id = ?")) {
|
||||||
|
statement.setString(1, safeType);
|
||||||
|
statement.setString(2, safeValue);
|
||||||
|
statement.setInt(3, safeAmount);
|
||||||
|
statement.setInt(4, pointsType);
|
||||||
|
statement.setInt(5, safeWeight);
|
||||||
|
statement.setString(6, safeLabel);
|
||||||
|
statement.setInt(7, safeSort);
|
||||||
|
statement.setInt(8, id);
|
||||||
|
statement.executeUpdate();
|
||||||
|
return id;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
LOGGER.error("Failed to save wheel prize {}", id, e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||||
PreparedStatement statement = connection.prepareStatement(
|
PreparedStatement statement = connection.prepareStatement(
|
||||||
"UPDATE wheel_prizes SET type = ?, value = ?, amount = ?, points_type = ?, weight = ?, label = ? WHERE id = ?")) {
|
"INSERT INTO wheel_prizes (type, value, amount, points_type, weight, label, enabled, sort_order) VALUES (?, ?, ?, ?, ?, ?, 1, ?)",
|
||||||
|
Statement.RETURN_GENERATED_KEYS)) {
|
||||||
statement.setString(1, safeType);
|
statement.setString(1, safeType);
|
||||||
statement.setString(2, safeValue);
|
statement.setString(2, safeValue);
|
||||||
statement.setInt(3, safeAmount);
|
statement.setInt(3, safeAmount);
|
||||||
statement.setInt(4, pointsType);
|
statement.setInt(4, pointsType);
|
||||||
statement.setInt(5, safeWeight);
|
statement.setInt(5, safeWeight);
|
||||||
statement.setString(6, safeLabel);
|
statement.setString(6, safeLabel);
|
||||||
statement.setInt(7, id);
|
statement.setInt(7, safeSort);
|
||||||
|
statement.executeUpdate();
|
||||||
|
|
||||||
|
try (ResultSet keys = statement.getGeneratedKeys()) {
|
||||||
|
if (keys.next()) return keys.getInt(1);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
LOGGER.error("Failed to insert wheel prize", e);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Soft-deletes every enabled prize whose id is not in {@code keptIds} by
|
||||||
|
* setting {@code enabled = 0}. This is intentionally non-destructive: rows
|
||||||
|
* stay in the table (so historical references and re-enabling remain
|
||||||
|
* possible) but {@link #loadPrizes()} only ever loads {@code enabled = 1}.
|
||||||
|
* An empty set disables all prizes.
|
||||||
|
*/
|
||||||
|
public void disablePrizesNotIn(Set<Integer> keptIds) {
|
||||||
|
if (keptIds == null) return;
|
||||||
|
|
||||||
|
StringBuilder sql = new StringBuilder("UPDATE wheel_prizes SET enabled = 0 WHERE enabled = 1");
|
||||||
|
if (!keptIds.isEmpty()) {
|
||||||
|
StringJoiner ids = new StringJoiner(",", " AND id NOT IN (", ")");
|
||||||
|
for (Integer keptId : keptIds) {
|
||||||
|
ids.add(Integer.toString(keptId));
|
||||||
|
}
|
||||||
|
sql.append(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||||
|
PreparedStatement statement = connection.prepareStatement(sql.toString())) {
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
LOGGER.error("Failed to save wheel prize {}", id, e);
|
LOGGER.error("Failed to disable removed wheel prizes", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.eu.habbo.messages.incoming.handshake;
|
package com.eu.habbo.messages.incoming.handshake;
|
||||||
|
|
||||||
|
import com.eu.habbo.Emulator;
|
||||||
import com.eu.habbo.messages.NoAuthMessage;
|
import com.eu.habbo.messages.NoAuthMessage;
|
||||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -24,6 +25,15 @@ public class MachineIDEvent extends MessageHandler {
|
|||||||
|
|
||||||
this.client.setMachineId(storedMachineId);
|
this.client.setMachineId(storedMachineId);
|
||||||
|
|
||||||
|
// Persist the machine fingerprint onto the user so machine/super bans can
|
||||||
|
// target it (createOfflineUserBan copies users.machine_id). The Nitro client
|
||||||
|
// sends this UniqueID packet right after the SSO ticket, so the Habbo is
|
||||||
|
// normally already loaded by the time we get here.
|
||||||
|
if (!storedMachineId.isEmpty() && this.client.getHabbo() != null && this.client.getHabbo().getHabboInfo() != null) {
|
||||||
|
this.client.getHabbo().getHabboInfo().setMachineID(storedMachineId);
|
||||||
|
Emulator.getThreading().run(this.client.getHabbo());
|
||||||
|
}
|
||||||
|
|
||||||
LOGGER.debug("Setting client MachineId to {}", storedMachineId);
|
LOGGER.debug("Setting client MachineId to {}", storedMachineId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,6 +161,12 @@ public class SecureLoginEvent extends MessageHandler {
|
|||||||
throw new NullPointerException(habbo.getHabboInfo().getUsername() + " has a NON EXISTING RANK!");
|
throw new NullPointerException(habbo.getHabboInfo().getUsername() + " has a NON EXISTING RANK!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the machine fingerprint already arrived (UniqueID before login),
|
||||||
|
// persist it so machine/super bans can target this user.
|
||||||
|
if (this.client.getMachineId() != null && !this.client.getMachineId().isEmpty()) {
|
||||||
|
this.client.getHabbo().getHabboInfo().setMachineID(this.client.getMachineId());
|
||||||
|
}
|
||||||
|
|
||||||
Emulator.getThreading().run(habbo);
|
Emulator.getThreading().run(habbo);
|
||||||
Emulator.getGameEnvironment().getHabboManager().addHabbo(habbo);
|
Emulator.getGameEnvironment().getHabboManager().addHabbo(habbo);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
+12
-1
@@ -6,6 +6,9 @@ import com.eu.habbo.messages.incoming.MessageHandler;
|
|||||||
import com.eu.habbo.messages.outgoing.wheel.WheelAdminPrizesComposer;
|
import com.eu.habbo.messages.outgoing.wheel.WheelAdminPrizesComposer;
|
||||||
import com.eu.habbo.messages.outgoing.wheel.WheelDataComposer;
|
import com.eu.habbo.messages.outgoing.wheel.WheelDataComposer;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class WheelAdminSavePrizesEvent extends MessageHandler {
|
public class WheelAdminSavePrizesEvent extends MessageHandler {
|
||||||
public static final String PERMISSION_KEY = "acc_wheeladmin";
|
public static final String PERMISSION_KEY = "acc_wheeladmin";
|
||||||
|
|
||||||
@@ -25,6 +28,12 @@ public class WheelAdminSavePrizesEvent extends MessageHandler {
|
|||||||
int count = this.packet.readInt();
|
int count = this.packet.readInt();
|
||||||
if (count <= 0 || count > WheelManager.MAX_PRIZES_PER_SAVE) return;
|
if (count <= 0 || count > WheelManager.MAX_PRIZES_PER_SAVE) return;
|
||||||
|
|
||||||
|
// The client sends the full authoritative list of prizes in display
|
||||||
|
// order. id <= 0 means "insert a new prize"; any existing prize whose
|
||||||
|
// id is absent from this list was removed in the editor and gets
|
||||||
|
// soft-disabled below.
|
||||||
|
Set<Integer> keptIds = new HashSet<>();
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
int id = this.packet.readInt();
|
int id = this.packet.readInt();
|
||||||
String type = this.packet.readString();
|
String type = this.packet.readString();
|
||||||
@@ -33,9 +42,11 @@ public class WheelAdminSavePrizesEvent extends MessageHandler {
|
|||||||
int pointsType = this.packet.readInt();
|
int pointsType = this.packet.readInt();
|
||||||
int weight = this.packet.readInt();
|
int weight = this.packet.readInt();
|
||||||
String label = this.packet.readString();
|
String label = this.packet.readString();
|
||||||
wheel.savePrize(id, type, value, amount, pointsType, weight, label);
|
int savedId = wheel.savePrize(id, type, value, amount, pointsType, weight, label, i);
|
||||||
|
if (savedId > 0) keptIds.add(savedId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wheel.disablePrizesNotIn(keptIds);
|
||||||
wheel.reload();
|
wheel.reload();
|
||||||
|
|
||||||
this.client.sendResponse(new WheelAdminPrizesComposer(wheel.getPrizes()));
|
this.client.sendResponse(new WheelAdminPrizesComposer(wheel.getPrizes()));
|
||||||
|
|||||||
Reference in New Issue
Block a user