package cn.citycraft.AuthMe.settings;

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.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import cn.citycraft.AuthMe.AuthMe;
import cn.citycraft.AuthMe.ConsoleLogger;
import cn.citycraft.AuthMe.datasource.DataSource;
import cn.citycraft.AuthMe.datasource.DataSource.DataSourceType;
import cn.citycraft.AuthMe.security.HashAlgorithm;
import cn.citycraft.PluginHelper.config.FileConfig;

public final class Settings {

	public static List<String> allowCommands;
	// This is not an option!
	public static boolean antiBotInAction = false;
	public static final File APLUGIN_FOLDER = AuthMe.getInstance().getDataFolder();
	public static final File AUTH_FILE = new File(APLUGIN_FOLDER, "auths.db");

	public static final File CACHE_FOLDER = new File(APLUGIN_FOLDER, "cache");

	public static List<String> countries;
	public static List<String> countriesBlacklist;
	public static List<String> emailBlacklist;
	public static List<String> emailWhitelist;
	public static List<String> forceCommands;
	public static List<String> forceCommandsAsConsole;

	public static List<String> forceRegisterCommands;
	public static List<String> forceRegisterCommandsAsConsole;
	public static DataSourceType getDataSource;
	public static List<String> getForcedWorlds;
	public static List<String> getJoinPermissions;
	public static List<String> getMySQLOtherUsernameColumn;
	public static String getNickRegex, getUnloggedinGroup, getMySQLHost, getMySQLPort, getMySQLUsername, getMySQLPassword, getMySQLDatabase, getMySQLTablename, getMySQLColumnName,
			getMySQLColumnPassword, getMySQLColumnIp, getMySQLColumnLastLogin, getMySQLColumnSalt, getMySQLColumnGroup, getMySQLColumnEmail, unRegisteredGroup, backupWindowsPath, getRegisteredGroup,
			getMySQLlastlocX, getMySQLlastlocY, getMySQLlastlocZ, rakamakUsers, rakamakUsersIp, getmailAccount, getmailPassword, getmailSMTP, getMySQLColumnId, getmailSenderName, getMailSubject,
			getMailText, getMySQLlastlocWorld, defaultWorld, getPhpbbPrefix, getWordPressPrefix, getMySQLColumnLogged, spawnPriority, crazyloginFileName, getPassRegex, getMySQLColumnRealName;
	public static HashAlgorithm getPasswordHash;
	public static List<String> getRestrictedIp;
	public static List<String> getUnrestrictedName;
	public static int getWarnMessageInterval, getSessionTimeout, getRegistrationTimeout, getMaxNickLength, getMinNickLength, getPasswordMinLen, getMovementRadius, getmaxRegPerIp, getNonActivatedGroup,
			passwordMaxLength, getRecoveryPassLength, getMailPort, maxLoginTry, captchaLength, saltLength, getmaxRegPerEmail, bCryptLog2Rounds, getPhpbbGroup, antiBotSensibility, antiBotDuration,
			delayRecall, getMaxLoginPerIp, getMaxJoinPerIp, getMySQLMaxConnections;
	public static boolean isPermissionCheckEnabled, isRegistrationEnabled, isForcedRegistrationEnabled, isTeleportToSpawnEnabled, isSessionsEnabled, isChatAllowed, isAllowRestrictedIp,
			isMovementAllowed, isKickNonRegisteredEnabled, isForceSingleSessionEnabled, isForceSpawnLocOnJoinEnabled, isSaveQuitLocationEnabled, isForceSurvivalModeEnabled, isResetInventoryIfCreative,
			isCachingEnabled, isKickOnWrongPasswordEnabled, getEnablePasswordVerifier, protectInventoryBeforeLogInEnabled, isBackupActivated, isBackupOnStart, isBackupOnStop, isStopEnabled,
			reloadSupport, rakamakUseIp, noConsoleSpam, removePassword, displayOtherAccounts, useCaptcha, emailRegistration, multiverse, bungee, banUnsafeIp, doubleEmailCheck, sessionExpireOnIpChange,
			disableSocialSpy, forceOnlyAfterLogin, useEssentialsMotd, usePurge, purgePlayerDat, purgeEssentialsFile, supportOldPassword, purgeLimitedCreative, purgeAntiXray, purgePermissions,
			enableProtection, enableAntiBot, recallEmail, useWelcomeMessage, broadcastWelcomeMessage, forceRegKick, forceRegLogin, checkVeryGames, delayJoinMessage, noTeleport, applyBlindEffect,
			customAttributes, generateImage, isRemoveSpeedEnabled;
	public static final File LOG_FILE = new File(APLUGIN_FOLDER, "authme.log");
	public static int purgeDelay = 60;
	public static final File SETTINGS_FILE = new File(APLUGIN_FOLDER, "config.yml");
	public static List<String> unsafePasswords;
	public static boolean useLogging = false;

