Example #1
0
/* --- 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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}