/* Banana-Chat - The first Open Source Knuddels Emulator
 * Copyright (C) 2011 - 2012 Flav <http://banana-coding.com>
 * 
 * Diese Dateien unterliegen dem Coprytight von Banana-Coding und
 * darf verändert, aber weder in andere Projekte eingefügt noch
 * reproduziert werden.
 * 
 * Der Emulator dient - sofern der Client nicht aus Eigenproduktion
 * stammt - nur zu Lernzwecken, das Hosten des originalen Knuddels Clients
 * ist auf eigene Gefahr und verstößt möglicherweise gegen Schutzrechte
 * der Knuddels.de GmbH & Co KG
 * 
 * Autoren: Flav (Grundversion), Localhost (Erweiterte Version), Kokos-Ice (Erweiterte Version)
 */



package netchat;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import tools.Reloader;
import java.net.Socket;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.regex.Pattern;
import java.text.SimpleDateFormat;
import game.WordMixRecord;
import java.io.File;
import tools.database.ConnectionPool;
import tools.database.PoolConnection;
import tools.Logger;

public class Server {
	private final static Server instance;
	private final Map<String, Client> clients;
	private final static ModuleTree moduleTree;
	Client butler;
	private List<String> logins;
	public static Map<String, Channel> channels;
	public static Map<String, Integer> badwords;
	public static Map<String, String> macros;
	public static Map<String, String[]> help;
	public static Map<Integer, String[]> tutorials;
	public static Map<String, String[]> functions;
	public static Map<String, String> james;
	public static Map<String, String> umfragen;
	public static List<String> werbung;
	public static List<String[]> news;
	public static Map<String, String[]> elections;
	public static Map<String, String[]> mentorsmileys;
	public static Map<String, String[]> toplisten;
	public static Map<Integer, String[]> smileys;
	public static Map<String, String> permissions;
	public static Map<Integer, String[]> smileyCategories;
	public static List<String> onlineUsers;
	public static Map<String, String[]> statistik;
	public static Map<String, String[]> plz;
	public static Map<String, String> todo;
	public static Map<String, String[]> syslog;
	public static Map<String, String[]> lotto;
	public static Map<String, Integer> luftlinie;
	public static Map<Long, String[]> actions;
	public static Map<Long, String[]> snp;
	public static ArrayList<String> sexy;
	public static ArrayList<String> wordmix;
	public static Map<String, String> lockedNicks;
	public static Map<Integer, String[]> invite;
	private int lottoJackpot, allKnuddels, allKontoKnuddels;
	private long update;
	static long serverOnline = System.currentTimeMillis()/1000;