	public static List<String> welcomeMsg;

	private static AuthMe plugin;

	protected static FileConfig configFile;

	public Settings(final AuthMe pl) {
		plugin = pl;
		configFile = (FileConfig) plugin.getConfig();
	}

	/**
	 * Config option for setting and check restricted user by username;ip ,
	 * return false if ip and name doesnt amtch with player that join the
	 * server, so player has a restricted access
	 */
	public static boolean getRestrictedIp(final String name, final String ip) {

		final Iterator<String> iter = getRestrictedIp.iterator();
		boolean trueonce = false;
		boolean namefound = false;
		while (iter.hasNext()) {
			final String[] args = iter.next().split(";");
			final String testname = args[0];
			final String testip = args[1];
			if (testname.equalsIgnoreCase(name)) {
				namefound = true;
				if (testip.equalsIgnoreCase(ip)) {
					trueonce = true;
				}
			}
		}
		return !namefound || trueonce;
	}

	public static boolean isEmailCorrect(final String email) {
		if (!email.contains("@")) {
			return false;
		}
		if (email.equalsIgnoreCase("your@email.com")) {
			return false;
		}
		final String emailDomain = email.split("@")[1];
		boolean correct = true;
		if (emailWhitelist != null && !emailWhitelist.isEmpty()) {
			for (final String domain : emailWhitelist) {
				if (!domain.equalsIgnoreCase(emailDomain)) {
					correct = false;
				} else {
					correct = true;
					break;
				}
			}
			return correct;
		}
		if (emailBlacklist != null && !emailBlacklist.isEmpty()) {
			for (final String domain : emailBlacklist) {
				if (domain.equalsIgnoreCase(emailDomain)) {
					correct = false;
					break;
				}
			}
		}
		return correct;
	}

