Sync LoginServer changes from L2jUnity.

This commit is contained in:
MobiusDev
2016-06-04 18:02:32 +00:00
parent 2d6440aafd
commit e003e87887
18 changed files with 278 additions and 92 deletions

View File

@ -1073,6 +1073,7 @@ public final class Config
public static double CP_REGEN_MULTIPLIER;
public static boolean IS_TELNET_ENABLED;
public static boolean SHOW_LICENCE;
public static boolean SHOW_PI_AGREEMENT;
public static boolean ACCEPT_NEW_GAMESERVER;
public static int SERVER_ID;
public static byte[] HEX_ID;
@ -2943,6 +2944,7 @@ public final class Config
DATABASE_MAX_IDLE_TIME = ServerSettings.getInt("MaximumDbIdleTime", 0);
SHOW_LICENCE = ServerSettings.getBoolean("ShowLicence", true);
SHOW_PI_AGREEMENT = ServerSettings.getBoolean("ShowPIAgreement", false);
AUTO_CREATE_ACCOUNTS = ServerSettings.getBoolean("AutoCreateAccounts", true);

View File

@ -138,7 +138,6 @@ public class GameServerThread extends Thread
final String serverName = getServerId() != -1 ? "[" + getServerId() + "] " + GameServerTable.getInstance().getServerNameById(getServerId()) : "(" + _connectionIPAddress + ")";
final String msg = "GameServer " + serverName + ": Connection lost: " + e.getMessage();
_log.info(msg);
broadcastToTelnet(msg);
}
finally
{
@ -257,14 +256,6 @@ public class GameServerThread extends Thread
}
}
public void broadcastToTelnet(String msg)
{
if (L2LoginServer.getInstance().getStatusServer() != null)
{
L2LoginServer.getInstance().getStatusServer().sendMessageToTelnets(msg);
}
}
public void kickPlayer(String account)
{
sendPacket(new KickPlayer(account));

View File

@ -36,7 +36,6 @@ import com.l2jmobius.commons.mmocore.SelectorConfig;
import com.l2jmobius.commons.mmocore.SelectorThread;
import com.l2jmobius.loginserver.network.L2LoginClient;
import com.l2jmobius.loginserver.network.L2LoginPacketHandler;
import com.l2jmobius.status.Status;
/**
* @author KenM
@ -49,7 +48,6 @@ public final class L2LoginServer
private static L2LoginServer _instance;
private GameServerListener _gameServerListener;
private SelectorThread<L2LoginClient> _selectorThread;
private Status _statusServer;
private Thread _restartLoginServer;
public static void main(String[] args)
@ -149,23 +147,6 @@ public final class L2LoginServer
System.exit(1);
}
if (Config.IS_TELNET_ENABLED)
{
try
{
_statusServer = new Status(Server.serverMode);
_statusServer.start();
}
catch (IOException e)
{
_log.log(Level.WARNING, "Failed to start the Telnet Server. Reason: " + e.getMessage(), e);
}
}
else
{
_log.info("Telnet server is currently disabled.");
}
try
{
_selectorThread.openServerSocket(bindAddress, Config.PORT_LOGIN);
@ -179,11 +160,6 @@ public final class L2LoginServer
}
}
public Status getStatusServer()
{
return _statusServer;
}
public GameServerListener getGameServerListener()
{
return _gameServerListener;

View File

@ -77,6 +77,7 @@ public class LoginController
private static final String ACCOUNT_ACCESS_LEVEL_UPDATE = "UPDATE accounts SET accessLevel = ? WHERE login = ?";
private static final String ACCOUNT_IPS_UPDATE = "UPDATE accounts SET pcIp = ?, hop1 = ?, hop2 = ?, hop3 = ?, hop4 = ? WHERE login = ?";
private static final String ACCOUNT_IPAUTH_SELECT = "SELECT * FROM accounts_ipauth WHERE login = ?";
private static final String ACCOUNT_OTP_SELECT = "SELECT value FROM account_data WHERE account_name = ? AND var = 'otp'";
private LoginController() throws GeneralSecurityException
{
@ -234,6 +235,18 @@ public class LoginController
return null;
}
try (PreparedStatement otpPs = con.prepareStatement(ACCOUNT_OTP_SELECT))
{
otpPs.setString(1, login);
try (ResultSet otpRset = otpPs.executeQuery())
{
if (otpRset.next())
{
info.setOTP(otpRset.getString(1));
}
}
}
clearFailedLoginAttemps(addr);
return info;
}

View File

@ -18,6 +18,8 @@ package com.l2jmobius.loginserver.model.data;
import java.util.Objects;
//import com.warrenstrange.googleauth.GoogleAuthenticator;
/**
* @author HorridoJoho
*/
@ -27,8 +29,9 @@ public final class AccountInfo
private final String _passHash;
private final int _accessLevel;
private final int _lastServer;
private String _otpKey;
public AccountInfo(String login, String passHash, int accessLevel, int lastServer)
public AccountInfo(final String login, final String passHash, final int accessLevel, final int lastServer)
{
Objects.requireNonNull(login, "login");
Objects.requireNonNull(passHash, "passHash");
@ -48,7 +51,25 @@ public final class AccountInfo
_lastServer = lastServer;
}
public boolean checkPassHash(String passHash)
public void setOTP(String otpKey)
{
_otpKey = otpKey;
}
public boolean checkOTP(int otp)
{
if (_otpKey == null)
{
// No OTP set
return true;
}
// final GoogleAuthenticator gAuth = new GoogleAuthenticator();
// return gAuth.authorize(_otpKey, otp);
return true;
}
public boolean checkPassHash(final String passHash)
{
return _passHash.equals(passHash);
}

View File

@ -97,8 +97,6 @@ public final class L2LoginClient extends MMOClient<MMOConnection<L2LoginClient>>
if (!isChecksumValid)
{
// _log.warning("Wrong checksum from client: " + toString());
// super.getConnection().close((SendablePacket<L2LoginClient>) null);
// return false;
}
return true;
}

