Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
making high score code work locally when not online.
- Loading branch information
Showing
15 changed files
with
980 additions
and
43 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?php | ||
/** Read in a CSV file and save the rows. */ | ||
// read CSV data from POST. | ||
$scores = @$_POST['scores']; | ||
|
||
/* Replace this w/ real information. */ | ||
$dsn = 'mysql:dbname=[dbname];host=[dbhost]'; | ||
$user = '[dbuser]'; | ||
$pass = '[dbpass]'; | ||
|
||
if (!isset($scores)) { | ||
echo "failure"; | ||
exit; | ||
} | ||
|
||
try { | ||
$dbh = new PDO($dsn, $user, $pass); | ||
} catch (PDOException $e) { | ||
echo "failure"; | ||
exit; | ||
} | ||
|
||
// TODO start transaction | ||
$q = 'INSERT INTO `scores` (clear, name, score) VALUES (?, ?, ?)'; | ||
$stmt = $dbh->prepare($q); | ||
|
||
// Get a file pointer to the score data. | ||
$fp = fopen('php://memory', 'r+'); | ||
fputs($fp, $scores); | ||
rewind($fp); | ||
|
||
try { | ||
$dbh->beginTransaction(); | ||
while (($score = fgetcsv($fp, 1000, ',')) !== FALSE) { | ||
$stmt->bindParam(1, $score[2], PDO::PARAM_INT); | ||
$stmt->bindParam(2, $score[0], PDO::PARAM_STR); | ||
$stmt->bindParam(3, $score[1], PDO::PARAM_INT); | ||
if (!$stmt->execute()) { | ||
// TODO rollback transaction | ||
echo "failure"; | ||
exit; | ||
} | ||
} | ||
$dbh->commit(); | ||
} catch (Exception $e) { | ||
$dbh->rollBack(); | ||
echo "failure"; // failed somewhere along the way | ||
exit; | ||
} | ||
|
||
echo "success"; | ||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package com.shade.score; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.InputStream; | ||
import java.io.InputStreamReader; | ||
import java.io.OutputStreamWriter; | ||
import java.net.URL; | ||
import java.net.URLConnection; | ||
import java.net.URLEncoder; | ||
import java.util.Scanner; | ||
|
||
import org.newdawn.slick.util.ResourceLoader; | ||
|
||
/** | ||
* Post all of the scores in a csv file to a server. | ||
* | ||
* @author Alexander Schearer <aschearer@gmail.com> | ||
*/ | ||
public class BatchWriter { | ||
|
||
private static final String NEWLINE = "\n"; | ||
private static final String SERVER = "http://anotherearlymorning.com/games/shade/batch.php"; | ||
|
||
private String path; | ||
|
||
public BatchWriter(String path) { | ||
this.path = path; | ||
} | ||
|
||
public boolean write() { | ||
try { | ||
String scores = collectScores(); | ||
String content = "scores=" + URLEncoder.encode(scores, "US-ASCII"); | ||
URL url = new URL(SERVER); | ||
URLConnection c = url.openConnection(); | ||
c.setConnectTimeout(2000); | ||
c.setDoOutput(true); | ||
OutputStreamWriter o = new OutputStreamWriter(c.getOutputStream()); | ||
// write the content | ||
o.write(content); | ||
o.flush(); | ||
o.close(); | ||
// read response and check for success | ||
BufferedReader i = new BufferedReader(new InputStreamReader(c | ||
.getInputStream())); | ||
String response = i.readLine(); | ||
return response.equals("success"); | ||
|
||
} catch (Exception e) { | ||
return false; | ||
} | ||
} | ||
|
||
private String collectScores() { | ||
StringBuilder builder = new StringBuilder(); | ||
Scanner reader = getScanner(); | ||
while (reader.hasNextLine()) { | ||
builder.append(reader.nextLine()); | ||
builder.append(NEWLINE); | ||
} | ||
return builder.toString(); | ||
} | ||
|
||
private Scanner getScanner() { | ||
InputStream stream = ResourceLoader.getResourceAsStream(path); | ||
return new Scanner(stream); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.shade.score; | ||
|
||
/** | ||
* Reader which will fall back to the local high score list if it cannot connect | ||
* to the server. | ||
* | ||
* @author Alexander Schearer <aschearer@gmail.com> | ||
*/ | ||
public class FailSafeHighScoreReader implements HighScoreReader { | ||
|
||
private static final String FILE = "states/highscore/scores.csv"; | ||
private static final String SERVER = "http://anotherearlymorning.com/games/shade/board.php"; | ||
|
||
private LocalHighScoreReader localReader; | ||
private RemoteHighScoreReader remoteReader; | ||
|
||
public FailSafeHighScoreReader() { | ||
localReader = new LocalHighScoreReader(FILE); | ||
remoteReader = new RemoteHighScoreReader(SERVER); | ||
} | ||
|
||
public String[][] getScores(int limit) { | ||
String[][] scores = remoteReader.getScores(limit); | ||
if (scores == null) { | ||
scores = localReader.getScores(limit); | ||
} | ||
return scores; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package com.shade.score; | ||
|
||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.net.URL; | ||
|
||
import org.newdawn.slick.util.ResourceLoader; | ||
|
||
/** | ||
* Write high scores to a remote server or locally if you cannot connect to the | ||
* server. | ||
* | ||
* Try to write current score to server | ||
* If failed then write locally, exit | ||
* If successful try to write each local score to server, continue | ||
* If failed then quit, exit | ||
* If successful then remove from local file, continue | ||
* | ||
* @author Alexander Schearer <aschearer@gmail.com> | ||
*/ | ||
public class FailSafeHighScoreWriter implements HighScoreWriter { | ||
|
||
private static final String FILE = "states/highscore/scores.csv"; | ||
private static final String SERVER = "http://anotherearlymorning.com/games/shade/post.php"; | ||
|
||
private LocalHighScoreWriter localWriter; | ||
private RemoteHighScoreWriter remoteWriter; | ||
private BatchWriter batchWriter; | ||
|
||
public FailSafeHighScoreWriter() { | ||
localWriter = new LocalHighScoreWriter(FILE); | ||
remoteWriter = new RemoteHighScoreWriter(SERVER); | ||
batchWriter = new BatchWriter(FILE); | ||
} | ||
|
||
public boolean write(String name, int score, boolean clear) { | ||
// try to write remotely | ||
if (remoteWriter.write(name, score, clear)) { | ||
// try to write past local scores to server | ||
if (batchWriter.write()) { | ||
// clear the file | ||
clearFile(FILE); | ||
} | ||
// else do nothing, they will get written later | ||
} else { | ||
// can't connect to server, write locally | ||
return localWriter.write(name, score, clear); | ||
} | ||
// wrote current score successfully | ||
return true; | ||
} | ||
|
||
private void clearFile(String f) { | ||
try { | ||
URL u = ResourceLoader.getResource(f); | ||
FileWriter w = new FileWriter(u.getPath()); | ||
w.flush(); | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,6 @@ | ||
package com.shade.score; | ||
|
||
import org.newdawn.slick.SlickException; | ||
|
||
public interface HighScoreWriter { | ||
|
||
public boolean write(String name, int score, boolean clear) throws SlickException; | ||
public boolean write(String name, int score, boolean clear); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package com.shade.score; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.InputStreamReader; | ||
import java.util.Collections; | ||
import java.util.Comparator; | ||
import java.util.LinkedList; | ||
|
||
import org.newdawn.slick.util.ResourceLoader; | ||
|
||
import com.shade.util.CsvReader; | ||
|
||
/** | ||
* Read high scores from a csv file located in the jar. | ||
* | ||
* This is useful if the remote server cannot be reached. | ||
* | ||
* @author Alexander Schearer <aschearer@gmail.com> | ||
*/ | ||
public class LocalHighScoreReader implements HighScoreReader { | ||
|
||
private static final int NAME = 0; | ||
private static final int SCORE = 1; | ||
private static final int CLEAR = 2; | ||
|
||
private CsvReader reader; | ||
|
||
public LocalHighScoreReader(String path) { | ||
InputStream stream = ResourceLoader.getResourceAsStream(path); | ||
InputStreamReader input = new InputStreamReader(stream); | ||
reader = new CsvReader(input); | ||
} | ||
|
||
/** | ||
* Returns all the scores if zero is passed. | ||
*/ | ||
public String[][] getScores(int limit) { | ||
LinkedList<String[]> rows = new LinkedList<String[]>(); | ||
try { | ||
while (reader.readRecord()) { | ||
String[] row = new String[3]; | ||
row[NAME] = reader.get(NAME); | ||
row[SCORE] = reader.get(SCORE); | ||
row[CLEAR] = reader.get(CLEAR); | ||
rows.add(row); | ||
} | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
} | ||
|
||
Collections.sort(rows, new Comparator<String[]>() { | ||
|
||
public int compare(String[] s1, String[] s2) { | ||
return s1[SCORE].compareTo(s2[SCORE]); | ||
} | ||
|
||
}); | ||
|
||
return firstN(rows, limit); | ||
} | ||
|
||
private String[][] firstN(LinkedList<String[]> rows, int limit) { | ||
limit = (limit == 0) ? rows.size() : limit; | ||
int size = (rows.size() > limit) ? limit : rows.size(); | ||
String[][] n = new String[size][3]; | ||
|
||
for (int i = 0; i < size; i++) { | ||
n[i][NAME] = rows.get(i)[NAME]; | ||
n[i][SCORE] = rows.get(i)[SCORE]; | ||
n[i][CLEAR] = rows.get(i)[CLEAR]; | ||
} | ||
return n; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package com.shade.score; | ||
|
||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.net.URL; | ||
|
||
import org.newdawn.slick.util.ResourceLoader; | ||
|
||
import com.shade.util.CsvWriter; | ||
|
||
public class LocalHighScoreWriter implements HighScoreWriter { | ||
|
||
private static final int NAME = 0; | ||
private static final int SCORE = 1; | ||
private static final int CLEAR = 2; | ||
|
||
private static final char COMMA = ','; | ||
private CsvWriter writer; | ||
|
||
public LocalHighScoreWriter(String path) { | ||
try { | ||
URL url = ResourceLoader.getResource(path); | ||
FileWriter stream = new FileWriter(url.getPath(), true); | ||
writer = new CsvWriter(stream, COMMA); | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
|
||
public boolean write(String name, int score, boolean clear) { | ||
String[] row = new String[3]; | ||
row[NAME] = name; | ||
row[SCORE] = score + ""; | ||
row[CLEAR] = (clear) ? "1" : "0"; | ||
return write(row[NAME], row[SCORE], row[CLEAR]); | ||
} | ||
|
||
protected boolean write(String name, String score, String clear) { | ||
String[] row = new String[] { name, score, clear }; | ||
try { | ||
writer.writeRecord(row); | ||
writer.flush(); | ||
} catch (IOException e) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
} |
Oops, something went wrong.