	public static void loadVariables() {
		isPermissionCheckEnabled = configFile.getBoolean("permission.EnablePermissionCheck", false);
		isForcedRegistrationEnabled = configFile.getBoolean("settings.registration.force", true);
		isRegistrationEnabled = configFile.getBoolean("settings.registration.enabled", true);
		isTeleportToSpawnEnabled = configFile.getBoolean("settings.restrictions.teleportUnAuthedToSpawn", false);
		getWarnMessageInterval = configFile.getInt("settings.registration.messageInterval", 5);
		isSessionsEnabled = configFile.getBoolean("settings.sessions.enabled", false);
		getSessionTimeout = configFile.getInt("settings.sessions.timeout", 10);
		getRegistrationTimeout = configFile.getInt("settings.restrictions.timeout", 30);
		isChatAllowed = configFile.getBoolean("settings.restrictions.allowChat", false);
		getMaxNickLength = configFile.getInt("settings.restrictions.maxNicknameLength", 20);
		getMinNickLength = configFile.getInt("settings.restrictions.minNicknameLength", 3);
		getPasswordMinLen = configFile.getInt("settings.security.minPasswordLength", 4);
		getNickRegex = configFile.getString("settings.restrictions.allowedNicknameCharacters", "[a-zA-Z0-9_?]*");
		isAllowRestrictedIp = configFile.getBoolean("settings.restrictions.AllowRestrictedUser", false);
		getRestrictedIp = configFile.getStringList("settings.restrictions.AllowedRestrictedUser");
		isMovementAllowed = configFile.getBoolean("settings.restrictions.allowMovement", false);
		isRemoveSpeedEnabled = configFile.getBoolean("settings.restrictions.removeSpeed", true);
		getMovementRadius = configFile.getInt("settings.restrictions.allowedMovementRadius", 100);
		getJoinPermissions = configFile.getStringList("GroupOptions.Permissions.PermissionsOnJoin");
		isKickOnWrongPasswordEnabled = configFile.getBoolean("settings.restrictions.kickOnWrongPassword", false);
		isKickNonRegisteredEnabled = configFile.getBoolean("settings.restrictions.kickNonRegistered", false);
		isForceSingleSessionEnabled = configFile.getBoolean("settings.restrictions.ForceSingleSession", true);
		isForceSpawnLocOnJoinEnabled = configFile.getBoolean("settings.restrictions.ForceSpawnLocOnJoinEnabled", false);
		isSaveQuitLocationEnabled = configFile.getBoolean("settings.restrictions.SaveQuitLocation", false);
		isForceSurvivalModeEnabled = configFile.getBoolean("settings.GameMode.ForceSurvivalMode", false);
		isResetInventoryIfCreative = configFile.getBoolean("settings.GameMode.ResetInventoryIfCreative", false);
		getmaxRegPerIp = configFile.getInt("settings.restrictions.maxRegPerIp", 1);
		getPasswordHash = getPasswordHash();
		getUnloggedinGroup = configFile.getString("settings.security.unLoggedinGroup", "unLoggedInGroup");
		getDataSource = getDataSource();
		isCachingEnabled = configFile.getBoolean("DataSource.caching", true);
		getMySQLHost = configFile.getString("DataSource.mySQLHost", "127.0.0.1");
		getMySQLPort = configFile.getString("DataSource.mySQLPort", "3306");
		getMySQLMaxConnections = configFile.getInt("DataSource.mySQLMaxConections", 25);
		getMySQLUsername = configFile.getString("DataSource.mySQLUsername", "authme");
		getMySQLPassword = configFile.getString("DataSource.mySQLPassword", "12345");
		getMySQLDatabase = configFile.getString("DataSource.mySQLDatabase", "authme");
		getMySQLTablename = configFile.getString("DataSource.mySQLTablename", "authme");
		getMySQLColumnEmail = configFile.getString("DataSource.mySQLColumnEmail", "email");
		getMySQLColumnName = configFile.getString("DataSource.mySQLColumnName", "username");
		getMySQLColumnPassword = configFile.getString("DataSource.mySQLColumnPassword", "password");
		getMySQLColumnIp = configFile.getString("DataSource.mySQLColumnIp", "ip");
		getMySQLColumnLastLogin = configFile.getString("DataSource.mySQLColumnLastLogin", "lastlogin");
		getMySQLColumnSalt = configFile.getString("ExternalBoardOptions.mySQLColumnSalt");
		getMySQLColumnGroup = configFile.getString("ExternalBoardOptions.mySQLColumnGroup", "");
		getMySQLlastlocX = configFile.getString("DataSource.mySQLlastlocX", "x");
		getMySQLlastlocY = configFile.getString("DataSource.mySQLlastlocY", "y");
		getMySQLlastlocZ = configFile.getString("DataSource.mySQLlastlocZ", "z");
		getMySQLlastlocWorld = configFile.getString("DataSource.mySQLlastlocWorld", "world");
		getMySQLColumnRealName = configFile.getString("DataSource.mySQLRealName", "realname");
		getNonActivatedGroup = configFile.getInt("ExternalBoardOptions.nonActivedUserGroup", -1);
		unRegisteredGroup = configFile.getString("GroupOptions.UnregisteredPlayerGroup", "");
		getUnrestrictedName = configFile.getStringList("settings.unrestrictions.UnrestrictedName");
		getRegisteredGroup = configFile.getString("GroupOptions.RegisteredPlayerGroup", "");
		getEnablePasswordVerifier = configFile.getBoolean("settings.restrictions.enablePasswordVerifier", true);
		protectInventoryBeforeLogInEnabled = configFile.getBoolean("settings.restrictions.ProtectInventoryBeforeLogIn", true);
		passwordMaxLength = configFile.getInt("settings.security.passwordMaxLength", 20);
		isBackupActivated = configFile.getBoolean("BackupSystem.ActivateBackup", false);
		isBackupOnStart = configFile.getBoolean("BackupSystem.OnServerStart", false);
		isBackupOnStop = configFile.getBoolean("BackupSystem.OnServeStop", false);
		backupWindowsPath = configFile.getString("BackupSystem.MysqlWindowsPath", "C:\\Program Files\\MySQL\\MySQL Server 5.1\\");
		isStopEnabled = configFile.getBoolean("Security.SQLProblem.stopServer", true);
		reloadSupport = configFile.getBoolean("Security.ReloadCommand.useReloadCommandSupport", true);
		allowCommands = configFile.getStringList("settings.restrictions.allowCommands");
		if (configFile.contains("allowCommands")) {
			if (!allowCommands.contains("/login")) {
				allowCommands.add("/login");
			}
			if (!allowCommands.contains("/register")) {
				allowCommands.add("/register");
			}
			if (!allowCommands.contains("/l")) {
				allowCommands.add("/l");
			}
			if (!allowCommands.contains("/reg")) {
				allowCommands.add("/reg");
			}
			if (!allowCommands.contains("/email")) {
				allowCommands.add("/email");
			}
			if (!allowCommands.contains("/captcha")) {
				allowCommands.add("/captcha");
			}
		}
		rakamakUsers = configFile.getString("Converter.Rakamak.fileName", "users.rak");
		rakamakUsersIp = configFile.getString("Converter.Rakamak.ipFileName", "UsersIp.rak");
		rakamakUseIp = configFile.getBoolean("Converter.Rakamak.useIp", false);
		noConsoleSpam = configFile.getBoolean("Security.console.noConsoleSpam", false);
		removePassword = configFile.getBoolean("Security.console.removePassword", true);
		getmailAccount = configFile.getString("Email.mailAccount", "");
		getmailPassword = configFile.getString("Email.mailPassword", "");
		getmailSMTP = configFile.getString("Email.mailSMTP", "smtp.gmail.com");
		getMailPort = configFile.getInt("Email.mailPort", 465);
		getRecoveryPassLength = configFile.getInt("Email.RecoveryPasswordLength", 8);
		getMySQLOtherUsernameColumn = configFile.getStringList("ExternalBoardOptions.mySQLOtherUsernameColumns");
		displayOtherAccounts = configFile.getBoolean("settings.restrictions.displayOtherAccounts", true);
		getMySQLColumnId = configFile.getString("DataSource.mySQLColumnId", "id");
		getmailSenderName = configFile.getString("Email.mailSenderName", "");
		useCaptcha = configFile.getBoolean("Security.captcha.useCaptcha", false);
		maxLoginTry = configFile.getInt("Security.captcha.maxLoginTry", 5);
		captchaLength = configFile.getInt("Security.captcha.captchaLength", 5);
		getMailSubject = configFile.getString("Email.mailSubject", "Your new AuthMe Password");
		getMailText = configFile.getString("Email.mailText",
				"Dear <playername>, <br /><br /> This is your new AuthMe password for the server <br /><br /> <servername> : <br /><br /> <generatedpass><br /><br />Do not forget to change password after login! <br /> /changepassword <generatedpass> newPassword");
		emailRegistration = configFile.getBoolean("settings.registration.enableEmailRegistrationSystem", false);
		saltLength = configFile.getInt("settings.security.doubleMD5SaltLength", 8);
		getmaxRegPerEmail = configFile.getInt("Email.maxRegPerEmail", 1);
		multiverse = configFile.getBoolean("Hooks.multiverse", true);
		bungee = configFile.getBoolean("Hooks.bungeecord", false);
		getForcedWorlds = configFile.getStringList("settings.restrictions.ForceSpawnOnTheseWorlds");
		banUnsafeIp = configFile.getBoolean("settings.restrictions.banUnsafedIP", false);
		doubleEmailCheck = configFile.getBoolean("settings.registration.doubleEmailCheck", false);
		sessionExpireOnIpChange = configFile.getBoolean("settings.sessions.sessionExpireOnIpChange", true);
		useLogging = configFile.getBoolean("Security.console.logConsole", false);
		disableSocialSpy = configFile.getBoolean("Hooks.disableSocialSpy", true);
		bCryptLog2Rounds = configFile.getInt("ExternalBoardOptions.bCryptLog2Round", 10);
		forceOnlyAfterLogin = configFile.getBoolean("settings.GameMode.ForceOnlyAfterLogin", false);
		useEssentialsMotd = configFile.getBoolean("Hooks.useEssentialsMotd", false);
		usePurge = configFile.getBoolean("Purge.useAutoPurge", false);
		purgeDelay = configFile.getInt("Purge.daysBeforeRemovePlayer", 60);
		purgePlayerDat = configFile.getBoolean("Purge.removePlayerDat", false);
		purgeEssentialsFile = configFile.getBoolean("Purge.removeEssentialsFile", false);
		defaultWorld = configFile.getString("Purge.defaultWorld", "world");
		getPhpbbPrefix = configFile.getString("ExternalBoardOptions.phpbbTablePrefix", "phpbb_");
		getPhpbbGroup = configFile.getInt("ExternalBoardOptions.phpbbActivatedGroupId", 2);
		supportOldPassword = configFile.getBoolean("settings.security.supportOldPasswordHash", false);
		getWordPressPrefix = configFile.getString("ExternalBoardOptions.wordpressTablePrefix", "wp_");
		purgeLimitedCreative = configFile.getBoolean("Purge.removeLimitedCreativesInventories", false);
		purgeAntiXray = configFile.getBoolean("Purge.removeAntiXRayFile", false);
		purgePermissions = configFile.getBoolean("Purge.removePermissions", false);
		enableProtection = configFile.getBoolean("Protection.enableProtection", false);
		countries = configFile.getStringList("Protection.countries");
		enableAntiBot = configFile.getBoolean("Protection.enableAntiBot", false);
		antiBotSensibility = configFile.getInt("Protection.antiBotSensibility", 5);
		antiBotDuration = configFile.getInt("Protection.antiBotDuration", 10);
		forceCommands = configFile.getStringList("settings.forceCommands");
		forceCommandsAsConsole = configFile.getStringList("settings.forceCommandsAsConsole");
		recallEmail = configFile.getBoolean("Email.recallPlayers", false);
		delayRecall = configFile.getInt("Email.delayRecall", 5);
		useWelcomeMessage = configFile.getBoolean("settings.useWelcomeMessage", true);
		unsafePasswords = configFile.getStringList("settings.security.unsafePasswords");
		countriesBlacklist = configFile.getStringList("Protection.countriesBlacklist");
		broadcastWelcomeMessage = configFile.getBoolean("settings.broadcastWelcomeMessage", false);
		forceRegKick = configFile.getBoolean("settings.registration.forceKickAfterRegister", false);
		forceRegLogin = configFile.getBoolean("settings.registration.forceLoginAfterRegister", false);
		getMySQLColumnLogged = configFile.getString("DataSource.mySQLColumnLogged", "isLogged");
		spawnPriority = configFile.getString("settings.restrictions.spawnPriority", "authme,essentials,multiverse,default");
		getMaxLoginPerIp = configFile.getInt("settings.restrictions.maxLoginPerIp", 0);
		getMaxJoinPerIp = configFile.getInt("settings.restrictions.maxJoinPerIp", 0);
		checkVeryGames = configFile.getBoolean("VeryGames.enableIpCheck", false);
		delayJoinMessage = configFile.getBoolean("settings.delayJoinMessage", false);
		noTeleport = configFile.getBoolean("settings.restrictions.noTeleport", false);
		crazyloginFileName = configFile.getString("Converter.CrazyLogin.fileName", "accounts.db");
		getPassRegex = configFile.getString("settings.restrictions.allowedPasswordCharacters", "[\\x21-\\x7E]*");
		applyBlindEffect = configFile.getBoolean("settings.applyBlindEffect", false);
		emailBlacklist = configFile.getStringList("Email.emailBlacklisted");
		emailWhitelist = configFile.getStringList("Email.emailWhitelisted");
		forceRegisterCommands = configFile.getStringList("settings.forceRegisterCommands");
		forceRegisterCommandsAsConsole = configFile.getStringList("settings.forceRegisterCommandsAsConsole");
		customAttributes = configFile.getBoolean("Hooks.customAttributes");
		generateImage = configFile.getBoolean("Email.generateImage", true);
		// Load the welcome message
		getWelcomeMessage();

	}

