I spent a lot of time today making this load bug report work better for Santorini. In the future I hope something like this gets added to BGA framework so it's automatically available in all projects. The "load bug report" button should move out of control panel into the game page, and it should be an easy one-click operation like I've done here
But in the meantime, other developers can do something similar to the below. I made it so you can type
loadBug(12345) in the chat and it will do all the necessary steps of loading the bug report into your current table. You can review all the game code at
https://github.com/AntonioSoler/bga-santorini but here's what I added specifically about load bug report:
---
Add loadBug() and loadBugSQL() to game.php:
Code: Select all
/*
* loadBug: in studio, type loadBug(20762) into the table chat to load a bug report from production
* client side JavaScript will fetch each URL below in sequence, then refresh the page
*/
public function loadBug($reportId)
{
$db = explode('_', self::getUniqueValueFromDB("SELECT SUBSTRING_INDEX(DATABASE(), '_', -2)"));
$game = $db[0];
$tableId = $db[1];
self::notifyAllPlayers('loadBug', "Trying to load <a href='https://boardgamearena.com/bug?id=$reportId' target='_blank'>bug report $reportId</a>", [
'urls' => [
// Emulates "load bug report" in control panel
"https://studio.boardgamearena.com/admin/studio/getSavedGameStateFromProduction.html?game=$game&report_id=$reportId&table_id=$tableId",
// Emulates "load 1" at this table
"https://studio.boardgamearena.com/table/table/loadSaveState.html?table=$tableId&state=1",
// Calls the function below to update SQL
"https://studio.boardgamearena.com/1/$game/$game/loadBugSQL.html?table=$tableId&report_id=$reportId",
// Emulates "clear PHP cache" in control panel
// Needed at the end because BGA is caching player info
"https://studio.boardgamearena.com/admin/studio/clearGameserverPhpCache.html?game=$game",
]
]);
}
/*
* loadBugSQL: in studio, this is one of the URLs triggered by loadBug() above
*/
public function loadBugSQL($reportId)
{
$studioPlayer = self::getCurrentPlayerId();
$players = $this->playerManager->getPlayers();
// Change for your game
// We are setting the current state to match the start of a player's turn if it's already game over
$sql = [
"UPDATE global SET global_value=" . ST_MOVE . " WHERE global_id=1 AND global_value=" . ST_BGA_GAME_END
];
foreach ($players as $player) {
$pId = $player->getId();
// All game can keep this SQL
$sql[] = "UPDATE player SET player_id=$studioPlayer WHERE player_id=$pId";
$sql[] = "UPDATE global SET global_value=$studioPlayer WHERE global_value=$pId";
$sql[] = "UPDATE stats SET stats_player_id=$studioPlayer WHERE stats_player_id=$pId";
// Change the below SQL to update the specific tables for your game
$sql[] = "UPDATE card SET card_location_arg=$studioPlayer WHERE card_location_arg=$pId";
$sql[] = "UPDATE piece SET player_id=$studioPlayer WHERE player_id=$pId";
$sql[] = "UPDATE log SET player_id=$studioPlayer WHERE player_id=$pId";
$sql[] = "UPDATE log SET action_arg=REPLACE(action_arg, $pId, $studioPlayer)";
// This could be improved, it assumes you had sequential studio accounts before loading
// e.g., quietmint0, quietmint1, quietmint2, etc. are at the table
$studioPlayer++;
}
$msg = "<b>Loaded <a href='https://boardgamearena.com/bug?id=$reportId' target='_blank'>bug report $reportId</a></b><hr><ul><li>" . implode(';</li><li>', $sql) . ';</li></ul>';
self::warn($msg);
self::notifyAllPlayers('message', $msg, []);
foreach ($sql as $q) {
self::DbQuery($q);
}
self::reloadPlayersBasicInfos();
}
Add loadBugSQL() to actions.php
Code: Select all
public function loadBugSQL()
{
self::setAjaxMode();
$reportId = (int) self::getArg('report_id', AT_int, true);
$this->game->loadBugSQL($reportId);
self::ajaxResponse();
}
Add loadBug notification handler to game.js.
Code: Select all
notif_loadBug: function (n) {
function fetchNextUrl() {
var url = n.args.urls.shift();
console.log('Fetching URL', url);
dojo.xhrGet({
url: url,
load: function (success) {
// This could be improved, I don't check the response for errors
console.log('Success for URL', url, success);
if (n.args.urls.length > 0) {
fetchNextUrl();
} else {
console.log('Done, reloading page');
window.location.reload();
}
}
});
}
console.log('Notif: load bug', n.args);
fetchNextUrl();
},