static void doparse(struct chatctx* ctx, xmlNode* top) { if(!top) return; xmlNode* next = top->next; if(top->type == XML_ELEMENT_NODE) { if(lookup_wanted(top->name) == W_CHAT) { process_chat(ctx, top); } else { doparse(ctx, top->children); // depth usually less than breadth } } else if(top->type == XML_HTML_DOCUMENT_NODE) { return doparse(ctx, top->children); // oops } return doparse(ctx, next); // tail recursion on -O2 }
/** * 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; }