/** * Process a chat message or command * * @remarks Scope: private * * @param player Player List player pointer * @param message Chat message */ void process_chat(struct PL_entry *player, bstring message) { if (message->data[0] == '/') { LOG(LOG_INFO, "Command: %s", message->data); send_directchat(player, message); // TODO: temporary who cmd bstring whocmd = bfromcstr("/who"); bstring lcmd = bfromcstr("/login"); if (binstrr(message, (whocmd->slen), whocmd) != BSTR_ERR) { pthread_rwlock_rdlock(&PL_rwlock); bstring whomsg = bformat("There are %d players online", PL_count); send_directchat(player, whomsg); pthread_rwlock_unlock(&PL_rwlock); bstrFree(whomsg); } else if(binstrr(message, (lcmd->slen), lcmd) != BSTR_ERR) { send_loginresp(player); } } else { send_chat(player, message); } }
/** * This internal method checks login predicates, populates the rest of the * Player List entry, and sends the initial packet stream to spawn the player. * * @remarks Scope: private * * @param player Player List player pointer * @param username inbound username from client login packet * @param ver inbound version from client login packet */ void process_login(struct PL_entry *player, bstring username, uint32_t ver) { // TODO: Future, async check of minecraft.net for user validity // TODO: Future, check against local ACL /* Check if the client version is compatible with the craftd version */ if (ver != 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(username); pthread_rwlock_unlock(&player->rwlock); send_loginresp(player); const int spawnradius = 5; #ifdef USE_CDGAME send_chunk_radius(player, Config.spawn.x, Config.spawn.z, spawnradius); send_spawnpos(player, Config.spawn.x, Config.spawn.y, Config.spawn.z); //send inv send_movelook(player, Config.spawn.x, Config.spawn.y + 6.1, Config.spawn.y + 6.2, Config.spawn.z, 0, 0, false); #endif /* Login message */ bstring loginmsg = bformat("Player %s has joined the game!", 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; }
/** * 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; }