Talk:RoboRumble/Development

From Robowiki
Jump to navigation Jump to search

Background Uploader -- Deprecated

This script is no longer necessary due to a server's upload speed-up.

This code, if run with a script in background after every iteration of roborumble's client, will upload your result while your client is fighting a new iteration, reducing the iteration time of 25% in the best case.

I'm actually patching roborumble 1.6.0 code to include this script's functionally (simply threading it and modifying the logging system for multi thread) in the hope this will be included in the next official roborumble's client

see after the code for installation instruction


ATTENTION: you MUST set roborumble.txt UPLOAD=NOT, ITERATION=NOT, and this code WORKS ONLY FOR 1VS1!! This script is no longer necessary due to a server's upload speed-up.


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

public class UploaderMain {

	static String infoThread;
	String clientVersion = "1";
	
	long maxTry = 10;
	
	public static void main(String args[]){
		
		String infoFilePath = "./roborumble/roborumble.txt";
		
		switch (args.length){
			case 2:
				infoFilePath = args[1];
				//whitout break;
			case 1:
				infoThread = args[0];
				break;
			case 0:
				infoThread = "";
				break;
			default:
				System.out.println("Usage: java UploaderMain [id] [path]\nid: name of this thread\npath: Path to roborumble settings file");
				return;
		}
		
		File test = new File(infoFilePath);
		if ( !test.exists() ){
			System.err.println("Roborumble setting file not found, try to specify his pah by default");
			return;
		}
		
		new UploaderMain(infoFilePath);
	}
	
	public UploaderMain(String infoFilePath){
		
		logOut("Starting Uploader");
		
//		read info from file
		ArrayList<String> allInfo = readFIle( infoFilePath );
//		extact info
		String[] info = findInfo(allInfo);
		
		if ((info == null) || (info.length != 2)){
			logErr("Roborumble settings file invalid");
			return;
		}
		
//		set info
		String uploadServerUrl = info[0];
		String battleFilePath = info[1];
		
//		read battle from file
		ArrayList<String> battles = readFIle( battleFilePath );
		
		if (battles == null){
			logErr("Battle files format invalid");
			return;
		}
		
//		delete old battle file
		File oldBattle = new File( battleFilePath );
		oldBattle.delete();
		
//		prepare data to be uploaded (only 1vs1 supported)
		battles = prepareToUpload1VS1(battles);
		
		ArrayList<String> battlesNotSend;
		long countTry = 0;
		while ((battles.size() > 0) && (countTry < maxTry)){
			battlesNotSend = new ArrayList<String>();
			for (String battle : battles){
				if ( !sendBattle(battle, uploadServerUrl) )
					battlesNotSend.add(battle);
			}
			battles = battlesNotSend; 
			countTry++;
		}
		logOut("Stopping Uploader, number of not uploaded battle: "+battles.size());
		if (battles.size() > 0)
			for (String battle:battles)
				write(battle+"\n", "results.txt");
	}

	private String[] findInfo(ArrayList<String> allInfo) {
		/*
		 * FIND INFO:
		 * at [0]: uploadServerUrl - RESULTSURL=
		 * at [1]: battleFilePath - OUTPUT=
		 */
		String[] info = new String[2];
		info[0] = null;
		info[1] = null;
		
		for (String ris : allInfo){
			if (ris.indexOf("RESULTSURL=") >= 0){
				info[0] = ris.substring(ris.indexOf("=")+1);
			}
			if (ris.indexOf("OUTPUT=") >= 0){
				info[1] = ris.substring(ris.indexOf("=")+1);
			}	
		}
		
		if ((info[0] != null)&&(info[1] != null))
			return info;
		
		return null;
	}

	private ArrayList<String> prepareToUpload1VS1(ArrayList<String> battles) {
		
		ArrayList<String> preparedBattles = new ArrayList<String>();
		
		String[] parametres = new String[6];
		String preparingBattle;
		
		for(int i = 0; i < battles.size(); i++){
			
			//extrapolate battlefield information
			parametres = battles.get(i).split(",");
			
			if ( parametres.length != 6 ){
				logErr( "invalid battlefield: "+battles.get(i) );
				continue;
			}
				
			
//			preparing string to upload
			preparingBattle = new String();
			preparingBattle += "version="+clientVersion;
			preparingBattle += "&game="+parametres[0];
			preparingBattle += "&rounds="+parametres[1];
			preparingBattle += "&field="+parametres[2];
			preparingBattle += "&user="+parametres[3];
			preparingBattle += "&time="+parametres[4];


				
//			extrapolate robot 1
			i++;
			parametres = battles.get(i).split(",");
				
//			if invalid information
			if ( parametres.length != 4 ){
				logErr( "invalid robot: "+battles.get(i) );
				continue;
			}
				
//			preparing string to upload
			preparingBattle += "&fname="+parametres[0];
			preparingBattle += "&fscore="+parametres[1];
			preparingBattle += "&fbulletd="+parametres[2];
			preparingBattle += "&fsurvival="+parametres[3];

//			extrapolate robot 2
			i++;
			parametres = battles.get(i).split(",");
				
//			if invalid information
			if ( parametres.length != 4 ){
				logErr( "invalid robot: "+battles.get(i) );
				continue;
			}
				
//			preparing string to upload
			preparingBattle += "&sname="+parametres[0];
			preparingBattle += "&sscore="+parametres[1];
			preparingBattle += "&sbulletd="+parametres[2];
			preparingBattle += "&ssurvival="+parametres[3];
			preparedBattles.add(preparingBattle);
		}
		
		return preparedBattles;
	}
	
