<commit_before>import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jibble.pircbot.Colors;

import uk.co.uwcs.choob.modules.Modules;
import uk.co.uwcs.choob.support.*;
import uk.co.uwcs.choob.support.events.*;

/**
 * Class to cache results
 *
 */
class QAuthResult {
	String account;
	long time;
}

/**
 * Choob plugin for performing authentication using Quakenet Q accounts.
 * 
 * @author <NAME>
 *
 */
public class QuakenetAuth {
	
	private static int TIMEOUT = 10000;
	
	private boolean hadToAuth = false;
	final Pattern validAuthReply = Pattern.compile("^\\-Information for user (.*) \\(using account (.*)\\):");
	final Pattern notAuthedReply = Pattern.compile("^User (.*) is not authed\\.$");

	private Modules mods;
	private IRCInterface irc;
	private Map<String, QAuthResult> qChecks;
	
	// In case Q auth is not possible.
	private boolean whoisfallback = false;
	
	public String[] info()	{
		return new String[] {
			"Q Auth checker plugin.",
			"The Choob Team",
			"<EMAIL>",
			"$Rev$$Date$"
		};
	}
	
	public QuakenetAuth(Modules mods, IRCInterface irc) {
		this.mods = mods;
		this.irc = irc;
		qChecks = new HashMap<String, QAuthResult>();		
	}
	
	// -- Commands -- //
	
	public String[] helpCommandEnableOverride = {
			"Used in case of Q downtime."
	};
	
	public void commandEnableOverride(Message mes) {
		whoisfallback = true;
		irc.sendContextReply(mes, "Okay.");
	}

	public String[] helpCommandAccount = {
			"Check the account name that a user is authed with.",
			"[<NickName>]",
			"<NickName> is an optional nick to check."
	};
	
	public void commandAccount(Message mes) throws ChoobException {
		String nick = mods.util.getParamString(mes);
		if (nick.length() == 0) {
			nick = mes.getNick();
		}
		
		String account = (String)mods.plugin.callAPI("QuakenetAuth", "Account", nick);
		if (account != null) {
			irc.sendContextReply(mes, nick + " is authed as " + account + ".");
		} else {
			irc.sendContextReply(mes, nick + " is not authed.");
		}
	}
	
	// -- API -- //
	public String[] helpApi = {
			"QuakenetAuth allows your plugin to poke Q and get auth status" +
			"on nicknames. It gives you a single API method: Account, which " +
			"takes a single String Parameter and returns a String. If the " +
			"returned String is not null, that is the account with which the " +
			"user is authenticated."
	};
	
	public String apiAccount(String nick) {
		QAuthResult result = getCachedQCheck(nick.toLowerCase());
		if (result != null)	{
			return result.account;
		}

		result = getNewQCheck(nick.toLowerCase());

		synchronized(result) {
			try {
				result.wait(30000); // Make sure if Q breaks we're not screwed
			} catch (InterruptedException e) {
				// Ooops, timeout
				return "FAIL";
			}
		}
		if (hadToAuth) {
			hadToAuth = false;
			result = getNewQCheck(nick.toLowerCase());

			synchronized(result) {
				try {
					result.wait(30000); // Make sure if Q breaks we're not screwed
				} catch (InterruptedException e) {
					// Ooops, timeout
					return "FAIL";
				}
			}
		}
		return result.account;
	}
	
	// -- Options -- //
	public String[] optionsGeneral = {
			"Qusername",
			"Qpassword"
	};
	
	public boolean optionCheckGeneralQusername(String value) {
		return true;
	}
	
	public String[] helpOptionQusername = {
			"Set this to the bot's Q username. When set in conjunction with" +
			"the password option the bot will authenticate itself."
	};
	
	public boolean optionCheckGeneralQpassword(String value) {
		return true;
	}
	
	public String[] helpOptionQpassword = {
			"Set this to the bot's Q password. When set in conjunction with" +
			"the username option the bot will authenticate itself."
	};
	
