void main_loop(void *connptr, MumbleClient::MumbleClientLib* mcl) { struct _conninfo *conninfo; _v3_net_message *msg; v3_event *ev; conninfo = connptr; if (debug >= 2) { v3_debuglevel(V3_DEBUG_PACKET | V3_DEBUG_PACKET_PARSE | V3_DEBUG_INFO); } if (! v3_login(conninfo->server, conninfo->username, conninfo->password, "")) { fprintf(stderr, "could not log in to ventrilo server: %s\n", _v3_error(NULL)); } while (keep_running) { // Handle the Mumble Client mcl->Pump(); // Handle incoming events msg = _v3_recv(V3_NONBLOCK); if ( msg != NULL ) { switch (_v3_process_message(msg)) { case V3_MALFORMED: _v3_debug(V3_DEBUG_INFO, "received malformed packet"); break; case V3_NOTIMPL: _v3_debug(V3_DEBUG_INFO, "packet type not implemented"); break; case V3_OK: _v3_debug(V3_DEBUG_INFO, "packet processed"); break; } // free(msg); // Looks like process_message handles freeing the memory used } // Handle any outgoing Events ev = v3_get_event(V3_NONBLOCK); if ( ev != NULL ) { if (debug) { fprintf(stderr, "vumble: got event type %d\n", ev->type); } switch (ev->type) { case V3_EVENT_DISCONNECT: keep_running = false; break; case V3_EVENT_LOGIN_COMPLETE: v3_change_channel(atoi(conninfo->channelid), ""); fprintf(stderr, "***********************************************************************************\n"); fprintf(stderr, "Connected to Ventrilo Server\n"); fprintf(stderr, "***********************************************************************************\n"); v3_serverprop_open(); break; } free(ev); } } }
JNIEXPORT jboolean JNICALL Java_com_jtxdriggers_android_ventriloid_VentriloInterface_login(JNIEnv* env, jobject obj, jstring server, jstring username, jstring password, jstring phonetic) { char* _server = get_string(env, server); char* _username = get_string(env, username); char* _password = get_string(env, password); char* _phonetic = get_string(env, phonetic); v3_get_event(V3_NONBLOCK); v3_set_server_opts(V3_USER_ACCEPT_PAGES, 1); v3_set_server_opts(V3_USER_ACCEPT_U2U, 1); v3_set_server_opts(V3_USER_ACCEPT_CHAT, 1); v3_set_server_opts(V3_USER_ALLOW_RECORD, 1); jint ret = v3_login(_server, _username, _password, _phonetic); release_string(env, server, _server); release_string(env, username, _username); release_string(env, password, _password); release_string(env, phonetic, _phonetic); return ret; }
JNIEXPORT void JNICALL Java_com_jtxdriggers_android_ventriloid_VentriloInterface_getevent(JNIEnv* env, jobject obj, jobject eventdata) { v3_event *ev = v3_get_event(V3_BLOCK); if(ev != NULL) { jclass event_class = get_class(env, eventdata); set_short(env, eventdata, event_class, "type", ev->type); switch(ev->type) { case V3_EVENT_PLAY_AUDIO: { // PCM data. jobject pcm = get_object(env, eventdata, event_class, "pcm", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_pcm;"); jclass pcm_class = get_class(env, pcm); set_int (env, pcm, pcm_class, "length", ev->pcm.length); set_int (env, pcm, pcm_class, "rate", ev->pcm.rate); set_short(env, pcm, pcm_class, "send_type", ev->pcm.send_type); set_byte (env, pcm, pcm_class, "channels", ev->pcm.channels); // User ID. jobject user = get_object(env, eventdata, event_class, "user", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_user;"); jclass user_class = get_class(env, user); set_short(env, user, user_class, "id", ev->user.id); // Sample. jobject data = get_object(env, eventdata, event_class, "data", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_data;"); jclass data_class = get_class(env, data); set_pcm_byte_array(env, data, data_class, "sample", ev->data->sample, ev->pcm.length); } break; case V3_EVENT_PING: { // Ping. set_int(env, eventdata, event_class, "ping", ev->ping); } break; case V3_EVENT_USER_TALK_END: case V3_EVENT_USER_TALK_MUTE: case V3_EVENT_CHAT_JOIN: case V3_EVENT_CHAT_LEAVE: case V3_EVENT_USER_GLOBAL_MUTE_CHANGED: case V3_EVENT_USER_CHANNEL_MUTE_CHANGED: case V3_EVENT_USER_RANK_CHANGE: { // User ID. jobject user = get_object(env, eventdata, event_class, "user", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_user;"); jclass user_class = get_class(env, user); set_short(env, user, user_class, "id", ev->user.id); } break; case V3_EVENT_USER_CHAN_MOVE: case V3_EVENT_USER_LOGOUT: case V3_EVENT_CHAN_REMOVE: { // User ID. jobject user = get_object(env, eventdata, event_class, "user", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_user;"); jclass user_class = get_class(env, user); set_short(env, user, user_class, "id", ev->user.id); // Channel ID. jobject channel = get_object(env, eventdata, event_class, "channel", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_channel;"); jclass channel_class = get_class(env, channel); set_short(env, channel, channel_class, "id", ev->channel.id); } break; case V3_EVENT_USER_MODIFY: case V3_EVENT_USER_LOGIN: { // User ID. jobject user = get_object(env, eventdata, event_class, "user", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_user;"); jclass user_class = get_class(env, user); set_short(env, user, user_class, "id", ev->user.id); // Channel ID. jobject channel = get_object(env, eventdata, event_class, "channel", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_channel;"); jclass channel_class = get_class(env, channel); set_short(env, channel, channel_class, "id", ev->channel.id); // Flags. set_int(env, eventdata, event_class, "flags", ev->flags); } break; case V3_EVENT_STATUS: { // Status message & percentage. jobject status = get_object(env, eventdata, event_class, "status", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_status;"); jclass status_class = get_class(env, status); set_byte(env, status, status_class, "percent", ev->status.percent); set_byte_array(env, status, status_class, "message", ev->status.message); } break; case V3_EVENT_LOGIN_COMPLETE: case V3_EVENT_LOGIN_FAIL: case V3_EVENT_DISCONNECT: case V3_EVENT_ADMIN_AUTH: case V3_EVENT_CHAN_ADMIN_UPDATED: case V3_EVENT_PERMS_UPDATED: { // No event data for these types! } break; case V3_EVENT_PRIVATE_CHAT_START: case V3_EVENT_PRIVATE_CHAT_END: case V3_EVENT_PRIVATE_CHAT_AWAY: case V3_EVENT_PRIVATE_CHAT_BACK: { // User IDs. jobject user = get_object(env, eventdata, event_class, "user", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_user;"); jclass user_class = get_class(env, user); set_short(env, user, user_class, "privchat_user1", ev->user.privchat_user1); set_short(env, user, user_class, "privchat_user2", ev->user.privchat_user2); } case V3_EVENT_PRIVATE_CHAT_MESSAGE: { // User IDs. jobject user = get_object(env, eventdata, event_class, "user", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_user;"); jclass user_class = get_class(env, user); set_short(env, user, user_class, "privchat_user1", ev->user.privchat_user1); set_short(env, user, user_class, "privchat_user2", ev->user.privchat_user2); // Chat message. jobject data = get_object(env, eventdata, event_class, "data", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_data;"); jclass data_class = get_class(env, data); set_byte_array(env, data, data_class, "chatmessage", ev->data->chatmessage); // Flags. set_int(env, eventdata, event_class, "flags", ev->flags); } break; case V3_EVENT_USERLIST_ADD: case V3_EVENT_USERLIST_MODIFY: { // Account fields. jobject data = get_object(env, eventdata, event_class, "data", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_data;"); jclass data_class = get_class(env, data); jobject account = get_object(env, data, data_class, "account", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_data$_account;"); jclass account_class = get_class(env, account); set_byte_array(env, account, account_class, "username", ev->data->account.username); } break; case V3_EVENT_CHAN_ADD: case V3_EVENT_CHAN_MODIFY: { // Channel id. jobject channel = get_object(env, eventdata, event_class, "channel", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_channel;"); jclass channel_class = get_class(env, channel); set_short(env, channel, channel_class, "id", ev->channel.id); } break; case V3_EVENT_DISPLAY_MOTD: { /* don't deal with any MOTD events here because they're useless // MOTD. jobject data = get_object(env, eventdata, event_class, "data", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_data;"); jclass data_class = get_class(env, data); set_byte_array(env, data, data_class, "motd", ev->data->motd); // Flags. set_int(env, eventdata, event_class, "flags", ev->flags); */ } break; case V3_EVENT_CHAN_BADPASS: { // Channel ID. jobject channel = get_object(env, eventdata, event_class, "channel", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_channel;"); jclass channel_class = get_class(env, channel); set_short(env, channel, channel_class, "id", ev->channel.id); // Error message. jobject error = get_object(env, eventdata, event_class, "error", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_error;"); jclass error_class = get_class(env, error); set_byte_array(env, error, error_class, "message", ev->error.message); } break; case V3_EVENT_ERROR_MSG: { // Error message & disconnect flag. jobject error = get_object(env, eventdata, event_class, "error", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_error;"); jclass error_class = get_class(env, error); set_byte_array(env, error, error_class, "message", ev->error.message); set_bool(env, error, error_class, "disconnected", ev->error.disconnected != 0); } break; case V3_EVENT_USER_TALK_START: { // PCM data. jobject pcm = get_object(env, eventdata, event_class, "pcm", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_pcm;"); jclass pcm_class = get_class(env, pcm); set_int (env, pcm, pcm_class, "rate", ev->pcm.rate); set_short(env, pcm, pcm_class, "send_type", ev->pcm.send_type); // User ID. jobject user = get_object(env, eventdata, event_class, "user", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_user;"); jclass user_class = get_class(env, user); set_short(env, user, user_class, "id", ev->user.id); } break; case V3_EVENT_CHAT_MESSAGE: { // User ID. jobject user = get_object(env, eventdata, event_class, "user", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_user;"); jclass user_class = get_class(env, user); set_short(env, user,user_class, "id", ev->user.id); // Chat message. jobject data = get_object(env, eventdata, event_class, "data", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_data;"); jclass data_class = get_class(env, data); set_byte_array(env, data, data_class, "chatmessage", ev->data->chatmessage); } break; case V3_EVENT_USERLIST_REMOVE: { // Account ID. jobject data = get_object(env, eventdata, event_class, "data", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_data;"); jclass data_class = get_class(env, data); jobject account = get_object(env, data, data_class, "account", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_data$_account;"); jclass account_class = get_class(env, account); set_short(env, account, account_class, "id", ev->account.id); } break; case V3_EVENT_USERLIST_CHANGE_OWNER: { // Account IDs. jobject data = get_object(env, eventdata, event_class, "data", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_data;"); jclass data_class = get_class(env, data); jobject account = get_object(env, data, data_class, "account", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_data$_account;"); jclass account_class = get_class(env, account); set_short(env, account, account_class, "id", ev->account.id); set_short(env, account, account_class, "id2", ev->account.id2); } break; case V3_EVENT_USER_PAGE: { // User ID. jobject user = get_object(env, eventdata, event_class, "user", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_user;"); jclass user_class = get_class(env, user); set_short(env, user, user_class, "id", ev->user.id); } break; case V3_EVENT_SERVER_PROPERTY_UPDATED: { jobject srvprop = get_object(env, eventdata, event_class, "serverproperty", "Lcom/jtxdriggers/android/ventriloid/VentriloEventData$_serverproperty;"); jclass srvprop_class = get_class(env, srvprop); set_short(env, srvprop, srvprop_class, "property", ev->serverproperty.property); set_byte(env, srvprop, srvprop_class, "value", ev->serverproperty.value); } break; } v3_free_event(ev); } }