	private boolean sendBattle(String battle, String uploadServerURL){
//		crea l'URL e la connessione HTTP con la servlet
		try{
			
			URL url = new URL(uploadServerURL);
			HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
			httpURLConnection.setRequestMethod( "POST" ) ;
			//httpURLConnection.setDoInput(true);
			httpURLConnection.setDoOutput(true);
			httpURLConnection.connect() ;
			

			OutputStreamWriter dataOutputStream = new OutputStreamWriter(httpURLConnection.getOutputStream());
			dataOutputStream.write( battle );
			dataOutputStream.flush();
			dataOutputStream.close();
			
			BufferedReader dataInputStream = new BufferedReader( new InputStreamReader( httpURLConnection.getInputStream() ) );
			String response = new String();
			boolean okUpload = false; 
			while(true){
				response = dataInputStream.readLine();
				if ( response == null )
					break;
				if ( response.indexOf("OK.") == 0 )
					okUpload = true;
				logOut("risposta: "+response);
			}
			dataInputStream.close();
			return okUpload;
			
		}catch(Exception e){
			logErr("error: "+e);
		}
		return false;
	}

	private void logOut(String string) {
		log(string, "./log/outUploader");
	}
	
	private void logErr(String string) {
		log(string, "./log/errUploader");
	}

	private void log(String string, String fileName) {
		write(infoThread+": "+string+"\n", fileName);
	}
	
	private void write(String string, String fileName) {
		try {
			BufferedWriter output = new BufferedWriter(new FileWriter(fileName, true));
			output.write(string);
			output.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private ArrayList<String> readFIle( String filePath ) {
		
		try{
			
			ArrayList<String> battles = new ArrayList<String>();
			FileReader battleFile = new FileReader( filePath );
			BufferedReader battleReader = new BufferedReader(battleFile);
			String battle = null;
			while(true){
				battle = battleReader.readLine();
				if (battle==null)
					break;
				battles.add(battle);
			}
			battleReader.close();
			
			return battles;
			
		}catch(Exception e){
			System.out.println("Error: "+e);
			return null;
		}
	}
}

thank to Rednaxela for code formatting

INSTALLATION copy and compile the code in the robocode home directory(where there is roborumble.bat and roborumble.sh), then if you are windows user create a new file "nameAsYouWant.bat" and write on it (script is not tested!):

:inizio

CALL roborumble.bat

START java UploaderMain
GOTO inizio

if you are under UNIX create a new directory "log" new file "nameAsYouWant.sh" and write on it the following code. This script is more advanced: in the log directory you will find the log of all client's iteration, with at the end the execution time. you can find also 2 log file of the uploader:

  1. errUpdaters.txt created and filled with the uploader's error (no error no file)
  2. outUploader.txt filled with server response and live time of uploaders
  3. results.txt

this last 2 file have to be deleted sometimes

#!/bin/bash
echo
count=0
while [ "$var1" != "fine" ]     #  while test "$var1" != "fine", forever
do
	let "count=count+1"
	date
	echo "battle n: " $count
	time ./roborumble.sh &> ./log/temp$count.txt
	java UploaderMain $count &
	echo
done  

exit 0

WARNING: in the robocode's home directory there will be created a file called results.txt with all unloaded battle; delete it sometimes, with errUpdaters.txt and outUpdaters.txt if you're using unix's script. --lestofante 00:09, 6 December 2008 (UTC)

Hmm, when implementing this functionality as a patch, could you make it an option? Or alternatively, at least also make an option for a delay between iterations? I don't like how hot my laptop CPU gets if it doesn't get any breaks ;) --Rednaxela 02:41, 6 December 2008 (UTC)

There are no threads on this page yet.