	static {
		instance = new Server();
		moduleTree = new ModuleTree("-188303753;20;PROTOCOL_HASH;CONFIRM_PROTOCOL_HASH;PROTOCOL_CONFIRMED;PROTOCOL_DATA;CHANGE_PROTOCOL;TEXT;LABEL;CHANNEL_NAME;IMAGE;SOUND;NICK;TITLE;INT_TIME_MILLIS;TIMEOUT_SECONDS;DURATION;INTERVAL;RED;GREEN;BLUE;COLOR;FONTSIZE;INT_ID;INT_HASH;INT_VALUE;SHORT_ID;STRING_ID;VALID;SELECTED;FOCUS;SHORT_TIME_MILLIS;DEFAULT_COLOR;DEFAULT_FONTSIZE;TEXTPANELTEXT;STRING_MAP;CONFIG;STRING_MAP_ENTRY;STRING_KEY;STRING_VALUE;MOUSEX;MOUSEY;EVENT_ID;WINDOW_ID;EVENT;TEXT_COLOR;BACKGROUND_COLOR;TOP_FADE_FROM;MIDDLE_FADE_TO;BOTTOM_SOLID;SPECULAR_SHADING;IS_DIFF;BIN_DATA;ZINDEX;WINDOWX;WINDOWY;WINDOW;FEEDBACK_DOMAIN;FEEDBACK_KEY;SERVER_FEEDBACK;OPENED_FS_ID;FRAMESTRING_CLOSED;FRAMESTRING_NOT_FOUND;FRAMESTRING_INITIALIZE_OPENED;CLASS_NAME;PREFETCH_MODULE;FS_STRING;UPDATE_OPENED_FRAMESTRING;BUTTON;ANALOG_BUTTON;SHOW_BUTTONS;BUTTON_ALIGN;CHAT_FUNCTION;NR_ANALOG_SEGMENTS;SEND_INTERVAL_MILLIS;COOLDOWN_INTERVAL_MILLIS;ICON;SORT_ICON_NICKNAMES_TO_TOP;SHOW_PREFIXICONS;REMOVE_ALL_PREFIXICONS;MODULE_ID;TIMEOUT_SECONDS_TOTAL;TIMEOUT_SECONDS_HURRY_UP;MAX_VOTES;MIN_VOTE_TOKEN_LINES;VOTE_TOKEN;MAX_VISIBLE_LOG_LINES;LOG_LINE;SHOW_BLOOD_BAR;TOKEN_CLICK_TEMPLATE;NR_STATUS_LINES;STATUS_BAR;STATUS_ABOVE_LOG;SHOW_VOTEBOX;VOTE_COUNT;UPDATE_VOTEBOX;SET_VOTEBOX_LOG;SET_VOTEBOX_STATUS;REMOVE_VOTEBOX;FINALIZE_VOTEBOX;UPDATE_VOTEBOX_TIMEOUT;BORDER_COLOR;VOTE_BARS_SETTING;VOTEBOX_BOX_SETTING;VOTEBOX_BUTTON_SETTING;TIMOUT_BAR_SETTING;VOTEBOX_SETTINGS;IMAGE_ID;VOTEBOX_IMAGE_CLICKED_SUCCESS;VOTE_BAR_WIN;VOTE_BAR_FIRST;VOTE_BAR_DRAW_FIRST;VOTE_BAR_REG;VOTE_BAR_LOSE;FOUR_COLOR_BAR;COLOR_TOP_TOP;COLOR_TOP;COLOR_BOT;COLOR_BOT_BOT;TOP_BOX_BACKGROUND_COLOR;TOP_BOX_TEXT_COLOR;MIDDLE_BOX_BACKGROUND_IMAGE;USE_BOLD_VOTE_TOKENS;TIMEOUT_BAR;BAR;SHOW_BARS;BAR_LENGTH_PIXEL;SIMPLE_BAR_UPDATE;BAR_TREND;BUTTON_TREND;ANALOG_TREND;BUTTON_BAR_SETTINGS;SEARCH_REQUEST_PARAMETERS;SEARCH_SORT_MODE;RESULT_COUNT_MINIMUM_NEEDED;SEARCH_NEW_REQUEST;AGE_FROM;AGE_TO;GENDER;SEARCH_REASON;SEARCH_TAG;SEARCH_OPTION;SHOW_MEMBERS_NEAR_ME;SHOW_NEW_MEMBERS;SEXUAL_ORIENTATION;OTHERS_FIND_ME_WHEN;UPDATE_FRIENDS;REQUEST_TOP_SEARCH_TAGS;RESULT_COUNT_START_OFFSET;SEARCH_UPDATE_REQUEST;STORE_SEARCH_OPTIONS;LOGIN_NICK;SEARCHER_AGE;SEARCHER_GENDER;SEARCHER_HAS_ZIP_CODE;SEARCHES_FIRST_TIME;OPEN_SEARCH_CHANNEL;RESULT;RESULT_START_INDEX;ESTIMATED_RESULT_COUNT;CLEAR_OLD_RESULTS;SEARCH_RESULT;FRIEND_RESULT;AGE;CURRENT_CHANNEL;IS_AFK;DISTANCE;MATCHING_PERCENT;IS_ONLINE;SEND_HI_OK;MINI_RESULT;SEARCH_RESULTS_CHANGED_ONLINESTATUS;CAME_ONLINE_RESULTS;GONE_OFFLINE_NICKS;FRIEND_RESULT_CHANGED_ONLINESTATUS;SHOW_TOP_SEARCH_TAGS;WHOIS_CONTENT;SHOW_MINIWHOIS;KEY_VALUE;MODULE_INIT;KEY;VALUE;COMMA_SEPARATED_NICK_LIST;INITIAL_TEXT;POST_OLD_MSG_TEXT;CLIENT_PP;IMAGE_PREFETCH;SOUND_PREFETCH;NICKLIST_SORT_TOGETHER;APPSTATS;BINGO_SHEET_ID;BINGO_SHEET_MATRIX_SIZE;BINGO_FIELD_STATES;INDEX;BINGO_PATTERN_ROW_WIDTH;MES_ID;BINGO_GAME_MESSAGE;BINGO_FIELD;BINGO_SHEET_STATE_CONST;BINGO_SHEET;BINGO_PATTERN_REFLECTED;BINGO_PATTERN;BINGO_CALLED_NUMBER;BINGO_FIELD_UPDATE;BINGO_SHEET_UPDATE;BINGO_ROUND;BINGO_HISTORY_UPDATE;BINGO_INIT;BINGO_UPDATE;BINGO_ACTIVE_TEXT;BINGO_ACTIVE_BUTTON_LABEL;BINGO_ACTIVE_BUTTON_COMMAND;BINGO_SET_STATE;FILENAME;PLAY_SOUND;SI_ID;SI_NAME;SI_DESCRIPTION;SI_LEVEL;SI_STOCKCOUNT;SI_COUNTDOWN_TO_REVEAL;SI_COUNTDOWN_TO_OUTOFSTOCK;SI_PRICE_CC;SI_PRICE_KNUDDELS;SI_OWNINGCOUNT;SI_LOCK;SHOP_ITEM;WINDOW_SIZE;SI_DESCRIPTION_LONG;SHOP_ITEM_DETAILS;SHOP_BUTTON;SHOP_MAINTAB;SHOP_BUTTONS;TAB_ID;TAB;SHOP_SUBTABS;TAB_ALIGNMENT;LOGO_IMAGE;SHOP_TITLE;USER_IMAGE;LOCALE;SHOP_USERSTATUS;SHOP_HEADER;UPDATE_SHOP_USERSTATUS;UPDATE_SHOP_ITEM;PERSONAL_HISTORY;NEW_SHOP_ITEMS;RECOMMENDED_SHOP_ITEMS;SHOP_MYSHOP;SHOP_VIEW;SHOP_MYSHOP_ITEM;REFERRAL_INFOTEXT;RESET_SCROLL_POS;SHOP_REFERRALS;SHOP_CLEAR_ITEMCACHE;SHOP_CLOSED;SHOP_REQUEST_ITEM_DETAILS;SHOP_CALL_OTHER;SHOP_REQUEST_ITEMS;INSTANT_WHOIS_CONTENT;SERVE_INSTANT_WHOIS;FORCED_SERVE_INSTANT_WHOIS;PANEL_SETTINGS;CONTENT_AREA_PIXEL_HEIGHT;CONTENT_AREA_PIXEL_WIDTH;IMAGEBOX_ID;SERVE_INSTANT_WHOIS_MISSING_USER;NICKLIST_COLOR;HI_WHOIS;INSTANT_WHOIS_PREFETCH_ITEM;INSTANT_WHOIS_PREFETCH;APPLET_INT_CONFIG_PARAM;APPLET_STRING_CONFIG_PARAM;CONFIGURE_APPLET;APPLET_INT_CONFIG_KEY;APPLET_STRING_CONFIG_KEY;REQUEST_INSTANT_WHOIS;REQUEST_RESPONSE_TIME;VIEW_TIME;INSTANT_WHOIS_STATS;W2_CONTENT;W2_HASHCODES;WAS_REQUESTED;SERVE_W2_NEW_WINDOW;W2_TARGET_WINDOW_ID;SERVE_W2;SERVE_W2_UPDATE;W2_TABS;W2_HEADER;W2_LEFT_COLUMN;W2_SELECTED_CENTER_TAB;W2_CENTER_COLUMN;W2_RIGHT_COLUMN;W2_SELECTED_BG;W2_TAB;SHOW_PARAMETER;W2_PARENTTAB_ID;W2_EDIT_COMMAND;ONLY_CENTER_COLUMN;W2_TARGET_WINDOW_ID_FLAGS;PAGE;CLOSED;FORCE_NO_MISSING;ADMIN_NO_MISSING;SOURCEID;REQUEST_W2;HASH_W2_TABS;HASH_W2_HEADER;HASH_W2_LEFTCOLUMN;HASH_W2_CENTERCOLUMN;HASH_W2_RIGHTCOLUMN;CLOSED_W2;CHANNELS;HI_BOX_ADDLINE;HI_BOX_REMOVE_LINE;HI_BOX_REMOVE_BOX;MESSAGE_OVERVIEW_UPDATE;POST_COUNT_CHANGED;PLZ;USERPLZ;REQUEST_DECODE;DECODE;SERVE_DECODE;PIXEL_URL;DEBUG_NOTIFY_USER;LOAD_TRACKING_PIXEL;SELECTED_ID;ANCHOR_ID;OWNER_NICK;REQUEST_W2EDIT;W2E_ENTRY;SAVE_W2E;ACTIONTYPE;W2E_ACTION;W2E_ACTIONLIST;SUGREQID;SUGTYPE;SUGTOKEN;SUGREQ;SUGRES;W2E_HEADER;MENU_ENTRY;WHOIS2_EDIT;COMPONENT_ID;LAYOUT_ITEM;POSITION;DIMENSION;LAYOUT_ITEM_TYPE;CONTENT;LAYOUT_ITEM_FLAG;LABEL_FONTSIZE;WIDTH;HEIGHT;XPOS;YPOS;SUCCESSFUL;WHOIS2_SAFE_RESULT;GUEST_APPLET_LOADED;STATUS_CODE;GUEST_CREATED;PREFFERED_CHANNEL;LOGIN_GUEST;GUEST_REGISTERED;ELEMENT_CLICKED_SUCCESS;W2GROUP_HEADER;W2GROUP_LEFT_COLUMN;W2GROUP_CENTER_COLUMN;SERVE_W2GROUP;MEMBERTYPE;REQUEST_W2GROUP;FROM_NICK;TO_NICK;SEND_FEEDBACK;WANDERING_KNUDDEL;WANDERING_KNUDDEL_DONE;TAB_NAME;OPEN_ON_LOAD;CLOSE_ON_INSERT;BOX_POSITION;USE_TRANSPARENCY;USE_ANIMATIONS;SB_TABS;SMILEY;SMILEY_SPECIAL;ADVERTISEMENT;SB_TAB;AMOUNT;REPLACEMENT;NAME;FAVORITE;SMILEY_INDEX;FEATURE_CMD;FEATURE_NAME;FEATURE_COOLDOWN;SB_DETAILS;SB_FAVORITE;SB_INVALIDATE;FORCE_PUSH;PUSH_DELAY;START_DV;DV_DATA;DV_SHOW;REQUEST_SB_TABS;REQUEST_SB_TAB;REQUEST_SB_DETAIL;TARGET_REPLACEMENT;REORDER_FAVORITES;STAT;STAT_REPORT;COUNT;HEARTLIGHT;HEARTLIGHT_DONE;NEXT_DATE_MODUL;FUNCTIONS;PARAMS;ACTIVATE_FUNCTIONS;DEACTIVATE_FUNCTIONS;NUM_COCONUTS;GAME_ID;NEW_COCONUT_GAME;COCONUT_ID;COCONUT_COLLECT;;5;;20;;;9;;23;;13;;13;;13;;13;;13;;13;;13;;4;;4;;4;;4;;2;;2;;2;;36;37;38;;2;;4;;4;;4;;3;;13;;1;;1;;1;;3;;39;;40;;50;51;25;;11;55;12;;53;;56;57;;13;;13;;3;;3;;3;;4;;32;61;43;58;59;60;;39;;39;;39;;39;;39;;65;66;67;;1;;13;;3;;3;;3;;32;61;31;72;73;69;70;71;;3;;13;;27;75;76;53;;13;;78;;78;;11;78;12;;13;;82;33;;13;;78;84;48;;25;28;89;90;;86;91;92;93;;27;11;86;12;11;87;12;;0;;13;;4;;4;;4;;30;11;28;12;;1;;27;11;94;12;95;;27;;13;;4;;4;;4;;4;;25;112;;4;;13;;1;;13;;4;;13;;1;;27;98;31;33;99;100;86;101;102;11;103;12;104;11;105;12;106;107;108;109;110;;4;;27;98;103;105;109;;27;98;105;109;;27;98;109;;27;98;;27;98;;27;98;33;;39;;127;128;129;130;131;;63;64;137;138;139;140;;63;119;68;;64;141;;27;98;119;120;121;122;123;;4;;27;98;125;;28;;132;;132;;132;;132;;133;134;135;136;;39;;39;;39;;39;;39;;39;;28;;1;;68;;31;68;144;;27;11;142;12;;3;;144;;68;;68;;68;;27;146;147;148;;154;155;156;11;157;12;11;158;12;11;159;12;160;161;162;11;163;12;;0;;3;;150;151;152;;2;;2;;0;;0;;13;;0;;0;;0;;0;;0;;;;3;;166;152;;150;;30;;2;;156;;1;;1;;27;169;170;171;172;173;150;;30;181;156;182;183;184;185;11;158;12;28;186;187;;4;;4;;1;;11;175;12;176;177;178;;11;175;12;;2;;27;;1;;3;;2;;1;;1;;30;186;;11;188;12;;11;175;12;;11;30;12;;190;191;;11;158;12;;13;;30;194;187;;198;199;;27;98;82;11;196;12;;13;;13;;13;;13;;13;;27;200;201;202;;11;28;12;;11;29;12;;27;11;30;12;;53;;5;;2;;0;;4;;2;;4;;213;25;;3;;0;;208;209;11;215;12;11;210;12;216;;1;;212;11;210;12;218;;13;;211;215;210;;208;11;221;12;11;214;12;;4;;208;220;223;;98;27;217;11;219;12;11;220;12;;98;27;11;222;12;11;219;12;11;214;12;11;224;12;;25;;25;;25;;98;27;208;216;227;228;229;;13;;27;98;231;;4;;13;;13;;2;;4;;33;;33;;6;;6;;2;;13;;233;234;235;236;28;119;237;238;239;240;241;242;243;;3;;52;;119;236;234;245;246;;251;25;40;47;;252;253;;11;248;12;11;249;12;;2;;251;254;25;40;47;11;233;12;;11;252;12;;0;;28;;25;;28;;13;;52;;255;256;250;257;258;259;;259;;11;244;12;;52;;11;233;12;;11;233;12;;260;263;264;265;;260;;260;;52;;1;;260;269;270;;;;233;;251;;11;233;12;;280;52;42;;41;277;;27;30;277;;281;282;283;;3;;3;;13;;41;;39;;27;30;277;285;;30;277;;27;11;287;12;;292;43;;293;57;;11;289;12;11;290;12;;0;;0;;30;27;41;42;;49;;49;;11;295;12;11;296;12;;305;306;307;308;309;310;11;311;12;;46;324;325;326;327;328;;1;;30;298;299;300;;4;;30;302;298;299;300;;30;;11;312;12;;11;52;12;;11;52;12;;45;;11;52;12;;11;52;12;;28;313;;45;314;315;;0;;45;;13;;1;;0;;3;;13;;1;;1;;13;;30;316;308;299;302;317;318;319;320;321;300;322;;4;;4;;4;;4;;4;;30;;11;27;12;;27;30;25;330;;27;30;;27;;48;53;;43;;13;;336;;11;44;12;;44;25;;11;339;12;;13;;1;;341;342;;45;;361;;13;;344;345;346;;45;57;;45;346;11;348;12;;3;;346;350;348;;346;350;11;348;12;;4;;4;;13;;353;354;355;;353;354;11;355;12;;52;;45;28;25;11;362;12;;358;344;345;346;11;359;12;;13;;45;363;364;365;11;366;12;11;367;12;54;26;368;;371;372;;369;370;;0;;13;;0;;40;;3;;3;;3;;3;;1;;45;373;;;3;;376;;13;;378;;;361;125;;52;;52;;52;;45;31;382;383;384;;3;;41;45;386;318;;30;;30;;1;;27;388;389;390;;27;;13;;1;;1;;2;;1;;1;;98;11;393;12;394;395;396;397;398;;28;404;405;406;407;;408;409;410;411;;13;;98;393;11;400;12;11;401;12;402;;2;;13;;13;;1;;3;;13;;13;;5;;98;405;25;;98;405;407;;98;393;;3;;4;;34;35;415;416;45;;11;62;12;11;74;12;;23;11;25;12;;;393;;405;;13;;11;405;12;423;;26;427;;98;11;425;12;;4;;27;389;390;;27;;98;27;25;;13;;13;;11;431;12;11;432;12;;11;431;12;;3;;4;;27;33;435;436;;4;;27;11;438;12;;:RIGHT;LEFT;;MATCHING;DISTANCE;AGE;SINGLESTATUS;;DOESNT_MATTER;FEMALE;MALE;;TALKING;FRIENDSHIP;FLIRT;MEETING;MARIAGE;EROTIC_TALKING;;ONLY_WITH_FOTO;PREFER_SINGLES;;NORMAL;PREFERRED;NEVER;;NORMAL;PREFERRED;NEVER;;HETERO;HOMO;BI;;THEY_ARE_LONGTERM_MEMBERS;THEY_MATCH_MY_SEARCH_CRITERIA;ONLY_WHILE_I_AM_IN_SEARCH_CHANNEL;NEVER;OFTEN;;ANY_STATE;NOT_SELECTED;SELECTED;DEAD;GLOWING;;ACTIVE;INACTIVE;BINGO;NO_BINGO_POSSIBLE;JACKPOT;GAME_END;;LEFT;RIGHT;;instantWhoisCornerRadius;instantWhoisMillisToRequest;instantWhoisMillisToRequestNickList;instantWhoisMillisToRequestW2;instantWhoisMillisToShow;instantWhoisMillisToHide;instantWhoisMillisToUpdateVisibleRequest;w2WindowWidth;w2WindowHeight;hiBoxWidth;hiBoxBasicHeight;hiBoxLineHeight;hiBoxLineSepHeight;hiBoxDistanceTop;hiBoxDistanceBottom;hiBoxDistanceRight;currentSeason;w2MapWToW2;publicMsgInPP;soundInPP;standAloneSBox;;noKeys;hiBoxBasicContent;hiBoxLineEndText;hiBoxLineSeperatorText;hiBoxBackgroundImageID;w2DefaultTab;imgProxyList;serverId;;FULL;STRETCHED;TILED;;regularTarget;noTarget;newTargetRequested;;TextField;TextPanel;TextArea;Image;Button;CheckBox;ComboBoxSelect;ComboBoxInput;Slider;EMPTY;ComplexGroupInput;ColorBox;ImageBox;TextToolbar;;ShowBulletPoint;TextAlignRight;TextAlignLeft;TextBold;TextItalic;PasswordInput;LabelLocationTop;LabelLocationLeft;LabelLocationRight;LabelLoactionBottom;LabelLocationCenter;LabelBold;LabelItalic;ButtonActionDispose;ButtonActionSubmit;UseImages;AlternativeDisplayMode;ComboBoxFreeInput;ImageHasBorder;DisableHighlightOnInputFocus;Disabled;ScrollingDisabled;SendbackText;NoAdd;;;");
        }

