Skip to content

Instantly share code, notes, and snippets.

@mg
Last active February 28, 2024 10:00
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mg/eee5e1ba24112577f104fd9556fa7295 to your computer and use it in GitHub Desktop.
Save mg/eee5e1ba24112577f104fd9556fa7295 to your computer and use it in GitHub Desktop.
Log gameplay to BGG example
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,
};
@jameskolts
Copy link

This helped me out on my personal project. Thanks for this.

@mg
Copy link
Author

mg commented Aug 21, 2023

This helped me out on my personal project. Thanks for this.

Great, glad to hear it.

@Dradass
Copy link

Dradass commented Feb 28, 2024

Thank you so much! Helped a lot in understanding cookies for a personal application

@mg
Copy link
Author

mg commented Feb 28, 2024

nice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment