Java read/write to a text file on my site for highscores

I have a game and I want to write a high score to a text file and read from it. This file will be stored on my site eg w_ww.mysite.com/hs.txt

I have some code for reading and writing which works when i write to a file on my computer but when i try to do the same thing online I can read but not write. Can anyone help me?

if i run my applet through Eclipse I can read/write but if I run a applet through a html file using firefox I can only read.

Here is my HTML code:


<HTML>
<HEAD>
</HEAD>
<BODY>
<applet code="Main.class" archive="Main.jar" width="800" height="600">
</applet>
</HTML>

here is my read and write:


URL url = null;
    		File f = null;
    		String fileToRead = "hs.txt"; //high scores text file
    		
    		//INIT
    		try
    		{
    			url = new URL(getCodeBase(), fileToRead);
    			f = new File(fileToRead);
    		}
    		catch(Exception e2)
    		{
    			m_taHighScores.append("Init failed...");//m_taHighScores is a text area in the applet which displays the highscores.

    		}
    		
    		//WRITE
    		try
    		{
	        	BufferedWriter out = new BufferedWriter(new FileWriter(f,true));
	        	out.write("HIGHSCORE: ");
	        	m_taHighScores.append("WRITING:" + "HIGHSCORE: " + String.valueOf(m_snake.m_iScore) + "\n");
	        	out.write(String.valueOf(m_snake.m_iScore)+"\n");
	        	out.close();
	        	m_taHighScores.append("WRITE SUCCEEDED \n");
    			
    		}
    		catch(Exception e2)
    		{
    			m_taHighScores.append("Write failed... \n");
    		}
    		
    		
    		//READ
			try 
			{
				
				StringBuffer strBuff;
				String line;
				  
				InputStream in = url.openStream();
				BufferedReader bf = new BufferedReader(new InputStreamReader(in));
				strBuff = new StringBuffer();
				while((line = bf.readLine()) != null)
				{
					strBuff.append(line + "\n");
				}
				m_taHighScores.append("READING: \n");
				m_taHighScores.append(strBuff.toString());
				m_taHighScores.append("READ SUCCEEDED \n");
			}
			catch (Exception e2) 
			{
				m_taHighScores.append("Read failed... \n");
			}
	       	
    		
    		//m_taHighScores.append("\n" + String.valueOf(m_snake.m_iScore));
    		m_taHighScores.setVisible(true);


thanks,
roland

You need to display more detail from those exceptions. At the very least, also display the error message:

m_taHighScores.append("Init failed: " + e2.getMessage());

What will be even better is to display the stack trace also:


// Get the stack trace as a string
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e2.printStackTrace(pw);
String stackTrace = sw.toString();

m_taHighScores.append("Init failed: " + e2.getMessage() + "\n" + stackTrace);

99% of the time, if some code is calling the getMessage method on Exception, it shouldn’t be because it hides both the stacktrace and the messages of any “cause” exceptions.

If applets can write to files on your web server then pretty soon your server will be part of a botnet. You need to set up a CGI script of some kind (e.g. a servlet, if you want to stick to Java) which handles a GET or POST request, validates it, and updates the file accordingly.

thankyou for your comments.
I worked hard today and yesterday making some php scripts to add high scores and made a POST function in my java applet which I got an example from: http://www.exampledepot.com/egs/java.net/Post.html. It works perfectly, except that: it only sends the data if i get it to read the response after sending and I have no idea why I would need to do that.

This is what I need to include to make it work. Why?
I am not using this to read, only write. I have a different function which reads from a text file so i didnt want to include this, but when i got rid of it I could not write data at all.


// Get the response
        BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line;
        while ((line = rd.readLine()) != null) {
            // Process line...
        }

It is the http protocol. For each request, there is a reply… even it is empty. What ever for an high score submition, the new high scores are usualy sent back.

You may use FTP to get a write access to the scores files, as well. That be faster and safer han php.

No, that’s a bad idea. It’s neither safer nor faster.

With server-side logic, you can add some constraints on what data you accept, and you can control the format of the file.
With just plain FTP, anyone can upload any file.

