diff options
Diffstat (limited to 'core/src/ch/asynk/rustanddust/util')
-rw-r--r-- | core/src/ch/asynk/rustanddust/util/DB.java | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/core/src/ch/asynk/rustanddust/util/DB.java b/core/src/ch/asynk/rustanddust/util/DB.java new file mode 100644 index 0000000..50a20a2 --- /dev/null +++ b/core/src/ch/asynk/rustanddust/util/DB.java @@ -0,0 +1,200 @@ +package ch.asynk.rustanddust.util; + +import java.security.MessageDigest; +import java.math.BigInteger; + +import com.badlogic.gdx.sql.Database; +import com.badlogic.gdx.sql.DatabaseCursor; +import com.badlogic.gdx.sql.DatabaseFactory; +import com.badlogic.gdx.sql.SQLiteGdxException; + +import ch.asynk.rustanddust.RustAndDust; + +public class DB +{ + private static final int DB_SCHEMA_VERSION = 1; + + public static final int NO_RECORDS = -1; + private static final String DIGEST = "SHA-256"; + + private Database db; + private MessageDigest md; + + private static final String TBL_CFG_CRT = "create table if not exists" + + " config ( key text primary key, value text not null);" + + " insert or ignore into config values(\"version\", " + DB_SCHEMA_VERSION + ");"; + + private static final String TBL_PLAYERS_CRT = "create table if not exists" + + " players ( _id integer primary key autoincrement," + + " hash text unique not null, gmail text unique not null, firstname text, lastname text" + + ");"; + + private static final String TBL_BATTLES_CRT = "create table if not exists" + + " battles ( _id integer primary key, name text" + + ");"; + + private static final String TBL_GAMES_CRT = "create table if not exists" + + " games ( _id integer primary key autoincrement," + + " _p1 integer not null, _p2 integer not null, _b integer not null," + + " m integer not null, ts datetime default current_timestamp," + + " foreign key (_p1) references players(_id)," + + " foreign key (_p2) references players(_id)," + + " foreign key (_b) references battles(_id)," + + " unique (_p1, _p2, _b)" + + ");"; + + private static final String TBL_TURNS_CRT = "create table if not exists" + + " turns ( _id integer primary key autoincrement, _g integer not null," + + " _p integer not null, hash text not null, payload text not null," + + " foreign key (_g) references games(_id)," + + " foreign key (_p) references players(_id)" + + ");"; + + private static final String TBL_STATES_CRT = "create table if not exists" + + " states ( _g integer unique not null," + + " hash text not null, payload text not null," + + " foreign key (_g) references games(_id)" + + ");"; + + private static final String INSERT_PLAYER = "insert or ignore into players(hash,gmail,firstname,lastname) values ('%s','%s','%s','%s');"; + private static final String GET_PLAYER_ID = "select _id from players where hash='%s';"; + private static final String UPDATE_BATTLE = "insert or replace into battles values (%d,'%s');"; + private static final String INSERT_GAME = "insert or ignore into games(_p1,_p2,_b,m) values (%d,%d,%d,%d);"; + private static final String GET_GAME_ID = "select _id from games where _p1=%d and _p2=%d and _b=%d;"; + private static final String INSERT_TURN = "insert into turns(_g,_p,hash,payload) values (%d,%d,'%s','%s'); update games set ts=current_timestamp where _id=%d;"; + private static final String INSERT_STATE = "insert or replace into states(_g,hash,payload) values (%d,'%s','%s'); update games set ts=current_timestamp where _id=%d;"; + private static final String GET_STATE = "select payload from states where _g=%d;"; + + private static final String DB_CRT = TBL_CFG_CRT + TBL_PLAYERS_CRT + TBL_BATTLES_CRT + TBL_GAMES_CRT + TBL_TURNS_CRT + TBL_STATES_CRT; + + public DB(String dbPath) + { + db = DatabaseFactory.getNewDatabase(dbPath, DB_SCHEMA_VERSION, DB_CRT, null); + db.setupDatabase(); + } + + public void setup() + { + try { + md = MessageDigest.getInstance(DIGEST); + } catch (java.security.NoSuchAlgorithmException e) { RustAndDust.error("NoSuchAlgorithm"); } + try { + db.openOrCreateDatabase(); + } catch (SQLiteGdxException e) { RustAndDust.error("openOrCreateDatabase"); } + } + + private String getDigest(String str) + { + String hash = null; + try { + hash = new BigInteger(1, md.digest(str.getBytes("UTF-8"))).toString(16); + } catch (java.io.UnsupportedEncodingException e) { RustAndDust.error("getDigest"); } + + return hash; + } + + public String storePlayer(String gmail, String firstname, String lastname) + { + String hash = getDigest(gmail + firstname + lastname); + if (hash == null) return null; + try { + db.execSQL(String.format(INSERT_PLAYER, hash, gmail, firstname, lastname)); + } catch (SQLiteGdxException e) { + RustAndDust.error("storePlayer"); + return null; + } + return hash; + } + + public int getPlayerId(String hash) + { + int ret = NO_RECORDS; + try { + DatabaseCursor cursor = db.rawQuery(String.format(GET_PLAYER_ID, hash)); + if (cursor.getCount() > 0) { + cursor.next(); + ret = cursor.getInt(0); + } + } catch (SQLiteGdxException e) { RustAndDust.error("getPlayerId"); } + return ret; + } + + public int storePlayerGetId(String gmail, String firstname, String lastname) + { + String hash = storePlayer(gmail, firstname, lastname); + if (hash == null) return NO_RECORDS; + return getPlayerId(hash); + } + + public void storeBattle(int id, String name) + { + try { + db.execSQL(String.format(UPDATE_BATTLE, id, name)); + } catch (SQLiteGdxException e) { RustAndDust.error("storeBattle"); } + } + + public void storeGame(int you, int opponent, int battle, int mode) + { + try { + db.execSQL(String.format(INSERT_GAME, you, opponent, battle, mode)); + } catch (SQLiteGdxException e) { RustAndDust.error("storeGame"); } + } + + public int getGameId(int you, int opponent, int battle, int mode) + { + int ret = NO_RECORDS; + try { + DatabaseCursor cursor = db.rawQuery(String.format(GET_GAME_ID, you, opponent, battle, mode)); + if (cursor.getCount() > 0) { + cursor.next(); + ret = cursor.getInt(0); + } + } catch (SQLiteGdxException e) { RustAndDust.error("getGameId"); } + return ret; + } + + public int storeGameGetId(int you, int opponent, int battle, int mode) + { + storeGame(you, opponent, battle, mode); + return getGameId(you, opponent, battle, mode); + } + + public boolean storeTurn(int game, int player, String payload) + { + try { + String hash = getDigest(payload); + if (hash == null) return false; + db.execSQL(String.format(INSERT_TURN, game, player, hash, payload, game)); + } catch (SQLiteGdxException e) { + RustAndDust.error("storeTurn"); + return false; + } + return true; + } + + public boolean storeState(int game, String payload) + { + try { + String hash = getDigest(payload); + if (hash == null) return false; + db.execSQL(String.format(INSERT_STATE, game, hash, payload, game)); + } catch (SQLiteGdxException e) { + RustAndDust.error("storeState"); + return false; + } + return true; + } + + public String loadState(int game) + { + String ret = null; + try { + DatabaseCursor cursor = db.rawQuery(String.format(GET_STATE, game)); + if (cursor.getCount() > 0) { + cursor.next(); + ret = cursor.getString(0); + } + } catch (SQLiteGdxException e) { RustAndDust.error("loadState"); } + return ret; + } +} |