/* --- Creating a user in a game --- */ static User * create_user (Game *game, const char *name, unsigned width, unsigned height) { User *user = dsk_malloc (sizeof (User)); Cell *cell; user->name = dsk_strdup (name); user->base.type = OBJECT_TYPE_USER; user->base.game = game; /* pick random unoccupied position */ teleport_object (&user->base); cell = game->cells + (user->base.x / CELL_SIZE) + (user->base.y / CELL_SIZE) * game->universe_width; add_object_to_game_list (&user->base); add_object_to_cell_list (&user->base); user->bullet_block = 0; user->bullet_x = user->bullet_y = 0; user->width = width; user->height = height; user->dead_count = 0; user->last_seen_time = dsk_dispatch_default ()->last_dispatch_secs; user->move_x = user->move_y = 0; user->last_update = (unsigned)(-1); return user; }
DskSslContext * dsk_ssl_context_new (DskSslContextOptions *options, DskError **error) { const SSL_METHOD *method = SSLv3_method (); SSL_CTX *ctx = SSL_CTX_new (method); DskSslContext *rv = dsk_object_new (&dsk_ssl_context_class); rv->ctx = ctx; if (options->password) { rv->password = dsk_strdup (options->password); SSL_CTX_set_default_passwd_cb (ctx, set_password_cb); SSL_CTX_set_default_passwd_cb_userdata (ctx, rv); } if (options->cert_filename) { if (SSL_CTX_use_certificate_file (ctx, options->cert_filename, SSL_FILETYPE_PEM) != 1) { dsk_set_error (error, "error using certificate file %s", options->cert_filename); dsk_object_unref (rv); return NULL; } } if (options->key_filename) { if (SSL_CTX_use_PrivateKey_file (ctx, options->key_filename, SSL_FILETYPE_PEM) != 1) { dsk_set_error (error, "error using key file %s", options->key_filename); dsk_object_unref (rv); return NULL; } } return rv; }
static Game * create_game (const char *name, unsigned width, unsigned height) { Game *game = dsk_malloc (sizeof (Game)); unsigned usize; unsigned i; game->name = dsk_strdup (name); game->next_game = all_games; all_games = game; game->universe_width = width; game->universe_height = height; usize = width * height; game->h_walls = generate_ones (usize); game->v_walls = generate_ones (usize); for (i = 0; i < N_OBJECT_TYPES; i++) game->objects[i] = NULL; game->generators = NULL; game->cells = dsk_malloc0 (sizeof (Cell) * width * height); game->latest_update = 0; game->wrap = DSK_TRUE; game->diag_bullets_bounce = DSK_TRUE; game->bullet_kills_player = DSK_TRUE; game->bullet_kills_generator = DSK_TRUE; game->pending_updates = NULL; /* Generate with Modified Kruskals Algorithm, see * http://en.wikipedia.org/wiki/Maze_generation_algorithm */ TmpWall *tmp_walls = dsk_malloc (sizeof (TmpWall) * usize * 2); TmpSetInfo *sets = dsk_malloc (sizeof (TmpSetInfo) * usize); /* connect the walls together in random order */ unsigned *scramble; scramble = dsk_malloc (sizeof (unsigned) * usize * 2); for (i = 0; i < usize * 2; i++) scramble[i] = i; for (i = 0; i < usize * 2; i++) swap_ints (scramble + random_int_range (usize * 2), scramble + random_int_range (usize * 2)); TmpWall *wall_list = NULL; for (i = 0; i < usize * 2; i++) { unsigned e = scramble[i]; unsigned h = e % 2; unsigned x = (e / 2) % width; unsigned y = e / (width * 2); if (!game->wrap) { if ((h && y == 0) || (!h && x == 0)) continue; } tmp_walls[e].prev = NULL; tmp_walls[e].next = wall_list; if (wall_list) wall_list->prev = tmp_walls + e; wall_list = tmp_walls + e; } for (i = 0; i < usize; i++) { sets[i].set_number = i; sets[i].next_in_set = sets + i; } while (wall_list != NULL) { /* Invariants: - the sets are in a ring by set number. - The wall_list only consists of walls that separate distinct sets. */ /* remove wall */ unsigned e = wall_list - tmp_walls; unsigned h = e % 2; unsigned x = (e / 2) % width; unsigned y = e / (width * 2); TmpSetInfo *si = sets + e / 2; TmpSetInfo *osi; if (h) { if (y == 0) osi = si + (height - 1) * width; else osi = si - width; game->h_walls[x + y * width] = 0; } else { if (x == 0) osi = si + width - 1; else osi = si - 1; game->v_walls[x + y * width] = 0; } dsk_assert (osi->set_number != si->set_number); TmpSetInfo *kring = osi->set_number < si->set_number ? osi : si; /* ring to keep */ TmpSetInfo *dring = osi->set_number < si->set_number ? si : osi; /* ring to change */ TmpSetInfo *dring_start = dring; /* combine sets (removing any walls that no longer separate different sets from the list of walls to remove) */ unsigned set = kring->set_number; do { unsigned x = (dring - sets) % width; unsigned y = (dring - sets) / width; int wall_idx; dring->set_number = set; #if 0 if (wall_list) { dsk_assert (wall_list->prev == NULL); TmpWall *t; for (t = wall_list; t; t = t->next) if (t->next) dsk_assert (t->next->prev == t); } #endif /* Maybe remove left wall from candidate set of walls. */ wall_idx = -1; if (x > 0 && (dring-1)->set_number == set) wall_idx = 2 * (x + y * width); else if (x == 0 && game->wrap && (dring+width-1)->set_number == set) wall_idx = 2 * (x + y * width); if (wall_idx >= 0) remove_tmp_wall (tmp_walls, wall_idx, &wall_list); /* Maybe remove right wall from candidate set of walls. */ wall_idx = -1; if (x < width - 1 && (dring+1)->set_number == set) wall_idx = 2 * ((x+1) + y * width); else if (x == width - 1 && game->wrap && (dring-width+1)->set_number == set) wall_idx = 2 * (0 + y * width); if (wall_idx >= 0) remove_tmp_wall (tmp_walls, wall_idx, &wall_list); /* Maybe remove top wall from candidate set of walls. */ wall_idx = -1; if (y > 0 && (dring-width)->set_number == dring->set_number) wall_idx = 2 * (x + y * width) + 1; else if (y == 0 && game->wrap && (dring+width*(height-1))->set_number == set) wall_idx = 2 * (x + y * width) + 1; if (wall_idx >= 0) remove_tmp_wall (tmp_walls, wall_idx, &wall_list); /* Maybe remove bottom wall from candidate set of walls. */ wall_idx = -1; if (y < height - 1 && (dring+width)->set_number == set) wall_idx = 2 * (x + (y+1) * width) + 1; else if (y == height - 1 && game->wrap && (dring-(height-1)*width)->set_number == set) wall_idx = 2 * (x + 0 * width) + 1; if (wall_idx >= 0) remove_tmp_wall (tmp_walls, wall_idx, &wall_list); dring = dring->next_in_set; } while (dring != dring_start); /* Merge the rings */ TmpSetInfo *old_dring_next = dring->next_in_set; dring->next_in_set = kring->next_in_set; kring->next_in_set = old_dring_next; } dsk_free (tmp_walls); dsk_free (sets); dsk_free (scramble); /* generate generators */ unsigned n_generators = 12 + rand () % 6; dsk_warning ("%u generators", n_generators); i = 0; while (i < n_generators) { unsigned idx = random_int_range (usize); Cell *cell = game->cells + idx; if (cell->generator == NULL) { cell->generator = dsk_malloc (sizeof (Generator)); cell->generator->game = game; cell->generator->x = (idx % width) * CELL_SIZE + CELL_SIZE/2; cell->generator->y = (idx / width) * CELL_SIZE + CELL_SIZE/2; dsk_warning ("created generator at %u,%u",cell->generator->x ,cell->generator->y); cell->generator->generator_prob = 0.01; cell->generator->next_in_game = game->generators; cell->generator->prev_in_game = NULL; if (game->generators) game->generators->prev_in_game = cell->generator; game->generators = cell->generator; i++; } } game->timer = dsk_main_add_timer_millis (update_period_msecs, (DskTimerFunc) game_update_timer_callback, game); return game; }
dsk_boolean dsk_client_stream_new (DskClientStreamOptions *options, DskClientStream **stream_out, DskOctetSink **sink_out, DskOctetSource **source_out, DskError **error) { DskClientStream *rv; dsk_boolean has_address = !ip_address_is_default (&options->address); /* check trivial usage considerations */ dsk_warn_if_fail (!(options->hostname != NULL && has_address), "ignoring ip-address because symbolic name given"); if (options->hostname != NULL || has_address) { if (options->port == 0) { dsk_set_error (error, "port must be non-zero for client (hostname is '%s')", options->hostname); return DSK_FALSE; } dsk_warn_if_fail (options->path == NULL, "cannot decide between tcp and local client"); } rv = dsk_object_new (&dsk_client_stream_class); rv->base_instance.sink = dsk_object_new (&dsk_client_stream_sink_class); rv->base_instance.source = dsk_object_new (&dsk_client_stream_source_class); rv->base_instance.sink->stream = dsk_object_ref (rv); rv->base_instance.source->stream = dsk_object_ref (rv); rv->reconnect_time_ms = -1; rv->idle_disconnect_time_ms = -1; rv->fd = -1; if (options->hostname != NULL) { if (dsk_hostname_looks_numeric (options->hostname)) rv->is_numeric_name = 1; rv->name = dsk_strdup (options->hostname); rv->port = options->port; } else if (has_address) { rv->is_numeric_name = 1; rv->name = dsk_ip_address_to_string (&options->address); rv->port = options->port; } else if (options->path != NULL) { rv->is_local_socket = 1; rv->name = dsk_strdup (options->path); } rv->idle_disconnect_time_ms = options->idle_disconnect_time; rv->reconnect_time_ms = options->reconnect_time; begin_connecting (rv); if (options->idle_disconnect_time >= 0) dsk_client_stream_set_max_idle_time (rv, options->idle_disconnect_time); if (options->reconnect_time >= 0) dsk_client_stream_set_reconnect_time (rv, options->reconnect_time); if (source_out) *source_out = rv->base_instance.source; else if (rv->base_instance.source) dsk_object_unref (rv->base_instance.source); if (sink_out) *sink_out = rv->base_instance.sink; else if (rv->base_instance.sink) dsk_object_unref (rv->base_instance.sink); if (stream_out) *stream_out = rv; else dsk_object_unref (rv); return DSK_TRUE; }