	public static boolean reloadcfg() {
		return configFile.reload();
	}

	public static void setValue(final String key, final Object value) {
		configFile.set(key, value);
		configFile.save();
	}

	public static void switchAntiBotMod(final boolean mode) {
		if (mode) {
			isKickNonRegisteredEnabled = true;
			antiBotInAction = true;
		} else {
			isKickNonRegisteredEnabled = configFile.getBoolean("settings.restrictions.kickNonRegistered", false);
			antiBotInAction = false;
		}
	}

	private static DataSourceType getDataSource() {
		final String key = "DataSource.backend";
		try {
			return DataSource.DataSourceType.valueOf(configFile.getString(key, "sqlite").toUpperCase());
		} catch (final IllegalArgumentException ex) {
			ConsoleLogger.showError("未知的数据库类型; 默认使用SQLite...");
			return DataSource.DataSourceType.SQLITE;
		}
	}

	private static HashAlgorithm getPasswordHash() {
		final String key = "settings.security.passwordHash";
		try {
			return HashAlgorithm.valueOf(configFile.getString(key, "SHA256").toUpperCase());
		} catch (final IllegalArgumentException ex) {
			ConsoleLogger.showError("未知的密码加密; 默认使用 SHA256 ...");
			return HashAlgorithm.SHA256;
		}
	}