	// -- Response Handling -- //
	public void onServerResponse(ServerResponse resp) {
		if (resp.getCode() == 401) {
			// 401 Nick not found.
			Matcher ma = Pattern.compile("^[^ ]+ ([^ ]+) ").matcher(resp.getResponse().trim());
			if (ma.find() && ma.group(1).trim().toLowerCase().equals("q")) {
				// Q is dead.
				// XXX Handle - perhaps using L?
				whoisfallback = true;
			}
		}
		
		if ((resp.getCode() == 330)) {
			// Whois authentication status line
			// This takes the format: <BOTnick> <Usernick> <Account> :is authed as
			Matcher ma = Pattern.compile("^(.*) (.*) (.*) \\:is authed as$").matcher(resp.getResponse().trim());
			if (ma.find()) {
				// Extract the data
				String nick = ma.group(2).trim();
				String account = ma.group(3).trim();
				
				// Store this data
				QAuthResult result = getNickCheck(nick.toLowerCase());
				if (result == null) {
					result = new QAuthResult();
					result.account = account;
					result.time = System.currentTimeMillis();
					synchronized(qChecks) {<commit_msg>Remove //XXX line that is no longer relevant.<commit_after>import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jibble.pircbot.Colors;

import uk.co.uwcs.choob.modules.Modules;
import uk.co.uwcs.choob.support.*;
import uk.co.uwcs.choob.support.events.*;

/**
 * Class to cache results
 *
 */
class QAuthResult {
	String account;
	long time;
}

/**
 * Choob plugin for performing authentication using Quakenet Q accounts.
 * 
 * @author <NAME>
 *
 */
public class QuakenetAuth {
	
	private static int TIMEOUT = 10000;
	
	private boolean hadToAuth = false;
	final Pattern validAuthReply = Pattern.compile("^\\-Information for user (.*) \\(using account (.*)\\):");
	final Pattern notAuthedReply = Pattern.compile("^User (.*) is not authed\\.$");

	private Modules mods;
	private IRCInterface irc;
	private Map<String, QAuthResult> qChecks;
	
	// In case Q auth is not possible.
	private boolean whoisfallback = false;
	
	public String[] info()	{
		return new String[] {
			"Q Auth checker plugin.",
			"The Choob Team",
			"<EMAIL>",
			"$Rev$$Date$"
		};
	}
	
	public QuakenetAuth(Modules mods, IRCInterface irc) {
		this.mods = mods;
		this.irc = irc;
		qChecks = new HashMap<String, QAuthResult>();		
	}
	
	// -- Commands -- //
	
	public String[] helpCommandEnableOverride = {
			"Used in case of Q downtime."
	};
	
	public void commandEnableOverride(Message mes) {
		whoisfallback = true;
		irc.sendContextReply(mes, "Okay.");
	}

	public String[] helpCommandAccount = {
			"Check the account name that a user is authed with.",
			"[<NickName>]",
			"<NickName> is an optional nick to check."
	};
	
	public void commandAccount(Message mes) throws ChoobException {
		String nick = mods.util.getParamString(mes);
		if (nick.length() == 0) {
			nick = mes.getNick();
		}
		
		String account = (String)mods.plugin.callAPI("QuakenetAuth", "Account", nick);
		if (account != null) {
			irc.sendContextReply(mes, nick + " is authed as " + account + ".");
		} else {
			irc.sendContextReply(mes, nick + " is not authed.");
		}
	}
	
	// -- API -- //
	public String[] helpApi = {
			"QuakenetAuth allows your plugin to poke Q and get auth status" +
			"on nicknames. It gives you a single API method: Account, which " +
			"takes a single String Parameter and returns a String. If the " +
			"returned String is not null, that is the account with which the " +
			"user is authenticated."
	};
	
	public String apiAccount(String nick) {
		QAuthResult result = getCachedQCheck(nick.toLowerCase());
		if (result != null)	{
			return result.account;
		}

		result = getNewQCheck(nick.toLowerCase());

		synchronized(result) {
			try {
				result.wait(30000); // Make sure if Q breaks we're not screwed
			} catch (InterruptedException e) {
				// Ooops, timeout
				return "FAIL";
			}
		}
		if (hadToAuth) {
			hadToAuth = false;
			result = getNewQCheck(nick.toLowerCase());

			synchronized(result) {
				try {
					result.wait(30000); // Make sure if Q breaks we're not screwed
				} catch (InterruptedException e) {
					// Ooops, timeout
					return "FAIL";
				}
			}
		}
		return result.account;
	}
	
	// -- Options -- //
	public String[] optionsGeneral = {
			"Qusername",
			"Qpassword"
	};
	
	public boolean optionCheckGeneralQusername(String value) {
		return true;
	}
	
	public String[] helpOptionQusername = {
			"Set this to the bot's Q username. When set in conjunction with" +
			"the password option the bot will authenticate itself."
	};
	
	public boolean optionCheckGeneralQpassword(String value) {
		return true;
	}
	
	public String[] helpOptionQpassword = {
			"Set this to the bot's Q password. When set in conjunction with" +
			"the username option the bot will authenticate itself."
	};
	
	// -- Response Handling -- //
	public void onServerResponse(ServerResponse resp) {
		if (resp.getCode() == 401) {
			// 401 Nick not found.
			Matcher ma = Pattern.compile("^[^ ]+ ([^ ]+) ").matcher(resp.getResponse().trim());
			if (ma.find() && ma.group(1).trim().toLowerCase().equals("q")) {
				// Q is dead, fall back to whois responses.
				whoisfallback = true;
			}
		}
		
		if ((resp.getCode() == 330)) {
			// Whois authentication status line
			// This takes the format: <BOTnick> <Usernick> <Account> :is authed as
			Matcher ma = Pattern.compile("^(.*) (.*) (.*) \\:is authed as$").matcher(resp.getResponse().trim());
			if (ma.find()) {
				// Extract the data
				String nick = ma.group(2).trim();
				String account = ma.group(3).trim();
				
				// Store this data
				QAuthResult result = getNickCheck(nick.toLowerCase());
				if (result == null) {
					result = new QAuthResult();
					result.account = account;
					result.time = System.currentTimeMillis();
					synchronized(qChecks) {
{'fraction_non_alphanumeric': 0.13762509027132983, 'fraction_numerical': 0.005777365108841432, 'mean_word_length': 3.1965367965367966, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7188235', 'n_tokens_mistral': 3596, 'n_tokens_neox': 3069, 'n_words': 897}