#!/usr/bin/perl

# Metaserver for Freeciv.
#
# No rights reserved, released to the public domain.

use strict;
use CGI;
use MIME::Base64;
use File::Basename;

my $userdef_savedata=dirname($0)."/freeciv-meta.dat";
my $userdef_lifetime=300;
my $userdef_encoding="utf-8";

my $cgi=new CGI;

my %dat;
my ($host)=$cgi->param("host");
my ($port)=$cgi->param("port");
my ($client_cap)=$cgi->param("client_cap");

&dat_load($userdef_savedata,\%dat);
&dat_lifetime($userdef_lifetime,\%dat);

if((length($host)>0)&&(length($port)>0)){# for freeciv-server
	print $cgi->header({-charset=>$userdef_encoding});
	$host=join(":",$host,$port);
	$dat{$host}{"LifeTime"}[0]=time();

	foreach my $key($cgi->param){
		my @param=$cgi->param($key);
		$dat{$host}{$key}=\@param;
	}
	if($dat{$host}{"bye"}[0]){undef($dat{$host});}# connection down
	&dat_save($userdef_savedata,\%dat);
} elsif(length($client_cap)>0){# for freeciv-client
	print $cgi->header({'-content-type'=>'text/plain',-charset=>$userdef_encoding});
	my @hosts=(keys %dat);
	for(my $n=0,my $mn=$#hosts;$n<=$mn;++$n){
		$host=$hosts[$n];
		print("[server$n]\n");
		print("host = \"".$dat{$host}{"host"}[0]."\"\n");
		print("port = \"".$dat{$host}{"port"}[0]."\"\n");
		print("version = \"".$dat{$host}{"version"}[0]."\"\n");
		print("capability = \"".$dat{$host}{"capability"}[0]."\"\n");
		print("state = \"".$dat{$host}{"state"}[0]."\"\n");
		print("topic = \"".$dat{$host}{"topic"}[0]."\"\n");
		print("message = \"".$dat{$host}{"message"}[0]."\"\n");
		print("available = \"".$dat{$host}{"available"}[0]."\"\n");
		print("serverid = \"".$dat{$host}{"serverid"}[0]."\"\n");
		print("nplayers = \"".($#{$dat{$host}{"plu[]"}}+1)."\"\n");
		print("player = { \"name\" , \"user\" , \"nation\" , \"type\" , \"host\"\n");
		for(my $f=0,my $mf=$#{$dat{$host}{"plu[]"}};$f<=$mf;++$f){
			print("\"".$dat{$host}{"plu[]"}[$f]."\",\"".$dat{$host}{"pll[]"}[$f]."\",\"".$dat{$host}{"pln[]"}[$f]."\",\"".$dat{$host}{"plt[]"}[$f]."\",\"".$dat{$host}{"plh[]"}[$f]."\"\n");
		}
		print("}\n");
		print("vars = {");
		for(my $f=0,my $mf=$#{$dat{$host}{"vn[]"}};$f<=$mf;++$f){
			print("\"".$dat{$host}{"vn[]"}[$f]."\",\"".$dat{$host}{"vv[]"}[$f]."\"\n");
		}
		print("}\n");
	}
	print("[main]\n");
	print("nservers=".($#hosts+1)."\n");
	print("\r\n");
} else {# for web-interface
	print $cgi->header({-charset=>$userdef_encoding});
	print("<HTML><BODY><PRE>\n");
	$host=$ENV{"REMOTE_ADDR"};

	print("<TABLE BORDER=1>\n");
	foreach my $host(keys %dat){
		print("<TR><TD>".$host."</TD><TD>STATE</TD><TD>".$dat{$host}{"state"}[0]."</TD></TR>\n");
		print("<TR><TD>".$host."</TD><TD>VERSION</TD><TD>".$dat{$host}{"version"}[0]."</TD></TR>\n");
		print("<TR><TD>".$host."</TD><TD>MESSAGE</TD><TD>".$dat{$host}{"message"}[0]."</TD></TR>\n");
		print("<TR><TD>".$host."</TD><TD>PATCHES</TD><TD>".$dat{$host}{"patches"}[0]."</TD></TR>\n");
		#print("<TR><TD>".$host."</TD><TD>CAPABILITY</TD><TD>".$dat{$host}{"capability"}[0]."</TD></TR>\n");
		#print("<TR><TD>".$host."</TD><TD>SERVERID</TD><TD>".$dat{$host}{"serverid"}[0]."</TD></TR>\n");
		for(my $f,my $mf=$#{$dat{$host}{"vn[]"}};$f<=$mf;++$f){
			print("<TR><TD>".$host."</TD><TD>".$dat{$host}{"vn[]"}[$f]."</TD><TD>".$dat{$host}{"vv[]"}[$f]."</TD></TR>\n");
		}
		for(my $f,my $mf=$#{$dat{$host}{"plu[]"}};$f<=$mf;++$f){
			print("<TR><TD>".$host."</TD><TD>".$dat{$host}{"plu[]"}[$f]."</TD><TD>".$dat{$host}{"pll[]"}[$f]."</TD><TD>".$dat{$host}{"pln[]"}[$f]."</TD><TD>".$dat{$host}{"plt[]"}[$f]."</TD><TD>".$dat{$host}{"plh[]"}[$f]."</TD></TR>\n");
		}
	}
	print("</TABLE>\n");

	print("</PRE></BODY></HTML>\n");
}

exit(0);

sub dat_load(){
	my ($fn,$dat)=@_;
	my @lines;
	if(open(my $fd,$fn)){@lines=<$fd>;close($fd);}

	foreach my $line(@lines){
		my @cols=split(/,/,$line);
		if($#cols=2){
			push(@{$$dat{MIME::Base64::decode($cols[0])}{MIME::Base64::decode($cols[1])}},MIME::Base64::decode($cols[2]));
		}
	}
}
sub dat_save(){
	my ($fn,$dat)=@_;
	my @lines;
	my @cols;
	print("keys: ".join(",",(keys %{$$dat{$host}}))."\n");
	foreach my $host(keys %{$dat}){
		$cols[0]=MIME::Base64::encode($host);
		$cols[0]=~s/\n//g;
		foreach my $key(keys %{$$dat{$host}}){
			$cols[1]=MIME::Base64::encode($key);
			$cols[1]=~s/\n//g;
			foreach my $data (@{$$dat{$host}{$key}}){
				$cols[2]=MIME::Base64::encode($data);
				$cols[2]=~s/\n//g;
				push(@lines,join(",",@cols));
			}
		}
	}
	if(open(my $fd,">$fn")){print($fd join("\n",@lines));close($fd);}
}
sub dat_lifetime(){
	my ($lifetime,$dat)=@_;
	foreach my $host(keys %{$dat}){
		if(($$dat{$host}{"LifeTime"}[0]+$lifetime)<time()){
			undef($$dat{$host});
		}
	}
}
