diff --git a/src/main/java/database/account/Account.java b/src/main/java/database/account/Account.java index 893ee00545..d82a18df31 100644 --- a/src/main/java/database/account/Account.java +++ b/src/main/java/database/account/Account.java @@ -13,10 +13,11 @@ import java.util.Objects; @Builder public record Account(int id, String name, String password, boolean acceptedTos, Byte gender, LocalDate birthdate, String pin, String pic, byte chrSlots, LoginState loginState, LocalDateTime lastLogin, - boolean banned, LocalDateTime tempBannedUntil) { + boolean banned, Byte banReason, String banDescription, LocalDateTime tempBannedUntil) { public Account { Objects.requireNonNull(name); Objects.requireNonNull(password); Objects.requireNonNull(birthdate); + Objects.requireNonNull(loginState); } } diff --git a/src/main/java/database/account/AccountRepository.java b/src/main/java/database/account/AccountRepository.java index 725310df3f..08763cd43f 100644 --- a/src/main/java/database/account/AccountRepository.java +++ b/src/main/java/database/account/AccountRepository.java @@ -20,7 +20,7 @@ public class AccountRepository { public Optional findByNameIgnoreCase(String name) { String sql = """ SELECT id, name, password, pin, pic, birthdate, gender, tos_accepted, chr_slots, login_state, - last_login, banned, temp_banned_until + last_login, banned, ban_reason, ban_description, temp_banned_until FROM account WHERE lower(name) = lower(:name)"""; try (Handle handle = connection.getHandle()) { @@ -34,7 +34,7 @@ public class AccountRepository { public Optional findById(int accountId) { String sql = """ SELECT id, name, password, pin, pic, birthdate, gender, tos_accepted, chr_slots, login_state, - last_login, banned, temp_banned_until + last_login, banned, ban_reason, ban_description, temp_banned_until FROM account WHERE id = :id"""; try (Handle handle = connection.getHandle()) { diff --git a/src/main/java/database/account/AccountRowMapper.java b/src/main/java/database/account/AccountRowMapper.java index c228a8d7e6..37bdefdcad 100644 --- a/src/main/java/database/account/AccountRowMapper.java +++ b/src/main/java/database/account/AccountRowMapper.java @@ -35,6 +35,8 @@ public class AccountRowMapper implements RowMapper { .map(Timestamp::toLocalDateTime) .orElse(null)) .banned(rs.getBoolean("banned")) + .banReason(rs.getByte("ban_reason")) + .banDescription(rs.getString("ban_description")) .tempBannedUntil(Optional.ofNullable(rs.getTimestamp("temp_banned_until")) .map(Timestamp::toLocalDateTime) .orElse(null)) diff --git a/src/main/java/net/server/handlers/login/LoginPasswordHandler.java b/src/main/java/net/server/handlers/login/LoginPasswordHandler.java index 7706a29ebf..e0dc4d6110 100644 --- a/src/main/java/net/server/handlers/login/LoginPasswordHandler.java +++ b/src/main/java/net/server/handlers/login/LoginPasswordHandler.java @@ -49,6 +49,7 @@ import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Timestamp; import java.util.Calendar; +import java.util.Objects; import java.util.Optional; public final class LoginPasswordHandler implements PacketHandler { @@ -107,22 +108,18 @@ public final class LoginPasswordHandler implements PacketHandler { } if (account.banned()) { - c.sendPacket(PacketCreator.getLoginFailed(3)); - // TODO: send ban reason instead of login failed, something like this: - // c.sendPacket(PacketCreator.getPermBan(c.getGReason())); + byte banReason = Objects.requireNonNullElse(account.banReason(), (byte) 0); + c.sendPacket(PacketCreator.getPermBan(banReason)); return; } - if (account.loginState() != LoginState.LOGGED_OUT) { - c.sendPacket(PacketCreator.getLoginFailed(7)); - return; - } - - c.setAccount(account); - - if (!account.acceptedTos()) { - c.sendPacket(PacketCreator.getLoginFailed(23)); - return; + boolean tempBanDisabled = false; + Calendar tempban = null; + if (!tempBanDisabled && (tempban = c.getTempBanCalendarFromDB()) != null) { + if (tempban.getTimeInMillis() > Calendar.getInstance().getTimeInMillis()) { + c.sendPacket(PacketCreator.getTempBan(tempban.getTimeInMillis(), c.getGReason())); + return; + } } boolean banCheckDisabled = false; @@ -138,13 +135,10 @@ public final class LoginPasswordHandler implements PacketHandler { c.sendPacket(PacketCreator.getTempBan()); } */ - boolean tempBanDisabled = false; - Calendar tempban = null; - if (!tempBanDisabled && (tempban = c.getTempBanCalendarFromDB()) != null) { - if (tempban.getTimeInMillis() > Calendar.getInstance().getTimeInMillis()) { - c.sendPacket(PacketCreator.getTempBan(tempban.getTimeInMillis(), c.getGReason())); - return; - } + + if (account.loginState() != LoginState.LOGGED_OUT) { + c.sendPacket(PacketCreator.getLoginFailed(7)); + return; } Integer failureCode = checkMultiClient(c); @@ -153,6 +147,13 @@ public final class LoginPasswordHandler implements PacketHandler { return; } + c.setAccount(account); + + if (!account.acceptedTos()) { + c.sendPacket(PacketCreator.getLoginFailed(23)); + return; + } + if (!accountService.setLoggedIn(c)) { c.sendPacket(PacketCreator.getLoginFailed(7)); } diff --git a/src/main/java/tools/PacketCreator.java b/src/main/java/tools/PacketCreator.java index 8ed601440e..c70b19ea38 100644 --- a/src/main/java/tools/PacketCreator.java +++ b/src/main/java/tools/PacketCreator.java @@ -683,12 +683,30 @@ public class PacketCreator { return p; } + /** + * @param reason + * 0: "This is an ID that has been deleted or blocked from connection. Please check again." + * 1: "You account has been blocked for hacking or illegal use of third-party programs. (...)" + * 2: "Your account has been blocked for using macro / auto-keyboard. (...)" + * 3: "Your account has been blocked for illicit promotion and advertising. (...)" + * 4: "Your account has been blocked for harassment. (...)" + * 5: "Your account has been blocked for using profane language. (...)" + * 6: "Your account has been blocked for scamming. (...)" + * 7: "Your account has been blocked for misconduct. (...)" + * 8: "Your account has been blocked for illegal cash transaction. (...)" + * 9: "Your account has been blocked for illegal charging/funding. Please contact customer support for further details. (...)" + * 10: "Your account has been blocked for temporary request. Please contact customer support for further details. (...)" + * 11: "Your account has been blocked for impersonating GM. (...)" + * 12: "Your account has been blocked for using illegal programs or violating the game policy. (...)" + * 13: "Your account has been blocked for one of cursing, scamming, or illegal trading via Megaphones. (...)" + * 14+ "The ID has been permanently blocked. So YOu won't be able to use this account." + */ public static Packet getPermBan(byte reason) { final OutPacket p = OutPacket.create(SendOpcode.LOGIN_STATUS); p.writeByte(2); // Account is banned p.writeByte(0); p.writeInt(0); - p.writeByte(0); + p.writeByte(reason); p.writeLong(getTime(-1)); return p; } diff --git a/src/main/resources/db/migration/postgresql/V0.2__account.sql b/src/main/resources/db/migration/postgresql/V0.2__account.sql index 6c4361155a..6769fdb923 100644 --- a/src/main/resources/db/migration/postgresql/V0.2__account.sql +++ b/src/main/resources/db/migration/postgresql/V0.2__account.sql @@ -16,7 +16,8 @@ CREATE TABLE account login_state smallint NOT NULL, last_login timestamp, banned boolean DEFAULT false NOT NULL, - banreason text, + ban_reason smallint, + ban_description text, temp_banned_until timestamp, greason smallint, ip text,