package javastory.client;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.concurrent.ScheduledFuture;
import javastory.cryptography.AesTransform;
import javastory.db.Database;
import javastory.io.GamePacket;
import javastory.io.PacketBuilder;
import javastory.server.TimerManager;
import javastory.server.handling.ServerPacketOpcode;
import org.apache.mina.core.session.IoSession;
/**
*
* @author shoftee
*/
public abstract class GameClient {
public static final String CLIENT_KEY = "CLIENT";
private int accountId = -1;
private String accountName;
private transient long lastPong;
private transient ScheduledFuture<?> idleTask = null;
private int channelId, worldId;
protected boolean loggedIn;
//
private final transient AesTransform clientCrypto;
private final transient AesTransform serverCrypto;
private final transient IoSession session;
private final transient String ip;
public GameClient(final AesTransform clientCrypto, final AesTransform serverCrypto, final IoSession session) {
this.clientCrypto = clientCrypto;
this.serverCrypto = serverCrypto;
this.session = session;
this.ip = session.getRemoteAddress().toString().split(":")[0];
}
public void disconnect() {
this.disconnect(false);
}
public abstract void disconnect(boolean immediately);
public int getAccountId() {
return this.accountId;
}
public final String getAccountName() {
return this.accountName;
}
public final AesTransform getClientCrypto() {
return this.clientCrypto;
}
public final AesTransform getServerCrypto() {
return this.serverCrypto;
}
public final String getSessionIP() {
return this.ip;
}
public void setAccountId(final int id) {
this.accountId = id;
}
public final void setAccountName(final String accountName) {
this.accountName = accountName;
}
public final void write(final GamePacket packet) {
this.session.write(packet);
}
protected IoSession getSession() {
return this.session;
}
public final long getLastPong() {
return this.lastPong;
}
public final void pongReceived() {
this.lastPong = System.currentTimeMillis();
}
public final void sendPing() {
final long then = System.currentTimeMillis();
this.session.write(getPingPacket());
TimerManager.getInstance().schedule(new Runnable() {
@Override
public void run() {
try {
if (GameClient.this.lastPong - then < 0) {
if (GameClient.this.session.isConnected()) {
GameClient.this.session.close(false);
}
}
} catch (final NullPointerException e) {
// client already gone
}
}
}, 150000000);
// note: idletime gets added to this too
}
private static GamePacket getPingPacket() {
final PacketBuilder builder = new PacketBuilder(16);
builder.writeAsShort(ServerPacketOpcode.PING.getValue());
return builder.getPacket();
}
public void unban() {
try {
final Connection con = Database.getConnection();
final PreparedStatement ps = con.prepareStatement("UPDATE accounts SET banned = 0 and banreason = '' WHERE id = ?");
ps.setInt(1, this.getAccountId());
ps.executeUpdate();
ps.close();
} catch (final SQLException e) {
System.err.println("Error while unbanning " + e);
}
}
public final ScheduledFuture<?> getIdleTask() {
return this.idleTask;
}
public final void setIdleTask(final ScheduledFuture<?> idleTask) {
this.idleTask = idleTask;
}
public final int getChannelId() {
return this.channelId;
}
public int getWorldId() {
return this.worldId;
}
public final void setChannelId(final int id) {
this.channelId = id;
}
public final void setWorldId(final int id) {
this.worldId = id;
}
public boolean isLoggedIn() {
return this.loggedIn;
}
protected void logOff() {
if (this.loggedIn) {
try {
final Connection con = Database.getConnection();
final PreparedStatement ps = con.prepareStatement("UPDATE `accounts` SET `loggedin` = ? WHERE `id` = ?");
ps.setBoolean(1, false);
ps.setInt(2, this.getAccountId());
ps.executeUpdate();
ps.close();
} catch (final SQLException e) {
System.err.println("error updating login state" + e);
}
}
}
}