View File

@ -24,6 +24,8 @@ import com.l2jmobius.commons.mmocore.ReceivablePacket;
import com.l2jmobius.loginserver.network.L2LoginClient.LoginClientState;
import com.l2jmobius.loginserver.network.clientpackets.AuthGameGuard;
import com.l2jmobius.loginserver.network.clientpackets.RequestAuthLogin;
import com.l2jmobius.loginserver.network.clientpackets.RequestPIAgreement;
import com.l2jmobius.loginserver.network.clientpackets.RequestPIAgreementCheck;
import com.l2jmobius.loginserver.network.clientpackets.RequestServerList;
import com.l2jmobius.loginserver.network.clientpackets.RequestServerLogin;
@ -93,6 +95,16 @@ public final class L2LoginPacketHandler implements IPacketHandler<L2LoginClient>
packet = new RequestServerList();
break;
}
case 0x0E:
{
packet = new RequestPIAgreementCheck(); // TODO: Verify names
break;
}
case 0x0F:
{
packet = new RequestPIAgreement();
break;
}
default:
{
debugOpcode(opcode, state);

View File

@ -26,6 +26,7 @@ import javax.crypto.Cipher;
import com.l2jmobius.Config;
import com.l2jmobius.loginserver.GameServerTable.GameServerInfo;
import com.l2jmobius.loginserver.LoginController;
import com.l2jmobius.loginserver.LoginController.AuthLoginResult;
import com.l2jmobius.loginserver.model.data.AccountInfo;
import com.l2jmobius.loginserver.network.L2LoginClient;
import com.l2jmobius.loginserver.network.L2LoginClient.LoginClientState;
@ -33,6 +34,7 @@ import com.l2jmobius.loginserver.network.serverpackets.AccountKicked;
import com.l2jmobius.loginserver.network.serverpackets.AccountKicked.AccountKickedReason;
import com.l2jmobius.loginserver.network.serverpackets.LoginFail.LoginFailReason;
import com.l2jmobius.loginserver.network.serverpackets.LoginOk;
import com.l2jmobius.loginserver.network.serverpackets.LoginOtpFail;
import com.l2jmobius.loginserver.network.serverpackets.ServerList;
/**
@ -95,17 +97,16 @@ public class RequestAuthLogin extends L2LoginClientPacket
@Override
public void run()
{
byte[] decUser = null;
byte[] decPass = null;
final L2LoginClient client = getClient();
byte[] decrypted = new byte[_newAuthMethod ? 256 : 128];
try
{
final Cipher rsaCipher = Cipher.getInstance("RSA/ECB/nopadding");
rsaCipher.init(Cipher.DECRYPT_MODE, client.getRSAPrivateKey());
decUser = rsaCipher.doFinal(_raw1, 0x00, 0x80);
rsaCipher.doFinal(_raw1, 0, 128, decrypted, 0);
if (_newAuthMethod)
{
decPass = rsaCipher.doFinal(_raw2, 0x00, 0x80);
rsaCipher.doFinal(_raw2, 0, 128, decrypted, 128);
}
}
catch (GeneralSecurityException e)
@ -118,18 +119,16 @@ public class RequestAuthLogin extends L2LoginClientPacket
{
if (_newAuthMethod)
{
_user = new String(decUser, 0x4E, 0xE).trim().toLowerCase();
_password = new String(decPass, 0x5C, 0x10).trim();
_user = new String(decrypted, 0x4E, 50).trim() + new String(decrypted, 0xCE, 14).trim();
_password = new String(decrypted, 0xDC, 16).trim();
_ncotp = (decrypted[0xFC] & 0xFF) | ((decrypted[0xFD] & 0xFF) << 8) | ((decrypted[0xFE] & 0xFF) << 16) | ((decrypted[0xFF] & 0xFF) << 24);
}
else
{
_user = new String(decUser, 0x5E, 0xE).trim().toLowerCase();
_password = new String(decUser, 0x6C, 0x10).trim();
_user = new String(decrypted, 0x5E, 14).trim();
_password = new String(decrypted, 0x6C, 16).trim();
_ncotp = (decrypted[0x7C] & 0xFF) | ((decrypted[0x7D] & 0xFF) << 8) | ((decrypted[0x7E] & 0xFF) << 16) | ((decrypted[0x7F] & 0xFF) << 24);
}
_ncotp = decUser[0x7c];
_ncotp |= decUser[0x7d] << 8;
_ncotp |= decUser[0x7e] << 16;
_ncotp |= decUser[0x7f] << 24;
}
catch (Exception e)
{
@ -137,8 +136,7 @@ public class RequestAuthLogin extends L2LoginClientPacket
return;
}
final InetAddress clientAddr = getClient().getConnection().getInetAddress();
final InetAddress clientAddr = client.getConnection().getInetAddress();
final LoginController lc = LoginController.getInstance();
final AccountInfo info = lc.retriveAccountInfo(clientAddr, _user, _password);
if (info == null)
@ -147,37 +145,36 @@ public class RequestAuthLogin extends L2LoginClientPacket
client.close(LoginFailReason.REASON_USER_OR_PASS_WRONG);
return;
}
else if (!info.checkOTP(_ncotp))
{
client.sendPacket(new LoginOtpFail());
return;
}
switch (lc.tryCheckinAccount(client, clientAddr, info))
final AuthLoginResult result = lc.tryCheckinAccount(client, clientAddr, info);
switch (result)
{
case AUTH_SUCCESS:
{
client.setAccount(info.getLogin());
client.setState(LoginClientState.AUTHED_LOGIN);
client.setSessionKey(lc.assignSessionKeyToClient(info.getLogin(), client));
lc.getCharactersOnAccount(info.getLogin());
if (Config.SHOW_LICENCE)
{
client.sendPacket(new LoginOk(getClient().getSessionKey()));
client.sendPacket(new LoginOk(client.getSessionKey()));
}
else
{
getClient().sendPacket(new ServerList(getClient()));
client.sendPacket(new ServerList(client));
}
break;
}
case INVALID_PASSWORD:
{
client.close(LoginFailReason.REASON_USER_OR_PASS_WRONG);
break;
}
case ACCOUNT_BANNED:
{
client.close(new AccountKicked(AccountKickedReason.REASON_PERMANENTLY_BANNED));
return;
}
case ALREADY_ON_LS:
{
final L2LoginClient oldClient = lc.getAuthedClient(info.getLogin());
if (oldClient != null)
{
@ -188,9 +185,7 @@ public class RequestAuthLogin extends L2LoginClientPacket
// kick also current client
client.close(LoginFailReason.REASON_ACCOUNT_IN_USE);
break;
}
case ALREADY_ON_GS:
{
final GameServerInfo gsi = lc.getAccountOnGameServer(info.getLogin());
if (gsi != null)
{
@ -203,7 +198,6 @@ public class RequestAuthLogin extends L2LoginClientPacket
}
}
break;
}
}
}
}

View File

@ -0,0 +1,42 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.loginserver.network.clientpackets;
import com.l2jmobius.loginserver.network.serverpackets.PIAgreementAck;
/**
* @author UnAfraid
*/
public class RequestPIAgreement extends L2LoginClientPacket
{
private int _accountId;
private int _status;
@Override
protected boolean readImpl()
{
_accountId = readD();
_status = readC();
return true;
}
@Override
public void run()
{
getClient().sendPacket(new PIAgreementAck(_accountId, _status));
}
}

View File

@ -0,0 +1,47 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.loginserver.network.clientpackets;
import com.l2jmobius.Config;
import com.l2jmobius.loginserver.network.serverpackets.PIAgreementCheck;
/**
* @author UnAfraid
*/
public class RequestPIAgreementCheck extends L2LoginClientPacket
{
private int _accountId;
@Override
protected boolean readImpl()
{
_accountId = readD();
byte[] padding0 = new byte[3];
byte[] checksum = new byte[4];
byte[] padding1 = new byte[12];
readB(padding0);
readB(checksum);
readB(padding1);
return true;
}
@Override
public void run()
{
getClient().sendPacket(new PIAgreementCheck(_accountId, Config.SHOW_PI_AGREEMENT ? 0x01 : 0x00));
}
}

View File

@ -91,7 +91,6 @@ public class GameServerAuth extends BaseRecievePacket
{
_log.info("Authed: id: " + server.getGameServerInfo().getId());
}
server.broadcastToTelnet("GameServer [" + server.getServerId() + "] " + GameServerTable.getInstance().getServerNameById(server.getServerId()) + " is connected");
server.setLoginConnectionState(GameServerState.AUTHED);
}
}

