<commit_before>package org.bukkit.virtualbukkit;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

public abstract class VirtualBukkit extends Thread {
	private volatile boolean running = false;
	
	public abstract InetSocketAddress listeningAddress();
	public abstract InetSocketAddress addressForVirtualHost(String hostname);
	
	public boolean isRunning() {
		return this.running;
	}
	
	public void terminate() {
		synchronized (this) { this.running = false; }
	}
	
	@Override
	public final void run() {
		try {
			this.safeRun();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	protected void safeRun() throws Exception {
		synchronized (this) { this.running = true; }

		ServerSocket ss = new ServerSocket(this.listeningAddress().getPort(), 10, this.listeningAddress().getAddress());
		
		while (this.isRunning()) {
			Socket s = ss.accept();
			byte[] b = new byte[512];
			int r = s.getInputStream().read(b);
			
//			System.out.println(b[0] + " " + b[1] + " "  + b[2] + " "  + b[3]);
			
			if (r > 0)
				this.handle(s, b, r);
		}
		
		ss.close();
	}
	
	protected void handle(final Socket src, final byte[] init, final int len) {
		new Thread() {
			{
				this.setDaemon(true);
			}
			
			@Override
			public void run() {
				try {
					InetSocketAddress addr = VirtualBukkit.this.addressForVirtualHost(new String(init, 4, init[3]));
					if (addr == null) {
						src.close();
						return;
					}<commit_msg>Handling old versions<commit_after>package org.bukkit.virtualbukkit;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

public abstract class VirtualBukkit extends Thread {
	private volatile boolean running = false;
	
	public abstract InetSocketAddress listeningAddress();
	public abstract InetSocketAddress addressForVirtualHost(String hostname);
	
	public boolean isRunning() {
		return this.running;
	}
	
	public void terminate() {
		synchronized (this) { this.running = false; }
	}
	
	@Override
	public final void run() {
		try {
			this.safeRun();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	protected void safeRun() throws Exception {
		synchronized (this) { this.running = true; }

		ServerSocket ss = new ServerSocket(this.listeningAddress().getPort(), 10, this.listeningAddress().getAddress());
		
		while (this.isRunning()) {
			Socket s = ss.accept();
			byte[] b = new byte[512];
			int r = s.getInputStream().read(b);
			
//			System.out.println(b[0] + " " + b[1] + " "  + b[2] + " "  + b[3]);
			
			if (r > 0)
				this.handle(s, b, r);
		}
		
		ss.close();
	}
	
	protected void handle(final Socket src, final byte[] init, final int len) {
		new Thread() {
			{
				this.setDaemon(true);
			}
			
			@Override
			public void run() {
				try {
					String host = null;
					
					if (init[0] == 2) {
						// up to 1.6.4
						int offset = 4 + 2 * (init[2] << 8 | init[3]);
						int strlen = init[offset++] << 8 | init[offset++];
						
						host = new String(init, offset, strlen * 2, "UTF-16");
					} else if (init[1] == 0) {
						// recent versions
						int offset = 3;
						int strlen = init[offset++];
						
						host = new String(init, offset, strlen, "UTF-8");
					}
					
					if (host == null) {
						src.close();
						return;
					}
					
					InetSocketAddress addr = VirtualBukkit.this.addressForVirtualHost(host);
					if (addr == null) {
						src.close();
						return;
					}
{'fraction_non_alphanumeric': 0.13842746400885936, 'fraction_numerical': 0.01107419712070875, 'mean_word_length': 2.9659714599341385, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4377307', 'n_tokens_mistral': 1464, 'n_tokens_neox': 1152, 'n_words': 300}