#!/usr/bin/perl

use IO::Socket;
use IO::Select;
require LWP::UserAgent;

# use URI::Escape; # you'll need this later i guess ...

$verb = 5;  # verbosity for console messages

$main = new IO::Socket::INET (LocalHost => 'entropy8zuper.org',
                              LocalPort => 1234,
                              Listen    => 50,
                              Proto     => 'tcp', 
                              Reuse     => 1 ) || die $!;



$zero = chr(0);
$/ = $zero;
$\ = $zero;
$| = 1;
#$bigboy = "littlegirl";
$you = "speck";
$numOfUsers = 999;
$xA = 50;
$yA = 250;
$xZ = 500;
$yZ = 250;
$var1 = 0;
$var2 = 0;
$var3 = 0;
$var4 = 0;

# Initialise IO::Select ------------------------------------------------

$handles = new IO::Select();
$handles->add($main);

$introLevel = 2;
$musicLevel = 1;#and 3!
$backgroundLevel = 5;
$soundLevel = 10;#till 20
$movieLevel = 50;#till 9998
$camerasLevel = 9999;
$chatLevel = 10000;
$toolLevel = 10001;
$guestLevel = 10002;
$foregroundLevel = 10005 * 10000;
$moviecoverLevel = 10008;
$lostconnectionLevel = 10010;

$curLevel = $movieLevel; 

$wirefirePath = "http://entropy8zuper.org/wirefire";
$moviePath = "$wirefirePath/movies/";
$nodeName = "response";

$moviePathlength = length $moviePath;

print "Starting listening cycle\n" if ($verb > 1);


LISTEN: while (1)
	{
	($pending) = IO::Select->select($handles, undef, undef, 60);
	foreach $sock (@$pending)
		{
		if ($sock == $main)
			{
			$num++;
			print "Got new connection: $num from ".$sock->sockhost()."\n" if ($verb > 2); 
			my $newsock = $sock->accept();
			$newsock->autoflush();
			$number{$newsock} = $num;
			$handles->add($newsock);

			#update movieLevel with last number from data2
			$file = "data2";
			open(INFO, $file);
			@lines = <INFO>;
			$lineNum = 0;
			foreach $line (@lines)
				{
				$lineNum = $lineNum + 1;
				}
			$lastLine = $lines[$lineNum-1];
			$lastLineLength = length $lastLine;
			$levelStart = index $lastLine, "curLevel=";
			$thisLevel = substr $lastLine, $levelStart + 10, $lastLineLength - $levelStart - 10 - 4;
			if ( $thisLevel > $movieLevel )
				{
				$movieLevel = $thisLevel;
				}
			close(INFO);
			}
		else
			{
			my $buf = <$sock>;
			if ($buf)
				{
				print "Existing socket $number{$sock} is pending: " if ($verb > 3);
				chomp $buf;
				print "$buf\n" if ($verb > 3);
				($data) = $buf =~ /data="(.*?)"/;
				$you = "".$sock->peerhost.":".$sock->peerport."";
				$numOfUsers = "".($handles->count - 1)."";
				$cat = substr $data, 0, 3;
				$swicat = substr $data, 0 + 24 + 8, 3;#base + number of letters + escaped characters
				$head = substr $data, 0, 3;
				if ( $head eq "cam" )
					{
					$nodeName = "cameraPos";
					$dataLength = length $data;
					@camData = split(/,/,$data);
					$data = $camData[0];
					$xA = $camData[1];
					$yA = $camData[2];
					$xZ = $camData[3];
					$yZ = $camData[4];
					}
				elsif ( $head eq "var" )
					{
					$nodeName = "vars";
					$dataLength = length $data;
					@varData = split(/,/,$data);
					$data = $varData[0];
					$var1 = $varData[1];
					$var2 = $varData[2];
					$var3 = $varData[3];
					$var4 = $varData[4];
					}
				elsif ( $head eq "fad" )
					{
					$nodeName = "fade";
					$dataLength = length $data;
					@varData = split(/,/,$data);
					$data = $varData[0];
					$cha = $varData[1];
					$lev = $varData[2];
					$num = $varData[3];
					}
				elsif ( $head eq "cht" )
					{
					$nodeName = "chat";
					$dataLength = length $data;
					$data = substr $data, 3, $dataLength-3;
					}
				elsif ( $head eq "kil" )
					{
					$nodeName = "kill";
					$dataLength = length $data;
					$data = substr $data, 3, $dataLength-3;
					}
				else
					{
					$nodeName = "response";
					if ( $cat eq "mus" )
						{
						if ( $musicLevel == 1 ) { $musicLevel = 3; }
						else { $musicLevel = 1; }
						$curLevel = $musicLevel;
						}
					elsif ( $cat eq "sou" )
						{
						if ( $soundLevel < 20 ) { $soundLevel++; }
						else { $soundLevel = 10; }
						$curLevel = $soundLevel;
						}
					elsif ( $cat eq "swi" && $swicat eq "sou" )
						{
						if ( $soundLevel < 20 ) { $soundLevel++; }
						else { $soundLevel = 10; }
						$curLevel = $soundLevel;
						}
					elsif ( $cat eq "for" )
						{
						$curLevel = $foregroundLevel
						}
					elsif ( $cat eq "bac" )
						{
						$curLevel = $backgroundLevel
						}
					else
						{
						$movieLevel++;
						$curLevel = $movieLevel;
						}
					#$bigboy = $data;
					}
				send2all($data);
				}
			else
				{
				print "Socket $number{$sock} is gone.\n" if ($verb > 2);
				$handles->remove($sock);
				}
			}
		}
	}

sub send2all
{
my ($msg) = @_;
#$xmlmsg =  qq|<response data="$msg" cat="$cat" swicat="$swicat" you="$you" numOfUsers="$numOfUsers" curLevel="$curLevel" />|;
$xmlmsg =  "<$nodeName data='$msg' cat='$cat' swicat='$swicat' you='$you' numOfUsers='$numOfUsers' curLevel='$curLevel' xA='$xA' yA='$yA' xZ='$xZ' yZ='$yZ' cha='$cha' lev='$lev' num='$num' var1='$var1' var2='$var2' var3='$var3' var4='$var4'/>";

foreach ($handles->can_write)
	{
	print $_ $xmlmsg;
	}

if ( $head ne "new" && $head ne "cam" && $head ne "var" && $head ne "cht" && $head ne "fad" )
	{
	#call wirefire2.pl to save data to file; doing this here causes mysterious extra character to appear
	$msgLength = length $msg;
	$theMovie = substr $msg, 0, $msgLength - 0;
		#$thisUrl = "$wirefirePath/data/wirefire2.pl?saveData=%3Cresponse%20data%3D%22$theMovie%22%20curLevel%3D%22$curLevel%22%20%2F%3E";
	$thisXML = "<response data=\"$theMovie\" curLevel=\"$curLevel\" />";
	$thisXML =~ s/</%3C/g;
	$thisXML =~ s/"/%22/g;
	$thisXML =~ s/=/%3D/g;
	$thisXML =~ s/>/%3E/g;
	$thisXML =~ s/&/%26/g;
	$thisXML =~ s/ /%20/g;
	$thisXML =~ s/\//%2F/g;
	$thisUrl = "$wirefirePath/data/wirefire2.pl?saveData=$thisXML";
	$ua = new LWP::UserAgent;
	$request = new HTTP::Request('GET', $thisUrl);
	$response = $ua->simple_request($request);
	}
}

print "Content-type: text/plain\n\n";
print "Socks server seems to have started.";