Batch Index du Forum
S’enregistrerRechercherFAQMembresGroupesConnexion
Répondre au sujet Page 1 sur 1
[C#] Serveur à la darkbox
Auteur Message
Répondre en citant
Message [C#] Serveur à la darkbox 
Salut !
Je suis en train de bosser sur MineBat, un jeu en batch, et pour cela, je souhaiterais dev ma propre commande externe. J'ai déjà fait une bonne partie du code, mais elle est lente.
Du coup, j'ai eu l'idée de reprendre le principe de serveur utilisé par Darkbox et SuperBox.
Je me suis donc penché sur le code de darkbox, le problème étant que je ne comprend rien (ou presque) au C Bannir

Du coup, si un âme charitable le veux bien, me faire un petit "tuto" détaillé sur la création d'un serveur tel que Darkbox en C#. (avec un lanceur de type call batch.bat | command)

-Aiixu (j'ai changé de pseudo mais la flemme de le changer sur le forum)




______________________________________________________
MineBat

Keep programming
Message Publicité 
PublicitéSupprimer les publicités ?


Répondre en citant
Message [C#] Serveur à la darkbox 
Salut !

Darkbox fonctionne avec un système de serveur par entrée console, maintenant, ça fonctionne comment ?

Bah pour expliquer ça, je vais m'appuyer sur le code de darkbox, mais je vais enlever l'entrée console, les arguments "classiques", les commandes "internes" et pleins d'autres trucs ce qui me donne :
Code:
[lang=c]
int main(int argc, char const *argv[])

  while (true) {
    darkbox_cmd cmd;

    if (parse_cmd(&cmd))
      {...}
  }
}

static bool parse_cmd(darkbox_cmd *command)
{
  char *str = command_buffer;

  read_string(str, MAX_COMMAND_SIZE);

  if (*str != '-' && *str != '/') {
    /* No command. */
    fputs(str, stdout);
    putchar(' ');

    if (strchr(str, '\n') != 0)
      /* do not break next line */
      return false;

    int c = 0;
    while (c != '\n' && c != EOF)
      putchar(c = getchar());

    if (c == EOF)
      exit(0);

    return false;
  }

  str++;

  /* use the count if specified in command */
  command->count = isdigit(*str)
      ? strtol(str, &str, 10) : 1;

  if (isalpha(*str)) {
    /* define literals */
    command->cmd = str;

    /* check literals */
    while (*str) {
      if (!isalpha(*str)) {
        fputs("Parsing error: Invalid litterals", stderr);
        return false;
      }
      str++;
    }
  } else {
    fputs("Parsing error: No command specified", stderr);
    return false;
  }

  return true;
}$

/* Read the next integer from stdin */
int read_int(void)
{
  char c;
  int pos = 0;

  /* skip beginning spaces */
  do
      c = getchar();
  while (isspace(c));

  while (!isspace(c) && pos < MAX_TEXT_LENGTH) {
    text_buffer[pos] = c;
    pos++;
    c = getchar();
  }

  text_buffer[pos++] = '\0';

  return strtol(text_buffer, NULL, 0);
}

/* Read the next argument from stdin */
static void read_string(char *buffer, const size_t max_length)
{
  char c;
  int pos = 0;

  /* skip beginning spaces */
  do
    c = getchar();
  while (isspace(c));

  /* quote mode */
  bool quote = c == '"';

  if (quote)
    /* skip quote chracter */
    c = getchar();

  char *end_chars = quote ? "\"" : " \n\r\t";

  while (!strchr(end_chars, c) && (pos < max_length) ) {
    if (c == '\\')
      /* skip escape chracter, the next chracter is not interpreted */
      c = getchar();

    buffer[pos] = c;
    pos++;

    c = getchar();
  }

  buffer[pos++] = '\0';
}
Donc du coup, on a la fonction main (qui est classique), parse_args, read_int et read_string.

parse_args se contente simplement de traiter les "commandes darkbox" en les lisant avec read_string en structure pour être ensuite interprété (en gros, ça utilise read_string pour faire des "commandes prêtes à être lancés")
read_int lit simplement un nombre par stdin, il est utilisé par exemple pour "-a 45" pour lire le 45.
read_string permet de lire une chaîne de caractère, le code de darkbox prend en compte l'échappement '\', les "chaînes de caractères avec et sans guillemets", en soit, c'est le plus intéressant comme il est possible avec read_string+Int.Parse en C# de remplacer (à quelques détails prêts) read_int.

Cependant, le C# n'est pas pareil que le C, et il y a quelques différences :
- les 'char *' (et char []) sont l'équivalent les strings en C# (ou alors des pointeurs unsafe en C# mais on évite)
- strchr équivaut à String.IndexOf (en C#)
- getchar a deux équivalents : Console.Read, Console.In.Read
- isspace équivaut à Char.IsWhiteSpace
- fputs/putchar : Console.Write
et peut-être d'autres, mais c'est l'essentiel

Sinon, non, je ne fais plus activement de C# pour le moment (je n'ai d'ailleurs pas d'IDE) donc je peux pas vraiment faire un code en C#.

Il est aussi possible de se baser sur ctcs_o (une réécriture en C de tcs_o (un darkbox-like)) comme base, plus court, mais plus complexe.
Code:
[lang=c]
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>

#include <windows.h>
#include <io.h>

#define STR_BUF_SIZE 1024

char str_buf[1024];
unsigned int ebx; /* HACK: read_str_'s ebx. */
int origin_x = 0, origin_y = 0;

char read_char_(void)
{
  int c = getchar();

  if (c == EOF)
    exit(0);

  return c;
}

void read_str_(void)
{
  int c = 0, str_mode = 0;

  /* Skip all spaces */
  while (isspace(c = read_char_())) {}

  if (c != '"') {
    ebx = 1; /* Offset in str_buf */
    str_mode = 1; /* Reading mode: space */
    str_buf[0] = c; /* NOTE: *str_buf = c; */
  } else {
    /* read_str_quote_ */
    ebx = 0; /* Offset is 0 */
    str_mode = 2; /* Reading mode: quote */
  }

  /* read_str_loop_ */
  while (true) {
    c = read_char_();

    if (c == '\\') {
      /* read_str_escape_ */
      /* Read next char (skip "\)" */
      c = read_char_();
    } else if (str_mode ? isspace(c) : (c == '"')) /* read_str_cmp_ */
      /* read_str_end_ */
      break;

    /* read_str_escape_end_ */
    if (ebx == STR_BUF_SIZE)
      break;

    str_buf[ebx] = c;
    ebx++;
  }

  /* read_str_end_ */
}

long read_number_(void)
{
  read_str_();

  /* Add '\0' to get a Null-terminated string. */
  str_buf[ebx] = '\0';

  return strtol(str_buf, NULL, 0);
}

/* Entry point. */
void _start(void)
{
  /* Get hOut */
  HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

  while (true) { /* loop_ */
    if (read_char_() != '-')
      continue;

    /* Get command char */
    switch (read_char_()) {
      case 'a': /* ascii_ */
        putchar(read_number_());
        break;

      case 'c': /* color_ */
        SetConsoleTextAttribute(hOut, read_number_());
        break;

      case 'd': /* disp_ */
        read_str_();

        write(1, str_buf, ebx);
        break;

      case 'n': /* new_line_ */
        putchar('\n');
        break;

      case 's': /* clear_ */
        /* Well */
        system("cls");
        break;

      case 'g':; /* goto_ */
        COORD p;
        p.X = origin_x + read_number_();
        p.Y = origin_y + read_number_();

        SetConsoleCursorPosition(hOut, p);
        break;

      case 'o': /* origin_ */
        origin_x = read_number_();
        origin_y = read_number_();
        break;

      case 'w': /* wait_ */
        Sleep(read_number_());
        break;

      case 'q': /* quit_ */
        exit(0);
        break;
    }
  }
}





______________________________________________________
Partager permet le savoir. Le savoir permet de partager de nouveau savoirs.
Répondre en citant
Message [C#] Serveur à la darkbox 
Ok, je vais essayer de faire un code et de le test mais a quoi correspond le
Code:
darkbox_cmd cmd
dans la fonction main et le
Code:
&cmd
en paramètre de
Code:
parse_cmd





______________________________________________________
MineBat

Keep programming
Message [C#] Serveur à la darkbox 


Montrer les messages depuis:
Répondre au sujet Page 1 sur 1
  



Index | créer un forum | Forum gratuit d’entraide | Annuaire des forums gratuits | Signaler une violation | Conditions générales d'utilisation
Copyright 2008 - 2016 // Batch