Package l2p.loginserver

Source Code of l2p.loginserver.GameServerTable

package l2p.loginserver;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.spec.RSAKeyGenParameterSpec;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;

import javolution.io.UTF8StreamReader;
import javolution.util.FastMap;
import javolution.xml.stream.XMLStreamConstants;
import javolution.xml.stream.XMLStreamException;
import javolution.xml.stream.XMLStreamReaderImpl;
import l2p.Config;
import l2p.database.DatabaseUtils;
import l2p.database.FiltredPreparedStatement;
import l2p.database.L2DatabaseFactory;
import l2p.database.ThreadConnection;
import l2p.gameserver.loginservercon.AdvIP;
import l2p.loginserver.gameservercon.GameServerInfo;
import l2p.util.GArray;
import l2p.util.Rnd;

public class GameServerTable
{
  private static Logger _log = Logger.getLogger(GameServerTable.class.getName());
  private static GameServerTable _instance;
  // Server Names Config
  static FastMap<Integer, String> _serverNames = new FastMap<Integer, String>().setShared(true);
  // Game Server Table
  private final Map<Integer, GameServerInfo> _gameServerTable = new FastMap<Integer, GameServerInfo>().setShared(true);
  // RSA Config
  private KeyPair[] _keyPairs;

  public static void load() throws SQLException, GeneralSecurityException
  {
    if(_instance == null)
    {
      _instance = new GameServerTable();
    }
    else
    {
      throw new IllegalStateException("Load can only be invoked a single time.");
    }
  }

  public static GameServerTable getInstance()
  {
    return _instance;
  }

  public GameServerTable() throws SQLException, NoSuchAlgorithmException, InvalidAlgorithmParameterException
  {
    loadServerNames();
    _log.info("Loaded " + _serverNames.size() + " server names");
    loadRegisteredGameServers();
    _log.info("Loaded " + _gameServerTable.size() + " registered Game Servers");
    loadRSAKeys();
    _log.info("Cached " + _keyPairs.length + " RSA keys for Game Server communication.");
  }

  private void loadRSAKeys() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException
  {
    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
    RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(512, RSAKeyGenParameterSpec.F4);
    keyGen.initialize(spec);
    _keyPairs = new KeyPair[Config.LOGIN_RSA_KEYPAIRS];
    for(int i = 0; i < _keyPairs.length; i++)
    {
      _keyPairs[i] = keyGen.genKeyPair();
    }
  }

  private void loadServerNames()
  {
    InputStream in = null;
    try
    {
      in = new FileInputStream("servername.xml");
      XMLStreamReaderImpl xpp = new XMLStreamReaderImpl();
      xpp.setInput(new UTF8StreamReader().setInput(in));
      for(int e = xpp.getEventType(); e != XMLStreamConstants.END_DOCUMENT; e = xpp.next())
      {
        if(e == XMLStreamConstants.START_ELEMENT)
        {
          if(xpp.getLocalName().toString().equals("server"))
          {
            Integer id = new Integer(xpp.getAttributeValue(null, "id").toString());
            String name = xpp.getAttributeValue(null, "name").toString();
            _serverNames.put(id, name);
          }
        }
      }
    }
    catch(FileNotFoundException e)
    {
      _log.warning("servername.xml could not be loaded: file not found");
    }
    catch(XMLStreamException xppe)
    {
      xppe.printStackTrace();
    }
    finally
    {
      try
      {
        if(in != null)
        {
          in.close();
        }
      }
      catch(Exception e)
      {
      }
    }
  }

  private void loadRegisteredGameServers() throws SQLException
  {
    ThreadConnection con = null;
    FiltredPreparedStatement statement = null;
    ResultSet rset = null;
    int id;
    try
    {
      con = L2DatabaseFactory.getInstance().getConnection();
      statement = con.prepareStatement("SELECT * FROM gameservers");
      rset = statement.executeQuery();
      GameServerInfo gsi;
      while(rset.next())
      {
        id = rset.getInt("server_id");
        gsi = new GameServerInfo(id, stringToHex(rset.getString("hexid")));
        _gameServerTable.put(id, gsi);
      }
    }
    finally
    {
      DatabaseUtils.closeDatabaseCSR(con, statement, rset);
    }
  }

  public Map<Integer, GameServerInfo> getRegisteredGameServers()
  {
    return _gameServerTable;
  }

  public GameServerInfo getRegisteredGameServerById(int id)
  {
    return _gameServerTable.get(id);
  }

  public boolean hasRegisteredGameServerOnId(int id)
  {
    return _gameServerTable.containsKey(id);
  }

  public boolean registerWithFirstAvailableId(GameServerInfo gsi)
  {
    // avoid two servers registering with the same "free" id
    synchronized(_gameServerTable)
    {
      for(Entry<Integer, String> entry : _serverNames.entrySet())
      {
        if(!_gameServerTable.containsKey(entry.getKey()))
        {
          _gameServerTable.put(entry.getKey(), gsi);
          gsi.setId(entry.getKey());
          return true;
        }
      }
    }
    return false;
  }

  public boolean register(int id, GameServerInfo gsi)
  {
    // avoid two servers registering with the same id
    synchronized(_gameServerTable)
    {
      if(!_gameServerTable.containsKey(id))
      {
        _gameServerTable.put(id, gsi);
        gsi.setId(id);
        return true;
      }
    }
    return false;
  }

  public void registerServerOnDB(GameServerInfo gsi)
  {
    this.registerServerOnDB(gsi.getHexId(), gsi.getId(), gsi.getExternalHost());
  }

  public void registerServerOnDB(byte[] hexId, int id, String externalHost)
  {
    ThreadConnection con = null;
    FiltredPreparedStatement statement = null;
    try
    {
      con = L2DatabaseFactory.getInstance().getConnection();
      statement = con.prepareStatement("INSERT INTO gameservers (hexid,server_id,host) values (?,?,?)");
      statement.setString(1, hexToString(hexId));
      statement.setInt(2, id);
      statement.setString(3, externalHost);
      statement.executeUpdate();
    }
    catch(SQLException e)
    {
      _log.warning("SQL error while saving gameserver: " + e);
    }
    finally
    {
      DatabaseUtils.closeDatabaseCS(con, statement);
    }
  }

  public String getServerNameById(int id)
  {
    return getServerNames().get(id);
  }

  public Map<Integer, String> getServerNames()
  {
    return _serverNames;
  }

  public KeyPair getKeyPair()
  {
    return _keyPairs[Rnd.get(_keyPairs.length)];
  }

  private byte[] stringToHex(String string)
  {
    return new BigInteger(string, 16).toByteArray();
  }

  private String hexToString(byte[] hex)
  {
    if(hex == null)
    {
      return "null";
    }
    return new BigInteger(hex).toString(16);
  }

  public GArray<String> status()
  {
    GArray<String> str = new GArray<String>();
    str.add("There are " + _gameServerTable.size() + " GameServers");
    for(GameServerInfo gsi : _gameServerTable.values())
    {
      str.add(gsi.toString());
    }
    return str;
  }

  public Boolean CheckSubNet(String ip, AdvIP advip)
  {
    String[] temp = ip.split("\\.");
    String[] temp2 = advip.bitmask.split("\\.");
    String result = "";
    for(int i = 0; i < temp.length; i++)
    {
      result += (Integer.valueOf(temp[i]) & Integer.valueOf(temp2[i])) + ".";
    }
    return result.equals(advip.ipmask.replace("\\.", "") + ".");
  }
}
TOP

Related Classes of l2p.loginserver.GameServerTable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.