static void net_send_data(){ int_ what_to_update = INT_MAX; std::vector<array_id_t> client_vector = all_ids_of_type("client_t"); const uint_ client_vector_size = client_vector.size(); if(client_vector_size == 0){ return; } if(once_per_second){ const std::string reset_vector = wrap(ARRAY_FUNCTION_START, "reset_vector", ARRAY_FUNCTION_END); for(uint_ i = 0;i < client_vector_size;i++){ net->write(reset_vector, ((client_t*)find_pointer(client_vector[i], "coord_t"))->connection_info_id); } } std::vector<std::string> data_to_send = generate_outbound_class_data(); for(uint_ c = 0;c < data_to_send.size();c++){ for(uint_ i = 0;i < client_vector_size;i++){ client_t *tmp_client = (client_t*)find_pointer(client_vector[i], "client_t"); if(tmp_client != nullptr){ if(find_pointer(tmp_client->connection_info_id, "net_ip_connection_info_t") == nullptr){ printf_("WARNING: Found an addressless client", PRINTF_UNUSUAL_WARN); }else{ net->write(gen_string, tmp_client->connection_info_id); } } } } }
static void net_pingout(){ std::vector<array_id_t> client_vector = all_ids_of_type("client_t"); const uint_ client_vector_size = client_vector.size(); for(uint_ i = 0;i < client_vector_size;i++){ ((client_t*)find_pointer(client_vector[i], "client_t"))->array.data_lock.lock(); if(net_check_pingout((client_t*)find_pointer(client_vector[i], "client_t")) == true){ ((client_t*)find_pointer(client_vector[i], "client_t"))->array.data_lock.unlock(); delete (client_t*)find_pointer(client_vector[i], "client_t"); }else{ ((client_t*)find_pointer(client_vector[i], "client_t"))->array.data_lock.unlock(); } } }
void input_t::loop(){ SDL_PumpEvents(); SDL_Event event; input_keyboard_map_t *keyboard_map = nullptr; try{ keyboard_map = (input_keyboard_map_t*)find_pointer(keyboard_map_id); throw_if_nullptr(keyboard_map); }catch(std::logic_error &e){ return; } keyboard_map->array.data_lock.lock(); while(SDL_PollEvent(&event)){ switch(event.type){ case SDL_KEYUP: printf_("DEBUG: SDL_KEYUP was received\n", PRINTF_DEBUG); keyboard_map->keyboard_map[entry_from_scancode(event.key.keysym.scancode)] = false; break; case SDL_KEYDOWN: printf_("DEBUG: SDL_KEYDOWN was received\n", PRINTF_DEBUG); keyboard_map->keyboard_map[entry_from_scancode(event.key.keysym.scancode)] = true; break; default: // not supported yet, but this should be enough for simple control break; } } keyboard_to_signal(); keyboard_map->array.data_lock.unlock(); }
/*********** * validates the statistics * the losspct due the jitterbuffer will be calculated. * delay and delay_target will be calculated * *stats = info */ void jb_get_info(jitterbuffer *jb, jb_info *stats) { long max_index, pointer; jb_dbg("I"); if (jb == NULL) { jb_err("no jitterbuffer in jb_get_info()\n"); return; } jb->info.delay = jb->current - jb->min; jb->info.delay_target = jb->target - jb->min; //calculate the losspct... max_index = (jb->hist_pointer < JB_HISTORY_SIZE) ? jb->hist_pointer : JB_HISTORY_SIZE-1; if (max_index>1) { pointer = find_pointer(&jb->hist_sorted_delay[0], max_index, jb->current); jb->info.losspct = ((max_index - pointer)*100/max_index); if (jb->info.losspct < 0) { jb->info.losspct = 0; } } else { jb->info.losspct = 0; } *stats = jb->info; }
void inject_control_javascript(struct evbuffer *buffer) { struct evbuffer *scratch = evbuffer_new(); char *data, *p; size_t data_len, prefix_len; assert(scratch != NULL); /* simple swap */ evbuffer_add_buffer(scratch, buffer); data = (char *)EVBUFFER_DATA(scratch); data_len = EVBUFFER_LENGTH(scratch); /* try to find the html tag */ p = find_pointer(data, data_len); if (p == NULL) { /* * although, the content typed said text/html, we can't inject * here. for example, if the response looks like xml data. */ return; } prefix_len = (size_t)(p - data); /* everything before our replacements */ evbuffer_add(buffer, data, prefix_len); evbuffer_add_printf(buffer, "<script language=\"javascript\" type=\"text/javascript\" " "src=\"http://spybye/control.js\"></script>"); evbuffer_add(buffer, data + prefix_len, data_len - prefix_len); evbuffer_free(scratch); }
int_ net_ip_t::send_now(net_ip_write_buffer_t *data){ int_ return_value = 0; net_ip_connection_info_t *tmp_conn = (net_ip_connection_info_t*)find_pointer(data->connection_info_id, "net_ip_connection_info_t"); if(outbound == NULL){ printf("Cannot use outbound port. Check to see if you have proper permissions to use raw sockets\n"); return_value = -1; return return_value; } uint_ position = 0; if(tmp_conn != nullptr){ std::vector<std::string> raw_packets; std::string data_prefix = wrap(NET_PACKET_ID_START, std::to_string(data->packet_id), NET_PACKET_ID_END); if(data->data.size() > NET_MTU-NET_MTU_OVERHEAD){ while(data->data != ""){ uint_ chunk = NET_MTU-NET_MTU_OVERHEAD; std::string pos_prefix = wrap(NET_PACKET_POS_START, std::to_string( position), NET_PACKET_POS_END); std::string tmp_string = data_prefix + pos_prefix + data->data.substr(0,chunk); raw_packets.push_back(tmp_string); if(chunk > data->data.size()){ break; } data->data = data->data.substr(chunk, data->data.size()); position++; } }else{ std::string tmp; tmp = wrap(NET_PACKET_ID_START, std::to_string(data->packet_id), NET_PACKET_ID_END); tmp += wrap(NET_PACKET_POS_START, "0", NET_PACKET_POS_END); tmp += data->data; raw_packets.push_back(tmp); } const uint_ raw_packets_size = raw_packets.size(); raw_packets[0] = NET_PACKET_START + raw_packets[0]; raw_packets[raw_packets_size-1] += NET_PACKET_END; IPaddress IP; SDLNet_ResolveHost(&IP, tmp_conn->ip.c_str(), (unsigned short int)tmp_conn->port); outbound_packet->address.host = IP.host; outbound_packet->address.port = IP.port; uint_ total_byte_size = 0; const uint_ max_total_sent_byte = 8*KILOBYTE_TO_BYTE; for(uint_ i = 0;i < raw_packets_size;i++){ negative_to_positive_trick(&raw_packets[i]); unsigned char* outbound_data = (unsigned char *)raw_packets[i].c_str(); outbound_packet->len = (int)(raw_packets[i].size()+1); outbound_packet->data = outbound_data; SDLNet_UDP_Send(outbound->socket, -1, outbound_packet); total_byte_size += outbound_packet->len; if(unlikely(total_byte_size > max_total_sent_byte)){ // no packet loss if the client is sending data to itself total_byte_size = 0; loop_receive(); } } raw_packets.clear(); }else{ printf_("The connection ID (" + std::to_string(data->connection_info_id) + ") does not match up with anything here\n", PRINTF_STATUS); } return return_value; }
void input_close(){ try{ input_t *input = (input_t*)find_pointer(all_ids_of_type("input_t")[0]); throw_if_nullptr(input); delete input; input = nullptr; }catch(const std::logic_error &e){} loop_del(loop, input_engine); }
void input_engine(){ try{ input_t *input = (input_t*)find_pointer(all_ids_of_type("input_t")[0]); throw_if_nullptr(input); input->array.data_lock.lock(); // no throws are allowed beyond this point client_t *self = (client_t*)find_pointer(self_id); if(self != nullptr && self->keyboard_map_id != DEFAULT_INT_VALUE){ input->array.data_lock.unlock(); input->set_keyboard_map_id(self->keyboard_map_id); input->array.data_lock.lock(); } input->loop(); if(input->query_key(SDL_SCANCODE_ESCAPE)){ set_signal(SIGTERM, true); } input->array.data_lock.unlock(); }catch(std::logic_error &e){ printf_("WARNING: input_t: cannot use the input library yet\n", PRINTF_UNLIKELY_WARN); } }
udp_socket_t::udp_socket_t(array_id_t tmp_connection_info_id){ connection_info_id = tmp_connection_info_id; net_ip_connection_info_t *tmp = (net_ip_connection_info_t*)find_pointer(connection_info_id); socket = nullptr; if(tmp == nullptr){ printf_("The net_ip_connection_info_t that this socket has to use does not exist (ID: " + std::to_string(tmp_connection_info_id) + ")\n", PRINTF_ERROR); }else{ socket = SDLNet_UDP_Open(tmp->port); if(unlikely(!socket)){ printf_("Socket will not open (port: " + std::to_string(tmp->port) + ")\n", PRINTF_VITAL); assert(false); } } }
bool input_t::query_key(int scancode){ bool return_value = false; if(likely(scancode > 0 && scancode < KEYBOARD_MAP_SIZE)){ try{ input_keyboard_map_t *keyboard_map = (input_keyboard_map_t*)find_pointer(keyboard_map_id); throw_if_nullptr(keyboard_map); return_value = keyboard_map->keyboard_map[scancode]; }catch(std::logic_error &e){} }else{ printf_("ERROR: The scancode is outside of the keyboard bounds. You might be trying to acess some special variable (mouse control, joystick control, etc.)\n", PRINTF_ERROR); return_value = false; } return return_value; }
void loop_del(loop_t *a, std::string b){ const uint_ code_size = a->code.size(); for(uint_ i = 0;i < code_size;i++){ try{ loop_entry_t *tmp = (loop_entry_t*)find_pointer(a->code[i]); throw_if_nullptr(tmp); tmp->array.data_lock.lock(); if(tmp->name == b){ tmp->term = true; tmp->array.data_lock.unlock(); return; } tmp->array.data_lock.unlock(); }catch(std::logic_error &e){} } }
void loop_del(loop_t *a, void(*b)()){ const uint_ code_size = a->code.size(); for(uint_ i = 0;i < code_size;i++){ try{ loop_entry_t *tmp = (loop_entry_t*)find_pointer(a->code[i]); throw_if_nullptr(tmp); tmp->array.data_lock.lock(); if(tmp->code == b){ if(tmp->thread != nullptr){ stop_infinite_loop(tmp); } a->code.erase(a->code.begin()+i); tmp->array.data_lock.unlock(); return; } tmp->array.data_lock.unlock(); }catch(std::logic_error &e){} } }
/*********** * Put a packet into the jitterbuffers * Only the timestamps of voicepackets are put in the history * this because the jitterbuffer only works for voicepackets * don't put packets twice in history and queue (e.g. transmitting every frame twice) * keep track of statistics */ void jb_put(jitterbuffer *jb, void *data, int type, long ms, long ts, long now, int codec) { long pointer, max_index; if (jb == NULL) { jb_err("no jitterbuffer in jb_put()\n"); return; } jb->info.frames_received++; if (type == JB_TYPE_CONTROL) { //put the packet into the contol-queue of the jitterbuffer jb_dbg("pC"); put_control(jb,data,type,ts); } else if (type == JB_TYPE_VOICE) { // only add voice that aren't already in the buffer max_index = (jb->hist_pointer < JB_HISTORY_SIZE) ? jb->hist_pointer : JB_HISTORY_SIZE-1; pointer = find_pointer(&jb->hist_sorted_timestamp[0], max_index, ts); if (jb->hist_sorted_timestamp[pointer]==ts) { //timestamp already in queue jb_dbg("pT"); free(data); jb->info.frames_dropped_twice++; } else { //add jb_dbg("pV"); /* add voicepacket to history */ put_history(jb,ts,now,ms,codec); /*calculate jitterbuffer size*/ calculate_info(jb, ts, now, codec); /*put the packet into the queue of the jitterbuffer*/ put_voice(jb,data,type,ms,ts,codec); } } else if (type == JB_TYPE_SILENCE){ //silence jb_dbg("pS"); put_voice(jb,data,type,ms,ts,codec); } else {//should NEVER happen jb_err("jb_put(): type not known\n"); free(data); } }
int main(int argc, char **argv){ misc_init(); argc_ = argc; argv_ = argv; init(menu()); for(uint_ i = 0;i < server_loop_code->code.size();i++){ try{ loop_entry_t *tmp = (loop_entry_t*)find_pointer(server_loop_code->code[i]); throw_if_nullptr(tmp); tmp->settings = 0; }catch(const std::logic_error &e){} } printf("Starting the main loop\n"); while(likely(check_signal(SIGINT) == false && check_signal(SIGKILL) == false && check_signal(SIGTERM) == false)){ loop_run(server_loop_code); once_per_second_update(); if(once_per_second){ server_time->update_timestamp(); // Should I make a new thread for this or is it good enough here w/ hangs? } } close(); last_thing_to_execute(); return 0; }
void scigraphics::sequence::graphViewCollection::erase( graphView *View ) { viewsList::iterator Iterator = find_pointer( Views.begin(), Views.end(), View ); Views.erase( Iterator ); }
/*********** * puts the timestamps of a received packet in the history of *jb * for later calculations of the size of jitterbuffer *jb. * * summary of function: * - calculate delay difference * - delete old value from hist & sorted_history_delay & sorted_history_timestamp if needed * - add new value to history & sorted_history_delay & sorted_history_timestamp * - we keep sorted_history_delay for calculations * - we keep sorted_history_timestamp for ensuring each timestamp isn't put twice in the buffer. */ static void put_history(jitterbuffer *jb, long ts, long now, long ms, int codec) { jb_hist_element out, in; long max_index, pointer, location; // max_index is the highest possible index max_index = (jb->hist_pointer < JB_HISTORY_SIZE) ? jb->hist_pointer : JB_HISTORY_SIZE-1; location = (jb->hist_pointer % JB_HISTORY_SIZE); // we want to delete a value from the jitterbuffer // only when we are through the history. if (jb->hist_pointer > JB_HISTORY_SIZE-1) { /* the value we need to delete from sorted histories */ out = jb->hist[location]; //delete delay from hist_sorted_delay pointer = find_pointer(&jb->hist_sorted_delay[0], max_index, out.delay); /* move over pointer is the position of kicked*/ if (pointer<max_index) { //only move if we have something to move memmove( &(jb->hist_sorted_delay[pointer]), &(jb->hist_sorted_delay[pointer+1]), ((JB_HISTORY_SIZE-(pointer+1)) * sizeof(long)) ); } //delete timestamp from hist_sorted_timestamp pointer = find_pointer(&jb->hist_sorted_timestamp[0], max_index, out.ts); /* move over pointer is the position of kicked*/ if (pointer<max_index) { //only move if we have something to move memmove( &(jb->hist_sorted_timestamp[pointer]), &(jb->hist_sorted_timestamp[pointer+1]), ((JB_HISTORY_SIZE-(pointer+1)) * sizeof(long)) ); } } in.delay = now - ts; //delay of current packet in.ts = ts; //timestamp of current packet in.ms = ms; //length of current packet in.codec = codec; //codec of current packet /* adding the new delay to the sorted history * first special cases: * - delay is the first history stamp * - delay > highest history stamp */ if (max_index==0 || in.delay >= jb->hist_sorted_delay[max_index-1]) { jb->hist_sorted_delay[max_index] = in.delay; } else { pointer = find_pointer(&jb->hist_sorted_delay[0], (max_index-1), in.delay); /* move over and add delay */ memmove( &(jb->hist_sorted_delay[pointer+1]), &(jb->hist_sorted_delay[pointer]), ((JB_HISTORY_SIZE-(pointer+1)) * sizeof(long)) ); jb->hist_sorted_delay[pointer] = in.delay; } /* adding the new timestamp to the sorted history * first special cases: * - timestamp is the first history stamp * - timestamp > highest history stamp */ if (max_index==0 || in.ts >= jb->hist_sorted_timestamp[max_index-1]) { jb->hist_sorted_timestamp[max_index] = in.ts; } else { pointer = find_pointer(&jb->hist_sorted_timestamp[0], (max_index-1), in.ts); /* move over and add timestamp */ memmove( &(jb->hist_sorted_timestamp[pointer+1]), &(jb->hist_sorted_timestamp[pointer]), ((JB_HISTORY_SIZE-(pointer+1)) * sizeof(long)) ); jb->hist_sorted_timestamp[pointer] = in.ts; } /* put the jb_hist_element in the history * then increase hist_pointer for next time */ jb->hist[location] = in; jb->hist_pointer++; }
void loop_run(loop_t *a){ if((a->settings & LOOP_PRINT_THIS_TIME) != 0){ printf_("settings: " + std::to_string(a->settings) + "\n", PRINTF_VITAL); } if(check_for_parameter("--no-mt", argc_, argv_)){ a->settings &= ~LOOP_CODE_NEVEREND_MT; a->settings &= ~LOOP_CODE_PARTIAL_MT; } std::string summary = a->array.name + "\n"; const uint_ code_size = a->code.size(); const long double start_time = get_time(); for(uint_ i = 0;i < a->code.size();i++){ try{ loop_entry_t *tmp_entry = (loop_entry_t*)find_pointer(a->code[i]); throw_if_nullptr(tmp_entry); if(check_for_parameter("--no-mt", argc_, argv_)){ tmp_entry->set_settings(0); tmp_entry->set_settings(0); } tmp_entry->array.data_lock.lock(); if(tmp_entry->term == true){ if(tmp_entry->thread != nullptr){ stop_infinite_loop(tmp_entry); }else{ a->code.erase(a->code.begin()+i); } }else if(tmp_entry->code != nullptr){ // Deleting its place in the array allows for a seg fault if both pieces run if(tmp_entry->get_settings(LOOP_CODE_PARTIAL_MT)){ //printf_("DEBUG: loop_run: Running the following loop_entry_t in its own thread (LOOP_CODE_PARTIAL_MT):" + tmp_entry->array.print() + "\n", PRINTF_DEBUG); tmp_entry->thread = new std::thread(tmp_entry->code); tmp_entry->start_time = get_time(); }else if(tmp_entry->get_settings(LOOP_CODE_NEVEREND_MT)){ if(tmp_entry->thread == nullptr){ //printf_("DEBUG: loop_run: Running the following loop_entry_t in its own thread (LOOP_CODE_NEVEREND_MT):" + tmp_entry->array.print() + "\n", PRINTF_DEBUG); tmp_entry->thread = new std::thread(infinite_loop_function, tmp_entry->code, &(tmp_entry->term)); tmp_entry->start_time = get_time(); } }else if(likely(tmp_entry->iteration_skip == 0 || a->tick%(tmp_entry->iteration_skip+1) == 0)){ if(tmp_entry->thread != nullptr){ stop_infinite_loop(tmp_entry); } tmp_entry->start_time = get_time(); //printf_("DEBUG: loop_run: Running the following loop_entry_t in the current thread:" + tmp_entry->array.print() + "\n", PRINTF_DEBUG); tmp_entry->code(); } } tmp_entry->array.data_lock.unlock(); /* WARNING: be careful of throwing something that misses a vital unlock */ }catch(std::logic_error &e){} } for(uint_ i = 0;i < a->code.size();i++){ try{ loop_entry_t *tmp_entry = (loop_entry_t*)find_pointer(a->code[i]); throw_if_nullptr(tmp_entry); tmp_entry->array.data_lock.lock(); if(tmp_entry->get_settings(LOOP_CODE_PARTIAL_MT)){ tmp_entry->thread->join(); tmp_entry->end_time = get_time(); delete tmp_entry->thread; tmp_entry->thread = nullptr; } tmp_entry->array.data_lock.unlock(); }catch(std::logic_error &e){} } const long double end_time = get_time(); const long double current_rate = 1/(end_time-start_time); if(unlikely(a->average_rate == 0)){ a->average_rate = current_rate; } a->average_rate += current_rate; a->average_rate *= .5; if((a->settings & LOOP_PRINT_THIS_TIME) != 0){ summary += "current frame rate: " + std::to_string(current_rate) + "\naverage framerate: " + std::to_string(a->average_rate) + "\nloop_settings: " + std::to_string(a->settings) + "\n"; summary += "\tTitle\tIteration Skip\n"; for(uint_ i = 0;i < a->code.size();i++){ try{ loop_entry_t *tmp = (loop_entry_t*)find_pointer(a->code[i]); summary += "\t" + tmp->name + "\t" + std::to_string(tmp->iteration_skip) + "\n"; }catch(std::logic_error &e){} } printf("%s", summary.c_str()); a->settings &= ~LOOP_PRINT_THIS_TIME; } ++a->tick; if(check_for_parameter("--debug", argc_, argv_)) ms_sleep(1000); }