View File

@ -46,7 +46,6 @@ public class PlayerInGame extends BaseRecievePacket
{
_log.info("Account " + account + " logged in GameServer: [" + server.getServerId() + "] " + GameServerTable.getInstance().getServerNameById(server.getServerId()));
}
server.broadcastToTelnet("Account " + account + " logged in GameServer " + server.getServerId());
}
}
}

View File

@ -44,7 +44,5 @@ public class PlayerLogout extends BaseRecievePacket
{
_log.info("Player " + account + " logged out from gameserver [" + server.getServerId() + "] " + GameServerTable.getInstance().getServerNameById(server.getServerId()));
}
server.broadcastToTelnet("Player " + account + " disconnected from GameServer " + server.getServerId());
}
}

View File

@ -0,0 +1,29 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.loginserver.network.serverpackets;
/**
* @author UnAfraid
*/
public class LoginOtpFail extends L2LoginServerPacket
{
@Override
protected void write()
{
writeC(0x0D);
}
}

View File

@ -0,0 +1,40 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.loginserver.network.serverpackets;
/**
* @author UnAfraid
*/
public class PIAgreementAck extends L2LoginServerPacket
{
private final int _accountId;
private final int _status;
public PIAgreementAck(int accountId, int status)
{
_accountId = accountId;
_status = status;
}
@Override
protected void write()
{
writeC(0x12);
writeD(_accountId);
writeC(_status);
}
}

View File

@ -0,0 +1,40 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.loginserver.network.serverpackets;
/**
* @author UnAfraid
*/
public class PIAgreementCheck extends L2LoginServerPacket
{
private final int _accountId;
private final int _status;
public PIAgreementCheck(int accountId, int status)
{
_accountId = accountId;
_status = status;
}
@Override
protected void write()
{
writeC(0x11);
writeD(_accountId);
writeC(_status);
}
}

View File

@ -63,7 +63,6 @@ public final class ServerList extends L2LoginServerPacket
private final List<ServerData> _servers;
private final int _lastServer;
private final Map<Integer, Integer> _charsOnServers;
private final Map<Integer, long[]> _charsToDelete;
class ServerData
{
@ -103,7 +102,7 @@ public final class ServerList extends L2LoginServerPacket
_ageLimit = 0;
_brackets = gsi.isShowingBrackets();
// If server GM-only - show status only to GMs
_status = (gsi.getStatus() == ServerStatus.STATUS_GM_ONLY) && (client.getAccessLevel() <= 0) ? ServerStatus.STATUS_DOWN : gsi.getStatus();
_status = gsi.getStatus() != ServerStatus.STATUS_GM_ONLY ? gsi.getStatus() : client.getAccessLevel() > 0 ? gsi.getStatus() : ServerStatus.STATUS_DOWN;
_serverId = gsi.getId();
}
}
@ -117,7 +116,6 @@ public final class ServerList extends L2LoginServerPacket
_servers.add(new ServerData(client, gsi));
}
_charsOnServers = client.getCharsOnServ();
_charsToDelete = client.getCharsWaitingDelOnServ();
}
@Override
@ -144,31 +142,14 @@ public final class ServerList extends L2LoginServerPacket
writeD(server._serverType); // 1: Normal, 2: Relax, 4: Public Test, 8: No Label, 16: Character Creation Restricted, 32: Event, 64: Free
writeC(server._brackets ? 0x01 : 0x00);
}
writeH(0x00); // unknown
writeH(0xA4); // unknown
if (_charsOnServers != null)
{
writeC(_charsOnServers.size());
for (int servId : _charsOnServers.keySet())
for (ServerData server : _servers)
{
writeC(servId);
writeC(_charsOnServers.get(servId));
if ((_charsToDelete == null) || !_charsToDelete.containsKey(servId))
{
writeC(0x00);
}
else
{
writeC(_charsToDelete.get(servId).length);
for (long deleteTime : _charsToDelete.get(servId))
{
writeD((int) ((deleteTime - System.currentTimeMillis()) / 1000));
}
}
writeC(server._serverId);
writeC(_charsOnServers.getOrDefault(server._serverId, 0));
}
}
else
{
writeC(0x00);
}
}
}