legend/
legend/area/
legend/player/
/* Copyright (c) 2005 Mackenzie Straight           <eiz@codealchemy.org> */
/* Use of this software for any purpose is allowed, provided this notice */
/* is preserved. It is provided as-is. If it breaks, you get to keep     */
/* both pieces.                                                          */

#ifndef _OPAS_H
#define _OPAS_H
#include <netinet/in.h>

#define BIT(x) (1 << x)
#define BUF_SIZE 1024
#define OPAS_VERSION (1 << 24)

#define min(x,y) ((x) < (y) ? (x) : (y))
#define max(x,y) ((x) > (y) ? (x) : (y))
#define clamp(x, lo, hi) max(lo, min(hi, x))

typedef struct opas_header opas_header_t;
typedef struct opas_request4 opas_request4_t;
typedef struct opas_reply_proxy opas_reply_proxy_t;
typedef struct opas_client opas_client_t;

typedef void dispatch_func(opas_client_t *, opas_header_t *);
struct opas_header {
    uint32_t bits;
};

struct opas_request4 {
    opas_header_t header;
    uint32_t user_data;
    struct in_addr ipaddr;
};

struct opas_reply_proxy {
    opas_header_t header;
    uint32_t user_data;
    struct in_addr ipaddr;
    int timestamp;
    short type;
    short port;
    char msg[1];
};

typedef enum {
    opas_state_header,
    opas_state_packet
} opas_state_t;

typedef enum {
    opas_packet_reply_neg,
    opas_packet_reply_proxy,
    opas_packet_error,
    opas_invalid_packet
} opas_packet_type_t;

struct opas_client {
    int sock;
    char inbuf[BUF_SIZE];
    int in_len;

    opas_state_t state;
    uint32_t st_len;
    uint32_t st_hdr;

    dispatch_func *dispatch;
} opas_client;


opas_client_t *opas_open(char *server, int port);
void opas_send_req4(opas_client_t *client, uint32_t user_data, struct in_addr ipaddr);
void opas_send_ping(opas_client_t *client);
void opas_set_dispatch(opas_client_t *client, dispatch_func func);
int opas_wait(opas_client_t *client);
int opas_dispatch(opas_client_t *client);
int opas_packet_length (opas_header_t *packet);
opas_packet_type_t opas_packet_type(opas_header_t *packet);

#endif /* _OPAS_H */