#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>
#include <string.h>
#include <ctype.h>

#define ERR -1
#define MAX 1024

SOCKET cb_sock;
WSADATA cb_ws;
hostent *cb_he;
struct sockaddr_in cb_a;

const char cb_hostname[] = "codersblock.net";
char cb_buff[MAX], cb_reply[MAX];
char cb_user[MAX] = {0}, cb_pass[MAX] = {0}, cb_game[MAX] = {0};
int cb_debug = 0;

char *cb_error(const char *msg) {
    fprintf(stderr, "%s\n", msg);
    return NULL;
}

int cb_urlencode(char *dest, const char *src) {
    /* urlencode all non-alphanumeric characters in the C-string 'src'
       store result in the C-string 'dest'
       return the length of the url encoded C-string
    */
    char *d;
    int i;
    for(i=0, d=dest; src[i]; i++) {
        if(isalnum((unsigned char)src[i])) *(d++) = src[i];
        else {
            sprintf(d, "%%%02X", src[i]);
            d += 3;
        }
    }   
    *d = 0;
    return d-dest;
}

int cb_init(int do_debug) {
    cb_debug = do_debug;
    if (WSAStartup(0x101, &cb_ws) == ERR) {
        cb_error("Could Not Create Socket");
        return 1;
    }
    return 0;
}

void cb_login(const char *tuser, const char *tpass, const char *tgame) {
    cb_urlencode(cb_user, tuser);
    cb_urlencode(cb_pass, tpass);
    cb_urlencode(cb_game, tgame);
}

char *cb_cmd(const char *cmd) {
    char *size, *msg;
    int status, len;
    char cpycmd[MAX];
    
    cb_sock = socket(AF_INET, SOCK_STREAM, 0);
    cb_he = gethostbyname(cb_hostname);
    if (!cb_he) return cb_error("Could Not Resolve Host Name");
    
    cb_a.sin_family = AF_INET;
    cb_a.sin_port = htons(80);
    cb_a.sin_addr.s_addr = *((unsigned long *)cb_he->h_addr);
    
    status = connect(cb_sock, (struct sockaddr *)&cb_a , sizeof(cb_a));
    if (status == ERR) return cb_error("Could Not Connect To Server");
    
    cb_urlencode(cpycmd, cmd);
    sprintf(cb_buff, "GET /arena/api.php?cmd=%s&name=%s&pass=%s&game=%s HTTP/1.1\r\nHost: %s\r\n\r\n", cpycmd, cb_user, cb_pass, cb_game, cb_hostname);
    
    if (cb_debug) printf("<<< %s\n-------------\n\n", cb_buff);
    
    status = send(cb_sock, cb_buff, strlen(cb_buff), 0);
    if (status == ERR) return cb_error("Could Not Request Web Page");
    
    status = recv(cb_sock, cb_buff, sizeof(cb_buff), 0);
    if (status == ERR) return cb_error("Could Not Receive Web Page");
  
    if (cb_debug) printf(">>> %s\n-------------\n\n", cb_buff);
      
    size = strstr(cb_buff, "MSG: ");
    if (!size) return cb_error("Malformed Server Response ID: 1");
    size += 5;
    
    msg = strchr(size, ' ');
    if (!msg) return cb_error("Malformed Server Response ID: 2");
    *msg = 0;
    
    len = atoi(size);
    memcpy(cb_reply, msg+1, len);
    cb_reply[len] = 0;
    
    return cb_reply;
}

int cb_cleanup() {
    return WSACleanup() == ERR;
}