well, php will be readable from world…
FTP can be checked with anonymous or a special user that does get access to score files under certain circumstances or folders, Java offers a great amount of crypted functions too.
I’d send the result as an encrypted or serialized object file, unless I can’t get an sftp access.

Making a bunch of hacks to secure ftp and verify the data is not in any way better than just writing some server-side logic (be it php or jsp or whatever).

Encryption will do you no good as the game client has to be able to encrypt it in the first place. Anyone can just look up how that encryption was done and reproduce those steps.

The (s)FTP route is also going to have horrible race condition issues when multiple clients try and add their high score into the high score file at the same time - if you’re lucky you’ll get one person’s score being overwritten, if you’re unlucky you’ll corrupt the whole file and lose all the scores. Plus since the login information will be publically available in your app, someone could just log in manually and delete the whole lot.

Just stick to keeping the high score logic server side with php/jsp/whatever and back it by a database.

Even if you do a PHP backing, how is that you can keep people from seeing how it’s sent? What I mean is, your game needs to send POST data or whatever to the PHP script, and the script has to somehow know what is real and what isn’t. In a simple sense, if I just send everything to submitScore.php and it takes a POST “score” variable, anyone can then send whatever score they want as long as they know that it’s being sent to submitScore.php. If you take the most obvious safeguard of adding a password POST parameter that your game sends (say it’s “h00ps”), then still someone can find that password in your game code and foil you anyway. So what’s the solution, here? How does the script know what’s good and what’s bad?

The only secure method I know of is to store input data and replay it on the server to recreate the score. That’s a PITA coding wise as you need a deterministic simulation (plus a headless version that can work on a server). Compromises usually involve sending a less complete replay/game state which can be verified easier on the server end at the trade off of being more easily faked. Sending meta-score info (num deaths, num kills, bonus multipliers, num powerups, etc.) and recreating the score from that is a nice compromise IMHO.

I’m not very confident with the PHP variant, as of POST param are visible (they may be encoded as well, e.g. Facebook make auth with something like a PHP scripted login) and will eventually need a browser to get the best results.
Then FTP is a way to mask datas and as long as the task can take whatever time it needs. After all, the user would not have to load an external application.

For I ain’t no j2ee expert, FTP seems to me the more accessible. afaik J2EE webserver (which are easy to set up but expensive to buy on the other part) would make things definitely more efficient with real-time client-server processes, like a mass multi-player game would need it.

Sorry to be blunt, but you’re very wrong!
FTP is every bit as visible, and is less secure as the user can upload any file he wants.

As Markus said, this is very wrong.

[quote]and will eventually need a browser to get the best results. After all, the user would not have to load an external application.
[/quote]
And this just makes no sense. What are you talking about?

Of course if you’re convinced that the hacky FTP solution is the way you want to do it then by all means do it. Just be prepared for it to come crashing down as soon as you release it to the public.

I dont know if this is the best way to do things but it worked for me.
i have a plain text file on my server for highscores, clients(applets and applications) can access this file(readonly).
they either do it directly using the http protocol or they can do it by passing a message to the java server application requesting the highscore data.
when it comes to updating the highscore they pass another message to the server application,the server application verifies the username and password and will update the file(i acually update a mysql database and get the server to periodically overwrite the text file).
so the clients access the file on the server by requesting the data from a java application on the server.
to display the data on the website i used php to read from the text file and display it.
I never let my clients alter files on my server directly they always have to verify themselves to a java application.
Word of warning if you try to do too many http calls too quickly your server will think its under a denial of service attack and you wont be able to read anything.

Thank you markmistry for your help ! this is definitely it.

Hmmm… same with Php

Whan an HTTP server give an DoS… your FTP server has explod far before (FTP session are far more longueur and are far more limited on the number of connection).

It depends… if your PHP script creates a new database connection for every hit (~17MB RAM) you’ll quickly swamp your RAM and the swap file too, with >100 concurrent http connections. FTP can handle this. I’ve seen this happening on (low end) 1GB servers with 1GB swapfile. In that state, the server is pretty much dead, it will become hard, if not impossible, to login using SSH, and once you do, even ls impossible, forget about shutdown, unix-load >100. Physical reboot saved the day.