/** * This internal method proxy packets from a pointer to a struct and * a packet type * * @remarks Scope: private * * @param bev buffer event * @param pkttype type of packet * @param packet Pointer to a packet struct */ void process_proxypacket(struct PL_entry *player, uint8_t pkttype, void * packet) { switch(pkttype) { case PID_LOGIN: { // TODO: Future, async check of minecraft.net for user validity // TODO: Future, check against local ACL struct packet_login* lpacket = (struct packet_login*) packet; /* Check if the client version is compatible with the craftd version */ if (lpacket->version != PROTOCOL_VERSION) { bstring dconmsg; dconmsg = bfromcstr("Client version is incompatible with this server."); send_kick(player, dconmsg); bstrFree(dconmsg); return; } /* Otherwise, finish populating their Player List entry */ pthread_rwlock_wrlock(&player->rwlock); player->username = bstrcpy(lpacket->username); Server *server = NULL; for(int i = 0; Config.proxy_servers[i] != NULL;i++) { if(strcmp(Config.proxy_servers[i]->name,Config.proxy_default_server)==0) server = Config.proxy_servers[i]; } if(server == NULL) LOG(LOG_CRIT,"Error getting server struct"); if(server != NULL) player->sev = create_servercon(player,server); player->loginpacket = Malloc(sizeof(struct packet_login)); memcpy(player->loginpacket, lpacket, sizeof(struct packet_login)); pthread_rwlock_unlock(&player->rwlock); send_loginresp(player); /* Login message */ bstring loginmsg = bformat("Player %s has joined the proxy server!", player->username->data); send_syschat(loginmsg); bstrFree(loginmsg); /* Send player MOTD */ for(int i = 0; i < Config_motdsz; ++i) { send_directchat(player, Config_motd[i]); } return; } case PID_HANDSHAKE: { process_handshake(player,((struct packet_handshake*) packet)->username); return; } case PID_CHAT: { struct packet_chat *cpacket = (struct packet_chat*)packet; if(cpacket->message->data[0] == '\\') { bstring lcmd = bfromcstr("\\login"); if(binstrr(cpacket->message,lcmd->slen,lcmd) != BSTR_ERR) { /* Don't do anything until properly tested //process_handshake(player,player->username); send_loginresp(player); //sleep(2); bufferevent_free(player->sev); pthread_rwlock_wrlock(&player->rwlock); player->sev = create_servercon(player,Config.proxy_servers[0]); pthread_rwlock_unlock(&player->rwlock); //sleep(2); //player->sev = create_servercon(player,NULL);*/ } //send_directchat(player,bformat("You are on a proxy server")); } else { if(player->sev) send_proxychat(player,cpacket->message); } break; } } return; }
/** * This internal method process packets from a pointer to a struct and * a packet type * * @remarks Scope: private * * @param player Player this method affects * @param pkttype Type of packet that 'packet' points to * @param packet Pointer to struct of packet type 'packetid' */ void process_packet(struct PL_entry *player, uint8_t pkttype, void * packet) { switch(pkttype) { case PID_LOGIN: { process_login(player, ((struct packet_login*) packet)->username, ((struct packet_login*) packet)->version); return; } case PID_HANDSHAKE: { process_handshake(player,((struct packet_handshake*) packet)->username); return; } case PID_CHAT: { process_chat(player,((struct packet_chat*) packet)->message); return; } case PID_PLAYERPOS: { pthread_rwlock_wrlock(&player->position.rwlock); int oldx = player->position.x/16, oldz = player->position.z/16; /* Flip bits */ player->position.x = Cswapd(((struct packet_playerpos*) packet)->x); player->position.y = Cswapd(((struct packet_playerpos*) packet)->y); player->position.z = Cswapd(((struct packet_playerpos*) packet)->z); int newx = player->position.x/16, newz = player->position.z/16; if (oldx != newx || oldz != newz) send_chunk_radius(player, player->position.x, player->position.z, RADIUS); pthread_rwlock_unlock(&player->position.rwlock); return; } case PID_PLAYERLOOK: { pthread_rwlock_wrlock(&player->position.rwlock); /* Flip bits */ player->position.yaw = Cswapf(((struct packet_look*) packet)->yaw); player->position.pitch = Cswapf(((struct packet_look*) packet)->pitch); pthread_rwlock_unlock(&player->position.rwlock); return; } case PID_PLAYERMOVELOOK: { pthread_rwlock_wrlock(&player->position.rwlock); int oldx = player->position.x/16, oldz = player->position.z/16; /* Flip bits */ player->position.x = Cswapd(((struct packet_movelook*) packet)->x); player->position.y = Cswapd(((struct packet_movelook*) packet)->y); player->position.z = Cswapd(((struct packet_movelook*) packet)->z); player->position.yaw = Cswapf(((struct packet_movelook*) packet)->yaw); player->position.pitch = Cswapf(((struct packet_movelook*) packet)->pitch); int newx = player->position.x/16, newz = player->position.z/16; if (oldx != newx || oldz != newz) send_chunk_radius(player, player->position.x, player->position.z, RADIUS); pthread_rwlock_unlock(&player->position.rwlock); return; } case PID_PLAYERDIG: { switch(((struct packet_dig*) packet)->status) { case STATUS_STARTED: { LOG(LOG_DEBUG, "block dig STARTED"); break; } case STATUS_DIGGING: { LOG(LOG_DEBUG, "block dig DIGGING"); break; } case STATUS_STOPPED: { LOG(LOG_DEBUG, "block dig STOPPED"); break; } case STATUS_BROKEN: { LOG(LOG_DEBUG, "block dig BROKEN"); break; } case STATUS_ITEMDROP: { LOG(LOG_DEBUG, "block dig ITEMDROP"); break; } } return; } case PID_DISCONNECT: { deferLogout(player); return; } default: { return; //Do nothing } } return; }