2016-06-16 12:52:42 -04:00

583 lines
18 KiB
Java

package fr.xephi.authme.datasource;
import com.google.common.annotations.VisibleForTesting;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.settings.Settings;
import javax.swing.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Deprecated flat file datasource. The only method guaranteed to work is {@link FlatFile#getAllAuths()}
* as to migrate the entries to {@link SQLite} when AuthMe starts.
*/
@Deprecated
public class FlatFile implements DataSource {
/*
* file layout:
*
* PLAYERNAME:HASHSUM:IP:LOGININMILLIESECONDS:LASTPOSX:LASTPOSY:LASTPOSZ:
* LASTPOSWORLD:EMAIL
*
* Old but compatible:
* PLAYERNAME:HASHSUM:IP:LOGININMILLIESECONDS:LASTPOSX:LASTPOSY
* :LASTPOSZ:LASTPOSWORLD PLAYERNAME:HASHSUM:IP:LOGININMILLIESECONDS
* PLAYERNAME:HASHSUM:IP PLAYERNAME:HASHSUM
*/
private final File source;
public FlatFile() {
AuthMe instance = AuthMe.getInstance();
source = new File(instance.getDataFolder(), "auths.db");
try {
source.createNewFile();
} catch (IOException e) {
ConsoleLogger.logException("Cannot open flatfile", e);
if (Settings.isStopEnabled) {
ConsoleLogger.showError("Can't use FLAT FILE... SHUTDOWN...");
instance.getServer().shutdown();
}
if (!Settings.isStopEnabled) {
instance.getServer().getPluginManager().disablePlugin(instance);
}
}
}
@VisibleForTesting
public FlatFile(File source) {
this.source = source;
}
@Override
public void reload() {
throw new UnsupportedOperationException("Flatfile no longer supported");
}
@Override
public synchronized boolean isAuthAvailable(String user) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(source));
String line;
while ((line = br.readLine()) != null) {
String[] args = line.split(":");
if (args.length > 1 && args[0].equalsIgnoreCase(user)) {
return true;
}
}
} catch (IOException ex) {
ConsoleLogger.showError(ex.getMessage());
return false;
} finally {
silentClose(br);
}
return false;
}
@Override
public HashedPassword getPassword(String user) {
PlayerAuth auth = getAuth(user);
if (auth != null) {
return auth.getPassword();
}
return null;
}
@Override
public synchronized boolean saveAuth(PlayerAuth auth) {
if (isAuthAvailable(auth.getNickname())) {
return false;
}
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(source, true));
bw.write(auth.getNickname() + ":" + auth.getPassword().getHash() + ":" + auth.getIp() + ":" + auth.getLastLogin() + ":" + auth.getQuitLocX() + ":" + auth.getQuitLocY() + ":" + auth.getQuitLocZ() + ":" + auth.getWorld() + ":" + auth.getEmail() + "\n");
} catch (IOException ex) {
ConsoleLogger.showError(ex.getMessage());
return false;
} finally {
silentClose(bw);
}
return true;
}
@Override
public synchronized boolean updatePassword(PlayerAuth auth) {
return updatePassword(auth.getNickname(), auth.getPassword());
}
@Override
// Note ljacqu 20151230: This does not persist the salt; it is not supported in flat file.
public boolean updatePassword(String user, HashedPassword password) {
user = user.toLowerCase();
if (!isAuthAvailable(user)) {
return false;
}
PlayerAuth newAuth = null;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(source));
String line;
while ((line = br.readLine()) != null) {
String[] args = line.split(":");
if (args[0].equals(user)) {
newAuth = buildAuthFromArray(args);
if (newAuth != null) {
newAuth.setPassword(password);
}
break;
}
}
} catch (IOException ex) {
ConsoleLogger.showError(ex.getMessage());
return false;
} finally {
silentClose(br);
}
if (newAuth != null) {
removeAuth(user);
saveAuth(newAuth);
}
return true;
}
@Override
public boolean updateSession(PlayerAuth auth) {
if (!isAuthAvailable(auth.getNickname())) {
return false;
}
PlayerAuth newAuth = null;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(source));
String line;
while ((line = br.readLine()) != null) {
String[] args = line.split(":");
if (args[0].equalsIgnoreCase(auth.getNickname())) {
newAuth = buildAuthFromArray(args);
if (newAuth != null) {
newAuth.setLastLogin(auth.getLastLogin());
newAuth.setIp(auth.getIp());
}
break;
}
}
} catch (IOException ex) {
ConsoleLogger.showError(ex.getMessage());
return false;
} finally {
silentClose(br);
}
if (newAuth != null) {
removeAuth(auth.getNickname());
saveAuth(newAuth);
}
return true;
}
@Override
public boolean updateQuitLoc(PlayerAuth auth) {
if (!isAuthAvailable(auth.getNickname())) {
return false;
}
PlayerAuth newAuth = null;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(source));
String line;
while ((line = br.readLine()) != null) {
String[] args = line.split(":");
if (args[0].equalsIgnoreCase(auth.getNickname())) {
newAuth = buildAuthFromArray(args);
if (newAuth != null) {
newAuth.setQuitLocX(auth.getQuitLocX());
newAuth.setQuitLocY(auth.getQuitLocY());
newAuth.setQuitLocZ(auth.getQuitLocZ());
newAuth.setWorld(auth.getWorld());
newAuth.setEmail(auth.getEmail());
}
break;
}
}
} catch (IOException ex) {
ConsoleLogger.showError(ex.getMessage());
return false;
} finally {
silentClose(br);
}
if (newAuth != null) {
removeAuth(auth.getNickname());
saveAuth(newAuth);
}
return true;
}
@Override
public Set<String> getRecordsToPurge(long until) {
BufferedReader br = null;
Set<String> list = new HashSet<>();
try {
br = new BufferedReader(new FileReader(source));
String line;
while ((line = br.readLine()) != null) {
String[] args = line.split(":");
if (args.length >= 4) {
if (Long.parseLong(args[3]) >= until) {
list.add(args[0]);
continue;
}
}
}
} catch (IOException ex) {
ConsoleLogger.showError(ex.getMessage());
return list;
} finally {
silentClose(br);
}
return list;
}
@Override
public void purgeRecords(Set<String> toPurge) {
BufferedReader br = null;
BufferedWriter bw = null;
ArrayList<String> lines = new ArrayList<>();
try {
br = new BufferedReader(new FileReader(source));
bw = new BufferedWriter(new FileWriter(source));
String line;
while ((line = br.readLine()) != null) {
String[] args = line.split(":");
if (args.length >= 4) {
if (toPurge.contains(args[0])) {
lines.add(line);
continue;
}
}
}
for (String l : lines) {
bw.write(l + "\n");
}
} catch (IOException ex) {
ConsoleLogger.showError(ex.getMessage());
return;
} finally {
silentClose(br);
silentClose(bw);
}
}
@Override
public synchronized boolean removeAuth(String user) {
if (!isAuthAvailable(user)) {
return false;
}
BufferedReader br = null;
BufferedWriter bw = null;
ArrayList<String> lines = new ArrayList<>();
try {
br = new BufferedReader(new FileReader(source));
String line;
while ((line = br.readLine()) != null) {
String[] args = line.split(":");
if (args.length > 1 && !args[0].equals(user)) {
lines.add(line);
}
}
bw = new BufferedWriter(new FileWriter(source));
for (String l : lines) {
bw.write(l + "\n");
}
} catch (IOException ex) {
ConsoleLogger.showError(ex.getMessage());
return false;
} finally {
silentClose(br);
silentClose(bw);
}
return true;
}
@Override
public synchronized PlayerAuth getAuth(String user) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(source));
String line;
while ((line = br.readLine()) != null) {
String[] args = line.split(":");
if (args[0].equalsIgnoreCase(user)) {
return buildAuthFromArray(args);
}
}
} catch (IOException ex) {
ConsoleLogger.showError(ex.getMessage());
return null;
} finally {
silentClose(br);
}
return null;
}
@Override
public synchronized void close() {
}
@Override
public boolean updateEmail(PlayerAuth auth) {
if (!isAuthAvailable(auth.getNickname())) {
return false;
}
PlayerAuth newAuth = null;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(source));
String line;
while ((line = br.readLine()) != null) {
String[] args = line.split(":");
if (args[0].equals(auth.getNickname())) {
newAuth = buildAuthFromArray(args);
if (newAuth != null) {
newAuth.setEmail(auth.getEmail());
}
break;
}
}
} catch (FileNotFoundException ex) {
ConsoleLogger.showError(ex.getMessage());
return false;
} catch (IOException ex) {
ConsoleLogger.showError(ex.getMessage());
return false;
} finally {
if (br != null) {
try {
br.close();
} catch (IOException ignored) {
}
}
}
if (newAuth != null) {
removeAuth(auth.getNickname());
saveAuth(newAuth);
}
return true;
}
@Override
public List<String> getAllAuthsByIp(String ip) {
BufferedReader br = null;
List<String> countIp = new ArrayList<>();
try {
br = new BufferedReader(new FileReader(source));
String line;
while ((line = br.readLine()) != null) {
String[] args = line.split(":");
if (args.length > 3 && args[2].equals(ip)) {
countIp.add(args[0]);
}
}
return countIp;
} catch (FileNotFoundException ex) {
ConsoleLogger.showError(ex.getMessage());
return new ArrayList<>();
} catch (IOException ex) {
ConsoleLogger.showError(ex.getMessage());
return new ArrayList<>();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException ignored) {
}
}
}
}
@Override
public int countAuthsByEmail(String email) {
BufferedReader br = null;
int countEmail = 0;
try {
br = new BufferedReader(new FileReader(source));
String line;
while ((line = br.readLine()) != null) {
String[] args = line.split(":");
if (args.length > 8 && args[8].equals(email)) {
++countEmail;
}
}
return countEmail;
} catch (IOException ex) {
ConsoleLogger.showError(ex.getMessage());
} finally {
if (br != null) {
try {
br.close();
} catch (IOException ignored) {
}
}
}
return 0;
}
@Override
public void purgeBanned(Set<String> banned) {
BufferedReader br = null;
BufferedWriter bw = null;
ArrayList<String> lines = new ArrayList<>();
try {
br = new BufferedReader(new FileReader(source));
String line;
while ((line = br.readLine()) != null) {
String[] args = line.split(":");
try {
if (banned.contains(args[0])) {
lines.add(line);
}
} catch (NullPointerException | ArrayIndexOutOfBoundsException ignored) {
}
}
bw = new BufferedWriter(new FileWriter(source));
for (String l : lines) {
bw.write(l + "\n");
}
} catch (IOException ex) {
ConsoleLogger.showError(ex.getMessage());
} finally {
silentClose(br);
silentClose(bw);
}
}
@Override
public DataSourceType getType() {
return DataSourceType.FILE;
}
@Override
public boolean isLogged(String user) {
return PlayerCache.getInstance().isAuthenticated(user);
}
@Override
public void setLogged(String user) {
}
@Override
public void setUnlogged(String user) {
}
@Override
public void purgeLogged() {
}
@Override
public int getAccountsRegistered() {
BufferedReader br = null;
int result = 0;
try {
br = new BufferedReader(new FileReader(source));
while ((br.readLine()) != null) {
result++;
}
} catch (Exception ex) {
ConsoleLogger.showError(ex.getMessage());
return result;
} finally {
silentClose(br);
}
return result;
}
@Override
public boolean updateRealName(String user, String realName) {
throw new UnsupportedOperationException("Flat file no longer supported");
}
@Override
public boolean updateIp(String user, String ip) {
throw new UnsupportedOperationException("Flat file no longer supported");
}
@Override
public List<PlayerAuth> getAllAuths() {
BufferedReader br = null;
List<PlayerAuth> auths = new ArrayList<>();
try {
br = new BufferedReader(new FileReader(source));
String line;
while ((line = br.readLine()) != null) {
String[] args = line.split(":");
PlayerAuth auth = buildAuthFromArray(args);
if (auth != null) {
auths.add(auth);
}
}
} catch (IOException ex) {
ConsoleLogger.logException("Error while getting auths from flatfile:", ex);
} finally {
silentClose(br);
}
return auths;
}
@Override
public List<PlayerAuth> getLoggedPlayers() {
throw new UnsupportedOperationException("Flat file no longer supported");
}
private static PlayerAuth buildAuthFromArray(String[] args) {
// Format allows 2, 3, 4, 7, 8, 9 fields. Anything else is unknown
if (args.length >= 2 && args.length <= 9 && args.length != 5 && args.length != 6) {
PlayerAuth.Builder builder = PlayerAuth.builder()
.name(args[0]).realName(args[0]).password(args[1], null);
if (args.length >= 3) builder.ip(args[2]);
if (args.length >= 4) builder.lastLogin(Long.parseLong(args[3]));
if (args.length >= 7) {
builder.locX(Double.parseDouble(args[4]))
.locY(Double.parseDouble(args[5]))
.locZ(Double.parseDouble(args[6]));
}
if (args.length >= 8) builder.locWorld(args[7]);
if (args.length >= 9) builder.email(args[8]);
return builder.build();
}
return null;
}
private static void silentClose(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ignored) {
// silent close
}
}
}
}