	public Server() {
		clients = new HashMap<String, Client>();
		onlineUsers = new ArrayList<String>();
		werbung = new ArrayList<String>();
		news = new ArrayList<String[]>();
		actions = new HashMap<Long, String[]>();
		snp = new HashMap<Long, String[]>();
		help = new HashMap<String, String[]>();
		statistik = new HashMap<String, String[]>();
		elections = new HashMap<String, String[]>();
		smileyCategories = new HashMap<Integer, String[]>();
		tutorials = new HashMap<Integer, String[]>();
		smileys = new HashMap<Integer, String[]>();
		lotto = new HashMap<String, String[]>();
		umfragen = new HashMap<String, String>();
		sexy = new ArrayList<String>();
		wordmix = new ArrayList<String>();
		lockedNicks = new HashMap<String, String>();
		plz = new HashMap<String, String[]>();
		invite = new HashMap<Integer, String[]>();
		todo = new HashMap<String, String>();
		syslog = new HashMap<String, String[]>();
		permissions = new HashMap<String, String>();
		luftlinie = new HashMap<String, Integer>();
		toplisten = new HashMap<String, String[]>();
		mentorsmileys = new HashMap<String, String[]>();
		james = new HashMap<String, String>();
		functions = new HashMap<String, String[]>();
		macros = new HashMap<String, String>();
		badwords = new HashMap<String, Integer>();
		butler = new Client(null);
		channels = new LinkedHashMap<String, Channel>();
		logins = new ArrayList<String>();
	}

