Consistently use Hwid domain object, fix login bypass
Login bypass (skip pin/pic) was broken due to an inconsistency in hwid format.
This commit is contained in:
@@ -89,7 +89,6 @@ public class MapleClient extends ChannelInboundHandlerAdapter {
|
||||
private final Type type;
|
||||
|
||||
private Hwid hwid;
|
||||
private String remoteHwid; // Mac address + hwid in one. Retrieved from client when attempting to enter game.
|
||||
private String remoteAddress;
|
||||
private volatile boolean inTransition;
|
||||
|
||||
@@ -269,14 +268,6 @@ public class MapleClient extends ChannelInboundHandlerAdapter {
|
||||
this.hwid = hwid;
|
||||
}
|
||||
|
||||
public String getRemoteHwid() {
|
||||
return remoteHwid;
|
||||
}
|
||||
|
||||
public void setRemoteHwid(String remoteHwid) {
|
||||
this.remoteHwid = remoteHwid;
|
||||
}
|
||||
|
||||
public String getRemoteAddress() {
|
||||
return remoteAddress;
|
||||
}
|
||||
@@ -618,7 +609,7 @@ public class MapleClient extends ChannelInboundHandlerAdapter {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int login(String login, String pwd, String nibbleHwid) {
|
||||
public int login(String login, String pwd, Hwid hwid) {
|
||||
int loginok = 5;
|
||||
|
||||
loginattempt++;
|
||||
@@ -676,7 +667,7 @@ public class MapleClient extends ChannelInboundHandlerAdapter {
|
||||
}
|
||||
|
||||
if (loginok == 0 || loginok == 4) {
|
||||
AntiMulticlientResult res = MapleSessionCoordinator.getInstance().attemptLoginSession(this, nibbleHwid, accId, loginok == 4);
|
||||
AntiMulticlientResult res = MapleSessionCoordinator.getInstance().attemptLoginSession(this, hwid, accId, loginok == 4);
|
||||
|
||||
switch (res) {
|
||||
case SUCCESS:
|
||||
@@ -756,16 +747,7 @@ public class MapleClient extends ChannelInboundHandlerAdapter {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public void updateHwid(String hwidClientString) {
|
||||
final Hwid hwid;
|
||||
try {
|
||||
hwid = Hwid.fromClientString(hwidClientString);
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.warn("Failed to create hwid from client string: {}", hwidClientString, e);
|
||||
this.disconnect(false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
public void updateHwid(Hwid hwid) {
|
||||
this.hwid = hwid;
|
||||
|
||||
try (Connection con = DatabaseConnection.getConnection();
|
||||
|
||||
@@ -112,20 +112,18 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
MapleCharacter player = wserv.getPlayerStorage().getCharacterById(cid);
|
||||
|
||||
String remoteHwid;
|
||||
final Hwid hwid;
|
||||
if (player == null) {
|
||||
remoteHwid = MapleSessionCoordinator.getInstance().pickLoginSessionHwid(c);
|
||||
if (remoteHwid == null) {
|
||||
hwid = MapleSessionCoordinator.getInstance().pickLoginSessionHwid(c);
|
||||
if (hwid == null) {
|
||||
c.disconnect(true, false);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Hwid clientHwid = player.getClient().getHwid();
|
||||
remoteHwid = clientHwid == null ? null : clientHwid.hwid();
|
||||
hwid = player.getClient().getHwid();
|
||||
}
|
||||
|
||||
c.setRemoteHwid(remoteHwid);
|
||||
c.setHwid(new Hwid(remoteHwid));
|
||||
c.setHwid(hwid);
|
||||
|
||||
if (!server.validateCharacteridInTransition(c, cid)) {
|
||||
c.disconnect(true, false);
|
||||
|
||||
@@ -5,8 +5,8 @@ import net.server.Server;
|
||||
import java.time.Instant;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
record HostHwid(String hwid, Instant expiry) {
|
||||
static HostHwid createWithDefaultExpiry(String hwid) {
|
||||
record HostHwid(Hwid hwid, Instant expiry) {
|
||||
static HostHwid createWithDefaultExpiry(Hwid hwid) {
|
||||
return new HostHwid(hwid, getDefaultExpiry());
|
||||
}
|
||||
|
||||
|
||||
@@ -27,20 +27,20 @@ class HostHwidCache {
|
||||
}
|
||||
}
|
||||
|
||||
void addEntry(String remoteHost, String remoteHwid) {
|
||||
hostHwidCache.put(remoteHost, HostHwid.createWithDefaultExpiry(remoteHwid));
|
||||
void addEntry(String remoteHost, Hwid hwid) {
|
||||
hostHwidCache.put(remoteHost, HostHwid.createWithDefaultExpiry(hwid));
|
||||
}
|
||||
|
||||
HostHwid getEntry(String remoteHost) {
|
||||
return hostHwidCache.get(remoteHost);
|
||||
}
|
||||
|
||||
String removeEntryAndGetItsHwid(String remoteHost) {
|
||||
Hwid removeEntryAndGetItsHwid(String remoteHost) {
|
||||
HostHwid hostHwid = hostHwidCache.remove(remoteHost);
|
||||
return hostHwid == null ? null : hostHwid.hwid();
|
||||
}
|
||||
|
||||
String getEntryHwid(String remoteHost) {
|
||||
Hwid getEntryHwid(String remoteHost) {
|
||||
HostHwid hostHwid = hostHwidCache.get(remoteHost);
|
||||
return hostHwid == null ? null : hostHwid.hwid();
|
||||
}
|
||||
|
||||
@@ -5,31 +5,22 @@ import java.util.regex.Pattern;
|
||||
public record Hwid (String hwid) {
|
||||
private static final int HWID_LENGTH = 8;
|
||||
// First part is a mac address (without dashes), second part is the hwid
|
||||
private static final Pattern VALID_RAW_HWID_PATTERN = Pattern.compile("[0-9A-F]{12}_[0-9A-F]{8}");
|
||||
private static final Pattern VALID_HOST_STRING_PATTERN = Pattern.compile("[0-9A-F]{12}_[0-9A-F]{8}");
|
||||
|
||||
public static boolean isValidRawHwid(String rawHwid) {
|
||||
return VALID_RAW_HWID_PATTERN.matcher(rawHwid).matches();
|
||||
private static boolean isValidHostString(String hostString) {
|
||||
return VALID_HOST_STRING_PATTERN.matcher(hostString).matches();
|
||||
}
|
||||
|
||||
public static Hwid fromClientString(String clientString) throws IllegalArgumentException {
|
||||
if (clientString == null) {
|
||||
throw new IllegalArgumentException("clientString must not be null");
|
||||
public static Hwid fromHostString(String hostString) throws IllegalArgumentException {
|
||||
if (hostString == null || !isValidHostString(hostString)) {
|
||||
throw new IllegalArgumentException("hostString has invalid format");
|
||||
}
|
||||
|
||||
String[] split = clientString.split("_");
|
||||
final String[] split = hostString.split("_");
|
||||
if (split.length != 2 || split[1].length() != HWID_LENGTH) {
|
||||
throw new IllegalArgumentException("Hwid validation failed for hwid: " + clientString);
|
||||
throw new IllegalArgumentException("Hwid validation failed for hwid: " + hostString);
|
||||
}
|
||||
|
||||
StringBuilder newHwid = new StringBuilder();
|
||||
String convert = split[1];
|
||||
|
||||
int len = convert.length();
|
||||
for (int i = len - 2; i >= 0; i -= 2) {
|
||||
newHwid.append(convert, i, i + 2);
|
||||
}
|
||||
newHwid.insert(4, "-");
|
||||
|
||||
return new Hwid(newHwid.toString());
|
||||
return new Hwid(split[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,22 +60,22 @@ public class MapleSessionCoordinator {
|
||||
private final SessionInitialization sessionInit = new SessionInitialization();
|
||||
private final LoginStorage loginStorage = new LoginStorage();
|
||||
private final Map<Integer, MapleClient> onlineClients = new HashMap<>(); // Key: account id
|
||||
private final Set<String> onlineRemoteHwids = new HashSet<>(); // Hwid/nibblehwid
|
||||
private final Set<Hwid> onlineRemoteHwids = new HashSet<>(); // Hwid/nibblehwid
|
||||
private final Map<String, Set<MapleClient>> loginRemoteHosts = new HashMap<>(); // Key: Ip (+ nibblehwid)
|
||||
private final HostHwidCache hostHwidCache = new HostHwidCache();
|
||||
|
||||
private MapleSessionCoordinator() {
|
||||
}
|
||||
|
||||
private static boolean attemptAccountAccess(int accountId, String nibbleHwid, boolean routineCheck) {
|
||||
private static boolean attemptAccountAccess(int accountId, Hwid hwid, boolean routineCheck) {
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
List<HwidRelevance> hwidRelevances = SessionDAO.getHwidRelevance(con, accountId);
|
||||
for (HwidRelevance hwidRelevance : hwidRelevances) {
|
||||
if (hwidRelevance.hwid().endsWith(nibbleHwid)) {
|
||||
if (hwidRelevance.hwid().endsWith(hwid.hwid())) {
|
||||
if (!routineCheck) {
|
||||
// better update HWID relevance as soon as the login is authenticated
|
||||
Instant expiry = HwidAssociationExpiry.getHwidAccountExpiry(hwidRelevance.relevance());
|
||||
SessionDAO.updateAccountAccess(con, nibbleHwid, accountId, expiry, hwidRelevance.getIncrementedRelevance());
|
||||
SessionDAO.updateAccountAccess(con, hwid, accountId, expiry, hwidRelevance.getIncrementedRelevance());
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -86,7 +86,7 @@ public class MapleSessionCoordinator {
|
||||
return true;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.warn("Failed to update account access. Account id: {}, nibbleHwid: {}", accountId, nibbleHwid, e);
|
||||
log.warn("Failed to update account access. Account id: {}, nibbleHwid: {}", accountId, hwid, e);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -188,9 +188,9 @@ public class MapleSessionCoordinator {
|
||||
}
|
||||
}
|
||||
|
||||
public AntiMulticlientResult attemptLoginSession(MapleClient client, String nibbleHwid, int accountId, boolean routineCheck) {
|
||||
public AntiMulticlientResult attemptLoginSession(MapleClient client, Hwid hwid, int accountId, boolean routineCheck) {
|
||||
if (!YamlConfig.config.server.DETERRED_MULTICLIENT) {
|
||||
client.setHwid(new Hwid(nibbleHwid));
|
||||
client.setHwid(hwid);
|
||||
return AntiMulticlientResult.SUCCESS;
|
||||
}
|
||||
|
||||
@@ -203,16 +203,16 @@ public class MapleSessionCoordinator {
|
||||
try {
|
||||
if (!loginStorage.registerLogin(accountId)) {
|
||||
return AntiMulticlientResult.MANY_ACCOUNT_ATTEMPTS;
|
||||
} else if (routineCheck && !attemptAccountAccess(accountId, nibbleHwid, routineCheck)) {
|
||||
} else if (routineCheck && !attemptAccountAccess(accountId, hwid, routineCheck)) {
|
||||
return AntiMulticlientResult.REMOTE_REACHED_LIMIT;
|
||||
} else if (onlineRemoteHwids.contains(nibbleHwid)) {
|
||||
} else if (onlineRemoteHwids.contains(hwid)) {
|
||||
return AntiMulticlientResult.REMOTE_LOGGEDIN;
|
||||
} else if (!attemptAccountAccess(accountId, nibbleHwid, routineCheck)) {
|
||||
} else if (!attemptAccountAccess(accountId, hwid, routineCheck)) {
|
||||
return AntiMulticlientResult.REMOTE_REACHED_LIMIT;
|
||||
}
|
||||
|
||||
client.setHwid(new Hwid(nibbleHwid));
|
||||
onlineRemoteHwids.add(nibbleHwid);
|
||||
client.setHwid(hwid);
|
||||
onlineRemoteHwids.add(hwid);
|
||||
|
||||
return AntiMulticlientResult.SUCCESS;
|
||||
} finally {
|
||||
@@ -220,11 +220,11 @@ public class MapleSessionCoordinator {
|
||||
}
|
||||
}
|
||||
|
||||
public AntiMulticlientResult attemptGameSession(MapleClient client, int accountId, String remoteHwid) {
|
||||
public AntiMulticlientResult attemptGameSession(MapleClient client, int accountId, Hwid hwid) {
|
||||
final String remoteHost = getSessionRemoteHost(client);
|
||||
if (!YamlConfig.config.server.DETERRED_MULTICLIENT) {
|
||||
hostHwidCache.addEntry(remoteHost, remoteHwid);
|
||||
hostHwidCache.addEntry(client.getRemoteAddress(), remoteHwid); // no HWID information on the loggedin newcomer session...
|
||||
hostHwidCache.addEntry(remoteHost, hwid);
|
||||
hostHwidCache.addEntry(client.getRemoteAddress(), hwid); // no HWID information on the loggedin newcomer session...
|
||||
return AntiMulticlientResult.SUCCESS;
|
||||
}
|
||||
|
||||
@@ -234,26 +234,26 @@ public class MapleSessionCoordinator {
|
||||
}
|
||||
|
||||
try {
|
||||
Hwid nibbleHwid = client.getHwid(); // thanks Paxum for noticing account stuck after PIC failure
|
||||
if (nibbleHwid == null) {
|
||||
Hwid clientHwid = client.getHwid(); // thanks Paxum for noticing account stuck after PIC failure
|
||||
if (clientHwid == null) {
|
||||
return AntiMulticlientResult.REMOTE_NO_MATCH;
|
||||
}
|
||||
|
||||
onlineRemoteHwids.remove(nibbleHwid);
|
||||
onlineRemoteHwids.remove(clientHwid);
|
||||
|
||||
if (!remoteHwid.endsWith(nibbleHwid.hwid())) {
|
||||
if (!hwid.equals(clientHwid)) {
|
||||
return AntiMulticlientResult.REMOTE_NO_MATCH;
|
||||
} else if (onlineRemoteHwids.contains(remoteHwid)) {
|
||||
} else if (onlineRemoteHwids.contains(hwid)) {
|
||||
return AntiMulticlientResult.REMOTE_LOGGEDIN;
|
||||
}
|
||||
|
||||
// assumption: after a SUCCESSFUL login attempt, the incoming client WILL receive a new IoSession from the game server
|
||||
|
||||
// updated session CLIENT_HWID attribute will be set when the player log in the game
|
||||
onlineRemoteHwids.add(remoteHwid);
|
||||
hostHwidCache.addEntry(remoteHost, remoteHwid);
|
||||
hostHwidCache.addEntry(client.getRemoteAddress(), remoteHwid);
|
||||
associateHwidAccountIfAbsent(remoteHwid, accountId);
|
||||
onlineRemoteHwids.add(hwid);
|
||||
hostHwidCache.addEntry(remoteHost, hwid);
|
||||
hostHwidCache.addEntry(client.getRemoteAddress(), hwid);
|
||||
associateHwidAccountIfAbsent(hwid, accountId);
|
||||
|
||||
return AntiMulticlientResult.SUCCESS;
|
||||
} finally {
|
||||
@@ -261,41 +261,32 @@ public class MapleSessionCoordinator {
|
||||
}
|
||||
}
|
||||
|
||||
private static void associateHwidAccountIfAbsent(String remoteHwid, int accountId) {
|
||||
private static void associateHwidAccountIfAbsent(Hwid hwid, int accountId) {
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
List<String> hwids = SessionDAO.getHwidsForAccount(con, accountId);
|
||||
List<Hwid> hwids = SessionDAO.getHwidsForAccount(con, accountId);
|
||||
|
||||
boolean containsRemoteHwid = hwids.stream().anyMatch(hwid -> hwid.contentEquals(remoteHwid));
|
||||
boolean containsRemoteHwid = hwids.stream().anyMatch(accountHwid -> accountHwid.equals(hwid));
|
||||
if (containsRemoteHwid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hwids.size() < YamlConfig.config.server.MAX_ALLOWED_ACCOUNT_HWID) {
|
||||
Instant expiry = HwidAssociationExpiry.getHwidAccountExpiry(0);
|
||||
SessionDAO.registerAccountAccess(con, accountId, remoteHwid, expiry);
|
||||
SessionDAO.registerAccountAccess(con, accountId, hwid, expiry);
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
log.warn("Failed to associate hwid {} with account id {}", remoteHwid, accountId, ex);
|
||||
log.warn("Failed to associate hwid {} with account id {}", hwid, accountId, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static MapleClient fetchInTransitionSessionClient(MapleClient client) {
|
||||
String remoteHwid = MapleSessionCoordinator.getInstance().getGameSessionHwid(client);
|
||||
if (remoteHwid == null) { // maybe this session was currently in-transition?
|
||||
Hwid hwid = MapleSessionCoordinator.getInstance().getGameSessionHwid(client);
|
||||
if (hwid == null) { // maybe this session was currently in-transition?
|
||||
return null;
|
||||
}
|
||||
|
||||
final int hwidLen = remoteHwid.length();
|
||||
final boolean isOnlyNibbleHwid = hwidLen <= 8;
|
||||
if (isOnlyNibbleHwid) {
|
||||
client.setHwid(new Hwid(remoteHwid));
|
||||
|
||||
} else {
|
||||
client.setRemoteHwid(remoteHwid);
|
||||
client.setHwid(Hwid.fromClientString(remoteHwid));
|
||||
}
|
||||
|
||||
MapleClient fakeClient = MapleClient.createMock();
|
||||
fakeClient.setHwid(hwid);
|
||||
Integer chrId = Server.getInstance().freeCharacteridInTransition(client);
|
||||
if (chrId != null) {
|
||||
try {
|
||||
@@ -316,26 +307,18 @@ public class MapleSessionCoordinator {
|
||||
final Hwid hwid = client.getHwid();
|
||||
client.setHwid(null); // making sure to clean up calls to this function on login phase
|
||||
if (hwid != null) {
|
||||
onlineRemoteHwids.remove(hwid.hwid());
|
||||
}
|
||||
|
||||
final String remoteHwid = client.getRemoteHwid();
|
||||
client.setRemoteHwid(null);
|
||||
if (remoteHwid != null) {
|
||||
onlineRemoteHwids.remove(remoteHwid);
|
||||
onlineRemoteHwids.remove(hwid);
|
||||
}
|
||||
|
||||
if (client != null) {
|
||||
final boolean isGameSession = hwid != null || remoteHwid != null;
|
||||
if (isGameSession) {
|
||||
final boolean isGameSession = hwid != null;
|
||||
if (isGameSession) {
|
||||
onlineClients.remove(client.getAccID());
|
||||
} else {
|
||||
MapleClient loggedClient = onlineClients.get(client.getAccID());
|
||||
|
||||
// do not remove an online game session here, only login session
|
||||
if (loggedClient != null && loggedClient.getSessionId() == client.getSessionId()) {
|
||||
onlineClients.remove(client.getAccID());
|
||||
} else {
|
||||
MapleClient loggedClient = onlineClients.get(client.getAccID());
|
||||
|
||||
// do not remove an online game session here, only login session
|
||||
if (loggedClient != null && loggedClient.getSessionId() == client.getSessionId()) {
|
||||
onlineClients.remove(client.getAccID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,14 +326,14 @@ public class MapleSessionCoordinator {
|
||||
client.closeSession();
|
||||
}
|
||||
}
|
||||
|
||||
public String pickLoginSessionHwid(MapleClient client) {
|
||||
|
||||
public Hwid pickLoginSessionHwid(MapleClient client) {
|
||||
String remoteHost = client.getRemoteAddress();
|
||||
// thanks BHB, resinate for noticing players from same network not being able to login
|
||||
return hostHwidCache.removeEntryAndGetItsHwid(remoteHost);
|
||||
}
|
||||
|
||||
public String getGameSessionHwid(MapleClient client) {
|
||||
public Hwid getGameSessionHwid(MapleClient client) {
|
||||
String remoteHost = getSessionRemoteHost(client);
|
||||
return hostHwidCache.getEntryHwid(remoteHost);
|
||||
}
|
||||
@@ -376,11 +359,11 @@ public class MapleSessionCoordinator {
|
||||
}
|
||||
|
||||
if (!onlineRemoteHwids.isEmpty()) {
|
||||
List<String> slist = new ArrayList<>(onlineRemoteHwids);
|
||||
Collections.sort(slist);
|
||||
List<Hwid> hwids = new ArrayList<>(onlineRemoteHwids);
|
||||
hwids.sort(Comparator.comparing(Hwid::hwid));
|
||||
|
||||
System.out.println("Current online HWIDs: ");
|
||||
for (String s : slist) {
|
||||
for (Hwid s : hwids) {
|
||||
System.out.println(" " + s);
|
||||
}
|
||||
}
|
||||
@@ -410,11 +393,11 @@ public class MapleSessionCoordinator {
|
||||
}
|
||||
|
||||
if (!onlineRemoteHwids.isEmpty()) {
|
||||
List<String> slist = new ArrayList<>(onlineRemoteHwids);
|
||||
Collections.sort(slist);
|
||||
List<Hwid> hwids = new ArrayList<>(onlineRemoteHwids);
|
||||
hwids.sort(Comparator.comparing(Hwid::hwid));
|
||||
|
||||
str += ("Current online HWIDs:\r\n");
|
||||
for (String s : slist) {
|
||||
for (Hwid s : hwids) {
|
||||
str += (" " + s + "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ public class SessionDAO {
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> getHwidsForAccount(Connection con, int accountId) throws SQLException {
|
||||
final List<String> hwids = new ArrayList<>();
|
||||
public static List<Hwid> getHwidsForAccount(Connection con, int accountId) throws SQLException {
|
||||
final List<Hwid> hwids = new ArrayList<>();
|
||||
|
||||
final String query = "SELECT hwid FROM hwidaccounts WHERE accountid = ?";
|
||||
try (PreparedStatement ps = con.prepareStatement(query)) {
|
||||
@@ -31,7 +31,7 @@ public class SessionDAO {
|
||||
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
hwids.add(rs.getString("hwid"));
|
||||
hwids.add(new Hwid(rs.getString("hwid")));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,12 +39,16 @@ public class SessionDAO {
|
||||
return hwids;
|
||||
}
|
||||
|
||||
public static void registerAccountAccess(Connection con, int accountId, String remoteHwid, Instant expiry)
|
||||
public static void registerAccountAccess(Connection con, int accountId, Hwid hwid, Instant expiry)
|
||||
throws SQLException {
|
||||
if (hwid == null) {
|
||||
throw new IllegalArgumentException("Hwid must not be null");
|
||||
}
|
||||
|
||||
final String query = "INSERT INTO hwidaccounts (accountid, hwid, expiresat) VALUES (?, ?, ?)";
|
||||
try (PreparedStatement ps = con.prepareStatement(query)) {
|
||||
ps.setInt(1, accountId);
|
||||
ps.setString(2, remoteHwid);
|
||||
ps.setString(2, hwid.hwid());
|
||||
ps.setTimestamp(3, Timestamp.from(expiry));
|
||||
|
||||
ps.executeUpdate();
|
||||
@@ -70,14 +74,14 @@ public class SessionDAO {
|
||||
return hwidRelevances;
|
||||
}
|
||||
|
||||
public static void updateAccountAccess(Connection con, String remoteHwid, int accountId, Instant expiry, int loginRelevance)
|
||||
public static void updateAccountAccess(Connection con, Hwid hwid, int accountId, Instant expiry, int loginRelevance)
|
||||
throws SQLException {
|
||||
final String query = "UPDATE hwidaccounts SET relevance = ?, expiresat = ? WHERE accountid = ? AND hwid LIKE ?";
|
||||
try (PreparedStatement ps = con.prepareStatement(query)) {
|
||||
ps.setInt(1, loginRelevance);
|
||||
ps.setTimestamp(2, Timestamp.from(expiry));
|
||||
ps.setInt(3, accountId);
|
||||
ps.setString(4, remoteHwid);
|
||||
ps.setString(4, hwid.hwid());
|
||||
|
||||
ps.executeUpdate();
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ import net.server.coordinator.session.Hwid;
|
||||
import net.server.coordinator.session.MapleSessionCoordinator;
|
||||
import net.server.coordinator.session.MapleSessionCoordinator.AntiMulticlientResult;
|
||||
import net.server.world.World;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
@@ -35,6 +37,7 @@ import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public final class CharSelectedHandler extends AbstractMaplePacketHandler {
|
||||
private static final Logger log = LoggerFactory.getLogger(CharSelectedHandler.class);
|
||||
|
||||
private static int parseAntiMulticlientError(AntiMulticlientResult res) {
|
||||
return switch (res) {
|
||||
@@ -51,9 +54,13 @@ public final class CharSelectedHandler extends AbstractMaplePacketHandler {
|
||||
int charId = slea.readInt();
|
||||
|
||||
String macs = slea.readMapleAsciiString();
|
||||
String hwid = slea.readMapleAsciiString();
|
||||
|
||||
if (!Hwid.isValidRawHwid(hwid)) {
|
||||
String hostString = slea.readMapleAsciiString();
|
||||
|
||||
final Hwid hwid;
|
||||
try {
|
||||
hwid = Hwid.fromHostString(hostString);
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.warn("Invalid host string: {}", hostString, e);
|
||||
c.announce(MaplePacketCreator.getAfterLoginError(17));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import net.server.coordinator.session.Hwid;
|
||||
import net.server.coordinator.session.MapleSessionCoordinator;
|
||||
import net.server.coordinator.session.MapleSessionCoordinator.AntiMulticlientResult;
|
||||
import net.server.world.World;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
@@ -14,24 +16,16 @@ import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public class CharSelectedWithPicHandler extends AbstractMaplePacketHandler {
|
||||
private static final Logger log = LoggerFactory.getLogger(CharSelectedWithPicHandler.class);
|
||||
|
||||
private static int parseAntiMulticlientError(AntiMulticlientResult res) {
|
||||
switch (res) {
|
||||
case REMOTE_PROCESSING:
|
||||
return 10;
|
||||
|
||||
case REMOTE_LOGGEDIN:
|
||||
return 7;
|
||||
|
||||
case REMOTE_NO_MATCH:
|
||||
return 17;
|
||||
|
||||
case COORDINATOR_ERROR:
|
||||
return 8;
|
||||
|
||||
default:
|
||||
return 9;
|
||||
}
|
||||
return switch (res) {
|
||||
case REMOTE_PROCESSING -> 10;
|
||||
case REMOTE_LOGGEDIN -> 7;
|
||||
case REMOTE_NO_MATCH -> 17;
|
||||
case COORDINATOR_ERROR -> 8;
|
||||
default -> 9;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -40,9 +34,13 @@ public class CharSelectedWithPicHandler extends AbstractMaplePacketHandler {
|
||||
int charId = slea.readInt();
|
||||
|
||||
String macs = slea.readMapleAsciiString();
|
||||
String hwid = slea.readMapleAsciiString();
|
||||
|
||||
if (!Hwid.isValidRawHwid(hwid)) {
|
||||
String hostString = slea.readMapleAsciiString();
|
||||
|
||||
final Hwid hwid;
|
||||
try {
|
||||
hwid = Hwid.fromHostString(hostString);
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.warn("Invalid host string: {}", hostString, e);
|
||||
c.announce(MaplePacketCreator.getAfterLoginError(17));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import client.MapleClient;
|
||||
import config.YamlConfig;
|
||||
import net.MaplePacketHandler;
|
||||
import net.server.Server;
|
||||
import net.server.coordinator.session.Hwid;
|
||||
import tools.BCrypt;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.HexTool;
|
||||
@@ -66,8 +67,8 @@ public final class LoginPasswordHandler implements MaplePacketHandler {
|
||||
|
||||
slea.skip(6); // localhost masked the initial part with zeroes...
|
||||
byte[] hwidNibbles = slea.read(4);
|
||||
String nibbleHwid = HexTool.toCompressedString(hwidNibbles);
|
||||
int loginok = c.login(login, pwd, nibbleHwid);
|
||||
Hwid hwid = new Hwid(HexTool.bytesToHex(hwidNibbles));
|
||||
int loginok = c.login(login, pwd, hwid);
|
||||
|
||||
|
||||
if (YamlConfig.config.server.AUTOMATIC_REGISTER && loginok == 5) {
|
||||
@@ -87,7 +88,7 @@ public final class LoginPasswordHandler implements MaplePacketHandler {
|
||||
c.setAccID(-1);
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
loginok = c.login(login, pwd, nibbleHwid);
|
||||
loginok = c.login(login, pwd, hwid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ import net.server.coordinator.session.Hwid;
|
||||
import net.server.coordinator.session.MapleSessionCoordinator;
|
||||
import net.server.coordinator.session.MapleSessionCoordinator.AntiMulticlientResult;
|
||||
import net.server.world.World;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
@@ -14,24 +16,16 @@ import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public final class RegisterPicHandler extends AbstractMaplePacketHandler {
|
||||
private static final Logger log = LoggerFactory.getLogger(RegisterPicHandler.class);
|
||||
|
||||
private static int parseAntiMulticlientError(AntiMulticlientResult res) {
|
||||
switch (res) {
|
||||
case REMOTE_PROCESSING:
|
||||
return 10;
|
||||
|
||||
case REMOTE_LOGGEDIN:
|
||||
return 7;
|
||||
|
||||
case REMOTE_NO_MATCH:
|
||||
return 17;
|
||||
|
||||
case COORDINATOR_ERROR:
|
||||
return 8;
|
||||
|
||||
default:
|
||||
return 9;
|
||||
}
|
||||
return switch (res) {
|
||||
case REMOTE_PROCESSING -> 10;
|
||||
case REMOTE_LOGGEDIN -> 7;
|
||||
case REMOTE_NO_MATCH -> 17;
|
||||
case COORDINATOR_ERROR -> 8;
|
||||
default -> 9;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -40,9 +34,13 @@ public final class RegisterPicHandler extends AbstractMaplePacketHandler {
|
||||
int charId = slea.readInt();
|
||||
|
||||
String macs = slea.readMapleAsciiString();
|
||||
String hwid = slea.readMapleAsciiString();
|
||||
|
||||
if (!Hwid.isValidRawHwid(hwid)) {
|
||||
String hostString = slea.readMapleAsciiString();
|
||||
|
||||
final Hwid hwid;
|
||||
try {
|
||||
hwid = Hwid.fromHostString(hostString);
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.warn("Invalid host string: {}", hostString, e);
|
||||
c.announce(MaplePacketCreator.getAfterLoginError(17));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import net.server.coordinator.session.Hwid;
|
||||
import net.server.coordinator.session.MapleSessionCoordinator;
|
||||
import net.server.coordinator.session.MapleSessionCoordinator.AntiMulticlientResult;
|
||||
import net.server.world.World;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Randomizer;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
@@ -15,24 +17,16 @@ import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public final class ViewAllCharRegisterPicHandler extends AbstractMaplePacketHandler {
|
||||
private static final Logger log = LoggerFactory.getLogger(ViewAllCharRegisterPicHandler.class);
|
||||
|
||||
private static int parseAntiMulticlientError(AntiMulticlientResult res) {
|
||||
switch (res) {
|
||||
case REMOTE_PROCESSING:
|
||||
return 10;
|
||||
|
||||
case REMOTE_LOGGEDIN:
|
||||
return 7;
|
||||
|
||||
case REMOTE_NO_MATCH:
|
||||
return 17;
|
||||
|
||||
case COORDINATOR_ERROR:
|
||||
return 8;
|
||||
|
||||
default:
|
||||
return 9;
|
||||
}
|
||||
return switch (res) {
|
||||
case REMOTE_PROCESSING -> 10;
|
||||
case REMOTE_LOGGEDIN -> 7;
|
||||
case REMOTE_NO_MATCH -> 17;
|
||||
case COORDINATOR_ERROR -> 8;
|
||||
default -> 9;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -42,9 +36,13 @@ public final class ViewAllCharRegisterPicHandler extends AbstractMaplePacketHand
|
||||
slea.readInt(); // please don't let the client choose which world they should login
|
||||
|
||||
String mac = slea.readMapleAsciiString();
|
||||
String hwid = slea.readMapleAsciiString();
|
||||
|
||||
if (!Hwid.isValidRawHwid(hwid)) {
|
||||
String hostString = slea.readMapleAsciiString();
|
||||
|
||||
final Hwid hwid;
|
||||
try {
|
||||
hwid = Hwid.fromHostString(hostString);
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.warn("Invalid host string: {}", hostString, e);
|
||||
c.announce(MaplePacketCreator.getAfterLoginError(17));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ import net.server.coordinator.session.Hwid;
|
||||
import net.server.coordinator.session.MapleSessionCoordinator;
|
||||
import net.server.coordinator.session.MapleSessionCoordinator.AntiMulticlientResult;
|
||||
import net.server.world.World;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Randomizer;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
@@ -36,24 +38,16 @@ import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public final class ViewAllCharSelectedHandler extends AbstractMaplePacketHandler {
|
||||
private static final Logger log = LoggerFactory.getLogger(ViewAllCharSelectedHandler.class);
|
||||
|
||||
private static int parseAntiMulticlientError(AntiMulticlientResult res) {
|
||||
switch (res) {
|
||||
case REMOTE_PROCESSING:
|
||||
return 10;
|
||||
|
||||
case REMOTE_LOGGEDIN:
|
||||
return 7;
|
||||
|
||||
case REMOTE_NO_MATCH:
|
||||
return 17;
|
||||
|
||||
case COORDINATOR_ERROR:
|
||||
return 8;
|
||||
|
||||
default:
|
||||
return 9;
|
||||
}
|
||||
return switch (res) {
|
||||
case REMOTE_PROCESSING -> 10;
|
||||
case REMOTE_LOGGEDIN -> 7;
|
||||
case REMOTE_NO_MATCH -> 17;
|
||||
case COORDINATOR_ERROR -> 8;
|
||||
default -> 9;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,9 +56,13 @@ public final class ViewAllCharSelectedHandler extends AbstractMaplePacketHandler
|
||||
slea.readInt(); // please don't let the client choose which world they should login
|
||||
|
||||
String macs = slea.readMapleAsciiString();
|
||||
String hwid = slea.readMapleAsciiString();
|
||||
|
||||
if (!Hwid.isValidRawHwid(hwid)) {
|
||||
String hostString = slea.readMapleAsciiString();
|
||||
|
||||
final Hwid hwid;
|
||||
try {
|
||||
hwid = Hwid.fromHostString(hostString);
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.warn("Invalid host string: {}", hostString, e);
|
||||
c.announce(MaplePacketCreator.getAfterLoginError(17));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import net.server.coordinator.session.Hwid;
|
||||
import net.server.coordinator.session.MapleSessionCoordinator;
|
||||
import net.server.coordinator.session.MapleSessionCoordinator.AntiMulticlientResult;
|
||||
import net.server.world.World;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Randomizer;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
@@ -15,24 +17,16 @@ import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public class ViewAllCharSelectedWithPicHandler extends AbstractMaplePacketHandler {
|
||||
private static final Logger log = LoggerFactory.getLogger(ViewAllCharSelectedWithPicHandler.class);
|
||||
|
||||
private static int parseAntiMulticlientError(AntiMulticlientResult res) {
|
||||
switch (res) {
|
||||
case REMOTE_PROCESSING:
|
||||
return 10;
|
||||
|
||||
case REMOTE_LOGGEDIN:
|
||||
return 7;
|
||||
|
||||
case REMOTE_NO_MATCH:
|
||||
return 17;
|
||||
|
||||
case COORDINATOR_ERROR:
|
||||
return 8;
|
||||
|
||||
default:
|
||||
return 9;
|
||||
}
|
||||
return switch (res) {
|
||||
case REMOTE_PROCESSING -> 10;
|
||||
case REMOTE_LOGGEDIN -> 7;
|
||||
case REMOTE_NO_MATCH -> 17;
|
||||
case COORDINATOR_ERROR -> 8;
|
||||
default -> 9;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -43,9 +37,13 @@ public class ViewAllCharSelectedWithPicHandler extends AbstractMaplePacketHandle
|
||||
slea.readInt(); // please don't let the client choose which world they should login
|
||||
|
||||
String macs = slea.readMapleAsciiString();
|
||||
String hwid = slea.readMapleAsciiString();
|
||||
|
||||
if (!Hwid.isValidRawHwid(hwid)) {
|
||||
String hostString = slea.readMapleAsciiString();
|
||||
|
||||
final Hwid hwid;
|
||||
try {
|
||||
hwid = Hwid.fromHostString(hostString);
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.warn("Invalid host string: {}", hostString, e);
|
||||
c.announce(MaplePacketCreator.getAfterLoginError(17));
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user