	private static void getWelcomeMessage() {
		final AuthMe plugin = AuthMe.getInstance();
		welcomeMsg = new ArrayList<>();
		if (!useWelcomeMessage) {
			return;
		}
		if (!(new File(plugin.getDataFolder() + File.separator + "welcome.txt").exists())) {
			try {
				final FileWriter fw = new FileWriter(plugin.getDataFolder() + File.separator + "welcome.txt", true);
				final BufferedWriter w = new BufferedWriter(fw);
				w.write("§6欢迎 §a{PLAYER} §6来到 §b{SERVER} §6服务器");
				w.newLine();
				w.write("§a当前服务器使用 §dAuthMe §a登陆系统 §6- §c重制 By:喵♂呜!");
				w.close();
			} catch (final IOException e) {
				e.printStackTrace();
			}
		}
		try {
			final FileReader fr = new FileReader(plugin.getDataFolder() + File.separator + "welcome.txt");
			final BufferedReader br = new BufferedReader(fr);
			String line;
			while ((line = br.readLine()) != null) {
				welcomeMsg.add(line);
			}
			br.close();
		} catch (final IOException e) {
			e.printStackTrace();
		}
	}

	public void mergeConfig() {
		boolean changes = false;
		if (configFile.contains("Xenoforo.predefinedSalt")) {
			configFile.set("Xenoforo.predefinedSalt", null);
			changes = true;
		}
		if (configFile.getString("settings.security.passwordHash", "SHA256").toUpperCase().equals("XFSHA1")
				|| configFile.getString("settings.security.passwordHash", "SHA256").toUpperCase().equals("XFSHA256")) {
			configFile.set("settings.security.passwordHash", "XENFORO");
			changes = true;
		}
		if (!configFile.contains("Protection.enableProtection")) {
			configFile.set("Protection.enableProtection", false);
			changes = true;
		}
		if (!configFile.contains("settings.restrictions.removeSpeed")) {
			configFile.set("settings.restrictions.removeSpeed", true);
			changes = true;
		}
		if (!configFile.contains("DataSource.mySQLMaxConections")) {
			configFile.set("DataSource.mySQLMaxConections", 25);
			changes = true;
		}
		if (!configFile.contains("Protection.countries")) {
			countries = new ArrayList<>();
			countries.add("US");
			countries.add("GB");
			configFile.set("Protection.countries", countries);
			changes = true;
		}
		if (!configFile.contains("Protection.enableAntiBot")) {
			configFile.set("Protection.enableAntiBot", false);
			changes = true;
		}
		if (!configFile.contains("Protection.antiBotSensibility")) {
			configFile.set("Protection.antiBotSensibility", 5);
			changes = true;
		}
		if (!configFile.contains("Protection.antiBotDuration")) {
			configFile.set("Protection.antiBotDuration", 10);
			changes = true;
		}
		if (!configFile.contains("settings.forceCommands")) {
			configFile.set("settings.forceCommands", new ArrayList<String>());
			changes = true;
		}
		if (!configFile.contains("settings.forceCommandsAsConsole")) {
			configFile.set("settings.forceCommandsAsConsole", new ArrayList<String>());
			changes = true;
		}
		if (!configFile.contains("Email.recallPlayers")) {
			configFile.set("Email.recallPlayers", false);
			changes = true;
		}
		if (!configFile.contains("Email.delayRecall")) {
			configFile.set("Email.delayRecall", 5);
			changes = true;
		}
		if (!configFile.contains("settings.useWelcomeMessage")) {
			configFile.set("settings.useWelcomeMessage", true);
			changes = true;
		}
		if (!configFile.contains("settings.security.unsafePasswords")) {
			final List<String> str = new ArrayList<>();
			str.add("123456");
			str.add("password");
			configFile.set("settings.security.unsafePasswords", str);
			changes = true;
		}
		if (!configFile.contains("Protection.countriesBlacklist")) {
			countriesBlacklist = new ArrayList<>();
			countriesBlacklist.add("A1");
			configFile.set("Protection.countriesBlacklist", countriesBlacklist);
			changes = true;
		}
		if (!configFile.contains("settings.broadcastWelcomeMessage")) {
			configFile.set("settings.broadcastWelcomeMessage", false);
			changes = true;
		}
		if (!configFile.contains("settings.registration.forceKickAfterRegister")) {
			configFile.set("settings.registration.forceKickAfterRegister", false);
			changes = true;
		}
		if (!configFile.contains("settings.registration.forceLoginAfterRegister")) {
			configFile.set("settings.registration.forceLoginAfterRegister", false);
			changes = true;
		}
		if (!configFile.contains("DataSource.mySQLColumnLogged")) {
			configFile.set("DataSource.mySQLColumnLogged", "isLogged");
			changes = true;
		}
		if (!configFile.contains("settings.restrictions.spawnPriority")) {
			configFile.set("settings.restrictions.spawnPriority", "authme,essentials,multiverse,default");
			changes = true;
		}
		if (!configFile.contains("settings.restrictions.maxLoginPerIp")) {
			configFile.set("settings.restrictions.maxLoginPerIp", 0);
			changes = true;
		}
		if (!configFile.contains("settings.restrictions.maxJoinPerIp")) {
			configFile.set("settings.restrictions.maxJoinPerIp", 0);
			changes = true;
		}
		if (configFile.getString("settings.restrictions.allowedNicknameCharacters").equals("[a-zA-Z0-9_?]*")) {
			configFile.set("settings.restrictions.allowedNicknameCharacters", "[a-zA-Z0-9_]*");
			changes = true;
		}
		if (!configFile.contains("settings.delayJoinMessage")) {
			configFile.set("settings.delayJoinMessage", false);
			changes = true;
		}
		if (!configFile.contains("settings.restrictions.noTeleport")) {
			configFile.set("settings.restrictions.noTeleport", false);
			changes = true;
		}
		if (configFile.contains("Converter.Rakamak.newPasswordHash")) {
			configFile.set("Converter.Rakamak.newPasswordHash", null);
			changes = true;
		}
		if (!configFile.contains("Converter.CrazyLogin.fileName")) {
			configFile.set("Converter.CrazyLogin.fileName", "accounts.db");
			changes = true;
		}
		if (!configFile.contains("settings.restrictions.allowedPasswordCharacters")) {
			configFile.set("settings.restrictions.allowedPasswordCharacters", "[\\x21-\\x7E]*");
			changes = true;
		}
		if (!configFile.contains("settings.applyBlindEffect")) {
			configFile.set("settings.applyBlindEffect", false);
			changes = true;
		}
		if (!configFile.contains("Email.emailBlacklisted")) {
			configFile.set("Email.emailBlacklisted", new ArrayList<String>());
			changes = true;
		}
		if (configFile.contains("Performances.useMultiThreading")) {
			configFile.set("Performances.useMultiThreading", null);
			changes = true;
		}
		if (configFile.contains("Performances")) {
			configFile.set("Performances", null);
			changes = true;
		}
		if (configFile.contains("Passpartu.enablePasspartu")) {
			configFile.set("Passpartu.enablePasspartu", null);
			changes = true;
		}
		if (configFile.contains("Passpartu")) {
			configFile.set("Passpartu", null);
			changes = true;
		}
		if (!configFile.contains("Email.emailWhitelisted")) {
			configFile.set("Email.emailWhitelisted", new ArrayList<String>());
			changes = true;
		}
		if (!configFile.contains("settings.forceRegisterCommands")) {
			configFile.set("settings.forceRegisterCommands", new ArrayList<String>());
			changes = true;
		}
		if (!configFile.contains("settings.forceRegisterCommandsAsConsole")) {
			configFile.set("settings.forceRegisterCommandsAsConsole", new ArrayList<String>());
			changes = true;
		}
		if (!configFile.contains("Hooks.customAttributes")) {
			configFile.set("Hooks.customAttributes", false);
			changes = true;
		}
		if (!configFile.contains("Purge.removePermissions")) {
			configFile.set("Purge.removePermissions", false);
			changes = true;
		}
		if (configFile.contains("Hooks.notifications")) {
			configFile.set("Hooks.notifications", null);
			changes = true;
		}
		if (configFile.contains("Hooks.chestshop")) {
			configFile.set("Hooks.chestshop", null);
			changes = true;
		}
		if (configFile.contains("Hooks.legacyChestshop")) {
			configFile.set("Hooks.legacyChestshop", null);
			changes = true;
		}
		if (!configFile.contains("Email.generateImage")) {
			configFile.set("Email.generateImage", true);
			changes = true;
		}
		if (!configFile.contains("DataSource.mySQLRealName")) {
			configFile.set("DataSource.mySQLRealName", "realname");
			changes = true;
		}

		if (changes) {
			plugin.getLogger().warning("已合并新的配置选项 - 这不是一个错误, 请不要反馈给我");
			plugin.getLogger().warning("请检查新的 config.yml 文件 并修改相关配置!");
		}
	}
}