	public static Server get() {
		return instance;
	}

	public long getUpdate() {
		return update;
	}
	
	public void setUpdate(long update) {
		this.update = update;
	}
	
	public int getLottoJackpot() {
		return lottoJackpot;
	}

	public void increaseLottoJackpot(int lottoJackpot) {
		this.lottoJackpot += lottoJackpot;
	}

	public void setLottoJackpot(int lottoJackpot) {
		this.lottoJackpot = lottoJackpot;
	}

	public int getAllKnuddels() {
		return allKnuddels;
	}

	public void increaseAllKnuddels(float knuddels) {
		this.allKnuddels += knuddels;
	}

	public ModuleTree getModuleTree() {
		return moduleTree;
	}

	public void setAllKnuddels(int allKnuddels) {
		this.allKnuddels = allKnuddels;
	}

	public void deseaseAllKnuddels(int allKnuddels) {
		this.allKnuddels -= allKnuddels;
	}

	public int getAllKontoKnuddels() {
		return allKontoKnuddels;
	}

	public void increaseAllKontoKnuddels(int allKontoKnuddels) {
		this.allKontoKnuddels += allKontoKnuddels;
	}

	public void setAllKontoKnuddels(int allKontoKnuddels) {
		this.allKontoKnuddels = allKontoKnuddels;
	}

