mirror of https://github.com/tstellar/bygfoot.git
Add json interface
This adds an initial version of a json interface to bygfoot. This is still in development so the interface may change in the future. This interface can be used for writing tests or for communication between a client and server. To use the interface, you can pass a json file with commands to bygfoot using the --json option.
This commit is contained in:
parent
3097ed92bc
commit
0524050959
|
@ -9,6 +9,20 @@ jobs:
|
|||
package-linux:
|
||||
runs-on:
|
||||
- ubuntu-16.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
build-type:
|
||||
- full
|
||||
- minimal
|
||||
include:
|
||||
- build-type: full
|
||||
extra-deps: libjson-c-dev
|
||||
build-suffix: ""
|
||||
- build-type: minimal
|
||||
extra-deps: ""
|
||||
build-suffix: -minimal
|
||||
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v2
|
||||
|
@ -16,13 +30,17 @@ jobs:
|
|||
- name: Install dependencies
|
||||
run: sudo apt-get install libglib2.0-dev libgtk2.0-dev libpango1.0-dev libatk1.0-dev libfreetype6-dev ninja-build
|
||||
|
||||
- name: Install extra dependencies
|
||||
if: ${{ matrix.extra-deps != '' }}
|
||||
run: sudo apt-get install ${{ matrix.extra-deps }}
|
||||
|
||||
- name: Package Bygfoot
|
||||
run: ./scripts/package.sh .
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "bygfoot-${{ env.BYGFOOT_VERSION }}-linux"
|
||||
name: "bygfoot-${{ env.BYGFOOT_VERSION }}-linux${{ matrix.build-suffix }}"
|
||||
path: "*.bz2"
|
||||
|
||||
package-windows:
|
||||
|
|
|
@ -26,6 +26,31 @@ include(GNUInstallDirs)
|
|||
add_definitions("-DPACKAGE_DATA_DIR=\"${CMAKE_INSTALL_FULL_DATADIR}\"")
|
||||
add_definitions("-DPACKAGE=\"${PROJECT_NAME}\"")
|
||||
|
||||
find_package(JSON-C)
|
||||
|
||||
if (JSON-C_FOUND)
|
||||
set(JSON-C_LIBRARIES json-c::json-c)
|
||||
else()
|
||||
pkg_check_modules(JSON-C json-c)
|
||||
endif()
|
||||
|
||||
if (JSON-C_FOUND)
|
||||
set(JSON_FILES src/json_interface.c src/json_serialize.c)
|
||||
add_definitions("-DENABLE_JSON")
|
||||
include_directories (${JSON-C_INCLUDE_DIRS})
|
||||
link_directories (${JSON-C_LIBRARY_DIRS})
|
||||
|
||||
include(CheckSymbolExists)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${JSON-C_LIBRARIES})
|
||||
check_symbol_exists(json_object_new_array_ext "json-c/json.h"
|
||||
HAVE_JSON_OBJECT_NEW_ARRAY_EXT)
|
||||
if (HAVE_JSON_OBJECT_NEW_ARRAY_EXT)
|
||||
add_definitions("-DHAVE_JSON_OBJECT_NEW_ARRAY_EXT")
|
||||
endif()
|
||||
|
||||
|
||||
endif()
|
||||
|
||||
add_executable(bygfoot WIN32
|
||||
src/bet.c src/bet.h src/bet_struct.h
|
||||
src/bygfoot.c src/bygfoot.h
|
||||
|
@ -111,13 +136,14 @@ add_executable(bygfoot WIN32
|
|||
src/youth_academy.c src/youth_academy.h
|
||||
src/zip/unzip.c src/zip/unzip.h
|
||||
src/zip/zip.c src/zip/zip.h
|
||||
${JSON_FILES}
|
||||
)
|
||||
# Some gtk headers use deprecated glib features, so disable this warning
|
||||
# since we can't do anything about it.
|
||||
target_compile_options(bygfoot PRIVATE -Wno-deprecated-declarations)
|
||||
# Link the target to the GTK+ libraries
|
||||
target_link_libraries (bygfoot ${GTK2_LIBRARIES} ${GLIB_LIBRARIES} m
|
||||
${ZLIB_LIBRARIES})
|
||||
${ZLIB_LIBRARIES} ${JSON-C_LIBRARIES})
|
||||
|
||||
install(TARGETS bygfoot)
|
||||
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
|
||||
#include "bygfoot.h"
|
||||
#include "file.h"
|
||||
#include "load_save.h"
|
||||
#include "gui.h"
|
||||
#include "misc.h"
|
||||
#include "start_end.h"
|
||||
#include "user.h"
|
||||
#include "start_end.h"
|
||||
#include "xml_country.h"
|
||||
|
||||
void
|
||||
|
@ -19,6 +22,23 @@ bygfoot_init(Bygfoot *bygfoot, enum BygfootFrontend frontend)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
bygfoot_load_bygfoot(Bygfoot *bygfoot, const gchar *id)
|
||||
{
|
||||
char save_dir[256];
|
||||
char save_path[256];
|
||||
/* FIXME: This is not secure */
|
||||
file_get_bygfoot_dir(save_dir);
|
||||
/* FIXME: There should be a helper function for this */
|
||||
sprintf(save_path, "%s%ssaves%s%s", save_dir, G_DIR_SEPARATOR_S, G_DIR_SEPARATOR_S, id);
|
||||
}
|
||||
|
||||
Country *bygfoot_load_country(Bygfoot *bygfoot, const gchar *country_name)
|
||||
{
|
||||
xml_country_read(country_name, NULL);
|
||||
return &country;
|
||||
}
|
||||
|
||||
User *bygfoot_add_user(Bygfoot *bygfoot, const gchar *username, Team *tm)
|
||||
{
|
||||
User new_user = user_new();
|
||||
|
|
|
@ -205,7 +205,13 @@ typedef struct
|
|||
gint paned_pos;
|
||||
} Windows;
|
||||
|
||||
typedef struct {
|
||||
gchar *json_filename;
|
||||
} CommandLineArgs;
|
||||
|
||||
void bygfoot_init(Bygfoot *bygfoot, enum BygfootFrontend frontend);
|
||||
void bygfoot_load_bygfoot(Bygfoot *bygfoot, const gchar *id);
|
||||
Country *bygfoot_load_country(Bygfoot *bygfoot, const gchar *country_name);
|
||||
User *bygfoot_add_user(Bygfoot *bygfoot, const gchar *username, Team *tm);
|
||||
void bygfoot_start_game(Bygfoot *bygfoot);
|
||||
void bygfoot_show_progress(const Bygfoot *bygfoot, gfloat value, const gchar *text, gint pictype);
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
#ifndef BYGFOOT_STRUCT_H
|
||||
#define BYGFOOT_STRUCT_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
enum BygfootFrontend {
|
||||
BYGFOOT_FRONTEND_GTK2
|
||||
BYGFOOT_FRONTEND_GTK2,
|
||||
BYGFOOT_FRONTEND_CONSOLE,
|
||||
};
|
||||
|
||||
/** This struct holds all of the global state for a bygfoot game. The goal
|
||||
|
@ -20,4 +23,5 @@ typedef struct
|
|||
/* @} */
|
||||
} Bygfoot;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -71,6 +71,9 @@ file_load_user_conf_file(User *user);
|
|||
gboolean
|
||||
file_check_home_dir(void);
|
||||
|
||||
void
|
||||
file_check_home_dir_create_dirs(void);
|
||||
|
||||
void
|
||||
file_check_home_dir_get_conf_files(GPtrArray **files_to_copy);
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
|
||||
#ifndef HAVE_JSON_OBJECT_NEW_ARRAY_EXT
|
||||
#define json_object_new_array_ext(size) json_object_new_array();
|
||||
#endif
|
|
@ -0,0 +1,663 @@
|
|||
|
||||
#include <json-c/json.h>
|
||||
#include <json-c/json_tokener.h>
|
||||
#include <json-c/json_object.h>
|
||||
#include "json_interface.h"
|
||||
#include "json_serialize.h"
|
||||
#include "user.h"
|
||||
#include "league_struct.h"
|
||||
#include "load_save.h"
|
||||
#include "misc.h"
|
||||
#include "team.h"
|
||||
#include "option.h"
|
||||
#include "start_end.h"
|
||||
|
||||
static int bygfoot_json_do_commands(Bygfoot *bygfoot, const json_object *commands);
|
||||
static int bygfoot_json_do_add_user(Bygfoot *bygfoot, const json_object *args);
|
||||
static struct json_object *bygfoot_json_call_load_bygfoot(Bygfoot *bygfoot, const json_object *args);
|
||||
static struct json_object *bygfoot_json_call_save_bygfoot(Bygfoot *bygfoot, const json_object *args);
|
||||
static struct json_object *bygfoot_json_call_add_country(Bygfoot *bygfoot, const json_object *args);
|
||||
static struct json_object *bygfoot_json_call_add_user(Bygfoot *bygfoot, const json_object *args);
|
||||
static struct json_object *bygfoot_json_call_start_bygfoot(Bygfoot *bygfoot, const json_object *args);
|
||||
static struct json_object *bygfoot_json_call_simulate_games(Bygfoot *bygfoot,
|
||||
const json_object *args);
|
||||
static struct json_object *bygfoot_json_call_get_tables(Bygfoot *bygfoot,
|
||||
const json_object *args);
|
||||
static struct json_object *bygfoot_json_call_get_players(Bygfoot *bygfoot,
|
||||
const json_object *args);
|
||||
static struct json_object *bygfoot_json_call_get_fixtures(Bygfoot *bygfoot,
|
||||
const json_object *args);
|
||||
static struct json_object *bygfoot_json_call_get_cups(Bygfoot *bygfoot,
|
||||
const json_object *args);
|
||||
static struct json_object *bygfoot_json_response_error(const char *command,
|
||||
const char *error);
|
||||
static json_object *
|
||||
bygfoot_json_fixture_to_json(const Fixture *fixture);
|
||||
static json_object * bygfoot_json_player_to_json(const Player *player);
|
||||
static json_object *bygfoot_json_user_to_json(const User *user);
|
||||
static json_object *bygfoot_json_table_to_json(const Table *table);
|
||||
|
||||
struct json_field {
|
||||
const gchar *name;
|
||||
enum json_type type;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
bygfoot_json_validate_arg_types(const struct json_object *args,
|
||||
const struct json_field *fields)
|
||||
{
|
||||
const struct json_field *field;
|
||||
|
||||
for (field = fields; field->name; field++ ) {
|
||||
struct json_object *value;
|
||||
if (!json_object_object_get_ex(args, field->name, &value))
|
||||
continue;
|
||||
if (!json_object_is_type(value, field->type))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int bygfoot_json_main(Bygfoot *bygfoot, const CommandLineArgs *cl_args)
|
||||
{
|
||||
gchar *contents;
|
||||
GError *error;
|
||||
struct json_object *json;
|
||||
enum json_tokener_error json_error;
|
||||
|
||||
/* Disable option to skip rounds without user games, so the simulate_games
|
||||
* command works correctly. */
|
||||
opt_set_int("int_opt_skip", 0);
|
||||
|
||||
if (!g_file_get_contents(cl_args->json_filename, &contents, NULL, &error)) {
|
||||
misc_print_error(&error, FALSE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
json = json_tokener_parse_verbose(contents, &json_error);
|
||||
if (!json) {
|
||||
fprintf(stderr, "Failed to parse json %s:\n", cl_args->json_filename);
|
||||
fprintf(stderr, "%s\n",
|
||||
json_tokener_error_desc(json_error));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Handle configuration options */
|
||||
/* TODO: Get option from json */
|
||||
//bygfoot_set_save_dir(bygfoot, NULL);
|
||||
|
||||
json_object_object_foreach(json, key, val) {
|
||||
if (!strcmp("commands", key))
|
||||
return bygfoot_json_do_commands(bygfoot, val);
|
||||
}
|
||||
fprintf(stderr, "commands key is not present");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bygfoot_json_do_commands(Bygfoot *bygfoot, const json_object *commands)
|
||||
{
|
||||
size_t i, num_commands;
|
||||
|
||||
static const struct json_func {
|
||||
const gchar *command;
|
||||
json_object* (*func)(Bygfoot *, const json_object *);
|
||||
} json_funcs[] = {
|
||||
{ "load_bygfoot", bygfoot_json_call_load_bygfoot },
|
||||
{ "save_bygfoot", bygfoot_json_call_save_bygfoot },
|
||||
{ "add_country", bygfoot_json_call_add_country },
|
||||
{ "add_user", bygfoot_json_call_add_user },
|
||||
{ "start_bygfoot", bygfoot_json_call_start_bygfoot },
|
||||
{ "simulate_games", bygfoot_json_call_simulate_games },
|
||||
{ "get_tables", bygfoot_json_call_get_tables },
|
||||
{ "get_players", bygfoot_json_call_get_players },
|
||||
{ "get_fixtures", bygfoot_json_call_get_fixtures },
|
||||
{ "cups", bygfoot_json_call_get_cups },
|
||||
{ NULL, NULL}
|
||||
};
|
||||
|
||||
if (!json_object_is_type(commands, json_type_array)) {
|
||||
fprintf(stderr, "json commands should be in an array\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
num_commands = json_object_array_length(commands);
|
||||
for (i = 0; i < num_commands; i++) {
|
||||
const json_object *command = json_object_array_get_idx(commands, i);
|
||||
struct json_object *response = NULL;
|
||||
// TODO: CHECK COMMAND SIZE
|
||||
|
||||
json_object_object_foreach(command, key, val) {
|
||||
const struct json_func *json_func;
|
||||
for (json_func = json_funcs; json_func->command; json_func++) {
|
||||
if (!strcmp(json_func->command, key)) {
|
||||
response = json_func->func(bygfoot, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!response) {
|
||||
response = bygfoot_json_response_error("commands", "command not recognized");
|
||||
}
|
||||
fprintf(stderr, "%s\n", json_object_to_json_string_ext(response, JSON_C_TO_STRING_PRETTY));
|
||||
json_object_put(response);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
bygfoot_json_validate_bygfoot_id(const json_object *args, json_object **error)
|
||||
{
|
||||
const gchar *id;
|
||||
/* Get the id field */
|
||||
json_object *id_obj = json_object_object_get(args, "id");
|
||||
|
||||
if (id_obj) {
|
||||
if(!json_object_is_type(id_obj, json_type_string)) {
|
||||
*error = bygfoot_json_response_error("",
|
||||
"field 'id' must be a string");
|
||||
return NULL;
|
||||
}
|
||||
return json_object_get_string(id_obj);
|
||||
}
|
||||
|
||||
*error = bygfoot_json_response_error("", "field 'id' is missing or NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct json_object *
|
||||
bygfoot_json_call_load_bygfoot(Bygfoot *bygfoot, const json_object *args)
|
||||
{
|
||||
const gchar *id = NULL;
|
||||
struct json_object *filename_obj;
|
||||
const gchar *filename;
|
||||
static const struct json_field fields [] = {
|
||||
{ "filename", json_type_string }
|
||||
};
|
||||
|
||||
if (!bygfoot_json_validate_arg_types(args, fields))
|
||||
return bygfoot_json_response_error("load_bygfoot",
|
||||
"wrong type for argument");
|
||||
|
||||
if (!json_object_object_get_ex(args, "filename", &filename_obj))
|
||||
return bygfoot_json_response_error("load_bygfoot",
|
||||
"filename argument is required");
|
||||
|
||||
filename = json_object_get_string(filename_obj);
|
||||
if (!g_file_test(filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
|
||||
return bygfoot_json_response_error("load_bygfoot", "file not found");
|
||||
|
||||
load_save_load_game(bygfoot, filename, FALSE);
|
||||
return json_object_new_object();
|
||||
}
|
||||
|
||||
static struct json_object *
|
||||
bygfoot_json_call_save_bygfoot(Bygfoot *bygfoot, const json_object *args)
|
||||
{
|
||||
const gchar *id = NULL;
|
||||
struct json_object *filename_obj;
|
||||
const gchar *filename;
|
||||
static const struct json_field fields [] = {
|
||||
{ "filename", json_type_string }
|
||||
};
|
||||
|
||||
if (!bygfoot_json_validate_arg_types(args, fields))
|
||||
return bygfoot_json_response_error("save_bygfoot",
|
||||
"wrong type for argument");
|
||||
|
||||
if (!json_object_object_get_ex(args, "filename", &filename_obj))
|
||||
return bygfoot_json_response_error("save_bygfoot",
|
||||
"filename argument is required");
|
||||
|
||||
filename = json_object_get_string(filename_obj);
|
||||
|
||||
load_save_save_game(bygfoot, filename);
|
||||
return json_object_new_object();
|
||||
}
|
||||
|
||||
static json_object *
|
||||
bygfoot_json_call_add_country(Bygfoot *bygfoot, const json_object *args)
|
||||
{
|
||||
gchar const *country_name = NULL;
|
||||
static const struct json_field fields [] = {
|
||||
{ "name", json_type_string },
|
||||
{ NULL, json_type_null }
|
||||
};
|
||||
const struct json_field *field;
|
||||
|
||||
for (field = fields; field->name; field++ ) {
|
||||
struct json_object *value = json_object_object_get(args, field->name);
|
||||
if (!value)
|
||||
continue;
|
||||
if (!json_object_is_type(value, field->type))
|
||||
continue;
|
||||
|
||||
if (!strcmp(field->name, "name"))
|
||||
country_name = json_object_get_string(value);
|
||||
}
|
||||
|
||||
if (!country_name)
|
||||
return bygfoot_json_response_error("add_country", "field 'country' is required");
|
||||
|
||||
bygfoot_load_country(bygfoot, country_name);
|
||||
return json_object_new_string("success");
|
||||
}
|
||||
|
||||
static json_object *bygfoot_json_call_add_user(Bygfoot *bygfoot, const json_object *args)
|
||||
{
|
||||
const char *command = "add_user";
|
||||
const char *username = NULL;
|
||||
const char *country_name = NULL;
|
||||
const char *team_name = NULL;
|
||||
struct json_object *response;
|
||||
Country *country;
|
||||
Team *tm;
|
||||
User *user;
|
||||
json_object_object_foreach(args, key, val) {
|
||||
if (!strcmp("username", key)) {
|
||||
if (!json_object_is_type(val, json_type_string)) {
|
||||
return bygfoot_json_response_error(command, "username must be of type string");
|
||||
}
|
||||
username = json_object_get_string(val);
|
||||
}
|
||||
if (!strcmp("country", key)) {
|
||||
if (!json_object_is_type(val, json_type_string)) {
|
||||
return bygfoot_json_response_error(command, "country must be of type string");
|
||||
}
|
||||
country_name = json_object_get_string(val);
|
||||
}
|
||||
if (!strcmp("team", key)) {
|
||||
if (!json_object_is_type(val, json_type_string)) {
|
||||
return bygfoot_json_response_error(command, "team must be of type string");
|
||||
}
|
||||
team_name = json_object_get_string(val);
|
||||
}
|
||||
}
|
||||
|
||||
if (!username) {
|
||||
return bygfoot_json_response_error(command, "field 'username' is required");
|
||||
}
|
||||
if (!country_name) {
|
||||
return bygfoot_json_response_error(command, "field 'country' is required");
|
||||
}
|
||||
if (!team_name) {
|
||||
return bygfoot_json_response_error(command, "field 'team' is required");
|
||||
}
|
||||
|
||||
country = bygfoot_load_country(bygfoot, country_name);
|
||||
tm = team_of_sid(team_name, country);
|
||||
user = bygfoot_add_user(bygfoot, username, tm);
|
||||
|
||||
response = json_object_new_object();
|
||||
json_object_object_add(response, "success", bygfoot_json_user_to_json(user));
|
||||
return response;
|
||||
}
|
||||
|
||||
static json_object *bygfoot_json_call_start_bygfoot(Bygfoot *bygfoot,
|
||||
const json_object *args)
|
||||
{
|
||||
unsigned i;
|
||||
bygfoot_start_game(bygfoot);
|
||||
|
||||
/* FIXME: We should really be doing this when the user is added, but
|
||||
* the user options get loaded during the bygfoot_start_bygfoot() call and w
|
||||
* can't add options before that.
|
||||
*/
|
||||
for (i = 0; i < users->len; i++) {
|
||||
/* We need to set this option to avoid activating the GUI.
|
||||
* FIXME: More work is needed to separate the logic from the GUI */
|
||||
option_set_int("int_opt_user_show_live_game", &usr(i).options, 0);
|
||||
}
|
||||
return json_object_new_string("success");
|
||||
}
|
||||
|
||||
static void simulate_weeks(Bygfoot *bygfoot, gint weeks)
|
||||
{
|
||||
gint num_weeks = 0;
|
||||
gint current_week = week;
|
||||
while (num_weeks < weeks) {
|
||||
do {
|
||||
end_week_round(bygfoot);
|
||||
} while (current_week == week);
|
||||
current_week = week;
|
||||
num_weeks++;
|
||||
}
|
||||
}
|
||||
|
||||
static struct json_object *bygfoot_json_call_simulate_games(Bygfoot *bygfoot,
|
||||
const json_object *args)
|
||||
{
|
||||
int32_t rounds = 0;
|
||||
int32_t weeks = 0;
|
||||
int32_t seasons = 0;
|
||||
unsigned i;
|
||||
json_object_object_foreach(args, key, val) {
|
||||
if (!strcmp("rounds", key)) {
|
||||
rounds = json_object_get_int(val);
|
||||
for (i = 0; i < rounds; i++) {
|
||||
end_week_round(bygfoot);
|
||||
}
|
||||
} else if (!strcmp("weeks", key)) {
|
||||
weeks = json_object_get_int(val);
|
||||
simulate_weeks(bygfoot, weeks);
|
||||
} else if (!strcmp("seasons", key)) {
|
||||
gint num_seasons = 0;
|
||||
gint start_week = week;
|
||||
gint current_season = season;
|
||||
seasons = json_object_get_int(val);
|
||||
while (num_seasons < seasons) {
|
||||
do {
|
||||
end_week_round(bygfoot);
|
||||
} while (current_season == season);
|
||||
current_season = season;
|
||||
num_seasons++;
|
||||
}
|
||||
simulate_weeks(bygfoot, start_week);
|
||||
}
|
||||
}
|
||||
|
||||
return json_object_new_string("success");
|
||||
}
|
||||
|
||||
static json_object *
|
||||
bygfoot_json_call_get_fixtures(Bygfoot *bygfoot, const json_object *args)
|
||||
{
|
||||
struct json_object *fixtures_obj = json_object_new_array();
|
||||
struct json_object *response, *data;
|
||||
int i;
|
||||
for (i = 0; i < country.leagues->len; i++) {
|
||||
const League *league = &g_array_index(country.leagues, League, i);
|
||||
int j;
|
||||
for (j = 0; j < league->fixtures->len; j++) {
|
||||
const Fixture *fixture = &g_array_index(league->fixtures, Fixture, j);
|
||||
json_object_array_add(fixtures_obj, bygfoot_json_fixture_to_json(fixture));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < country.cups->len; i++) {
|
||||
const Cup *cup = &g_array_index(country.cups, Cup, i);
|
||||
int j;
|
||||
for (j = 0; j < cup->fixtures->len; j++) {
|
||||
const Fixture *fixture = &g_array_index(cup->fixtures, Fixture, j);
|
||||
json_object_array_add(fixtures_obj, bygfoot_json_fixture_to_json(fixture));
|
||||
}
|
||||
}
|
||||
|
||||
data = json_object_new_object();
|
||||
response = json_object_new_object();
|
||||
|
||||
json_object_object_add(data, "fixtures", fixtures_obj);
|
||||
json_object_object_add(response, "success", data);
|
||||
return response;
|
||||
}
|
||||
|
||||
static json_object *
|
||||
bygfoot_json_call_get_tables(Bygfoot *bygfoot, const json_object *args)
|
||||
{
|
||||
gchar const *country_name = NULL;
|
||||
static const struct json_field fields [] = {
|
||||
{ NULL, json_type_null }
|
||||
};
|
||||
const struct json_field *field;
|
||||
int i;
|
||||
struct json_object *response, *data, *tables;
|
||||
|
||||
for (field = fields; field->name; field++ ) {
|
||||
struct json_object *value = json_object_object_get(args, field->name);
|
||||
if (!value)
|
||||
continue;
|
||||
if (!json_object_is_type(value, field->type))
|
||||
continue;
|
||||
}
|
||||
|
||||
tables = json_object_new_array();
|
||||
//GArray *leagues, *cups;
|
||||
for (i = 0; i < country.leagues->len; i++) {
|
||||
const League *league = &g_array_index(country.leagues, League, i);
|
||||
int j;
|
||||
for (j = 0; j < league->tables->len; j++) {
|
||||
const Table *table = &g_array_index(league->tables, Table, j);
|
||||
json_object_array_add(tables, bygfoot_json_table_to_json(table));
|
||||
}
|
||||
}
|
||||
response = json_object_new_object();
|
||||
data = json_object_new_object();
|
||||
json_object_object_add(data, "tables", tables);
|
||||
json_object_object_add(response, "success", data);
|
||||
return response;
|
||||
}
|
||||
|
||||
static json_object *
|
||||
bygfoot_json_call_get_players(Bygfoot *bygfoot, const json_object *args)
|
||||
{
|
||||
struct json_object *players_obj = json_object_new_array();
|
||||
struct json_object *response, *data;
|
||||
int i;
|
||||
for (i = 0; i < country.leagues->len; i++) {
|
||||
const League *league = &g_array_index(country.leagues, League, i);
|
||||
int j;
|
||||
for (j = 0; j < league->teams->len; j++) {
|
||||
const Team *team = &g_array_index(league->teams, Team, j);
|
||||
int k;
|
||||
for (k = 0; k < team->players->len; k++) {
|
||||
const Player *player = &g_array_index(team->players, Player, k);
|
||||
json_object_array_add(players_obj, bygfoot_json_player_to_json(player));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
response = json_object_new_object();
|
||||
data = json_object_new_object();
|
||||
json_object_object_add(data, "players", players_obj);
|
||||
json_object_object_add(response, "success", data);
|
||||
return response;
|
||||
}
|
||||
|
||||
static json_object *
|
||||
bygfoot_json_call_get_cups(Bygfoot *bygfoot, const json_object *args)
|
||||
{
|
||||
|
||||
struct json_object *cups_obj = json_object_new_array_ext(country.cups->len);
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < country.cups->len; i++) {
|
||||
const Cup *cup = &g_array_index(country.cups, Cup, i);
|
||||
json_object_array_add(cups_obj, bygfoot_json_serialize_cup(cup, NULL));
|
||||
}
|
||||
|
||||
return cups_obj;
|
||||
}
|
||||
|
||||
|
||||
static json_object *
|
||||
bygfoot_json_live_game_stats_to_json(const LiveGameStats *stats, gint team_index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static json_object *
|
||||
bygfoot_json_fixture_stats_to_json(const Fixture *fixture, gint team_index)
|
||||
{
|
||||
struct json_object *team_obj = json_object_new_object();
|
||||
struct json_object *stats_obj = json_object_new_object();
|
||||
|
||||
static const struct key_index {
|
||||
const gchar *key;
|
||||
gint index;
|
||||
} result_fields[] = {
|
||||
{ "goals_regulation", 0 },
|
||||
{ "goals_extra_time", 1 },
|
||||
{ "goals_penalty_shootout", 2 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static const struct key_index live_stats_fields[] = {
|
||||
{ "goals_regular", LIVE_GAME_STAT_VALUE_GOALS_REGULAR },
|
||||
{ "shots", LIVE_GAME_STAT_VALUE_SHOTS },
|
||||
{ "shot_percentage", LIVE_GAME_STAT_VALUE_SHOT_PERCENTAGE },
|
||||
{ "possession", LIVE_GAME_STAT_VALUE_POSSESSION },
|
||||
{ "penalties", LIVE_GAME_STAT_VALUE_PENALTIES },
|
||||
{ "fouls", LIVE_GAME_STAT_VALUE_FOULS },
|
||||
{ "cards", LIVE_GAME_STAT_VALUE_CARDS },
|
||||
{ "reds", LIVE_GAME_STAT_VALUE_REDS } ,
|
||||
{ "injuries", LIVE_GAME_STAT_VALUE_INJURIES },
|
||||
{ NULL, LIVE_GAME_STAT_VALUE_END }
|
||||
};
|
||||
|
||||
const struct key_index *iter;
|
||||
|
||||
if (!fixture->live_game)
|
||||
return stats_obj;
|
||||
|
||||
for (iter = result_fields; iter->key; iter++) {
|
||||
gint value = fixture->result[team_index][iter->index];
|
||||
json_object_object_add(stats_obj, iter->key, json_object_new_int64(value));
|
||||
}
|
||||
|
||||
/* Note it seems like fixture->live_game does not persist when the game is
|
||||
* over, so that is why we are not including it in the json. */
|
||||
return stats_obj;
|
||||
}
|
||||
|
||||
static json_object *
|
||||
bygfoot_json_fixture_to_json(const Fixture *fixture)
|
||||
{
|
||||
struct json_object *fixture_obj = json_object_new_object();
|
||||
struct json_object *home_team_obj = json_object_new_object();
|
||||
struct json_object *away_team_obj = json_object_new_object();
|
||||
json_object_object_add(fixture_obj, "id", json_object_new_int64(fixture->id));
|
||||
json_object_object_add(fixture_obj, "league_id", json_object_new_int64(fixture->clid));
|
||||
json_object_object_add(fixture_obj, "round", json_object_new_int64(fixture->round));
|
||||
json_object_object_add(fixture_obj, "replay_number", json_object_new_int64(fixture->replay_number));
|
||||
json_object_object_add(fixture_obj, "week", json_object_new_int64(fixture->week_number));
|
||||
json_object_object_add(fixture_obj, "round", json_object_new_int64(fixture->week_round_number));
|
||||
|
||||
json_object_object_add(home_team_obj, "id", json_object_new_int64(fixture->team_ids[0]));
|
||||
json_object_object_add(home_team_obj, "stats",
|
||||
bygfoot_json_fixture_stats_to_json(fixture, 0));
|
||||
json_object_object_add(fixture_obj, "home_team", home_team_obj);
|
||||
|
||||
json_object_object_add(away_team_obj, "id", json_object_new_int64(fixture->team_ids[1]));
|
||||
json_object_object_add(away_team_obj, "stats",
|
||||
bygfoot_json_fixture_stats_to_json(fixture, 1));
|
||||
json_object_object_add(fixture_obj, "away_team", away_team_obj);
|
||||
|
||||
return fixture_obj;
|
||||
}
|
||||
|
||||
static json_object *
|
||||
bygfoot_json_player_games_goals_to_json(const GArray *stats)
|
||||
{
|
||||
int i;
|
||||
struct json_object *stats_obj = json_object_new_array_ext(stats->len);
|
||||
for (i = 0; i < stats->len; i++) {
|
||||
const PlayerGamesGoals *league_stats = &g_array_index(stats,
|
||||
PlayerGamesGoals, i);
|
||||
struct json_object *league_stats_obj = json_object_new_object();
|
||||
json_object_object_add(league_stats_obj, "league_id",
|
||||
json_object_new_int64(league_stats->clid));
|
||||
json_object_object_add(league_stats_obj, "games",
|
||||
json_object_new_int64(league_stats->games));
|
||||
json_object_object_add(league_stats_obj, "goals",
|
||||
json_object_new_int64(league_stats->goals));
|
||||
json_object_object_add(league_stats_obj, "shots",
|
||||
json_object_new_int64(league_stats->shots));
|
||||
json_object_array_add(stats_obj, league_stats_obj);
|
||||
}
|
||||
return stats_obj;
|
||||
}
|
||||
|
||||
static json_object *
|
||||
bygfoot_json_player_to_json(const Player *player)
|
||||
{
|
||||
struct json_object *player_obj = json_object_new_object();
|
||||
json_object_object_add(player_obj, "name", json_object_new_string(player->name));
|
||||
json_object_object_add(player_obj, "season_stats",
|
||||
bygfoot_json_player_games_goals_to_json(player->games_goals));
|
||||
|
||||
return player_obj;
|
||||
}
|
||||
|
||||
static json_object *
|
||||
bygfoot_json_team_to_json(const Team *team)
|
||||
{
|
||||
struct json_object *team_obj = json_object_new_object();
|
||||
|
||||
json_object_object_add(team_obj, "name",
|
||||
json_object_new_string(team->name));
|
||||
return team_obj;
|
||||
}
|
||||
|
||||
static json_object *
|
||||
bygfoot_json_table_element_to_json(const TableElement *element)
|
||||
{
|
||||
struct json_object *element_obj = json_object_new_object();
|
||||
|
||||
json_object_object_add(element_obj, "team",
|
||||
bygfoot_json_team_to_json(element->team));
|
||||
json_object_object_add(element_obj, "old_rank",
|
||||
json_object_new_int64(element->old_rank));
|
||||
json_object_object_add(element_obj, "played",
|
||||
json_object_new_int64(element->values[TABLE_PLAYED]));
|
||||
json_object_object_add(element_obj, "won",
|
||||
json_object_new_int64(element->values[TABLE_WON]));
|
||||
json_object_object_add(element_obj, "draw",
|
||||
json_object_new_int64(element->values[TABLE_DRAW]));
|
||||
json_object_object_add(element_obj, "lost",
|
||||
json_object_new_int64(element->values[TABLE_LOST]));
|
||||
json_object_object_add(element_obj, "gf",
|
||||
json_object_new_int64(element->values[TABLE_GF]));
|
||||
json_object_object_add(element_obj, "ga",
|
||||
json_object_new_int64(element->values[TABLE_GA]));
|
||||
json_object_object_add(element_obj, "gd",
|
||||
json_object_new_int64(element->values[TABLE_GD]));
|
||||
json_object_object_add(element_obj, "pts",
|
||||
json_object_new_int64(element->values[TABLE_PTS]));
|
||||
return element_obj;
|
||||
}
|
||||
|
||||
static json_object *
|
||||
bygfoot_json_table_to_json(const Table *table)
|
||||
{
|
||||
struct json_object *table_obj = json_object_new_object();
|
||||
struct json_object *elements_obj = json_object_new_array_ext(table->elements->len);
|
||||
int i;
|
||||
|
||||
json_object_object_add(table_obj, "name", json_object_new_string(table->name));
|
||||
json_object_object_add(table_obj, "id", json_object_new_int64(table->clid));
|
||||
json_object_object_add(table_obj, "round", json_object_new_int64(table->round));
|
||||
|
||||
|
||||
for (i = 0; i < table->elements->len; i++) {
|
||||
const TableElement *element = &g_array_index(table->elements,
|
||||
TableElement, i);
|
||||
json_object_array_add(elements_obj,
|
||||
bygfoot_json_table_element_to_json(element));
|
||||
}
|
||||
json_object_object_add(table_obj, "elements", elements_obj);
|
||||
return table_obj;
|
||||
}
|
||||
|
||||
static json_object *bygfoot_json_user_to_json(const User *user)
|
||||
{
|
||||
struct json_object *json = json_object_new_object();
|
||||
struct json_object *user_obj = json_object_new_object();
|
||||
json_object_object_add(user_obj, "name", json_object_new_string(user->name));
|
||||
json_object_object_add(json, "user", user_obj);
|
||||
return json;
|
||||
}
|
||||
|
||||
static struct json_object *bygfoot_json_response_error(const char *command,
|
||||
const char *error)
|
||||
{
|
||||
struct json_object *json = json_object_new_object();
|
||||
json_object_object_add(json, "message", json_object_new_string(error));
|
||||
return json;
|
||||
}
|
||||
|
||||
static void bygfoot_json_error_to_console(const char *command, const char *error)
|
||||
{
|
||||
struct json_object *json = bygfoot_json_response_error(command, error);
|
||||
fprintf(stderr, "%s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
|
||||
json_object_put(json);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef JSON_INTERFACE_H
|
||||
#define JSON_INTERFACE_H
|
||||
|
||||
#include <json-c/json_object.h>
|
||||
#include "bygfoot.h"
|
||||
|
||||
|
||||
int bygfoot_json_main(Bygfoot *bygfoot, const CommandLineArgs *cl_args);
|
||||
|
||||
struct json_object *bygfoot_json_call_get_countries(Bygfoot *bygfoot, const json_object *args);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,284 @@
|
|||
/** \file json_serialize.c
|
||||
*
|
||||
*
|
||||
* This contains functions for converting Bygfoot objects to json. The general
|
||||
* strategy is to only serialize values that are unchanged during a Bygfoot
|
||||
* game.
|
||||
*
|
||||
* Object members that can change as the result of game play should be
|
||||
* queried with functions directly.
|
||||
*
|
||||
* Parent: Full, Child: Full : Fields == NULL, recursive = TRUE
|
||||
* Parent: Full, Child: ID: Fields == NULL, recursive = FALSE
|
||||
* Parent: ID: Fields == IDs
|
||||
* Child field in filter: IDs
|
||||
* Child field in filter, recursive = TRUE: FULL
|
||||
*
|
||||
*/
|
||||
|
||||
#include <json-c/json_object.h>
|
||||
#include <glib.h>
|
||||
#include "json_serialize.h"
|
||||
#include "league_struct.h"
|
||||
|
||||
static void
|
||||
serialize_gchar_array_callback(gpointer string, gpointer user_data)
|
||||
{
|
||||
struct json_object *obj = (struct json_object*)user_data;
|
||||
json_object_array_add(obj, json_object_new_string(string));
|
||||
}
|
||||
|
||||
static struct json_object*
|
||||
serialize_gchar_array(GPtrArray* ptr_array)
|
||||
{
|
||||
struct json_object *array_obj = json_object_new_array_ext(ptr_array->len);
|
||||
int i;
|
||||
|
||||
g_ptr_array_foreach(ptr_array, serialize_gchar_array_callback, array_obj);
|
||||
|
||||
return array_obj;
|
||||
}
|
||||
|
||||
|
||||
static GHashTable*
|
||||
fields_to_hash_table(gchar **fields)
|
||||
{
|
||||
gchar *field;
|
||||
GHashTable *hash_table;
|
||||
|
||||
if (!fields)
|
||||
return NULL;
|
||||
|
||||
hash_table = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
for (field = *fields; field; field++) {
|
||||
g_hash_table_add(hash_table, field);
|
||||
}
|
||||
return hash_table;
|
||||
}
|
||||
struct json_object *
|
||||
bygfoot_json_serialize_country_list(GPtrArray *country_list)
|
||||
{
|
||||
return serialize_gchar_array(country_list);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define SERIALIZE_OBJECT_FIELD_FILTER(json_object, object, field, \
|
||||
serialize_func, field_list) \
|
||||
if (!field_list || g_hash_table_contains(field_list, #field)) { \
|
||||
json_object_object_add(json_object, #field, serialize_func(object->field)); \
|
||||
}
|
||||
|
||||
#define SERIALIZE_OBJECT_FIELD_STRUCT(json_object, object, field, \
|
||||
serialize_func, field_list) \
|
||||
if (!field_list || g_hash_table_contains(field_list, #field)) { \
|
||||
json_object_object_add(json_object, #field, serialize_func(object->field, field_list)); \
|
||||
}
|
||||
|
||||
#define SERIALIZE_OBJECT_FIELD(json_object, object, field, serialize_func) \
|
||||
SERIALIZE_OBJECT_FIELD_FILTER(json_object, object, field, serialize_func, NULL)
|
||||
|
||||
struct json_object *
|
||||
bygfoot_json_serialize_country(const Country *country)
|
||||
{
|
||||
struct json_object *country_obj = json_object_new_object();
|
||||
|
||||
#define SERIALIZE_COUNTRY_FIELD(field, serialize_func) \
|
||||
SERIALIZE_OBJECT_FIELD(country_obj, country, field, serialize_func)
|
||||
SERIALIZE_COUNTRY_FIELD(name, json_object_new_string);
|
||||
SERIALIZE_COUNTRY_FIELD(symbol, json_object_new_string);
|
||||
SERIALIZE_COUNTRY_FIELD(sid, json_object_new_string);
|
||||
SERIALIZE_COUNTRY_FIELD(rating, json_object_new_int64);
|
||||
SERIALIZE_COUNTRY_FIELD(reserve_promotion_rules, json_object_new_int64);
|
||||
// SERIALIZE_COUNTRY_FIELD(leagues, bygfoot_json_serialize_league_array);
|
||||
// SERIALIZE_COUNTRY_FIELD(cups, bygfoot_json_serialize_cup_array);
|
||||
// SERIALIZE_COUNTRY_FIELD(allcups, bygfoot_json_serialize_cup_ptr_array);
|
||||
|
||||
#undef SERIALIZE_COUNTRY_FIELD
|
||||
|
||||
return country_obj;
|
||||
}
|
||||
|
||||
struct json_object *
|
||||
bygfoot_json_serialize_league_array(const GArray *league_array)
|
||||
{
|
||||
struct json_object *league_array_obj =
|
||||
json_object_new_array_ext(league_array->len);
|
||||
gint i;
|
||||
for (i = 0; i < league_array->len; i++) {
|
||||
const League *league = &g_array_index(league_array, League, i);
|
||||
json_object_array_add(league_array_obj,
|
||||
bygfoot_json_serialize_league(league));
|
||||
}
|
||||
return league_array_obj;
|
||||
}
|
||||
|
||||
struct json_object *
|
||||
bygfoot_json_serialize_league(const League *league)
|
||||
{
|
||||
struct json_object *league_obj = json_object_new_object();
|
||||
|
||||
#define SERIALIZE_LEAGUE_FIELD(field, serialize_func) \
|
||||
SERIALIZE_OBJECT_FIELD(league_obj, league, field, serialize_func);
|
||||
|
||||
SERIALIZE_LEAGUE_FIELD(name, json_object_new_string);
|
||||
SERIALIZE_LEAGUE_FIELD(short_name, json_object_new_string);
|
||||
SERIALIZE_LEAGUE_FIELD(sid, json_object_new_string);
|
||||
SERIALIZE_LEAGUE_FIELD(symbol, json_object_new_string);
|
||||
SERIALIZE_LEAGUE_FIELD(names_file, json_object_new_string);
|
||||
}
|
||||
|
||||
struct json_object *
|
||||
bygfoot_json_serialize_stadium(Stadium stadium, GHashTable *fields)
|
||||
{
|
||||
struct json_object *stadium_obj = json_object_new_object();
|
||||
Stadium *stadium_ptr = &stadium;
|
||||
|
||||
#define SERIALIZE_STADIUM_FIELD(field, serialize_func) \
|
||||
SERIALIZE_OBJECT_FIELD_FILTER(stadium_obj, stadium_ptr, field, serialize_func, fields);
|
||||
|
||||
SERIALIZE_STADIUM_FIELD(name, json_object_new_string);
|
||||
SERIALIZE_STADIUM_FIELD(capacity, json_object_new_int64);
|
||||
SERIALIZE_STADIUM_FIELD(average_attendance, json_object_new_int64);
|
||||
SERIALIZE_STADIUM_FIELD(possible_attendance, json_object_new_int64);
|
||||
SERIALIZE_STADIUM_FIELD(safety, json_object_new_double);
|
||||
SERIALIZE_STADIUM_FIELD(ticket_price, json_object_new_double);
|
||||
|
||||
return stadium_obj;
|
||||
}
|
||||
|
||||
struct json_object *
|
||||
bygfoot_json_serialize_team(const Team *team, GHashTable *fields)
|
||||
{
|
||||
|
||||
struct json_object *team_obj = json_object_new_object();
|
||||
|
||||
#define SERIALIZE_TEAM_FIELD(field, serialize_func) \
|
||||
SERIALIZE_OBJECT_FIELD_FILTER(team_obj, team, field, serialize_func, fields);
|
||||
#define SERIALIZE_TEAM_FIELD_STRUCT(field, serialize_func) \
|
||||
SERIALIZE_OBJECT_FIELD_STRUCT(team_obj, team, field, serialize_func, fields);
|
||||
|
||||
SERIALIZE_TEAM_FIELD(name, json_object_new_string);
|
||||
SERIALIZE_TEAM_FIELD(symbol, json_object_new_string);
|
||||
SERIALIZE_TEAM_FIELD(names_file, json_object_new_string);
|
||||
SERIALIZE_TEAM_FIELD(def_file, json_object_new_string);
|
||||
SERIALIZE_TEAM_FIELD(strategy_sid, json_object_new_string);
|
||||
SERIALIZE_TEAM_FIELD(clid, json_object_new_int64);
|
||||
SERIALIZE_TEAM_FIELD(id, json_object_new_int64);
|
||||
SERIALIZE_TEAM_FIELD(structure, json_object_new_int64);
|
||||
SERIALIZE_TEAM_FIELD(style, json_object_new_int64);
|
||||
SERIALIZE_TEAM_FIELD(boost, json_object_new_int64);
|
||||
SERIALIZE_TEAM_FIELD(average_talent, json_object_new_double);
|
||||
SERIALIZE_TEAM_FIELD(luck, json_object_new_double);
|
||||
SERIALIZE_TEAM_FIELD_STRUCT(stadium, bygfoot_json_serialize_stadium);
|
||||
//SERIALIZE_TEAM_FIELD_STRUCT(players, bygfoot_json_serialize_players);
|
||||
SERIALIZE_TEAM_FIELD(first_team_sid, json_object_new_string);
|
||||
SERIALIZE_TEAM_FIELD(first_team_id, json_object_new_int64);
|
||||
SERIALIZE_TEAM_FIELD(reserve_level, json_object_new_int64);
|
||||
|
||||
return team_obj;
|
||||
}
|
||||
|
||||
static void
|
||||
serialize_team_pointers_callback(gpointer team, gpointer user_data)
|
||||
{
|
||||
gchar *fields[] = {
|
||||
"name",
|
||||
"id"
|
||||
};
|
||||
GHashTable *hash_table = fields_to_hash_table(fields);
|
||||
struct json_object *obj = (struct json_object*)user_data;
|
||||
json_object_array_add(obj, bygfoot_json_serialize_team((Team*)team, hash_table));
|
||||
}
|
||||
|
||||
struct json_object *
|
||||
bygfoot_json_serialize_team_ptrs(GPtrArray *team_ptrs, GHashTable *fields)
|
||||
{
|
||||
struct json_object *array_obj = json_object_new_array_ext(team_ptrs->len);
|
||||
|
||||
g_ptr_array_foreach(team_ptrs, serialize_team_pointers_callback, array_obj);
|
||||
|
||||
return array_obj;
|
||||
}
|
||||
|
||||
struct json_object *
|
||||
bygfoot_json_serialize_cup_round(const CupRound *round,
|
||||
GHashTable *fields)
|
||||
{
|
||||
struct json_object *cup_round_obj = json_object_new_object();
|
||||
|
||||
#define SERIALIZE_CUP_ROUND_FIELD(field, serialize_func) \
|
||||
SERIALIZE_OBJECT_FIELD_FILTER(cup_round_obj, round, field, serialize_func, fields);
|
||||
#define SERIALIZE_CUP_ROUND_FIELD_STRUCT(field, serialize_func) \
|
||||
SERIALIZE_OBJECT_FIELD_STRUCT(cup_round_obj, round, field, serialize_func, fields);
|
||||
|
||||
SERIALIZE_CUP_ROUND_FIELD(name, json_object_new_string);
|
||||
SERIALIZE_CUP_ROUND_FIELD(home_away, json_object_new_boolean);
|
||||
SERIALIZE_CUP_ROUND_FIELD(replay, json_object_new_int64);
|
||||
SERIALIZE_CUP_ROUND_FIELD(neutral, json_object_new_boolean);
|
||||
SERIALIZE_CUP_ROUND_FIELD(randomise_teams, json_object_new_boolean);
|
||||
SERIALIZE_CUP_ROUND_FIELD(round_robin_number_of_groups, json_object_new_int64);
|
||||
SERIALIZE_CUP_ROUND_FIELD(round_robin_number_of_advance, json_object_new_int64);
|
||||
SERIALIZE_CUP_ROUND_FIELD(round_robin_number_of_best_advance, json_object_new_int64);
|
||||
SERIALIZE_CUP_ROUND_FIELD(round_robins, json_object_new_int64);
|
||||
//SERIALIZE_CUP_ROUND_FIELD(rr_breaks, bygfoot_json_serialize_int_array);
|
||||
SERIALIZE_CUP_ROUND_FIELD(new_teams, json_object_new_int64);
|
||||
SERIALIZE_CUP_ROUND_FIELD(byes, json_object_new_int64);
|
||||
SERIALIZE_CUP_ROUND_FIELD(delay, json_object_new_int64);
|
||||
//SERIALIZE_CUP_ROUND_FIELD(two_match_weeks, bygfoot_json_serialize_int_int_array);
|
||||
SERIALIZE_CUP_ROUND_FIELD_STRUCT(team_ptrs, bygfoot_json_serialize_team_ptrs);
|
||||
//SERIALIZE_CUP_ROUND_FIELD(choose_teams, bygfoot_json_serialize_choose_teams);
|
||||
//SERIALIZE_CUP_ROUND_FIELD(tables, bygfoot_json_serialize_tables);
|
||||
//SERIALIZE_CUP_ROUND_FIELD(waits, bygfoot_json_seriialize_waits);
|
||||
|
||||
return cup_round_obj;
|
||||
}
|
||||
|
||||
struct json_object *
|
||||
bygfoot_json_serialize_cup_rounds(const GArray *rounds,
|
||||
GHashTable *fields)
|
||||
{
|
||||
struct json_object *rounds_array_obj =
|
||||
json_object_new_array_ext(rounds->len);
|
||||
gint i;
|
||||
for (i = 0; i < rounds->len; i++) {
|
||||
const CupRound *round = &g_array_index(rounds, CupRound, i);
|
||||
json_object_array_add(rounds_array_obj,
|
||||
bygfoot_json_serialize_cup_round(round, fields));
|
||||
}
|
||||
return rounds_array_obj;
|
||||
}
|
||||
|
||||
struct json_object *
|
||||
bygfoot_json_serialize_cup(const Cup *cup, GHashTable *fields)
|
||||
{
|
||||
struct json_object *cup_obj = json_object_new_object();
|
||||
|
||||
#define SERIALIZE_CUP_FIELD(field, serialize_func) \
|
||||
SERIALIZE_OBJECT_FIELD_FILTER(cup_obj, cup, field, serialize_func, fields);
|
||||
#define SERIALIZE_CUP_FIELD_STRUCT(field, serialize_func) \
|
||||
SERIALIZE_OBJECT_FIELD_STRUCT(cup_obj, cup, field, serialize_func, fields);
|
||||
|
||||
SERIALIZE_CUP_FIELD(name, json_object_new_string);
|
||||
SERIALIZE_CUP_FIELD(short_name, json_object_new_string);
|
||||
SERIALIZE_CUP_FIELD(symbol, json_object_new_string);
|
||||
SERIALIZE_CUP_FIELD(sid, json_object_new_string);
|
||||
SERIALIZE_CUP_FIELD(id, json_object_new_int64);
|
||||
SERIALIZE_CUP_FIELD(group, json_object_new_int64);
|
||||
SERIALIZE_CUP_FIELD(last_week, json_object_new_int64);
|
||||
SERIALIZE_CUP_FIELD(week_gap, json_object_new_int64);
|
||||
SERIALIZE_CUP_FIELD(add_week, json_object_new_int64);
|
||||
SERIALIZE_CUP_FIELD(yellow_red, json_object_new_int64);
|
||||
SERIALIZE_CUP_FIELD(talent_diff, json_object_new_double);
|
||||
SERIALIZE_CUP_FIELD(next_fixture_update_week, json_object_new_int64);
|
||||
SERIALIZE_CUP_FIELD(next_fixture_update_week_round, json_object_new_int64);
|
||||
SERIALIZE_CUP_FIELD(properties, serialize_gchar_array);
|
||||
SERIALIZE_CUP_FIELD_STRUCT(rounds, bygfoot_json_serialize_cup_rounds);
|
||||
// SERIALIZE_CUP_FIELD(bye
|
||||
SERIALIZE_CUP_FIELD_STRUCT(teams, bygfoot_json_serialize_team_ptrs);
|
||||
SERIALIZE_CUP_FIELD(team_names, serialize_gchar_array);
|
||||
// SERIALIZE_CUP_FIELD(fixtures,
|
||||
// SERIALIZE_CUP_FIELD(week_breaks
|
||||
// SERIALIZE_CUP_FIELD(skip_weeks_with
|
||||
return cup_obj;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef JSON_SERIALIZE_H
|
||||
#define JSON_SERIALIZE_H
|
||||
|
||||
#include "bygfoot.h"
|
||||
#include "cup_struct.h"
|
||||
#include "league_struct.h"
|
||||
#include "json_compat.h"
|
||||
|
||||
struct json_object *
|
||||
bygfoot_json_serialize_country_list(GPtrArray *country_list);
|
||||
|
||||
struct json_object *
|
||||
bygfoot_json_serialize_country(const Country *country);
|
||||
|
||||
struct json_object *
|
||||
bygfoot_json_serialize_league_array(const GArray *league_array);
|
||||
|
||||
struct json_object *
|
||||
bygfoot_json_serialize_league(const League *league);
|
||||
|
||||
struct json_object *
|
||||
bygfoot_json_serialize_team_ptrs(GPtrArray *team_ptrs,
|
||||
GHashTable *fields);
|
||||
|
||||
struct json_object *
|
||||
bygfoot_json_serialize_cup(const Cup *cup, GHashTable *fields);
|
||||
#endif
|
49
src/main.c
49
src/main.c
|
@ -38,6 +38,9 @@
|
|||
#include "file.h"
|
||||
#include "free.h"
|
||||
#include "job_struct.h"
|
||||
#ifdef ENABLE_JSON
|
||||
#include "json_interface.h"
|
||||
#endif
|
||||
#include "language.h"
|
||||
#include "lg_commentary.h"
|
||||
#include "live_game.h"
|
||||
|
@ -70,6 +73,39 @@
|
|||
(cl switch -l). */
|
||||
gboolean load_last_save;
|
||||
|
||||
/** Parse command line options used for selecting the frontend or backend to
|
||||
* use with bygfoot.
|
||||
*/
|
||||
static void
|
||||
main_parse_frontend_backend_cl_arguments(gint *argc, gchar ***argv, CommandLineArgs *args)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GOptionContext *context = NULL;
|
||||
GOptionEntry entries[] = {
|
||||
{ "json", 0, 0, G_OPTION_ARG_FILENAME, &args->json_filename,
|
||||
"JSON file containing commands to run. bygfoot will run the "
|
||||
"commands in this file and then exit", "FILE"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
if(argc == NULL || argv == NULL)
|
||||
return;
|
||||
|
||||
context = g_option_context_new(_("- a simple and addictive GTK2 football manager"));
|
||||
g_option_context_set_ignore_unknown_options(context, TRUE);
|
||||
g_option_context_add_main_entries(context, entries, GETTEXT_PACKAGE);
|
||||
g_option_context_add_group(context, gtk_get_option_group (FALSE));
|
||||
g_option_context_parse(context, argc, argv, &error);
|
||||
g_option_context_free(context);
|
||||
|
||||
if(error != NULL)
|
||||
{
|
||||
misc_print_error(&error, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Parse the command line arguments given by the user. */
|
||||
void
|
||||
main_parse_cl_arguments(gint *argc, gchar ***argv, Bygfoot *bygfoot)
|
||||
|
@ -411,6 +447,7 @@ main_init(gint *argc, gchar ***argv, Bygfoot *bygfoot)
|
|||
main (gint argc, gchar *argv[])
|
||||
{
|
||||
Bygfoot bygfoot;
|
||||
CommandLineArgs cl_args;
|
||||
#ifdef DEBUG
|
||||
printf("main\n");
|
||||
#endif
|
||||
|
@ -425,6 +462,18 @@ main (gint argc, gchar *argv[])
|
|||
dup2 (fd1, 1);
|
||||
int fd2 = open ("stderr.log", O_CREAT|O_WRONLY|O_TRUNC, 0666);
|
||||
dup2 (fd2, 2);
|
||||
#endif
|
||||
memset(&cl_args, 0, sizeof(cl_args));
|
||||
#ifdef ENABLE_JSON
|
||||
main_parse_frontend_backend_cl_arguments(&argc, &argv, &cl_args);
|
||||
|
||||
if (cl_args.json_filename) {
|
||||
bygfoot_init(&bygfoot, BYGFOOT_FRONTEND_CONSOLE);
|
||||
main_init(&argc, &argv, &bygfoot);
|
||||
file_check_home_dir_create_dirs();
|
||||
validate_country_files();
|
||||
return bygfoot_json_main(&bygfoot, &cl_args);
|
||||
}
|
||||
#endif
|
||||
bygfoot_init(&bygfoot, BYGFOOT_FRONTEND_GTK2);
|
||||
gtk_init (&argc, &argv);
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
|
||||
bygfoot_bin=$1
|
||||
bygfoot_bindir=`dirname $bygfoot_bin`
|
||||
|
||||
status=0
|
||||
countries=" \
|
||||
albania \
|
||||
andorra \
|
||||
armenia \
|
||||
austria \
|
||||
azerbaijan \
|
||||
belarus \
|
||||
belgium \
|
||||
bosnia_herzegovina \
|
||||
bulgaria \
|
||||
croatia \
|
||||
cyprus \
|
||||
czech \
|
||||
denmark \
|
||||
england \
|
||||
estonia \
|
||||
faroe_islands \
|
||||
finland \
|
||||
france \
|
||||
n_macedonia \
|
||||
georgia \
|
||||
germany \
|
||||
gibraltar \
|
||||
greece \
|
||||
hungary \
|
||||
iceland \
|
||||
ireland \
|
||||
israel \
|
||||
italy \
|
||||
kazakhstan \
|
||||
kosovo \
|
||||
latvia \
|
||||
liechtenstein \
|
||||
lithuania \
|
||||
luxembourg \
|
||||
malta \
|
||||
moldova \
|
||||
montenegro \
|
||||
n_ireland \
|
||||
netherlands \
|
||||
norway \
|
||||
poland \
|
||||
portugal \
|
||||
romania \
|
||||
russia \
|
||||
san_marino \
|
||||
scotland \
|
||||
serbia \
|
||||
slovakia \
|
||||
slovenia \
|
||||
spain \
|
||||
sweden \
|
||||
switzerland \
|
||||
turkey \
|
||||
ukraine \
|
||||
wales"
|
||||
|
||||
json_file=`mktemp`
|
||||
|
||||
pushd $bygfoot_bindir
|
||||
|
||||
for c in $countries; do
|
||||
cat <<EOF > $json_file
|
||||
{ 'commands' : [
|
||||
{ 'add_country' : { 'name' : '$c' }},
|
||||
{ 'start_bygfoot' : { }},
|
||||
{ 'simulate_games' : {'seasons' : 2 }},
|
||||
]}
|
||||
EOF
|
||||
|
||||
tmphome=`mktemp -d`
|
||||
if HOME=$tmphome ./bygfoot --random-seed=1 --json=$json_file; then
|
||||
echo "$c: PASS"
|
||||
else
|
||||
echo "$c: FAIL"
|
||||
status=1
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
exit $status
|
|
@ -0,0 +1,36 @@
|
|||
set -e
|
||||
|
||||
bygfoot_bin=$1
|
||||
bygfoot_bindir=`dirname $bygfoot_bin`
|
||||
|
||||
json_file=`mktemp`
|
||||
save_dir=`mktemp -d`
|
||||
|
||||
cat <<EOF > $json_file
|
||||
{ 'commands' : [
|
||||
{ 'add_country' : { 'name' : 'faroe_islands' }},
|
||||
{ 'start_bygfoot' : {}},
|
||||
{ 'simulate_games' : {'weeks' : 5}},
|
||||
{ 'save_bygfoot' : {'filename' : '$save_dir/save0.zip'}},
|
||||
{ 'load_bygfoot' : {'filename' : '$save_dir/save0.zip'}},
|
||||
{ 'save_bygfoot' : {'filename' : '$save_dir/save1.zip'}},
|
||||
{ 'simulate_games' : {'years' : 1}},
|
||||
]}
|
||||
EOF
|
||||
|
||||
echo $save_dir
|
||||
tmphome=`mktemp -d`
|
||||
pushd $bygfoot_bindir
|
||||
HOME=$tmphome ./bygfoot --random-seed=1 --json=$json_file
|
||||
|
||||
for f in save0 save1; do
|
||||
|
||||
mkdir -p $save_dir/$f
|
||||
unzip -q $save_dir/$f.zip -d $save_dir/$f
|
||||
sed -i "s/${f}___//g" $save_dir/$f/*
|
||||
for file in `ls $save_dir/$f`; do
|
||||
new_name=`echo $file | sed "s/${f}___//g"`
|
||||
mv $save_dir/$f/$file $save_dir/$f/$new_name
|
||||
done
|
||||
done
|
||||
diff -r $save_dir/save0 $save_dir/save1
|
Loading…
Reference in New Issue