Stage 2 of DB rebuild

This commit is contained in:
duckietm
2026-04-07 15:02:45 +02:00
parent 46230d0709
commit 5e3a43a62b
4 changed files with 146 additions and 146 deletions
@@ -7,9 +7,9 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.function.BiConsumer;
public final class SqlQueries {
@@ -21,6 +21,11 @@ public final class SqlQueries {
T map(ResultSet rs) throws SQLException;
}
@FunctionalInterface
public interface RowConsumer {
void accept(ResultSet rs) throws SQLException;
}
@FunctionalInterface
public interface ParameterBinder<P> {
void bind(PreparedStatement ps, P value) throws SQLException;
@@ -60,6 +65,19 @@ public final class SqlQueries {
}
}
public static void forEach(String sql, RowConsumer consumer, Object... params) {
try (Connection c = Emulator.getDatabase().getDataSource().getConnection();
PreparedStatement ps = c.prepareStatement(sql)) {
bindAll(ps, params);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
consumer.accept(rs);
}
}
} catch (SQLException e) {
throw new DataAccessException("forEach failed: " + sql, e);
}
}
public static int update(String sql, Object... params) {
try (Connection c = Emulator.getDatabase().getDataSource().getConnection();
@@ -71,7 +89,7 @@ public final class SqlQueries {
}
}
public static <P> int[] batchUpdate(String sql, List<P> items, ParameterBinder<P> binder) {
public static <P> int[] batchUpdate(String sql, Collection<? extends P> items, ParameterBinder<P> binder) {
try (Connection c = Emulator.getDatabase().getDataSource().getConnection();
PreparedStatement ps = c.prepareStatement(sql)) {
for (P item : items) {
@@ -1,6 +1,7 @@
package com.eu.habbo.habbohotel.achievements;
import com.eu.habbo.Emulator;
import com.eu.habbo.database.SqlQueries;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.habbohotel.users.HabboBadge;
@@ -49,16 +50,12 @@ public class AchievementManager {
if (habbo != null) {
progressAchievement(habbo, achievement, amount);
} else {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
PreparedStatement statement = connection.prepareStatement("" +
"INSERT INTO users_achievements_queue (user_id, achievement_id, amount) VALUES (?, ?, ?) " +
"ON DUPLICATE KEY UPDATE amount = amount + ?")) {
statement.setInt(1, habboId);
statement.setInt(2, achievement.id);
statement.setInt(3, amount);
statement.setInt(4, amount);
statement.execute();
} catch (SQLException e) {
try {
SqlQueries.update(
"INSERT INTO users_achievements_queue (user_id, achievement_id, amount) VALUES (?, ?, ?) "
+ "ON DUPLICATE KEY UPDATE amount = amount + ?",
habboId, achievement.id, amount, amount);
} catch (SqlQueries.DataAccessException e) {
LOGGER.error("Caught SQL exception", e);
}
}
@@ -203,44 +200,41 @@ public class AchievementManager {
}
public static void createUserEntry(Habbo habbo, Achievement achievement) {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO users_achievements (user_id, achievement_name, progress) VALUES (?, ?, ?)")) {
statement.setInt(1, habbo.getHabboInfo().getId());
statement.setString(2, achievement.name);
statement.setInt(3, 1);
statement.execute();
} catch (SQLException e) {
try {
SqlQueries.update(
"INSERT INTO users_achievements (user_id, achievement_name, progress) VALUES (?, ?, ?)",
habbo.getHabboInfo().getId(), achievement.name, 1);
} catch (SqlQueries.DataAccessException e) {
LOGGER.error("Caught SQL exception", e);
}
}
public static void saveAchievements(Habbo habbo) {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users_achievements SET progress = ? WHERE achievement_name = ? AND user_id = ? LIMIT 1")) {
statement.setInt(3, habbo.getHabboInfo().getId());
for (Map.Entry<Achievement, Integer> map : habbo.getHabboStats().getAchievementProgress().entrySet()) {
statement.setInt(1, map.getValue());
statement.setString(2, map.getKey().name);
statement.addBatch();
}
statement.executeBatch();
} catch (SQLException e) {
int userId = habbo.getHabboInfo().getId();
try {
SqlQueries.batchUpdate(
"UPDATE users_achievements SET progress = ? WHERE achievement_name = ? AND user_id = ? LIMIT 1",
habbo.getHabboStats().getAchievementProgress().entrySet(),
(ps, entry) -> {
ps.setInt(1, entry.getValue());
ps.setString(2, entry.getKey().name);
ps.setInt(3, userId);
});
} catch (SqlQueries.DataAccessException e) {
LOGGER.error("Caught SQL exception", e);
}
}
public static int getAchievementProgressForHabbo(int userId, Achievement achievement) {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT progress FROM users_achievements WHERE user_id = ? AND achievement_name = ? LIMIT 1")) {
statement.setInt(1, userId);
statement.setString(2, achievement.name);
try (ResultSet set = statement.executeQuery()) {
if (set.next()) {
return set.getInt("progress");
}
}
} catch (SQLException e) {
try {
return SqlQueries.queryOne(
"SELECT progress FROM users_achievements WHERE user_id = ? AND achievement_name = ? LIMIT 1",
rs -> rs.getInt("progress"),
userId, achievement.name).orElse(0);
} catch (SqlQueries.DataAccessException e) {
LOGGER.error("Caught SQL exception", e);
return 0;
}
return 0;
}
public void reload() {
@@ -1,6 +1,7 @@
package com.eu.habbo.habbohotel.campaign.calendar;
import com.eu.habbo.Emulator;
import com.eu.habbo.database.SqlQueries;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.messages.outgoing.events.calendar.AdventCalendarProductComposer;
import com.eu.habbo.plugin.events.users.calendar.UserClaimRewardEvent;
@@ -33,27 +34,27 @@ public class CalendarManager {
public boolean reload() {
this.dispose();
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM calendar_campaigns WHERE enabled = 1")) {
try (ResultSet set = statement.executeQuery()) {
while (set.next()) {
calendarCampaigns.put(set.getInt("id"), new CalendarCampaign(set));
}
}
} catch (SQLException e) {
try {
SqlQueries.query(
"SELECT * FROM calendar_campaigns WHERE enabled = 1",
CalendarCampaign::new)
.forEach(c -> calendarCampaigns.put(c.getId(), c));
} catch (SqlQueries.DataAccessException e) {
LOGGER.error("Caught SQL exception", e);
return false;
}
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM calendar_rewards")) {
try (ResultSet set = statement.executeQuery()) {
while (set.next()) {
CalendarCampaign campaign = calendarCampaigns.get(set.getInt("campaign_id"));
if(campaign != null){
campaign.addReward(new CalendarRewardObject(set));
}
}
}
} catch (SQLException e) {
try {
SqlQueries.query(
"SELECT * FROM calendar_rewards",
rs -> Map.entry(rs.getInt("campaign_id"), new CalendarRewardObject(rs)))
.forEach(entry -> {
CalendarCampaign campaign = calendarCampaigns.get(entry.getKey());
if (campaign != null) {
campaign.addReward(entry.getValue());
}
});
} catch (SqlQueries.DataAccessException e) {
LOGGER.error("Caught SQL exception", e);
return false;
}
@@ -94,14 +95,12 @@ public class CalendarManager {
public boolean deleteCampaign(CalendarCampaign campaign) {
calendarCampaigns.remove(campaign.getId());
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM calendar_campaigns WHERE id = ? LIMIT 1")) {
statement.setInt(1, campaign.getId());
return statement.execute();
} catch (SQLException e) {
try {
return SqlQueries.update("DELETE FROM calendar_campaigns WHERE id = ? LIMIT 1", campaign.getId()) > 0;
} catch (SqlQueries.DataAccessException e) {
LOGGER.error("Caught SQL exception", e);
return false;
}
return false;
}
public CalendarCampaign getCalendarCampaign(String campaignName) {
@@ -136,14 +135,15 @@ public class CalendarManager {
habbo.getHabboStats().calendarRewardsClaimed.add(new CalendarRewardClaimed(habbo.getHabboInfo().getId(), campaign.getId(), day, object.getId(), new Timestamp(System.currentTimeMillis())));
habbo.getClient().sendResponse(new AdventCalendarProductComposer(true, object, habbo));
object.give(habbo);
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO calendar_rewards_claimed (user_id, campaign_id, day, reward_id, timestamp) VALUES (?, ?, ?, ?, ?)")) {
statement.setInt(1, habbo.getHabboInfo().getId());
statement.setInt(2, campaign.getId());
statement.setInt(3, day);
statement.setInt(4, object.getId());
statement.setInt(5, Emulator.getIntUnixTimestamp());
statement.execute();
} catch (SQLException e) {
try {
SqlQueries.update(
"INSERT INTO calendar_rewards_claimed (user_id, campaign_id, day, reward_id, timestamp) VALUES (?, ?, ?, ?, ?)",
habbo.getHabboInfo().getId(),
campaign.getId(),
day,
object.getId(),
Emulator.getIntUnixTimestamp());
} catch (SqlQueries.DataAccessException e) {
LOGGER.error("Caught SQL exception", e);
}
}
@@ -1,6 +1,7 @@
package com.eu.habbo.habbohotel.users;
import com.eu.habbo.Emulator;
import com.eu.habbo.database.SqlQueries;
import com.eu.habbo.habbohotel.catalog.CatalogItem;
import com.eu.habbo.habbohotel.games.Game;
import com.eu.habbo.habbohotel.games.GamePlayer;
@@ -14,7 +15,6 @@ import com.eu.habbo.habbohotel.rooms.RoomTile;
import com.eu.habbo.habbohotel.rooms.RoomUnit;
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserStatusComposer;
import gnu.trove.map.hash.TIntIntHashMap;
import gnu.trove.procedure.TIntIntProcedure;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -104,53 +104,47 @@ public class HabboInfo implements Runnable {
private void loadCurrencies() {
this.currencies = new TIntIntHashMap();
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM users_currency WHERE user_id = ?")) {
statement.setInt(1, this.id);
try (ResultSet set = statement.executeQuery()) {
while (set.next()) {
this.currencies.put(set.getInt("type"), set.getInt("amount"));
}
}
} catch (SQLException e) {
try {
SqlQueries.forEach(
"SELECT * FROM users_currency WHERE user_id = ?",
rs -> this.currencies.put(rs.getInt("type"), rs.getInt("amount")),
this.id);
} catch (SqlQueries.DataAccessException e) {
LOGGER.error("Caught SQL exception", e);
}
}
private void saveCurrencies() {
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO users_currency (user_id, type, amount) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE amount = ?")) {
this.currencies.forEachEntry(new TIntIntProcedure() {
@Override
public boolean execute(int a, int b) {
try {
statement.setInt(1, HabboInfo.this.getId());
statement.setInt(2, a);
statement.setInt(3, b);
statement.setInt(4, b);
statement.addBatch();
} catch (SQLException e) {
LOGGER.error("Caught SQL exception", e);
}
return true;
}
});
statement.executeBatch();
} catch (SQLException e) {
LOGGER.error("Caught SQL exception", e);
List<int[]> entries = new ArrayList<>(this.currencies.size());
this.currencies.forEachEntry((type, amount) -> {
entries.add(new int[]{type, amount});
return true;
});
try {
SqlQueries.batchUpdate(
"INSERT INTO users_currency (user_id, type, amount) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE amount = ?",
entries,
(ps, e) -> {
ps.setInt(1, this.id);
ps.setInt(2, e[0]);
ps.setInt(3, e[1]);
ps.setInt(4, e[1]);
});
} catch (SqlQueries.DataAccessException ex) {
LOGGER.error("Caught SQL exception", ex);
}
}
private void loadSavedSearches() {
this.savedSearches = new ArrayList<>();
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM users_saved_searches WHERE user_id = ?")) {
statement.setInt(1, this.id);
try (ResultSet set = statement.executeQuery()) {
while (set.next()) {
this.savedSearches.add(new NavigatorSavedSearch(set.getString("search_code"), set.getString("filter"), set.getInt("id")));
}
}
} catch (SQLException e) {
try {
this.savedSearches = SqlQueries.query(
"SELECT * FROM users_saved_searches WHERE user_id = ?",
rs -> new NavigatorSavedSearch(rs.getString("search_code"), rs.getString("filter"), rs.getInt("id")),
this.id);
} catch (SqlQueries.DataAccessException e) {
LOGGER.error("Caught SQL exception", e);
this.savedSearches = new ArrayList<>();
}
}
@@ -182,26 +176,22 @@ public class HabboInfo implements Runnable {
public void deleteSavedSearch(NavigatorSavedSearch search) {
this.savedSearches.remove(search);
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM users_saved_searches WHERE id = ?")) {
statement.setInt(1, search.getId());
statement.execute();
} catch (SQLException e) {
try {
SqlQueries.update("DELETE FROM users_saved_searches WHERE id = ?", search.getId());
} catch (SqlQueries.DataAccessException e) {
LOGGER.error("Caught SQL exception", e);
}
}
private void loadMessengerCategories() {
this.messengerCategories = new ArrayList<>();
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT * FROM messenger_categories WHERE user_id = ?")) {
statement.setInt(1, this.id);
try (ResultSet set = statement.executeQuery()) {
while (set.next()) {
this.messengerCategories.add(new MessengerCategory(set.getString("name"), set.getInt("user_id"), set.getInt("id")));
}
}
} catch (SQLException e) {
try {
this.messengerCategories = SqlQueries.query(
"SELECT * FROM messenger_categories WHERE user_id = ?",
rs -> new MessengerCategory(rs.getString("name"), rs.getInt("user_id"), rs.getInt("id")),
this.id);
} catch (SqlQueries.DataAccessException e) {
LOGGER.error("Caught SQL exception", e);
this.messengerCategories = new ArrayList<>();
}
}
@@ -232,10 +222,9 @@ public class HabboInfo implements Runnable {
public void deleteMessengerCategory(MessengerCategory category) {
this.messengerCategories.remove(category);
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("DELETE FROM messenger_categories WHERE id = ?")) {
statement.setInt(1, category.getId());
statement.execute();
} catch (SQLException e) {
try {
SqlQueries.update("DELETE FROM messenger_categories WHERE id = ?", category.getId());
} catch (SqlQueries.DataAccessException e) {
LOGGER.error("Caught SQL exception", e);
}
}
@@ -389,12 +378,10 @@ public class HabboInfo implements Runnable {
public void setPixels(int pixels) {
this.setCurrencyAmount(0, pixels);
this.run();
}
public void addPixels(int pixels) {
this.addCurrencyAmount(0, pixels);
this.run();
}
public int getLastOnline() {
@@ -588,25 +575,26 @@ public class HabboInfo implements Runnable {
public void run() {
this.saveCurrencies();
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("UPDATE users SET motto = ?, online = ?, look = ?, gender = ?, credits = ?, last_login = ?, last_online = ?, home_room = ?, ip_current = ?, `rank` = ?, machine_id = ?, username = ?, background_id = ?, background_stand_id = ?, background_overlay_id = ? WHERE id = ?")) {
statement.setString(1, this.motto);
statement.setString(2, this.online ? "1" : "0");
statement.setString(3, this.look);
statement.setString(4, this.gender.name());
statement.setInt(5, this.credits);
statement.setInt(7, this.lastOnline);
statement.setInt(6, Emulator.getIntUnixTimestamp());
statement.setInt(8, this.homeRoom);
statement.setString(9, this.ipLogin);
statement.setInt(10, this.rank != null ? this.rank.getId() : 1);
statement.setString(11, this.machineID);
statement.setString(12, this.username);
statement.setInt(13, this.InfostandBg);
statement.setInt(14, this.InfostandStand);
statement.setInt(15, this.InfostandOverlay);
statement.setInt(16, this.id);
statement.executeUpdate();
} catch (SQLException e) {
try {
SqlQueries.update(
"UPDATE users SET motto = ?, online = ?, look = ?, gender = ?, credits = ?, last_login = ?, last_online = ?, home_room = ?, ip_current = ?, `rank` = ?, machine_id = ?, username = ?, background_id = ?, background_stand_id = ?, background_overlay_id = ? WHERE id = ?",
this.motto,
this.online ? "1" : "0",
this.look,
this.gender.name(),
this.credits,
Emulator.getIntUnixTimestamp(),
this.lastOnline,
this.homeRoom,
this.ipLogin,
this.rank != null ? this.rank.getId() : 1,
this.machineID,
this.username,
this.InfostandBg,
this.InfostandStand,
this.InfostandOverlay,
this.id);
} catch (SqlQueries.DataAccessException e) {
LOGGER.error("Caught SQL exception", e);
}
}