I've been trying to figure out a way to implement an online high score system for my game in Java. I have tried JDBC, but I found out that my shared hosting server does not allow MySQL connections from JDBC.

My high score system only needs to insert and show 10 scores and names.

First of all, I understand that I can only make hackers struggle, but not 100% protect it. (Though chances are not so high that someone would want to hack into a small game)So, now I'm here considering other options...

1. Executing php script from Java to connect MySQL. Aside from protecting against MySQL injection, I am going to use ProGuard to make effort protecting against decompiles and set temporary password for insertion.

2. Just writing on a .txt file. My concern is security. If this choice works, how would I increase the level of security?

Personally, for security I like the first option best. I've used php and Java, but never together, so I don't personally know off the top of my head how to implement this, but I am sure you can find something easily enough.

However, if it were me I would just use the .txt option and not bother about security at all. Then if later it turns out to actually be a problem and people actually are hacking into the high scores list, then I'd change my implementation. This is mostly because I am way lazy though. It really depends on how popular you think your game is going to be.

Go for the textfile first. You probably dont need database functionality when only using a highscore.(only adds more work and potential problems)

Important is that the php handling the inputparameters propperly (look up php security for that)and that you add some verification into the send scores, so someone can not easily manipulate the scores bymanually sending one.For a small game some simple checksum procedure might be enough to avoid most simple "hacks".The hacker would have to decompile your game first to figure out how to manipulate the scores.

To be really save you would need a propper account validation system,so you could erase manipulated scores (and users)

-> make a log of send scores!, dont just directly isert/replace them in the highscore, so you can (if needed) manually revert back to the correct entries.

At first, I thought of .txt file as an option, but I will exclude that. First of all, it's not how score system is supposed to be done. It will also teach me some lessons.

I will go with php/MySQL solution.

I'm trying to come up with a way to prevent people just accessing the url and submitting fake scores. If someone decompiles my code, they will find out the url. Even if I set up a constant password in Java to send to php script, they can see that although it's better than nothing. The sum check would also be found in the decompiled code. ProGuard will help me make it slightly harder, but I think it's still not enough. It might be enough for this game, but I want to learn how to raise security level (again, I understand it's impossible to make it impossible).

I have searched around to get inputs, but not successful, yet. A replay of game events is not an option for me. Aside from complexity, I think it will consume execution time.

I rather imagine sqlite would be more than adequate to record high scores, no need to have another moving part with a separate mysql db.

Anyone determined to send fake score data can do so, and there's really nothing you can do about it other than move all your game logic server-side. Even then someone could automate the game with a bot, though that's a harder problem, most people won't bother with it, and you should take it as a good sign of popularity if they do.

Anyone determined to send fake score data can do so, and there's really nothing you can do about it other than move all your game logic server-side. Even then someone could automate the game with a bot, though that's a harder problem, most people won't bother with it, and you should take it as a good sign of popularity if they do.

That's true. Well, I will be monitoring the table anyways. I will manually delete fake record if I see any suspicious.

The only possible issue I found would be the concurrency. It says that the database locks reading/writing when one is in process. Though it says the lock would last for a few dozen milliseconds at most usually. I guess I shouldn't consider this as an issue for this case since there won't be that many people.

All I need is fetch, insert, and delete of a record. So I think I should consider SQLite as my solution, now.

But I do want to add some kind of protection in the code at least protecting from modifying the score board by just passing scores through url.

You can put and probably should put in some basic scrambling just to protect against casual score spoofing, but anyone determined to find the key will still find it very quickly. It's literally impossible to solve unless you control everything down to the hardware of the client.

It's literally impossible to solve unless you control everything down to the hardware of the client.

Or, somehow you submit a replay of the high scoring game to the server, and validate it somehow (ghost racers in a racing game are a good example).

However that involves running a headless version of your game on the server. And having a deterministic game so you can play it back and get the same result on the server. And people can still cheat if they can make a 'perfect' game recording.

Basically it's a lot of work for very little gain. I'd just put some basic protection like a checksum and leave it at that.

One easy extra step can be to make only certain scores possible legitimately. Many arcade games do this where the smallest amount of points you can get is (say) 100, but you get 1 point when you use a continue. That means you can look at the high score table and see that a score of 235005 used five continues to get that. If you only allowed (say) scores that are a multiple of 3 then most casual hackers won't notice and will probably submit an invalid score.

People who cheat usually aren't subtle - they'll give themselves a score of 99999999999999 and forget about it after a week. So maybe think about a moderation tool where you can block IPs or user names, or at the very least easily remove obvious cheated scores.

That's right. I should know the score limit one can get, so I can set that if statement in my script.

I have some questions for the script.