	public void deseaseAllKontoKnuddels(int allKontoKnuddels) {
		this.allKontoKnuddels -= allKontoKnuddels;
	}

	public Client getButler() {
		return butler;
	}

	public void setButler(Client butler) {
		this.butler = butler;
	}

	public Client getNRS() {
		return getClient("Notruf-System");
	}

	public void addIP(String ip) {
		logins.add(ip);
	}

	public boolean checkIP(String ip) {
		int count = 0;

		for (String s : logins) {
			if (s.equals(ip)) {
				count++;
			}
		}

		return count > 7;
	}

        public boolean checkEmail(String email) {
		int count = 0;

		for (String s : logins) {
			if (s.equals(email)) {
				count++;
			}
		}

		return count > 7;
	}
        
        
        
        
	public void clearIPs() {
		logins.clear();
	}

	public Client getClient(String target) {
		synchronized (clients) {
			return clients.get(target.toLowerCase());
		}
	}

	public Collection<Client> getClients() {
		synchronized (clients) {
			return clients.values();
		}
	}

	public static int countChars(String input, char toCount) {
		int counter = 0;

		for (char c : input.toCharArray()) {
			if (c != toCount)
				continue;
			counter++;
		}

		return counter;
	}

	public void addClient(Client client) {
		synchronized (clients) {
			clients.put(client.getName().toLowerCase(), client);
		}
	}

	public void removeClient(String name) {
		synchronized (clients) {
			clients.remove(name.toLowerCase());
		}
	}

	public Channel getChannel(String name) {
		return channels.get(name.toLowerCase());
	}

	public Collection<Channel> getChannels() {
		return channels.values();
	}

	public static void removeChannel(String name) {
		synchronized (channels) {
			channels.remove(name.toLowerCase());
		}
	}

	public void createChannel(String name, int temp, String owner,
			int butlerexist, String design, String topic) {
		Random random = new Random();
		int randomInt = random.nextInt(5);

		String styleimage = "";
		String styleid = "";
		String pos = "0";

		if (design == null) {
			if (randomInt == 0) {
				styleimage = "-";
				styleid = "1";
				pos = "0";
			} else if (randomInt == 1) {
				styleimage = "style31.gif";
				styleid = "2";
				pos = "17";
			} else if (randomInt == 2) {
				styleimage = "style32.gif";
				styleid = "3";
				pos = "20";
			} else if (randomInt == 3) {
				styleimage = "style33.jpg";
				styleid = "4";
				pos = "17";
			} else {
				styleimage = "style34.gif";
				styleid = "5";
				pos = "17";
			}
		} else {
			if (design.equals("Blumentapete")) {
				styleimage = "style31.gif";
				styleid = "2";
				pos = "17";
			} else if (design.equals("Blaue Wolken")) {
				styleimage = "style34.gif";
				styleid = "5";
				pos = "17";
			} else if (design.equals("Kerze")) {
				styleimage = "style41.gif";
				styleid = "8";
				pos = "20";
			} else if (design.equals("Hansi und eine Handvoll Herzen")) {
				styleimage = "style35.gif";
				styleid = "9";
				pos = "17";
			} else if (design.equals("Pferde auf grün")) {
				styleimage = "style36.gif";
				styleid = "10";
				pos = "17";
			} else if (design.equals("Sterne")) {
				styleimage = "style37.gif";
				styleid = "11";
				pos = "17";
			} else if (design.equals("Erdbeeren")) {
				styleimage = "style38.gif";
				styleid = "12";
				pos = "17";
			} else if (design.equals("Kirschen")) {
				styleimage = "style39.gif";
				styleid = "13";
				pos = "17";
			} else if (design.equals("Stifte Radierer und Knöpfe")) {
				styleimage = "style40.gif";
				styleid = "14";
				pos = "17";
			}
		}

		Server.get()
				.query(String
						.format("INSERT INTO channels set name='%s', cls='',cmutes='',mutes='',tochter='',hz='',size='25', backgroundImage='%s', backgroundPosition='%s', style='%s', info='%s', temp='%s', owner='%s', password='%s', bannedFunctions='%s', visible='%s', cms='%s',category='0'",
								name,
								String.format("pics/channels/%s", styleimage),
								pos, styleid, "", temp, owner, "", "", 0, ""));

		PoolConnection pcon = ConnectionPool.getConnection();
		PreparedStatement ps = null;

		try {
			Connection con = pcon.connect();
			ps = con.prepareStatement("SELECT * FROM channels where name='"
					+ name + "'");
			ResultSet rs = ps.executeQuery();

			while (rs.next()) {
				Map<Integer, ChannelStyle> channelStyles = new HashMap<Integer, ChannelStyle>();

				PoolConnection pcon2 = ConnectionPool.getConnection();
				PreparedStatement ps2 = null;

				try {
					Connection con2 = pcon2.connect();
					ps2 = con2.prepareStatement("SELECT * FROM channelstyles");
					ResultSet rs2 = ps2.executeQuery();

					while (rs2.next()) {
						channelStyles.put(rs2.getInt("id"), new ChannelStyle(
								rs2));
					}
				} catch (SQLException e) {
					e.printStackTrace();
				} finally {
					if (ps2 != null) {
						try {
							ps2.close();
						} catch (SQLException e) {
						}
					}

					pcon2.close();
				}

				Channel channel2 = new Channel(rs, channelStyles.get(rs
						.getInt("style")));

				if (butlerexist == 1) {
					butler.joinChannel(channel2);
					channel2.addClient(butler);
				}

				channels.put(rs.getString("name").toLowerCase(), channel2);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if (ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
				}
			}

			pcon.close();
		}
	}

	public boolean checkCodeActivated(String code) {
		return Settings.getCodes().contains(String.format("|%s~", code));
	}

