This will allow you to register in-game when you insert an unregistered account name.
Credits to Jelly for helping me test.
The password is set to SHA1 instantly after the account is created.
On the first login the password gets updated to SHA512 with the salt.
lastknownip column added to the accounts table.
Correct reading of the lastknownip(Socket removed).
New AutoRegister.java class file.
Changed ban/enabled check to && instead of ||.
*New* int in AutoRegister.java allowing you to change how many times a player can register under the same ip.
*New* boolean in AutoRegister.java allowing you to enable/disable auto register.
*New* Automatic login after the account is created!!
Add the lastknownip column to accounts table in the database.
In AutoRegister.java you can change these values to your preference.Code:ALTER TABLE `accounts` ADD COLUMN `lastknownip` VARCHAR(30) NOT NULL DEFAULT '' AFTER `macs`;
Change autoRegister value to true or false to enable or disable auto registration. Default is true.
Change ACCOUNTS_PER_IP value to change how many accounts can be created on one ip. Default set to 1.Code:private static final boolean autoRegister = true; //enable = true or disable = false
In LoginCrypto.javaCode:private static final int ACCOUNTS_PER_IP = 1; //change the value to the amount of accounts you want allowed for each ip
Replace
withCode:private static String hexSha1(String in) {
In LoginPasswordHandler.javaCode:public static String hexSha1(String in) {
Add import.
then replaceCode:import net.sf.odinms.client.AutoRegister;
withCode:loginok = c.login(login, pwd, ipBan || macBan);
In MapleClient.java.Code:if (AutoRegister.getAccountExists(login) != false) { loginok = c.login(login, pwd, ipBan || macBan); } else if (AutoRegister.autoRegister != false && (!ipBan || !macBan)) { AutoRegister.createAccount(login, pwd, c.getSession().getRemoteAddress().toString()); if (AutoRegister.success != false) { loginok = c.login(login, pwd, ipBan || macBan); } }
Replace the entire public int login code block with this.
Finally create a new java class file in net.sf.odinms.client named AutoRegister and replace the contents withCode:public int login(String login, String pwd, boolean ipMacBanned) { int loginok = 5; Connection con = DatabaseConnection.getConnection(); try { PreparedStatement ps = con .prepareStatement("SELECT id,password,salt,tempban,banned,gm,macs,lastknownip,greason FROM accounts WHERE name = ?"); ps.setString(1, login); ResultSet rs = ps.executeQuery(); if (rs.next()) { int banned = rs.getInt("banned"); accId = rs.getInt("id"); int igm = rs.getInt("gm"); String passhash = rs.getString("password"); String salt = rs.getString("salt"); gm = igm > 0; greason = rs.getByte("greason"); tempban = getTempBanCalendar(rs); if ((banned == 0 && !ipMacBanned) || banned == -1) { PreparedStatement ips = con.prepareStatement("INSERT INTO iplog (accountid, ip) VALUES (?, ?)"); ips.setInt(1, accId); ips.setString(2, session.getRemoteAddress().toString()); ips.executeUpdate(); ips.close(); } //update the lastknownip for the player on a successful login if the ip changes if (!rs.getString("lastknownip").equals(session.getRemoteAddress().toString())) { PreparedStatement lkip = con.prepareStatement("UPDATE accounts SET lastknownip = ? where id = ?"); String sockAddr = session.getRemoteAddress().toString(); lkip.setString(1, sockAddr.substring(1, sockAddr.lastIndexOf(':'))); lkip.setInt(2, accId); lkip.executeUpdate(); lkip.close(); } // do NOT track ALL mac addresses ever used /*String[] macData = rs.getString("macs").split(", "); for (String mac : macData) { if (!mac.equals("")) macs.add(mac); }*/ ps.close(); // if (gm > 0) { // session.write(MaplePacketCreator.getAuthSuccessRequestPin(getAccountName())); // return finishLogin(true); // } if (banned == 1) { loginok = 3; } else { // this is to simplify unbanning // all known ip and mac bans associated with the current // client // will be deleted if (banned == -1) unban(); if (getLoginState() > MapleClient.LOGIN_NOTLOGGEDIN) { // already loggedin loggedIn = false; loginok = 7; } else { boolean updatePasswordHash = false; // Check if the passwords are correct here. :B if (LoginCryptoLegacy.isLegacyPassword(passhash) && LoginCryptoLegacy.checkPassword(pwd, passhash)) { // Check if a password upgrade is needed. loginok = 0; updatePasswordHash = true; } else if (salt == null && LoginCrypto.checkSha1Hash(passhash, pwd)) { loginok = 0; updatePasswordHash = true; } else if (LoginCrypto.checkSaltedSha512Hash(passhash, pwd, salt)) { loginok = 0; } else { loggedIn = false; loginok = 4; } if (updatePasswordHash) { PreparedStatement pss = con.prepareStatement("UPDATE `accounts` SET `password` = ?, `salt` = ? WHERE id = ?"); try { String newSalt = LoginCrypto.makeSalt(); pss.setString(1, LoginCrypto.makeSaltedSha512Hash(pwd, newSalt)); pss.setString(2, newSalt); pss.setInt(3, accId); pss.executeUpdate(); } finally { pss.close(); } } } } } rs.close(); ps.close(); } catch (SQLException e) { log.error("ERROR", e); } return loginok; }
Code:/* This file is part of the OdinMS Maple Story Server Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc> Matthias Butz <matze@odinms.de> Jan Christian Meyer <vimes@odinms.de> This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation. You may not use, modify or distribute this program under any other version of the GNU Affero General Public License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.odinms.client; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.ResultSet; import net.sf.odinms.database.DatabaseConnection; public class AutoRegister { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MapleClient.class); private static final int ACCOUNTS_PER_IP = 1; //change the value to the amount of accounts you want allowed for each ip public static final boolean autoRegister = true; //enable = true or disable = false public static boolean success = false; // DONT CHANGE public static boolean getAccountExists(String login) { boolean accountExists = false; Connection con = DatabaseConnection.getConnection(); try { PreparedStatement ps = con.prepareStatement("SELECT name FROM accounts WHERE name = ?"); ps.setString(1, login); ResultSet rs = ps.executeQuery(); if(rs.first()) accountExists = true; } catch (Exception ex) { log.error("ERROR", ex); } return accountExists; } public static void createAccount(String login, String pwd, String eip) { String sockAddr = eip; Connection con; //connect to database or halt try { con = DatabaseConnection.getConnection(); } catch (Exception ex) { log.error("ERROR", ex); return; } try { PreparedStatement ipc = con.prepareStatement("SELECT lastknownip FROM accounts WHERE lastknownip = ?"); ipc.setString(1, sockAddr.substring(1, sockAddr.lastIndexOf(':'))); ResultSet rs = ipc.executeQuery(); if (rs.first() == false || rs.last() == true && rs.getRow() < ACCOUNTS_PER_IP) { try { PreparedStatement ps = con.prepareStatement("INSERT INTO accounts (name, password, email, birthday, macs, lastknownip) VALUES (?, ?, ?, ?, ?, ?)"); ps.setString(1, login); ps.setString(2, LoginCrypto.hexSha1(pwd)); ps.setString(3, "no@email.provided"); ps.setString(4, "2008-04-07"); ps.setString(5, "00-00-00-00-00-00"); ps.setString(6, sockAddr.substring(1, sockAddr.lastIndexOf(':'))); ps.executeUpdate(); ps.close(); success = true; } catch (SQLException ex) { log.error("ERROR", ex); return; } } ipc.close(); rs.close(); } catch (SQLException ex) { log.error("ERROR", ex); return; } } }



![[RELEASE] In-game Auto Register + Auto Login](http://ragezone.com/hyper728.png)


