/* FIXME: Provide real queue */ static void net_internal_queueadd(const char *player, const char *message, int type, int playertype) { Guru *guru; char *listtoken; char *token; int i; char realmessage[1024]; /* Add dummy field on dummy messages */ if((message) && (type == GURU_PRIVMSG)) { snprintf(realmessage, sizeof(realmessage), "%s %s", guruname, message); message = realmessage; } /* Insert new grubby structure */ guru = (Guru*)ggz_malloc(sizeof(Guru)); guru->type = type; if(player) guru->player = ggz_strdup(player); else guru->player = NULL; guru->playertype = playertype; if(message) { guru->message = ggz_strdup(message); guru->list = NULL; listtoken = ggz_strdup(message); token = strtok(listtoken, " ,./:?!\'"); i = 0; while(token) { guru->list = (char**)ggz_realloc(guru->list, (i + 2) * sizeof(char*)); guru->list[i] = (char*)ggz_malloc(strlen(token) + 1); strcpy(guru->list[i], token); guru->list[i + 1] = NULL; i++; token = strtok(NULL, " ,./:?!\'"); } ggz_free(listtoken); } else { guru->message = NULL; guru->list = NULL; } /* Recognize direct speech */ if((guru->type == GURU_CHAT) && (guru->list) && (guru->list[0])) if(!strcasecmp(guru->list[0], guruname)) guru->type = GURU_DIRECT; /* Insert structure into queue */ queuelen++; queue = (Guru**)ggz_realloc(queue, sizeof(Guru*) * queuelen); queue[queuelen - 2] = guru; queue[queuelen - 1] = NULL; }
static int _io_read_rankings(GGZMod *ggzmod) { int i, num; char *name; int position, score; GGZList *rankings; if (ggz_read_int(ggzmod->fd, &num) < 0) return -1; rankings = ggz_list_create(NULL, NULL, (ggzEntryDestroy)rankings_free, GGZ_LIST_ALLOW_DUPS); for (i = 0; i < num; i++) { if (ggz_read_string_alloc(ggzmod->fd, &name) < 0 || ggz_read_int(ggzmod->fd, &position) < 0 || ggz_read_int(ggzmod->fd, &score) < 0) { return -1; } GGZRanking *rank = (GGZRanking*)ggz_malloc(sizeof(GGZRanking)); rank->position = position; rank->score = score; rank->name = name; ggz_list_insert(rankings, rank); } _ggzmod_handle_rankings(ggzmod, rankings); ggz_list_free(rankings); return 0; }
static int _io_read_info(GGZMod *ggzmod) { int i, num; int seat_num; char *realname, *photo, *host; GGZList *infos; if (ggz_read_int(ggzmod->fd, &num) < 0) return -1; infos = ggz_list_create(NULL, NULL, (ggzEntryDestroy)infos_free, GGZ_LIST_ALLOW_DUPS); for (i = 0; i < num; i++) { if (ggz_read_int(ggzmod->fd, &seat_num) < 0 || ggz_read_string_alloc_null(ggzmod->fd, &realname) < 0 || ggz_read_string_alloc_null(ggzmod->fd, &photo) < 0 || ggz_read_string_alloc_null(ggzmod->fd, &host) < 0) { return -1; } GGZPlayerInfo *info = (GGZPlayerInfo*)ggz_malloc(sizeof(GGZPlayerInfo)); info->realname = realname; info->photo = photo; info->host = host; info->num = seat_num; ggz_list_insert(infos, info); } _ggzmod_handle_info(ggzmod, infos); ggz_list_free(infos); return 0; }
static void put_global_message(char *mark, char *msg) { global_message_list_t *gml; ggz_debug(DBG_MISC, "Setting global message for '%s'. Length is %zd.", mark, strlen(msg)); if (!mark || !msg) ggz_error_msg("put_global_message called on NULL string."); for (gml = game.message_head; gml != NULL; gml = gml->next) { if (!strcmp(mark, gml->mark)) { ggz_free(gml->message); gml->message = ggz_strdup(msg); return; } } gml = ggz_malloc(sizeof(global_message_list_t)); gml->mark = ggz_strdup(mark); gml->message = ggz_strdup(msg); if (game.message_tail) game.message_tail->next = gml; game.message_tail = gml; if (!game.message_head) game.message_head = gml; }
GGZServer *_ggzcore_server_new(void) { GGZServer *server; server = ggz_malloc(sizeof(*server)); _ggzcore_server_reset(server); return server; }
void _ggzcore_server_init_roomlist(GGZServer * server, const int num) { int i; server->num_rooms = num; server->rooms = ggz_malloc(num * sizeof(*server->rooms)); for (i = 0; i < num; i++) server->rooms[i] = NULL; }
void send_last_hand(void) { int *lengths = ggz_malloc(game.num_seats * sizeof(*lengths)); card_t **cardlist = ggz_malloc(game.num_seats * sizeof(*cardlist)); hand_t *hand; seat_t s; for (s = 0; s < game.num_seats; s++) { hand = &game.seats[s].hand; hand->hand_size = hand->full_hand_size; cards_sort_hand(hand); lengths[s] = hand->full_hand_size; cardlist[s] = hand->cards; } net_broadcast_global_cardlist_message("Previous Hand", lengths, cardlist); ggz_free(lengths); ggz_free(cardlist); }
void send_last_trick(void) { int *lengths = ggz_malloc(game.num_seats * sizeof(*lengths)); card_t **cardlist = ggz_malloc(game.num_seats * sizeof(*cardlist)); card_t *cardlist2 = ggz_malloc(game.num_seats * sizeof(*cardlist2)); seat_t s; for (s = 0; s < game.num_seats; s++) { if (game.seats[s].player >= 0) { lengths[s] = 1; cardlist[s] = &cardlist2[s]; cardlist[s][0] = game.seats[s].table; } else lengths[s] = 0; } net_broadcast_global_cardlist_message("Last Trick", lengths, cardlist); ggz_free(lengths); ggz_free(cardlist); ggz_free(cardlist2); }
GtkWidget *create_chat_widget(void) { GtkWidget *vbox, *text, *inputline; ChatWidgets *list; GtkWidget *sw; vbox = gtk_vbox_new(FALSE, 0); /* Create a scrolled window for the chat lines. */ sw = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); gtk_widget_set_size_request(sw, -1, 50); /* The chatlines themselves go into a text window. */ text = gtk_text_view_new(); gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(text), FALSE); gtk_container_add(GTK_CONTAINER(sw), text); gtk_widget_set_name(text, "chatline"); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD); gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text), 5); /* Text entry widget. */ inputline = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(vbox), inputline, FALSE, FALSE, 3); gtk_widget_show_all(vbox); list = ggz_malloc(sizeof(*list)); list->next = chats; list->container = vbox; list->text = text; chats = list; g_signal_connect(inputline, "activate", G_CALLBACK(inputline_return), NULL); g_signal_connect(vbox, "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &list->container); return vbox; }
static void bridge_init_game(void) { seat_t s; game.specific = ggz_malloc(sizeof(bridge_game_t)); set_num_seats(4); set_num_teams(2); for (s = 0; s < game.num_seats; s++) { assign_seat(s, s); /* one player per seat */ assign_team(s % 2, s); } game.cumulative_scores = 0; /* TODO: for now we won't use bridge scoring */ BRIDGE.declarer = -1; }
void server_profiles_load(void) { guint i, count; char** profiles; Server* server; /* Clear any previous list */ if (servers) { g_list_foreach(servers, server_free_node, NULL); g_list_free(servers); servers = NULL; } /* Clear list of deleted servers */ if (deleted) { g_list_foreach(deleted, server_free_node, NULL); g_list_free(deleted); deleted = NULL; } ggzcore_conf_read_list("Servers", "ProfileList", (int*)&count, &profiles); for (i = 0; i < count; i++) { server = ggz_malloc(sizeof(Server)); server->name = profiles[i]; server->host = ggzcore_conf_read_string(server->name, "Host", NULL); server->port = ggzcore_conf_read_int(server->name, "Port", 5688); server->type = ggzcore_conf_read_int(server->name, "Type", GGZ_LOGIN_GUEST); server->login = ggzcore_conf_read_string(server->name, "Login", NULL); if (server->type == GGZ_LOGIN) server->password = ggzcore_conf_read_string(server->name, "Password", NULL); server_list_add(server); } server_list_print(); if (profiles) ggz_free(profiles); }
GGZPlayer *_ggzcore_player_new(void) { GGZPlayer *player; player = ggz_malloc(sizeof(GGZPlayer)); /* Set to invalid table */ player->table = -1; player->perms = 0; /* Assume no lag */ player->lag = -1; player->wins = NO_RECORD; player->losses = NO_RECORD; player->ties = NO_RECORD; player->forfeits = NO_RECORD; player->rating = NO_RATING; player->ranking = NO_RANKING; player->highscore = NO_HIGHSCORE; return player; }
int map_save(combat_game * map) { unsigned int hash; char filename[128]; char options[20]; char *map_data; int handle, a; hash = _generate_hash((char*)combat_options_string_write(map, 1)); snprintf(filename, sizeof(filename), "%s/%s.%u", GLOBAL_MAPS, map->name, hash); handle = ggz_conf_parse(filename, GGZ_CONF_RDWR | GGZ_CONF_CREATE); if (handle < 0) { snprintf(filename, sizeof(filename), "%s/.ggz/combat/maps/%s.%u", getenv("HOME"), map->name, hash); handle = ggz_conf_parse(filename, GGZ_CONF_RDWR | GGZ_CONF_CREATE); if (handle < 0) { snprintf(filename, sizeof(filename), "%s/.ggz", getenv("HOME")); mkdir(filename, S_IRWXU | S_IRGRP | S_IXGRP); snprintf(filename, sizeof(filename), "%s/.ggz/combat", getenv("HOME")); mkdir(filename, S_IRWXU | S_IRGRP | S_IXGRP); snprintf(filename, sizeof(filename), "%s/.ggz/combat/maps", getenv("HOME")); mkdir(filename, S_IRWXU | S_IRGRP | S_IXGRP); snprintf(filename, sizeof(filename), "%s/.ggz/combat/maps/%s.%u", getenv("HOME"), map->name, hash); handle = ggz_conf_parse(filename, GGZ_CONF_RDWR | GGZ_CONF_CREATE); if (handle < 0) { // Give up game_message ("I couldn't write the map to disk"); return -1; } } } // Width/height ggz_conf_write_int(handle, "map", "width", map->width); ggz_conf_write_int(handle, "map", "height", map->height); // Army data for (a = 0; a < 12; a++) ggz_conf_write_int(handle, "army", file_unit_name[a], map->army[map->number][a]); // Map data map_data = (char *)ggz_malloc(map->width * map->height + 1); for (a = 0; a < map->width * map->height; a++) { if (GET_OWNER(map->map[a].type) >= 0) { // Intial position! map_data[a] = GET_OWNER(map->map[a].type) + 49; } else { // Get's terrain switch (LAST(map->map[a].type)) { case T_OPEN: map_data[a] = 'O'; break; case T_NULL: map_data[a] = 'N'; break; case T_LAKE: map_data[a] = 'L'; break; } } } map_data[map->width * map->height] = 0; ggz_conf_write_string(handle, "map", "data", map_data); // Options snprintf(options, sizeof(filename), "%lX", map->options); ggz_conf_write_string(handle, "options", "bin1", options); ggz_conf_commit(handle); return 0; }
void map_load(combat_game * _game, char *filename, gboolean *changed) { int handle; unsigned int hash; char hash_str[32]; char *new_filename; char *options; int a, b; char *terrain_data; if (changed) *changed = FALSE; handle = ggz_conf_parse(filename, GGZ_CONF_RDONLY); if (handle < 0) { fprintf(stderr, "Couldn't load map %s.\n", filename); assert(0); return; } /* Get the data from the file */ // Width / Height _game->width = ggz_conf_read_int(handle, "map", "width", 10); _game->height = ggz_conf_read_int(handle, "map", "height", 10); for (a = 0; a < 12; a++) { ARMY(_game, a) = ggz_conf_read_int(handle, "army", file_unit_name[a], 0); } // Terrain data terrain_data = ggz_conf_read_string(handle, "map", "data", NULL); _game->map = (tile *) ggz_malloc(_game->width * _game->height * sizeof(tile)); if (terrain_data) { a = strlen(terrain_data); while (--a >= 0) { switch (terrain_data[a]) { case 'O': _game->map[a].type = T_OPEN; break; case 'L': _game->map[a].type = T_LAKE; break; case 'N': _game->map[a].type = T_NULL; break; case '1': _game->map[a].type = OWNER(0) + T_OPEN; break; case '2': _game->map[a].type = OWNER(1) + T_OPEN; break; default: _game->map[a].type = T_OPEN; break; } } } // Options options = ggz_conf_read_string(handle, "options", "bin1", NULL); if (options) sscanf(options, "%lx", &_game->options); a = strlen(filename) - 1; while (a >= 0 && filename[a] != '/') a--; b = a + 1; while (b < strlen(filename) && filename[b] != '.') b++; _game->name = (char *)ggz_malloc(b - a); strncpy(_game->name, filename + a + 1, b - a - 1); _game->name[b - a - 1] = 0; // Well, now that we have loaded the map, let's check it's hash! hash = _generate_hash((char*)combat_options_string_write(_game, 1)); snprintf(hash_str, sizeof(hash_str), ".%u", hash); if (strstr(filename, hash_str) == NULL) { // Hash don't match!! ggz_error_msg ("Filename for map %s should be %s.%u, and not %s", _game->name, _game->name, hash, filename); // Let's rename it! new_filename = (char *)ggz_malloc(strlen(filename) + strlen(hash_str) + 14); for (a = strlen(filename); a >= 0; a--) { if (filename[a] == '.') break; } strncpy(new_filename, filename, a); new_filename[a] = 0; strcat(new_filename, hash_str); if (rename(filename, new_filename) != 0) { /* I have no idea why != 0 is used as the comparison here. It seems quite wrong. */ if (changed) *changed = TRUE; } }; }
void _ggzcore_server_init_typelist(GGZServer * server, const int num) { server->num_gametypes = num; server->gametypes = ggz_malloc(num * sizeof(*server->gametypes)); }
static GGZModule *pick_module(GGZGameType * gt) { const char *name = ggzcore_gametype_get_name(gt); const char *engine = ggzcore_gametype_get_prot_engine(gt); const char *version = ggzcore_gametype_get_prot_version(gt); int i, j, preserve; GGZModule *module; GGZModule **frontends; int *modulenumbers; char *preferred; int num; GGZModuleEnvironment env; /* Check (again) how many modules are registered for this game type */ ggzcore_reload(); num = ggzcore_module_get_num_by_type(name, engine, version); if (num == 0) { return NULL; } /* If there's only one choice, use it regardless of frontend */ if (num == 1) return ggzcore_module_get_nth_by_type(name, engine, version, 0); /* See if the user has a listed preference. */ preferred = ggzcore_conf_read_string("GAME", name, NULL); if (preferred) { for (i = 0; i < num; i++) { const char *frontend; module = ggzcore_module_get_nth_by_type(name, engine, version, i); frontend = ggzcore_module_get_frontend(module); if (strcasecmp(preferred, frontend) == 0) { ggz_debug("modules", "User preferred %s frontend for %s", frontend, name); return module; } } } /* More than one frontend: pop up a window and let the player choose. */ frontends = ggz_malloc((num + 1) * sizeof(*frontends)); modulenumbers = ggz_malloc((num + 1) * sizeof(int)); j = 0; for (i = 0; i < num; i++) { module = ggzcore_module_get_nth_by_type(name, engine, version, i); env = ggzcore_module_get_environment(module); if ((env == GGZ_ENVIRONMENT_XWINDOW) || (env == GGZ_ENVIRONMENT_XFULLSCREEN)) { frontends[j] = module; modulenumbers[j] = i; j++; } } frontends[j] = NULL; i = ask_user_to_pick_module(frontends, modulenumbers, &preserve); if (i < 0) return NULL; module = ggzcore_module_get_nth_by_type(name, engine, version, i); ggz_free(frontends); ggz_free(modulenumbers); if (preserve) { const char *frontend = ggzcore_module_get_frontend(module); ggzcore_conf_write_string("GAME", name, frontend); ggzcore_conf_commit(); } return module; }
/* Switch on a filedescriptor */ int ggz_tls_enable_fd(int fd, GGZTLSType mode, GGZTLSVerificationType verify) { int ret, ret2; STACK_OF(SSL_CIPHER) *stack; SSL_CIPHER *cipher; int bits; char *cipherlist; SSL *_tls; int _tls_active; struct list_entry *entry; _state = 1; _tls_active = 0; if((mode != GGZ_TLS_CLIENT) && (mode != GGZ_TLS_SERVER)) { TLSERROR("Wrong mode."); return 0; } if(!_tlsctx) tls_init(verify); _tls = SSL_new(_tlsctx); if(_tls) { cipherlist = NULL; stack = SSL_get_ciphers(_tls); while((cipher = (SSL_CIPHER*)sk_pop(stack)) != NULL) { printf("* Cipher: %s\n", SSL_CIPHER_get_name(cipher)); printf(" Bits: %i\n", SSL_CIPHER_get_bits(cipher, &bits)); printf(" Used bits: %i\n", bits); printf(" Version: %s\n", SSL_CIPHER_get_version(cipher)); printf(" Description: %s\n", SSL_CIPHER_description(cipher, NULL, 0)); if(cipherlist) { cipherlist = (char*)realloc(cipherlist, (strlen(cipherlist) + 1) + strlen(SSL_CIPHER_get_name(cipher)) + 1); strcat(cipherlist, ":"); strcat(cipherlist, SSL_CIPHER_get_name(cipher)); } else { cipherlist = (char*)malloc(strlen(SSL_CIPHER_get_name(cipher)) + 1); strcpy(cipherlist, SSL_CIPHER_get_name(cipher)); } } printf("Available ciphers: %s\n", cipherlist); ret = SSL_set_cipher_list(_tls, cipherlist); if(!ret) TLSERROR("Cipher selection failed."); ret = SSL_set_fd(_tls, fd); if(!ret) TLSERROR("Assignment to connection failed."); else { SSL_set_read_ahead(_tls, 1); if(mode == GGZ_TLS_SERVER) { tls_certkey(_tls); if(_state) { SSL_set_accept_state(_tls); ret = SSL_accept(_tls); } } else { SSL_set_connect_state(_tls); ret = SSL_connect(_tls); } if((ret != 1) || (!_state)) { printf("Ret: %i, State: %i\n", ret, _state); TLSERROR("Handshake failed."); ret2 = ERR_get_error(); printf("EXT: %s\n%s\n%s\n%s\n%s\n", tls_exterror(_tls, ret), ERR_error_string(ret2, NULL), ERR_lib_error_string(ret2), ERR_func_error_string(ret2), ERR_reason_error_string(ret2)); } else { printf(">>>>> Handshake successful.\n"); if((mode == GGZ_TLS_SERVER) || (verify == GGZ_TLS_VERIFY_NONE)) _tls_active = 1; else { printf(">>>>> Client side, thus checking Certificate.\n"); printf("Negotiated cipher: %s\n", SSL_get_cipher(_tls)); printf("Shared ciphers: %s\n", SSL_get_shared_ciphers(_tls, NULL, 0)); if(SSL_get_peer_certificate(_tls)) { if(SSL_get_verify_result(_tls) == X509_V_OK) { _tls_active = 1; } else { printf("Error code: %li\n", SSL_get_verify_result(_tls)); TLSERROR("Invalid certificate, or certificate is not self-signed."); } } else TLSERROR("Couldn't get certificate."); } } entry = (struct list_entry*)ggz_malloc(sizeof(struct list_entry)); entry->tls = _tls; entry->fd = fd; entry->active = _tls_active; ggz_list_insert(openssllist, entry); return 1; } } return 0; }