	public String parseSmileys(Client target, String message) {
		int maxSmileys = 2;
		int usedSmileys = 0;

			for (String code : mentorsmileys.keySet()) {
				String[] split = mentorsmileys.get(code);
				String id = split[1];
				int mentorPoints = Integer.parseInt(split[0]);

				for(int i=0;i<=message.indexOf(code);i++) {
					if (target.getMentorPoints() >= mentorPoints || target.hasPermission("useallmentorsmileys")) {
						if(usedSmileys < maxSmileys) {
							message = message.replaceFirst(Pattern.quote(code),
									String.format("°>%s...b.my_2.gif<°", id));
							
							usedSmileys++;
						}
					}
				}
			}

			for (String sm : target.getSmileys().split("\\|")) {
				if (!sm.isEmpty()) {
					int smi = Integer.parseInt(sm.split("~")[0]);

					for (int smiley : smileys.keySet()) {
						if (smiley == smi) {
							String[] split = smileys.get(smiley);
							String syntax = split[0];
							String replacement = split[1];
							
							for(int i=0;i<=message.indexOf(syntax);i++) {
								if(usedSmileys < maxSmileys) {
									message = message.replaceFirst(
											Pattern.quote(syntax),
											String.format("°>%s<°", replacement));
								}
								
								usedSmileys++;
							}
						}
					}
				} 
		}

		return message;
	}

	public String getURL() {
		return "http://cuddly.sytes.net/";
	}

	public boolean isInteger(String text) {
		try {
			Integer.parseInt(text);
		} catch (Exception ex) {
			return false;
		}

		return true;
	}

	public String timeStampToDate(long timestamp) {
		Date da = new Date(timestamp * 1000);
		SimpleDateFormat uhrzeits = new SimpleDateFormat("dd.MM.yyyy");
		String zeit = uhrzeits.format(da);

		return zeit;
	}

	public String textToIll(String text) {
		StringBuilder tex = new StringBuilder();
		int test = 1;

		for (String rcp : text.split(" ")) {
			String[] texte = { "*schnief*", "*hust*", "*schnupf*", "*röchel*" };
			String lala = texte[new Random().nextInt(texte.length)];
			String rofl = String.format(" %s ", lala);

			tex.append(test == 1 ? rofl : "").append(rcp).append(rofl);
			test++;
		}

		return tex.toString();
	}

	public String timeStampToTime(long string) {
		Date da = new Date(string * 1000);
		SimpleDateFormat uhrzeits = new SimpleDateFormat("HH:mm:ss");
		String zeit = uhrzeits.format(da);

		return zeit;
	}

	public void newRose(Client von, String an, String text, long time) {
		Client to = Server.get().getClient(an);
		
		if(to != null) {
			to.newRoses.add(new String[] {von.getName(), text, String.valueOf(time)});
		}
		
		query(String
				.format("insert into `roses` set von = '%s', an = '%s', text = '%s', uhrzeit = '%s'",
						von.getName(), an,
						Server.get()
								.parseSmileys(von, text.replace("'", "\\'")),
						time));
	}

