Last active
February 28, 2024 10:00
-
-
Save mg/eee5e1ba24112577f104fd9556fa7295 to your computer and use it in GitHub Desktop.
Log gameplay to BGG example
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
import 'dart:convert'; | |
import 'package:http/http.dart' as http; | |
const BGGLOGIN_URL = 'https://boardgamegeek.com/login/api/v1'; | |
const BGGUPLOAD_URL = 'https://boardgamegeek.com/geekplay.php'; | |
enum UploadResult { | |
Success, | |
UsernamePassword, | |
NetworkError, | |
ServerError, | |
} | |
Future<UploadResult> uploadToBgg( | |
String username, | |
String password, | |
Game game, | |
List<PlayerWorth> result, | |
String location, | |
) async { | |
try { | |
// login into BGG | |
final loginResponse = await http.post( | |
BGGLOGIN_URL, | |
headers: {'Content-Type': 'application/json'}, | |
body: jsonEncode( | |
{ | |
'credentials': { | |
'username': username, | |
'password': password, | |
}, | |
}, | |
), | |
); | |
if (loginResponse.statusCode == 400) return UploadResult.UsernamePassword; | |
// setup session cookie | |
// "bggusername=USERNAME; bggpassword=PASSWORDHASH; SessionID=SESSIONID;" | |
String sessionCookie = ''; | |
for (final cookie in loginResponse.headers['set-cookie'].split(';')) { | |
if (cookie.startsWith('bggusername')) { | |
sessionCookie += (cookie.length > 0 ? ' ' : '') + cookie + ';'; | |
continue; | |
} | |
var idx = cookie.indexOf('bggpassword='); | |
if (idx != -1) { | |
sessionCookie += (cookie.length > 0 ? ' ' : '') + | |
'bggpassword=' + | |
cookie.substring(idx + 12) + | |
';'; | |
continue; | |
} | |
idx = cookie.indexOf('SessionID='); | |
if (idx != -1) { | |
sessionCookie += (cookie.length > 0 ? ' ' : '') + | |
'SessionID=' + | |
cookie.substring(idx + 10) + | |
';'; | |
continue; | |
} | |
} | |
// setup body | |
final gameResultBody = {..._kGameResultBodyTemplate}; | |
gameResultBody['objectid'] = game.bggId; | |
final now = new DateTime.now(); | |
gameResultBody['playdate'] = | |
'${now.year}-${now.month.toString().padLeft(2, '0')}-${now.day.toString().padLeft(2, '0')}'; | |
gameResultBody['date'] = now.toIso8601String(); | |
gameResultBody['location'] = location; | |
final gameResult = [...result]; | |
gameResult.sort((a, b) => b.worth - a.worth); | |
// setup results | |
final playersResult = []; | |
var winningScore; | |
for (var i = 0; i < gameResult.length; i++) { | |
final playerResult = gameResult[i]; | |
if (winningScore == null) { | |
winningScore = playerResult.worth; | |
} | |
playersResult.add({ | |
'name': playerResult.player.name, | |
'username': playerResult.player.bggUsername, | |
'score': playerResult.worth, | |
'win': playerResult.worth == winningScore ? true : null, | |
}); | |
} | |
gameResultBody['players'] = playersResult; | |
final uploadResponse = await http.post( | |
BGGUPLOAD_URL, | |
headers: { | |
'cookie': sessionCookie, | |
'Content-Type': 'application/json;charset=UTF-8', | |
}, | |
body: jsonEncode(gameResultBody), | |
); | |
if (uploadResponse.statusCode >= 500) return UploadResult.ServerError; | |
if (uploadResponse.statusCode >= 400) return UploadResult.NetworkError; | |
return UploadResult.Success; | |
} catch (e) { | |
return UploadResult.ServerError; | |
} | |
} | |
const _kGameResultBodyTemplate = { | |
'ajax': 1, | |
'objecttype': 'thing', | |
'action': 'save', | |
'quantity': 1, | |
'length': 0, | |
}; |
This helped me out on my personal project. Thanks for this.
Great, glad to hear it.
Thank you so much! Helped a lot in understanding cookies for a personal application
nice!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This helped me out on my personal project. Thanks for this.