I was going to do queries to check whether the score is to be saved or not. For example, I need to find and delete the lowest score to add a new higher score if the score board is full. (assuming I'm only keeping the top 15) I could do sort query to keep the scores sorted at the DB level every time I insert a new score. Else, I could do the sorting/determining score insertion after fetching into array. The latter would do more on php code to keep the SQL statements to minimum. Since reading/writing at the same will lock the table, I think doing less queries is important even though we might be talking about milliseconds.

Just log the high score reports into your database, and do all the sorting and filtering and de-duplication logic with a query. Your inserts will be faster, and if you screw up somewhere, you can just fix the query and none of your data will be lost or corrupted.

So a replay on server side solution can be cheated if someone copy/paste the decompiled source code and make the game easier(obfuscated code gets tough though possible to cheat). It would also break through checksum. (if I'm not misunderstood)

Isn't SQLite too vulnerable because it doesn't have password? If someone finds out the url to the database file, he can access it from anywhere. I understand that the point we have been discussing is that hackers will find their way if they want to.

How can checksum be implemented in this case? Can you give a brief explanation or direct me to a link?

Scrambling would be for example, when sending the player name/score from java, the order of string is shifted by pattern and when receiving from script, shift them back?

Isn't SQLite too vulnerable because it doesn't have password? If someone finds out the url to the database file, he can access it from anywhere. I understand that the point we have been discussing is that hackers will find their way if they want to.

The database must not be accessible from the web. Your code accesses it, nothing else.

Hi, appreciate more people! Σ ♥ = ¾Learn how to award medals... and work your way up the social rankings!

How can checksum be implemented in this case? Can you give a brief explanation or direct me to a link?

Scrambling would be for example, when sending the player name/score from java, the order of string is shifted by pattern and when receiving from script, shift them back?

You post the player name, score, and checksum(player,score,secret), where secret is some bit of data you bury in your code, however cleverly you want. The server also knows this secret, so it runs the same checksum function, and if they don't match, then something is wrong.

Something like this would suffice. The secret here is really weak, but any string you compute will work as long as it's constant or otherwise fully deterministic on name and score.

This is all security through obscurity, but every fancy version of this is just a variation on the same thing, just with trickier and trickier ways to establish a shared secret, up to and including running nearly arbitrary bytecode (which is how the java-based BD+ copy protection scheme works)

If your server program is Java, I would recommend h2 or hsqldb. Last I looked, your server program was PHP, which comes with sqlite support in most builds. Your java program does not access the database directly, it talks to a server program that itself accesses the database.

I'm calling the php file from Java app on client side. The php script connects to SQLite. I was worried that if someone finds that path to the database file, they can write their own script to connect it. (though I don't know how they can find out the folder hierarchy)

I'm calling the php file from Java app on client side. The php script connects to SQLite. I was worried that if someone finds that path to the database file, they can write their own script to connect it. (though I don't know how they can find out the folder hierarchy)

As expected no ra4king here. He has leader board for his snake applet game. You may ask him.

I have over 50 unread posts, I haven't been catching up with JGO posts these days.

Anyway, for my Snake and JDoodle Jump, I use text files, not databases. However, it may be fun and all to try out text files but it's best to go the database way.

More info on my highscore system:I use a 2 text file system, where one contains the top daily/weekly/monthly/all-time top scores, and the other (ALL file) holds every single submitted score.When a player submits a score, my server adds the score to the ALL file, then it checks if it alters the top scores, the score is inserted in order into the top scores list and then the file is re-written.

I have got the basic operations working with SQLite. Though I'm not done, yet. I placed the db file outside web root.

I thought about just storing the top 20 records to keep the operation time as fast as possible. Every time a record is added when there are 20 records, it would update the lowest score possessing the oldest date. The newer and higher score would be on top. Problem is eventually the score board gets full with same high scores. I never thought of daily/weekly/monthly thing. I think it would be a good idea to implement on mine, too.

Again, don't bother with UPDATE. Just insert new scores into the DB and use a query to pick the top ones. Just add an index on the score and it'll be as fast as anything you can imagine.

It used to be that a skillful player could own the entire high score board, but the modern idiom (for games that still actually keep score at all) is to only allow one entry per player. So what you want is a query like this:

There is one thing I'm struggling with. If I insert a new high score with new name, it gets on the top.

My issue is that the player with same name scoring the same score as the highest after second time does not put his position up. For example...

I insert a highest score with name "A" which gets on top.Then I insert a higher score with name "B" which appear on top.If I insert a score same as "B" with name "A", it does not go on top.However, if I insert a same score with name "C", it gets on top.

Yah sorry that ordering should have been DESC unless you wanted a low-score list

You probably should order by highscore, not score, but that shouldn't actually change the results. I'm otherwise not seeing anything obviously wrong with the query. Could you maybe put up a sql dump of your current score database on a pastebin? Should be able to do it with sqlite3 /path/to/scores.db '.dump Records'

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org