package games.strategy.engine.lobby.server.userDB;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Utilitiy class to create/read/delete muted macs (there is no update).
*/
public class MutedMacController {
private static final Logger s_logger = Logger.getLogger(MutedMacController.class.getName());
/**
* Mute the mac permanently.
*/
public void addMutedMac(final String mac) {
addMutedMac(mac, null);
}
/**
* Mute the given mac. If muteTill is not null, the mute will expire when muteTill is reached.
*
* <p>
* If this mac is already muted, this call will update the mute_end.
* </p>
*/
public void addMutedMac(final String mac, final Date muteTill) {
if (isMacMuted(mac)) {
removeMutedMac(mac);
}
Timestamp muteTillTs = null;
if (muteTill != null) {
muteTillTs = new Timestamp(muteTill.getTime());
}
s_logger.fine("Muting mac:" + mac);
final Connection con = Database.getConnection();
try {
final PreparedStatement ps = con.prepareStatement("insert into muted_macs (mac, mute_till) values (?, ?)");
ps.setString(1, mac);
ps.setTimestamp(2, muteTillTs);
ps.execute();
ps.close();
con.commit();
} catch (final SQLException sqle) {
if (sqle.getErrorCode() == 30000) {
// this is ok
// the mac is muted as expected
s_logger.info("Tried to create duplicate muted mac:" + mac + " error:" + sqle.getMessage());
return;
}
s_logger.log(Level.SEVERE, "Error inserting muted mac:" + mac, sqle);
throw new IllegalStateException(sqle.getMessage());
} finally {
DbUtil.closeConnection(con);
}
}
public void removeMutedMac(final String mac) {
s_logger.fine("Removing muted mac:" + mac);
final Connection con = Database.getConnection();
try {
final PreparedStatement ps = con.prepareStatement("delete from muted_macs where mac = ?");
ps.setString(1, mac);
ps.execute();
ps.close();
con.commit();
} catch (final SQLException sqle) {
s_logger.log(Level.SEVERE, "Error deleting muted mac:" + mac, sqle);
throw new IllegalStateException(sqle.getMessage());
} finally {
DbUtil.closeConnection(con);
}
}
/**
* Is the given mac muted? This may have the side effect of removing from the
* database any mac's whose mute has expired.
*/
public boolean isMacMuted(final String mac) {
final long muteTill = getMacUnmuteTime(mac);
return muteTill > System.currentTimeMillis();
}
public long getMacUnmuteTime(final String mac) {
long result = -1;
boolean expired = false;
final String sql = "select mac, mute_till from muted_macs where mac = ?";
final Connection con = Database.getConnection();
try {
final PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1, mac);
final ResultSet rs = ps.executeQuery();
final boolean found = rs.next();
if (found) {
final Timestamp muteTill = rs.getTimestamp(2);
result = muteTill.getTime();
if (result < System.currentTimeMillis()) {
s_logger.fine("Mute expired for:" + mac);
expired = true;
}
} else {
result = -1;
}
rs.close();
ps.close();
} catch (final SQLException sqle) {
s_logger.info("Error for testing muted mac existence:" + mac + " error:" + sqle.getMessage());
throw new IllegalStateException(sqle.getMessage());
} finally {
DbUtil.closeConnection(con);
}
// If the mute has expired, allow the mac
if (expired) {
removeMutedMac(mac);
// Signal as not-muted
result = -1;
}
return result;
}
public List<String> getMacsThatAreStillMuted(final List<String> macs) {
final List<String> results = new ArrayList<>();
final String sql = "select mac, mute_till from muted_macs where mac = ?";
final Connection con = Database.getConnection();
try {
for (final String mac : macs) {
boolean found = false;
boolean expired = false;
final PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1, mac);
final ResultSet rs = ps.executeQuery();
found = rs.next();
// If the mute has expired, allow the mac
if (found) {
final Timestamp muteTill = rs.getTimestamp(2);
if (muteTill != null && muteTill.getTime() < System.currentTimeMillis()) {
s_logger.fine("Mute expired for: " + mac);
expired = true;
}
}
rs.close();
ps.close();
if (found && !expired) {
results.add(mac);
}
}
} catch (final SQLException sqle) {
s_logger.info("Error testing whether macs were muted: " + macs);
throw new IllegalStateException(sqle.getMessage());
} finally {
DbUtil.closeConnection(con);
}
return results;
}
}