#!/usr/bin/perl -I.
# Dreamcast Version
# SONIC ADVENTURE
# Chao Download Data
# 


use strict;

use CGI;
use	DC;
use DB;


## Set up variables
use vars	(	'$dc',	# DC object
				'$DBaseUser',
				'$DBaseChao',
				'@IN',
				'$CHAO',
				'$errorURL',
				'$vmsurl',
				'$vmsdir',
				'$browserid',
			);

#...............................................

	my $q = new CGI;
	$dc = new DC($q);
	$dc->q->import_names('IN');
	$browserid = -1;

	$errorURL = "chao_down.html";
	$vmsurl = 'http://sonic.games.dreamcast.com/tmp';
	$vmsdir = '/web/sonic.games/tmp';
	my $fileid = sprintf "%08d", $$;

	my ($errN, $errstr, $dbh, $sth, @row);

    &check_data;

	($dbh, $errstr) = DB::openOracleConnection();
	if( !$dbh )
	{
		$dc->error("[getchao] Error connecting to database: $errstr", $errorURL);
	}

    ($errN, $errstr, @row) = DB::getRow_ChaoByUK( $dbh, $dc->DBaseTable('CHAO'), $IN::UserKey );
	if ($errN)
	{
		$dc->error("[getchao] Fetching Chao info: $errN .... $errstr", $errorURL);
	}
	if (@row eq "")
	{
		$dc->error("[getchao] User key does not exist", $errorURL);
	}

	DB::closeOracleConnection( $dbh );

    if($row[$dc->ChaoOff('PW')] ne "") {
        if($IN::password ne $row[$dc->ChaoOff('PW')]) {
            $dc->error("[getchao] Incorrect password.  Please try again.", $errorURL);
        }
    }

	make_vmsfile($fileid, $row[$dc->ChaoOff('CHAO')]);

    # Send Chao Data
	my $location = "${vmsurl}/${fileid}.VMI";
	print $dc->q->redirect(-location=>$location);

exit(0);

