package client; import constants.GameConstants; import database.DatabaseConnection; import java.io.UnsupportedEncodingException; import java.security.NoSuchAlgorithmException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.regex.Pattern; import tools.Triple; public class MapleCharacterUtil { private static final Pattern namePattern = Pattern.compile("[a-zA-Z0-9]{4,12}"); private static final Pattern petPattern = Pattern.compile("[a-zA-Z0-9]{4,12}"); public static boolean canCreateChar(final String name, final boolean gm) { return getIdByName(name) == -1 && isEligibleCharName(name, gm); } public static boolean isEligibleCharName(final String name, final boolean gm) { if (name.length() > 12) { return false; } if (gm) { return true; } if (name.length() < 3 || !namePattern.matcher(name).matches()) { return false; } for (String z : GameConstants.RESERVED) { if (name.indexOf(z) != -1) { return false; } } return true; } public static boolean canChangePetName(final String name) { if (petPattern.matcher(name).matches()) { for (String z : GameConstants.RESERVED) { if (name.indexOf(z) != -1) { return false; } } return true; } return false; } public static String makeMapleReadable(final String in) { String wui = in.replace('I', 'i'); wui = wui.replace('l', 'L'); wui = wui.replace("rn", "Rn"); wui = wui.replace("vv", "Vv"); wui = wui.replace("VV", "Vv"); return wui; } public static int getIdByName(final String name) { Connection con = DatabaseConnection.getConnection(); try { final int id; try (PreparedStatement ps = con.prepareStatement("SELECT id FROM characters WHERE name = ?")) { ps.setString(1, name); try (ResultSet rs = ps.executeQuery()) { if (!rs.next()) { rs.close(); ps.close(); return -1; } id = rs.getInt("id"); } } return id; } catch (SQLException e) { System.err.println("error 'getIdByName' " + e); } return -1; } // -2 = An unknown error occured // -1 = Account not found on database // 0 = You do not have a second password set currently. // 1 = The password you have input is wrong // 2 = Password Changed successfully public static int Change_SecondPassword(final int accid, final String password, final String newpassword) { Connection con = DatabaseConnection.getConnection(); try { PreparedStatement ps = con.prepareStatement("SELECT * from accounts where id = ?"); ps.setInt(1, accid); try (ResultSet rs = ps.executeQuery()) { if (!rs.next()) { rs.close(); ps.close(); return -1; } String secondPassword = rs.getString("2ndpassword"); final String salt2 = rs.getString("salt2"); if (secondPassword != null && salt2 != null) { secondPassword = LoginCrypto.rand_r(secondPassword); } else if (secondPassword == null && salt2 == null) { rs.close(); ps.close(); return 0; } if (!check_ifPasswordEquals(secondPassword, password, salt2)) { rs.close(); ps.close(); return 1; } } ps.close(); String SHA1hashedsecond; try { SHA1hashedsecond = LoginCryptoLegacy.encodeSHA1(newpassword); } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { return -2; } ps = con.prepareStatement("UPDATE accounts set 2ndpassword = ?, salt2 = ? where id = ?"); ps.setString(1, SHA1hashedsecond); ps.setString(2, null); ps.setInt(3, accid); if (!ps.execute()) { ps.close(); return 2; } ps.close(); return -2; } catch (SQLException e) { System.err.println("error 'getIdByName' " + e); return -2; } } private static boolean check_ifPasswordEquals(final String passhash, final String pwd, final String salt) { // Check if the passwords are correct here. :B if (LoginCryptoLegacy.isLegacyPassword(passhash) && LoginCryptoLegacy.checkPassword(pwd, passhash)) { // Check if a password upgrade is needed. return true; } else if (salt == null && LoginCrypto.checkSha1Hash(passhash, pwd)) { return true; } else if (LoginCrypto.checkSaltedSha512Hash(passhash, pwd, salt)) { return true; } return false; } //id accountid gender public static Triple<Integer, Integer, Integer> getInfoByName(String name, int world) { try { Connection con = DatabaseConnection.getConnection(); Triple<Integer, Integer, Integer> id; try (PreparedStatement ps = con.prepareStatement("SELECT * FROM characters WHERE name = ? AND world = ?")) { ps.setString(1, name); ps.setInt(2, world); try (ResultSet rs = ps.executeQuery()) { if (!rs.next()) { rs.close(); ps.close(); return null; } id = new Triple<>(rs.getInt("id"), rs.getInt("accountid"), rs.getInt("gender")); } } return id; } catch (SQLException e) { } return null; } public static void setNXCodeUsed(String name, String code) throws SQLException { Connection con = DatabaseConnection.getConnection(); try (PreparedStatement ps = con.prepareStatement("UPDATE nxcode SET `user` = ?, `valid` = 0 WHERE code = ?")) { ps.setString(1, name); ps.setString(2, code); ps.execute(); } } public static void sendNote(String to, String name, String msg, int fame) { try { Connection con = DatabaseConnection.getConnection(); try (PreparedStatement ps = con.prepareStatement("INSERT INTO notes (`to`, `from`, `message`, `timestamp`, `gift`) VALUES (?, ?, ?, ?, ?)")) { ps.setString(1, to); ps.setString(2, name); ps.setString(3, msg); ps.setLong(4, System.currentTimeMillis()); ps.setInt(5, fame); ps.executeUpdate(); } } catch (SQLException e) { System.err.println("Unable to send note" + e); } } public static Triple<Boolean, Integer, Integer> getNXCodeInfo(String code) throws SQLException { Triple<Boolean, Integer, Integer> ret = null; Connection con = DatabaseConnection.getConnection(); try (PreparedStatement ps = con.prepareStatement("SELECT `valid`, `type`, `item` FROM nxcode WHERE code LIKE ?")) { ps.setString(1, code); try (ResultSet rs = ps.executeQuery()) { if (rs.next()) { ret = new Triple<>(rs.getInt("valid") > 0, rs.getInt("type"), rs.getInt("item")); } } } return ret; } }