NickG

Untitled

Feb 26th, 2014
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.98 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <time.h>
  6. #include <uv.h>
  7. #include "mcp.h"
  8.  
  9. typedef struct {
  10.     uint8_t *base;
  11.     uint8_t *cur;
  12.     size_t len;
  13.     size_t used;
  14.     size_t rem;
  15. } client_buf_t;
  16.  
  17. typedef struct {
  18.     int state;
  19.     client_buf_t client_buf;
  20.     int32_t read_len;
  21.     uv_tcp_t tcp;
  22.     uv_connect_t connect_req;
  23.     uv_shutdown_t shutdown_req;
  24. } client_t;
  25.  
  26. static mcp_hs00_t handshake = {
  27.     .protocol_version = 4,
  28.     .addr_len         = sizeof("127.0.0.1")-1,
  29.     .server_addr      = "127.0.0.1",
  30.     .server_port      = 25565,
  31.     .next_state       = 1
  32. };
  33.  
  34. static mcp_ss00_t ping_req;
  35.  
  36. client_t* client_init(client_t *client, uint8_t *buf, size_t len) {
  37.     client->state = 0;
  38.     client->client_buf.base = buf;
  39.     client->client_buf.cur = buf;
  40.     client->client_buf.len = len;
  41.     client->client_buf.used = 0;
  42.     client->client_buf.rem = 0;
  43.     client->read_len = -1;
  44.     client->tcp.data = client;
  45.     return client;
  46. }
  47.  
  48. void buf_alloc(uv_handle_t *tcp, size_t size, uv_buf_t *buf) {
  49.     client_t *client = (client_t*)tcp->data;
  50.     client_buf_t *client_buf = &client->client_buf;
  51.     if(
  52.         (size > client_buf->len - client_buf->used) &&
  53.         (size <= client_buf->len - client_buf->rem)
  54.     ) {
  55.         memmove(client_buf->base, client_buf->cur, client_buf->rem);
  56.         client_buf->cur = client_buf->base;
  57.         client_buf->used = client_buf->rem;
  58.     } else if(size > client_buf->len - client_buf->rem) {
  59.         size_t s = ((size + client_buf->rem)/client_buf->len)+1;
  60.         s = s*client_buf->len;
  61.         uint8_t *c = memcpy(malloc(s), client_buf->cur, client_buf->rem);
  62.         free(client_buf->base);
  63.         client_buf->base = c;
  64.         client_buf->cur = c;
  65.         client_buf->len = s;
  66.     }
  67.  
  68.     *buf = uv_buf_init(
  69.         (char*)client_buf->base + client_buf->used,
  70.         client_buf->len - client_buf->used
  71.     );
  72. }
  73.  
  74. void client_close_cb(uv_handle_t* handle) {
  75.     client_t *client = (client_t*)handle->data;
  76.     client_buf_t *client_buf = &client->client_buf;
  77.     free(client_buf->base);
  78.     free(client);
  79. }
  80.  
  81. void client_write_cb(uv_write_t *req, int status) {
  82.     free(req->data);
  83.     free(req);
  84. }
  85.  
  86. void client_read_cb(uv_stream_t *tcp, ssize_t nread, const uv_buf_t *buf) {
  87.     client_t *client = (client_t*)tcp->data;
  88.     client_buf_t *client_buf = &client->client_buf;
  89.     int ret;
  90.  
  91.     if(nread<0) {
  92.         uv_close((uv_handle_t*)tcp, client_close_cb);
  93.         return;
  94.     } else if(nread == 0) {
  95.         return;
  96.     }
  97.  
  98.     client_buf->used += nread;
  99.     client_buf->rem  += nread;
  100.  
  101.     for(;;) {
  102.         if(client->read_len < 0) {
  103.             ret = mcp_decode_varint(
  104.                 &client->read_len,
  105.                 client_buf->cur,
  106.                 client_buf->rem
  107.             );
  108.             if(ret < 0) {
  109.                 client->read_len = -1;
  110.                 break;
  111.             }
  112.             client_buf->cur += ret;
  113.             client_buf->rem -= ret;
  114.         }
  115.         if(client_buf->rem < client->read_len) {
  116.             break;
  117.         }
  118.    
  119.         int32_t packet_id;
  120.         ret = mcp_decode_varint(
  121.             &packet_id,
  122.             client_buf->cur,
  123.             client_buf->rem
  124.         );
  125.         client_buf->cur += ret;
  126.         client_buf->rem -= ret;
  127.         switch(client->state) {
  128.             case 0x02: switch(packet_id) {
  129.                 case 0x00: ;
  130.                     mcp_sc00_t psc00;
  131.                     ret = mcp_decode_sc00(&psc00, client_buf->cur, client_buf->rem);
  132.                     fwrite(psc00.resp, sizeof(char), psc00.resp_len, stdout);
  133.                     printf("\n");
  134.                    
  135.                     break;
  136.                 case 0x01: ;
  137.                     mcp_sc01_t psc01;
  138.                     ret = mcp_decode_sc01(&psc01, client_buf->cur, client_buf->rem);
  139.                     printf("Ping Time: %d\n", psc01.ping_time);
  140.                     break;
  141.                 default:
  142.                     printf("%s\n", "Entered P default, something is wrong");
  143.                     ret = 0;
  144.                     break;
  145.             } break;
  146.  
  147.             default:
  148.                 printf("%s\n", "Entered S default, something is wrong");
  149.                 break;
  150.         }
  151.         client_buf->cur += ret;
  152.         client_buf->rem -= ret;
  153.     }
  154. }
  155.  
  156. void client_write_handshake(client_t *client) {
  157.     uv_write_t *req;
  158.     uv_buf_t buf;
  159.     uint8_t pbuf[4096];
  160.     int ret = mcp_encode_hs00(pbuf, &handshake, 4096);
  161.     buf = uv_buf_init(memcpy(malloc(ret), pbuf, ret), ret);
  162.     req = malloc(sizeof(*req));
  163.     req->data = buf.base;
  164.     client->state = 0x02;
  165.     uv_write(req, (uv_stream_t*)&client->tcp, &buf, 1, client_write_cb);
  166. }
  167.  
  168. void client_write_pingreq(client_t *client) {
  169.     uv_write_t *req;
  170.     uv_buf_t buf;
  171.     uint8_t pbuf[4096];
  172.     int ret = mcp_encode_ss00(pbuf, &ping_req, 4096);
  173.     buf = uv_buf_init(memcpy(malloc(ret), pbuf, ret), ret);
  174.     req = malloc(sizeof(*req));
  175.     req->data = buf.base;
  176.     uv_write(req, (uv_stream_t*)&client->tcp, &buf, 1, client_write_cb);
  177. }
  178.  
  179. void client_connect_cb(uv_connect_t *req, int status) {
  180.     client_t *client = (client_t*)req->handle->data;
  181.     client_write_handshake(client);
  182.     client_write_pingreq(client);
  183.     uv_read_start(req->handle, buf_alloc, client_read_cb);
  184. }
  185.  
  186. int main(int argc, char *argv[]) {
  187.     struct sockaddr_in server_addr;
  188.     uv_loop_t *loop = uv_default_loop();
  189.     client_t *myclient = malloc(sizeof(*myclient));
  190.     client_init(myclient, malloc(4096), 4096);
  191.     uv_ip4_addr("127.0.0.1", 25565, &server_addr);
  192.     uv_tcp_init(loop, &myclient->tcp);
  193.     uv_tcp_connect(
  194.         &myclient->connect_req,
  195.         &myclient->tcp,
  196.         (struct sockaddr*)&server_addr,
  197.         client_connect_cb
  198.     );
  199.     return uv_run(loop, UV_RUN_DEFAULT);
  200. }
Advertisement
Add Comment
Please, Sign In to add comment