#--------------------------------------------------------
# Data Check
#--------------------------------------------------------
sub check_data {
    if($IN::UserKey eq "") {
        $dc->error("[getchao] Invalid user key was given \"$IN::UserKey\".", $errorURL);
    }

	if ($dc->q->referer() !~ m(^http://sonic\.games\.dreamcast\.com/))
	{
		$dc->error("[getchao] File request denied.<BR>Only authorized URLs allowed.", $errorURL);
	}

	$browserid = $dc->get_browser();
	if ($browserid == -1)
	{
		$dc->error("[getchao] File request denied.<BR>Only authorized browsers allowed.", $errorURL);
	}
}

#--------------------------------------------------------
# Cancel Unnecessary VMS Files
#--------------------------------------------------------
sub del_vmsfile {
	my $filename = shift;

	unlink("${vmsdir}/${filename}.VMI");
	unlink("${vmsdir}/${filename}.VMS");
}

#--------------------------------------------------------
# Create the VMS files for download
#--------------------------------------------------------
sub make_vmsfile {
	my $filename = shift;
	my $CHAO = shift;

	# Clear out old VMS and VMI files sitting on the system
	&del_vmsfile($filename);

	# Create the VMS file
    if(open(VMSFILE,">${vmsdir}/${filename}.VMS")) {
        my $vmsdata = "";

        # Read data for Chao header.
		if (($browserid >= 0) && ($browserid < 2))
		{
			# US and European chao download file
			if(open(FILE,"chaoheader.bin")) {
				read(FILE,$vmsdata,3072);
				close(FILE);
			} else {
				&error("Failure to read data.");
				$dc->error("[getchao] Failure to read \"chaoheader.bin\".", $errorURL);
			}
		} elsif ($browserid == 2)
		{
			# Japanese chao download file
			if(open(FILE,"jpchaoheader.bin")) {
				read(FILE,$vmsdata,3072);
				close(FILE);
			} else {
				&error("Failure to read data.");
				$dc->error("[getchao] Failure to read \"jpchaoheader.bin\".", $errorURL);
			}
		}
        $vmsdata .= $CHAO;
        for(my $i=0;$i<512;$i++) {
            $vmsdata .= pack("c",0);
        }
        print VMSFILE $vmsdata;
        close(VMSFILE);
        chmod(0666,"${vmsdir}/${filename}.VMS");
    } else {
        $dc->error("[getchao] Failure to create VMS file \"${filename}\".", $errorURL);
    }

	# Create the VMI file
    if(open(VMIFILE,">${vmsdir}/${filename}.VMI")) {
		my $vmidata = "";

        $vmidata = &make_vmidata($filename, 0);
        print VMIFILE $vmidata;

        close(VMIFILE);
        chmod(0666,"${vmsdir}/${filename}.VMI");
    } else {
        $dc->error("[getchao] Failure to create VMI file \"${filename}\".", $errorURL);
    }

}

#........................................................
# Creating VMI data.
sub make_vmidata {
	my $filename = shift;
	my $checksum = shift;

    my ($i, @var, $version);
	my @VMIDATA = ();

    my (@vmiheader) = (	
        83, 111, 110, 105, 99, 32, 65, 100, 118, 101,110,116,117, 114,101, 32,
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        83, 101,103, 97,32, 69,110, 116,101,114,112, 114,105, 115,101,115,
        0,0,0, 0,0, 0,0, 0,  0,  0,  0,  0,  0,  0,  0,  0
        );

    for($i=0;$i<68;$i++) {
        $VMIDATA[$i+4] = $vmiheader[$i];
    }

    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
    $mon++;
    $VMIDATA[68]= ($year+1900 & 255);	# year (Low Byte)
    $VMIDATA[69]= ($year+1900 >> 8);	# year (High Byte)
    $VMIDATA[70]= $mon;			# month
    $VMIDATA[71]= $mday;		# day
    $VMIDATA[72]= $hour;		# hour
    $VMIDATA[73]= $min;			# minute
    $VMIDATA[74]= $sec;			# second
    $VMIDATA[75]= $wday;		# day of the week
    $VMIDATA[76]= 0;			# Version (superior rank)
    $VMIDATA[77]= 0;			# Version (inferior rank)
    $VMIDATA[78]= 1;			# # of files (inferior rank)
    $VMIDATA[79]= 0;			# # of files (superior rank)

    @var=split(//,$filename);
    for($i=0;$i<8;$i++) {
        $VMIDATA[$i+80] = ord($var[$i]);	# File names on server
    }

	$version = $dc->get_browser();
	if ($version == 0)
	{
		# US - Planet Web Version
		$VMIDATA[0] = $VMIDATA[80] & 65;		# Checksum
		$VMIDATA[1] = $VMIDATA[81] & 71;		#
		$VMIDATA[2] = $VMIDATA[82] & 69;		#
		$VMIDATA[3] = $VMIDATA[83] & 83;		#
	} else {
		# Japanese and European Version
		$VMIDATA[0] = $VMIDATA[80] & 83;		# Checksum
		$VMIDATA[1] = $VMIDATA[81] & 69;		#
		$VMIDATA[2] = $VMIDATA[82] & 71;		#
		$VMIDATA[3] = $VMIDATA[83] & 65;		#
	}

    @var=split(//,'SONICADV__VM');
    for($i=0;$i<12;$i++) {
        $VMIDATA[$i+88] = ord($var[$i]);	# VMS file names
    }

    $VMIDATA[100] = 3;			# Attributes
    $VMIDATA[101] = 0;			# Attributes
    $VMIDATA[102] = 0;			# Attributes
    $VMIDATA[103] = 0;			# Attributes
    $VMIDATA[104] = 0;			# File size
    $VMIDATA[105] = 16;			# File size
    $VMIDATA[106] = 0;			# File size
    $VMIDATA[107] = 0;			# File size

	my $vmidata = "";
	for($i=0;$i<108;$i++) {
        $vmidata .= pack("C",$VMIDATA[$i]);
    }

    return $vmidata;
}

#------------------------ EOF --------------------------

