Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (497)
Games in Android Showcase (114)
games submitted by our members
Games in WIP (563)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  Ideas for Online High Score System  (Read 9190 times)
0 Members and 1 Guest are viewing this topic.
Offline miga

Junior Member


Medals: 2
Projects: 1



« Posted 2012-03-14 07:47:27 »

Hello,

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?

Which way is preferred? Any thoughts are appreciated.

Miga's Hobby Programming - http://www.migapro.com
Offline DavidW

Junior Member


Medals: 3
Exp: 7 years



« Reply #1 - Posted 2012-03-14 09:32:36 »

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.

You should probably not take my advice here.  Tongue

Hello!
Offline Damocles
« Reply #2 - Posted 2012-03-14 11:35:26 »

Keep it simple.

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 by
manually 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.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #3 - Posted 2012-03-14 22:22:42 »

I'd go for a web language of your choice (I'd favour python or perl, but php would be fine) and a database backend. Then submit and fetch high scores over simple http requests.

A simple database is easy to set up, and it saves you having to deal with concurrent updates/modifications (which is a bit of a pain if you're just using a file on your server).

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline miga

Junior Member


Medals: 2
Projects: 1



« Reply #4 - Posted 2012-03-16 01:22:28 »

Thanks guys.

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.

Any suggestions to increase security level?

Miga's Hobby Programming - http://www.migapro.com
Offline sproingie

JGO Kernel


Medals: 202



« Reply #5 - Posted 2012-03-16 01:31:54 »

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.

Offline miga

Junior Member


Medals: 2
Projects: 1



« Reply #6 - Posted 2012-03-16 02:16:39 »

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.


I have never used SQLite, so I just read about it.  http://www.sqlite.org/whentouse.html

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.

Miga's Hobby Programming - http://www.migapro.com
Offline sproingie

JGO Kernel


Medals: 202



« Reply #7 - Posted 2012-03-16 03:55:44 »

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. 
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #8 - Posted 2012-03-16 12:15:26 »

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.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline ReBirth
« Reply #9 - Posted 2012-03-16 12:34:35 »

If it's android game, you can use Scoreloop or Swarm.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline miga

Junior Member


Medals: 2
Projects: 1



« Reply #10 - Posted 2012-03-16 18:48:13 »

It's for a desktop game.

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.

Which of these 2 ways is more efficient for SQLite?

Miga's Hobby Programming - http://www.migapro.com
Offline sproingie

JGO Kernel


Medals: 202



« Reply #11 - Posted 2012-03-16 19:41:04 »

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.

Offline miga

Junior Member


Medals: 2
Projects: 1



« Reply #12 - Posted 2012-03-17 08:27:58 »

I see.

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?

Miga's Hobby Programming - http://www.migapro.com
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 799
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #13 - Posted 2012-03-17 17:21:31 »

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
Offline sproingie

JGO Kernel


Medals: 202



« Reply #14 - Posted 2012-03-17 18:15:07 »

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.
1  
2  
3  
String makeChecksum(String name, int score) {
  return org.apache.commons.codec.digest.DigestUtils.md5Hex(name + score.toString() + "mysuperseekritword");
}


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)

Offline miga

Junior Member


Medals: 2
Projects: 1



« Reply #15 - Posted 2012-03-17 19:26:43 »

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

What about if they write their own code to access it? File location is all it needs to open connection, right?

sproingie,

Thanks a lot for your consistent replies and advises. I integrated the apache commons codec library into my java project.


Miga's Hobby Programming - http://www.migapro.com
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 799
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #16 - Posted 2012-03-17 19:30:41 »

The database must not be accessible from the web. Your code accesses it, nothing else.
What about if they write their own code to access it? File location is all it needs to open connection, right?
If the database is not in the web-root, nobody can access it from the web.

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

Junior Member


Medals: 2
Projects: 1



« Reply #17 - Posted 2012-03-17 19:34:13 »

Right, but how would I connect through my Java program in that case?

Miga's Hobby Programming - http://www.migapro.com
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 799
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #18 - Posted 2012-03-17 20:23:02 »

Running the java app on the server, connecting to the file, outside the web-root persecutioncomplex

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

JGO Kernel


Medals: 202



« Reply #19 - Posted 2012-03-17 20:58:41 »

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.
Offline miga

Junior Member


Medals: 2
Projects: 1



« Reply #20 - Posted 2012-03-17 21:43:01 »

Sorry, I think I got myself confused when I wrote my last replies.

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)

Miga's Hobby Programming - http://www.migapro.com
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 799
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #21 - Posted 2012-03-17 21:44:05 »

Sorry, I think I got myself confused when I wrote my last replies.

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)

The database must not be accessible from the web. Your code accesses it, nothing else.
What about if they write their own code to access it? File location is all it needs to open connection, right?
If the database is not in the web-root, nobody can access it from the web.

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

JGO Kernel


Medals: 202



« Reply #22 - Posted 2012-03-17 22:30:06 »

Don't put your database in a folder that's accessable from the web.  It's that simple.  Even if you do, the worst anyone should be able to do is download it.

Offline ReBirth
« Reply #23 - Posted 2012-03-18 03:11:05 »

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

Offline ra4king

JGO Kernel


Medals: 345
Projects: 3
Exp: 5 years


I'm the King!


« Reply #24 - Posted 2012-03-21 18:37:12 »

As expected no ra4king here. He has leader board for his snake applet game. You may ask him.
Grin 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.

Offline miga

Junior Member


Medals: 2
Projects: 1



« Reply #25 - Posted 2012-03-21 22:13:17 »

Thanks for the comments.

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.

Miga's Hobby Programming - http://www.migapro.com
Offline sproingie

JGO Kernel


Medals: 202



« Reply #26 - Posted 2012-03-22 00:16:50 »

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:

1  
select name, max(score) as highscore from scores group by name order by highscore limit 20

Offline miga

Junior Member


Medals: 2
Projects: 1



« Reply #27 - Posted 2012-03-22 00:33:58 »

Yea, same names get messy. Excluding same names from display sounds good.

I will implement these things I learned from here.

I appreciate you guy's comments. Thanks a lot.

Miga's Hobby Programming - http://www.migapro.com
Offline miga

Junior Member


Medals: 2
Projects: 1



« Reply #28 - Posted 2012-03-23 04:11:54 »

I'm almost done with this system.

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.

My table is structured as following: "CREATE TABLE Records (name TEXT, score INTEGER, date DATE)"

The date contains with the format, "Y-m-d H:i:s".

This is the query I'm doing to get them.
$query = "SELECT name, MAX(score) as highscore FROM Records GROUP BY name ORDER BY score DESC, date DESC LIMIT 0, 10";

Can someone suggest what I'm doing wrong?

Miga's Hobby Programming - http://www.migapro.com
Offline sproingie

JGO Kernel


Medals: 202



« Reply #29 - Posted 2012-03-23 16:58:20 »

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

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'


Pages: [1] 2
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

UprightPath (20 views)
2014-09-20 20:14:06

BurntPizza (26 views)
2014-09-19 03:14:18

Dwinin (40 views)
2014-09-12 09:08:26

Norakomi (70 views)
2014-09-10 13:57:51

TehJavaDev (95 views)
2014-09-10 06:39:09

Tekkerue (49 views)
2014-09-09 02:24:56

mitcheeb (70 views)
2014-09-08 06:06:29

BurntPizza (52 views)
2014-09-07 01:13:42

Longarmx (39 views)
2014-09-07 01:12:14

Longarmx (45 views)
2014-09-07 01:11:22
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!