package ru.alastar.main;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.security.MessageDigest;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Hashtable;
import ru.alastar.database.DatabaseClient;
import ru.alastar.requests.AuthPacketRequest;
import ru.alastar.requests.RegistrationPacketRequest;
import ru.alastar.responses.AddServerResponse;
import ru.alastar.responses.AuthResponse;
import ru.alastar.responses.RegisterResponse;
import ru.alastar.responses.ServerListing;
import com.esotericsoftware.kryonet.Connection;
public class Server
{
private static com.esotericsoftware.kryonet.Server server;
public static Hashtable<String, ServerInfo> servers = new Hashtable<String, ServerInfo>();
public static Hashtable<InetSocketAddress, ConnectedClient> clients = new Hashtable<InetSocketAddress, ConnectedClient>();
public static Hashtable<String, Account> accounts = new Hashtable<String, Account>();
public static void startServer()
{
try
{
DatabaseClient.Start();
server = new com.esotericsoftware.kryonet.Server();
server.start();
server.bind(Integer.parseInt(Configuration.GetEntryValue("port")),
Integer.parseInt(Configuration.GetEntryValue("port")) + 1);
server.addListener(new TListener(server));
} catch (Exception e)
{
handleError(e);
}
}
static void handleError(Exception e)
{
e.printStackTrace();
}
public static boolean hasClient(Connection connection)
{
if (clients.containsKey(connection.getRemoteAddressUDP()))
return true;
else
return false;
}
public static void addClient(Connection connection)
{
clients.put(connection.getRemoteAddressUDP(), new ConnectedClient(
connection));
}
public static ConnectedClient getClient(Connection c)
{
if(clients.containsKey(c.getRemoteAddressUDP()))
return clients.get(c.getRemoteAddressUDP());
else
return null;
}
public static void removeClient(Connection connection)
{
clients.remove(connection.getRemoteAddressUDP());
MainClass.Log("[CONN]","Connection removed. Count: " + clients.size());
}
public static void LoadConfig()
{
try
{
File configFile = null;
FileReader fr;
BufferedReader br;
FileWriter fw;
BufferedWriter bw;
String s;
configFile = new File("config.cfg");
if (!configFile.exists())
{
configFile.createNewFile();
fw = new FileWriter(configFile);
bw = new BufferedWriter(fw);
bw.write("port=2526\n");
bw.write("poolerPort=3526\n");
bw.write("dbName=te_login\n");
bw.write("dbUser=root\n");
bw.write("dbPass=\n");
bw.flush();
fw.close();
bw.close();
}
fr = new FileReader(configFile);
br = new BufferedReader(fr);
// Reading configuration
while ((s = br.readLine()) != null)
{
if (s.split("=").length > 1)
{
Configuration.AddEntry(s.split("=")[0], s.split("=")[1]);
} else
{
Configuration.AddEntry(s.split("=")[0], "");
}
}
br.close();
fr.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
public static void ProcessAuth(AuthPacketRequest object, Connection c)
{
try
{
MainClass.Log("[AUTH]", "Passing account " + object.login + " password - " + object.pass +"...", false);
ResultSet rs = DatabaseClient
.commandExecute("SELECT * FROM accounts WHERE login='"
+ object.login + "' LIMIT 1;");
AuthResponse r = new AuthResponse();
if (Logged(object))
{
r.locale = false;
r.msg = "This account is already logged in!";
r.localeId = 0;
r.state = AuthState.AlreadyLogged;
MainClass.Log("already logged!\n", false);
} else if (!rs.next())
{
r.locale = false;
r.msg = "This account is not exists!";
r.localeId = 0;
r.state = AuthState.AccountNotExists;
MainClass.Log("not exists!\n", false);
} else if(rs.getString("password").equals(encrypt(object.pass)))
{
r.locale = false;
r.msg = "Succesfully logged in!";
r.localeId = 0;
r.state = AuthState.Success;
Account a = new Account(rs.getInt("id"), rs.getString("login"), rs.getString("password"), rs.getString("mail"));
getClient(c).setAccount(a);
accounts.put(object.login, a);
SendServerList(c);
MainClass.Log("OK!\n", false);
}
else
{
r.locale = false;
r.msg = "Invalid credentials!";
r.localeId = 0;
r.state = AuthState.InvalidCredentials;
MainClass.Log("invalid credentials!\n", false);
}
Server.SendTo(c, r);
} catch (SQLException e)
{
e.printStackTrace();
}
}
private static void SendServerList(Connection c)
{
ServerListing sl = new ServerListing();
sl.state = ServerListingState.Begin;
Server.SendTo(c, sl);
AddServerResponse r = new AddServerResponse();
for(String serverName: servers.keySet())
{
r.name = serverName;
r.address = servers.get(serverName).address;
Server.SendTo(c, r);
}
sl.state = ServerListingState.End;
Server.SendTo(c, sl);
}
private static void SendTo(Connection c, Object r)
{
c.sendUDP(r);
}
private static void SendTo(ConnectedClient c, Object r)
{
c.connection.sendUDP(r);
}
private static boolean Logged(AuthPacketRequest object)
{
if(accounts.get(object.login) != null)
return true;
else
return false;
}
public static String encrypt(String string)
{
try
{
byte[] bytesOfMessage = string.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(bytesOfMessage);
return new String(thedigest, "UTF-8");
} catch (Exception e)
{
e.printStackTrace();
}
return null;
}
public static boolean hasAccount(ConnectedClient c)
{
if(c.account != null){
if(accounts.containsKey(c.account.login))
return true;
else
return false;}
else
return false;
}
public static void removeAccount(ConnectedClient c)
{
accounts.remove(c.account.login);
}
public static void ProcessRegistration(RegistrationPacketRequest object, Connection connection)
{
try
{
ResultSet regRS = DatabaseClient
.commandExecute("SELECT * FROM accounts WHERE login='"
+ object.login + "' AND mail='" + object.mail + "'");
RegisterResponse r = new RegisterResponse();
if (regRS.next())
{
r.successful = false;
SendTo(connection, r);
} else
{
CreateAccount(object.login, object.pass, object.mail,
getClient(connection));
r.successful = true;
SendTo(connection, r);
}
} catch (SQLException e)
{
handleError(e);
}
}
private static int getAccountFreeId()
{
try
{
ResultSet rs = DatabaseClient
.commandExecute("SELECT max(id) as id FROM accounts");
int i = 0;
if (rs.next())
{
i = rs.getInt("id");
}
return i + 1;
} catch (SQLException e)
{
handleError(e);
}
return -1;
}
private static void CreateAccount(String login, String pass, String mail,
ConnectedClient client)
{
ResultSet accountExists = DatabaseClient
.commandExecute("SELECT * FROM accounts WHERE login='" + login
+ "'");
RegisterResponse r = new RegisterResponse();
MainClass.Log("[AUTH]", "Passing account registration login - " + login + " password - " + pass +"...", false);
try
{
if (accountExists.next())
{
MainClass.Log("failed!\n", false);
r.successful = false;
r.reason = "That account with given mail and login is already exists!";
} else
{
MainClass.Log("OK!\n", false);
r.successful = true;
DatabaseClient
.commandExecute("INSERT INTO accounts(id, login, password, mail) VALUES("
+ Server.getAccountFreeId()
+ ",'"
+ login
+ "','"
+ encrypt(pass)
+ "','"
+ mail
+ "')");
}
SendTo(client, r);
} catch (Exception e)
{
handleError(e);
}
}
public static boolean hasAccount(String login)
{
if(accounts.containsKey(login)){
return true;
}
else
{
return false;
}
}
public static Account getAccount(String login)
{
return accounts.get(login);
}
}