	public void query(String text) {
		PoolConnection pcon = ConnectionPool.getConnection();
		PreparedStatement ps = null;

		try {
			Connection con = pcon.connect();
			ps = con.prepareStatement(text);
			ps.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if (ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
				}
			}

			pcon.close();
		}
	}

	public static int count(String query) {
		PoolConnection pcon = ConnectionPool.getConnection();
		PreparedStatement ps = null;

		try {
			Connection con = pcon.connect();
			ps = con.prepareStatement(query);
			ResultSet rs = ps.executeQuery();

			if (rs.next()) {
				return rs.getInt("a");
			}

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if (ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
				}
			}

			pcon.close();
		}

		return 0;
	}
	

	public void newMessage(Client dest, String an, String betreff,
			String message, long time) {
		Client target = Server.get().getClient(an);

		if (target != null) {
			for (Channel lol : target.getChannels()) {
				target.sendButlerMessage(
						lol.getName(),
						"°%-1°°BB°_°m°°>_h"
								+ dest.getName().replace("<", "\\<")
								+ "|/serverpp \"|/w \"<r°_ hat dir gerade eine Nachricht"
								+ (betreff.isEmpty() ? "" : String.format(
										" (_%s_)", betreff))
								+ " geschickt. Sie liegt nun in deinem °>_hBriefkasten|/m<°.°#°°>mailclosed-outerglow.png<>--<>|/m<>--<° _°BB>Jetzt lesen|/m<r°_"+(target.getMessageSound() == 1 ? "°>m-notify_001.mp<°":""));
			}
			
			target.newMessages.add(new String[] {String.valueOf(time), dest.getName(), betreff, message});
		}
		
		dest.sentMessages.add(new String[] {String.valueOf(time), an, betreff, message});

		query(String
				.format("insert into `messages` set `an` = '%s', `betreff` = '%s', `text` = '%s', `time` = '%s', `von` = '%s'",
						an, betreff.replace("'", "\\'"), String
								.format("%s%s",
										parseSmileys(dest, message).replace(
												"'", "\\'"),
										!dest.getSignatur().isEmpty() ? String
												.format("##%s",
														dest.getSignatur())
												: ""), time, dest.getName()));
	}

	public boolean checkCcm(String nick, Channel channel, int typ) {
		if (typ == 3) {
			return channel.getMutes().contains(String.format("|%s|", nick));
		} else {
			return channel.getCmutes().contains(String.format("|%s|", nick));
		}
	}
	
	public void newSysLogEntry(String sender, String reason) {
		String time = String.valueOf(System.currentTimeMillis()/1000);
		
		query(String.format("INSERT INTO `syslog` SET `time` = '%s', `name` = '%s', `text` = '%s'", time, sender, reason));
		syslog.put(time, new String[] {sender, reason});
	}

	static byte[] buffer;
    static String[] stringBuffer = new String[256];
    static int[] posBuffer = new int[256]; 
    
    @SuppressWarnings("deprecation")
	static String getRes(int pos) {
         int posByte = pos & 0xFF;
         if(posBuffer[posByte] != pos) {
              posBuffer[posByte] = pos;
              pos = pos < 0 ? pos & 0xFFFF : pos;
              String returnStr = new String(buffer, 0, pos, buffer[pos - 1] & 0xFF).intern();
              stringBuffer[posByte] = returnStr;
         }
         return stringBuffer[posByte];
    }
    
    static boolean load() throws IOException {
    	try {
    		InputStream resourceStream = new FileInputStream("res.class");
         
              byte decodeByte;
              int len = resourceStream.read() << 16 |  resourceStream.read() << 8 | (decodeByte = (byte)  resourceStream.read());
              len = len < 0 ? len & 0xFFFF : len;
              buffer = new byte[len];
              int offset = 0;
              
              while(len > 0) {
                   int res;
                   if((res = resourceStream.read(buffer, offset, len))  < 0) break;
                   len -= res; 
                   res += offset;
                   
                   while(offset < res) {
                        buffer[offset] = (byte) (buffer[offset++] ^ decodeByte);
                   }
              } 
              
              resourceStream.close();
    	}catch(IOException ex) {
    		return false;
    	}
              
        return true;
    }
	
	private void loadConfigs() {
        try { 
             load();
        } catch(IOException ioe) {
             ioe.printStackTrace();
        }

        
		PoolConnection pcon = ConnectionPool.getConnection();
		Statement stmt = null;

		try {
			Connection con = pcon.connect();
			stmt = con.createStatement();
			ResultSet rs = stmt
					.executeQuery("SELECT `name` FROM `accounts` ORDER BY `id`");
			rs.next();
			butler.login(rs.getString("name"));
			rs.close();
			rs = stmt.executeQuery("SELECT * FROM `channelstyles`");
			Map<Integer, ChannelStyle> channelStyles = new HashMap<Integer, ChannelStyle>();

			while (rs.next()) {
				try {
				channelStyles.put(rs.getInt("id"), new ChannelStyle(rs));
				}catch(Exception ex) {
					
				}
			}
			rs.close();
			rs = stmt.executeQuery("SELECT * FROM `channels` ORDER BY name");

			while (rs.next()) {
				Channel channel = new Channel(rs, channelStyles.get(rs
						.getInt("style")));
				butler.joinChannel(channel);
				channel.addClient(butler);
				channels.put(rs.getString("name").toLowerCase(), channel);
			}
			rs.close();
			rs = stmt.executeQuery("SELECT * FROM `settings`");
			rs.next();
			new Settings(rs);
			rs.close();
			rs = stmt.executeQuery("SELECT * FROM `badword`");

			while (rs.next()) {
				badwords.put(rs.getString("text").toLowerCase(),
						rs.getInt("juschu"));
			}
			rs.close();
			rs = stmt.executeQuery("SELECT macro,texts FROM `macros`");
			while (rs.next()) {
				macros.put(rs.getString("macro"), rs.getString("texts"));
			}
			rs.close();
			rs = stmt.executeQuery("SELECT word,title,text FROM `help`");
			while (rs.next()) {
				help.put(rs.getString("word"), new String[] {rs.getString("title"), rs.getString("text")});
			}
			rs.close();
			rs = stmt.executeQuery("SELECT * FROM `umfragen`");
			while (rs.next()) {
				umfragen.put(rs.getString("frage"), rs.getString("antworten"));
			}
			rs.close();
			rs = stmt.executeQuery("SELECT * FROM `syslog`");
			while (rs.next()) {
				syslog.put(rs.getString("time"), new String[] {rs.getString("name"), rs.getString("text") });
			}
			rs.close();
			rs = stmt
					.executeQuery("SELECT count(id) as a from accounts where lotto!=0");
			while (rs.next()) {
				setLottoJackpot(rs.getInt("a"));
			}
			rs.close();
			rs = stmt.executeQuery("select sum(knuddels) as a from accounts");
			while (rs.next()) {
				setAllKnuddels(rs.getInt("a"));
			}
			rs.close();
			rs = stmt
					.executeQuery("select sum(kontoKnuddels) as a from accounts");
			while (rs.next()) {
				setAllKontoKnuddels(rs.getInt("a"));
			}
			rs.close();
			rs = stmt
					.executeQuery("select text from werbung");
			while (rs.next()) {
				werbung.add(rs.getString("text"));
			}
			rs.close();
			rs = stmt
					.executeQuery("SELECT function,rank,description FROM `functions`");
			while (rs.next()) {
				String[] fm = new String[2];
				fm[0] = String.valueOf(rs.getInt("rank"));
				fm[1] = rs.getString("description");
				
				functions.put(rs.getString("function"), fm);
			}
			rs.close();
			rs = stmt.executeQuery("SELECT word,text FROM `butler`");
			while (rs.next()) {
				james.put(rs.getString("word"), rs.getString("text"));
			}
			rs.close();
			rs = stmt.executeQuery("SELECT von,an,text,uhrzeit FROM `news`");
			while (rs.next()) {
				news.add(new String[] {rs.getString("von"), rs.getString("an"), rs.getString("text"), rs.getString("uhrzeit")});
			}
			rs.close();
			rs = stmt
					.executeQuery("SELECT von,text FROM todo order by id desc");
			while (rs.next()) {
				todo.put(rs.getString("text"), rs.getString("von"));
			}
			rs.close();
			rs = stmt
					.executeQuery("SELECT `SENTENCE` FROM `wordmix` ORDER BY RAND()");
			while (rs.next()) {
				wordmix.add(rs.getString("SENTENCE"));
			}
			rs.close();
			rs = stmt.executeQuery("SELECT word,text,name FROM `toplisten`");
			while (rs.next()) {
				toplisten.put(rs.getString("word").toLowerCase(), new String[] { rs.getString("name"), rs.getString("text")});
			}
			rs.close();
			rs = stmt
					.executeQuery("SELECT * FROM `mentorsmileys` order by id desc");
			while (rs.next()) {
				mentorsmileys.put(rs.getString("code"),
						new String[] {rs.getString("mentorPoints"), rs.getString("id"), rs.getString("name"), rs.getString("description")});
			}
			rs.close();
			rs = stmt
					.executeQuery("SELECT * FROM `smileys` order by id");
			while (rs.next()) {
				smileys.put(
						rs.getInt("id"), new String[] {rs.getString("syntax"), rs.getString("replacement"), rs.getString("category"), rs.getString("name"), rs.getString("description"), rs.getString("feature")});
			}
			rs.close();
			rs = stmt
					.executeQuery("SELECT * FROM statistik order by uhrzeit desc");
			while (rs.next()) {
				long bla = rs.getLong("uhrzeit");
				statistik.put(rs.getString("question"), new String[] {rs.getString("text"), rs.getString("stimmen"), String.format("%s %s", get().timeStampToDate(bla), get().timeStampToTime(bla))});
			}
			rs.close();
			rs = stmt.executeQuery("SELECT * FROM plz");
			while (rs.next()) {
				plz.put(rs.getString("plz"), new String[] {rs.getString("city"), rs.getString("bundesland")});
			}
			rs.close();
			rs = stmt.executeQuery("SELECT `name`, `sperre`, `sperrevon`, `sperrewann` FROM `accounts` WHERE `sperre` != '0' order by sperrewann desc");
			while (rs.next()) {
				long sperre = rs.getLong("sperre");
				
				lockedNicks.put(rs.getString("name"), String.format("%s~%s~%s", rs.getString("sperrevon"),
								rs.getString("sperrewann"),
								sperre == 1 ? " " : timeStampToDate(rs.getLong("sperre"))));
			}
			rs.close();
			rs = stmt.executeQuery("SELECT * FROM lotto order by id desc");
			while (rs.next()) {
				lotto.put(
						rs.getString("datum"), new String[] {rs.getString("name"), rs.getString("zahl"), rs.getString("knuddels")});
			}
			rs.close();
			rs = stmt.executeQuery("SELECT * FROM snp order by wann desc");
			while (rs.next()) {
				snp.put(rs.getLong("wann"), new String[] {rs.getString("nick"), rs.getString("von")});
			}
			rs.close();
			rs = stmt.executeQuery("SELECT * FROM smileykategorien");
			while (rs.next()) {
				smileyCategories.put(rs.getInt("id"), new String[] {rs.getString("name"), rs.getString("price")});
			}
			rs.close();
			rs = stmt.executeQuery("SELECT * FROM wahlen");
			while (rs.next()) {
				elections.put(rs.getString("name"), new String[] {rs.getString("aktiv"), rs.getString("nomiPhase"), rs.getString("wahlPhase"), rs.getString("endPhase"), rs.getString("nominated")});
			}
			rs.close();
			rs = stmt.executeQuery("SELECT * FROM luftlinie");
			while (rs.next()) {
				luftlinie.put(
						String.format("%s~%s", rs.getString("a"),
								rs.getString("b")), rs.getInt("number"));
			}
			rs.close();
			rs = stmt.executeQuery("SELECT * FROM permissions");
			while (rs.next()) {
				permissions.put(rs.getString("permission"), rs.getString("rights"));
			}
			rs.close();
			rs = stmt.executeQuery("SELECT * FROM tutorials");
			while (rs.next()) {
				tutorials.put(rs.getInt("tutid"), new String[] {rs.getString("titel"), rs.getString("header"), rs.getString("erklarung"), rs.getString("hintergrund"), rs.getString("merke"), rs.getString("rang"), rs.getString("minuten"), rs.getString("funktion")});
			}
			rs.close();
			rs = stmt.executeQuery("SELECT * FROM wordmixrekord where 1");
			if(rs.next()) {
				WordMixRecord.setNick(rs.getString("nick"));
				WordMixRecord.setSentence(rs.getString("sentence"));
				WordMixRecord.setPoints(rs.getFloat("points"));
				WordMixRecord.setSeconds(rs.getFloat("seconds"));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if (stmt != null) {
				try {
					stmt.close();
				} catch (SQLException e) {
				}
			}

			pcon.close();
		}
	}
@SuppressWarnings("resource")
	private void listen(int port) {
		try {
			final ServerSocket listener = new ServerSocket(port);
                        
                        
System.out.println("_________      ______________________        "); 
System.out.println("__  ____/___  _______  /_____  /__  /____  __"); 
System.out.println("_  /    _  / / /  __  /_  __  /__  /__  / / /"); 
System.out.println("/ /___  / /_/ // /_/ / / /_/ / _  / _  /_/ / "); 
System.out.println("\\____/  \\__,_/ \\__,_/  \\__,_/  /_/  _\\__, /  "); 
System.out.println("                                    /____/   "); 
      
                        System.out.println("");
			System.out.println("                                                         Autor: Kokos-Ice");
                        System.out.println("");
                        System.out.println("Lizenz: Free");
                        System.out.println("");
                        
                        
                        File jar = new File("dist/cuddlychat.jar");
                        String lastModified = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(jar.lastModified());
                        
                        System.out.println(String.format("Version: 2.1", lastModified));
                        System.out.println(String.format("JAR-DATUM: %s", lastModified));
                        
                        
			int hour = Integer.parseInt(new SimpleDateFormat("HH")
					.format(new Date()));
			int minute = Integer.parseInt(new SimpleDateFormat("mm")
					.format(new Date()));
			int minutes = 0;

			if (minute < 30) {
				minutes = 3;
			} else {
				hour++;
			}

			/*getChannel("Quiz")
					.setTopic(
							String.format(
									"Jede volle Stunde beginnt in diesem Channel das große °BB>_2Quizturnier|/h Quiz<r° für alle Mitglieder.#Die nächste Quizrunde findet um %s:%s0:00 statt.",
									hour, minutes));
*/
			if (Settings.getCronjob() < System.currentTimeMillis() / 1000) {
				tools.Cronjob.execute();
			} else {
				System.out.println(String.format("Aktualisierung: %s %s",
						timeStampToDate(Settings.getCronjob()),
						timeStampToTime(Settings.getCronjob())));
			}

                        System.out.println("");
                        Logger.handle(null,String.format("Starlight Chat ONLINE auf Port %s.", port));
			Logger.handle(null,String.format("%s betritt den Chat", getButler().getName()));
			onlineUsers.add(getButler().getName());
			Settings.increaseRevision(1);

			Thread settings = new Thread(new Runnable() {
				public void run() {
					while (true) {
						try {
							Reloader.run();
						} catch (ConcurrentModificationException ex) {
						}

						String time = new SimpleDateFormat("HH:mm:ss")
								.format(new Date());
						int minutes = Integer.parseInt(time.substring(3, 5));
						
						if (time.equals("00:02:00")) {
							tools.Cronjob.execute();
						} else if (time.equals("20:55:00")) {
							List<String> answers = new ArrayList<String>();
						
							Object[] question = Server.umfragen.keySet().toArray();
							
							String randomQuestion = (String) question[new Random().nextInt(umfragen.size())];
							String answer = umfragen.get(randomQuestion);
							
							for(String ans : answer.split(";")) {
								answers.add(ans);
							}
							
							new Poll(null, randomQuestion, answers).create();
						} else if(time.endsWith(":00:00")) {
							for (Client ob : Server.get().getClients()) {
								ob.setHealsperre((byte)0);
								ob.setImmunsperre((byte)0);
								ob.setSun((byte)0);
							}

							query("update accounts set healsperre='0', sun='0', immunsperre='0'");
						} else if(minutes %2 != 1 && time.endsWith(":00")) {
							clearIPs();
						}

						try {
							Thread.sleep(1000);
						} catch (InterruptedException ex) {
						}
					}

				}
			});

			settings.start();
			
			while (true) {
				Socket socket = listener.accept();
				new SessionHandler(socket).start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		instance.loadConfigs();
		instance.listen(1338);
	}

}