/*! * \brief Print the list of files in the specified SimplePost instance. * * \param[in] args Arguments passed to this program * * \return true if all files being served by the specified instance were * enumerated successfully, false if not */ static bool __list_files(const simplearg_t args) { simplepost_file_t files; // List of files being served by the server ssize_t count; // Number of files being served char count_buf[1024]; // COUNT string of the file being served size_t failures = 0; // Number of files we failed to print count = simplecmd_get_files(args->pid, &files); if(count < 0) { impact(0, "%s: Failed to get the list of files being served by the %s instance with PID %d\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, args->pid); return false; } for(simplepost_file_t p = files; p; p = p->next) { if(simplestr_count_to_str(count_buf, sizeof(count_buf)/sizeof(count_buf[0]), p->count) == 0) { impact(0, "%s: Failed to convert the %s COUNT to a string\n", SP_MAIN_HEADER_NAMESPACE, p->file); ++failures; continue; } printf("[PID %d] Serving %s on %s %s\n", args->pid, p->file, p->url, count_buf); } simplepost_file_free(files); return (failures == 0); }
/*! * \brief Cleanly shut down the specified SimplePost instance. * * \param[in] args Arguments passed to this program * * \return true if the instance was shut down successfully, false if not */ static bool __shutdown_inst(const simplearg_t args) { const unsigned short max_sleep = 5; // Maximum number of seconds to wait for the other instance to terminate const unsigned short sleep_res = 1; // Number of seconds to wait between checks for the other instance unsigned short sleep_count = 0; // Number of seconds that we have waited for the other instance impact(1, "%s: Shutting down the %s instance with PID %d ...\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, args->pid); if(kill(args->pid, SIGTERM) == -1) { impact(0, "%s: Failed to kill the %s instance with PID %d: %s\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, args->pid, strerror(errno)); return false; } while(sleep_count < max_sleep) { sleep(sleep_res); if(kill(args->pid, 0) == -1 && errno == ESRCH) break; sleep_count += sleep_res; } if(sleep_count >= max_sleep) { impact(0, "%s: %s %d did not shut down after %hu seconds!\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, args->pid, sleep_count); return false; } return true; }
/*! * \brief Safely handle SIGPIPE by completely resetting the command server. * * \note This function effectively takes the nuclear option to handling * command communication errors. Maybe the Chernobyl kind of nuclear (initiate * damage control and start over), not Hiroshima (permanently wipe out * everything in sight), but it is definitely *not* subtle. * * \param[in] sig Signal to handle */ static void __server_reset_pipe(int sig) { // Unused parameters (void) sig; if(cmdd) { impact(0, "%s: LOCAL SOCKET COMMUNICATION ERROR!\n", SP_MAIN_HEADER_NAMESPACE); impact(2, "%s: Attempting to restart command server ...\n", SP_MAIN_HEADER_NAMESPACE); simplecmd_free(cmdd); cmdd = simplecmd_init(); if(cmdd) { impact(2, "%s: Command server restarted\n", SP_MAIN_HEADER_NAMESPACE); } else { impact(2, "%s: Failed to restart command server\n", SP_MAIN_HEADER_NAMESPACE); } } else { impact(0, "%s: Highly improbable! Received SIGPIPE with no active local sockets!\n", SP_MAIN_HEADER_NAMESPACE); } }
/*! * \brief Process a request accepted by the server. * * \param[in] p SimplePost command + client socket wrapper * * \return NULL */ static void* __process_request(void* p) { struct simplecmd_request* scrp = (struct simplecmd_request*) p; // Properly cast SimplePost command request handle simplecmd_t scp = scrp->scp; // SimplePost command instance to act on int sock = scrp->client_sock; // Socket the client connected on free(scrp); scrp = p = NULL; char* command; // Command to process size_t length; // Length of the command string bool response; // Command handler return value ++(scp->client_count); length = __sock_recv(sock, NULL, &command); if(command == NULL || length == 0) goto error; response = -1; for(unsigned int i = SP_COMMAND_MIN; i <= SP_COMMAND_MAX; ++i) { if(strcmp(command, __command_handlers[i].request) == 0) { impact(2, "%s: Request 0x%lx: Responding to %s command\n", SP_COMMAND_HEADER_NAMESPACE, pthread_self(), __command_handlers[i].request); response = (*__command_handlers[i].handler)(scp, sock); break; } } #ifdef DEBUG if(response) { impact(2, "%s: Request 0x%lx: Successfully processed %s command\n", SP_COMMAND_HEADER_NAMESPACE, pthread_self(), command); } else { impact(2, "%s: Request 0x%lx: Failed to process %s command\n", SP_COMMAND_HEADER_NAMESPACE, pthread_self(), command); } #endif // DEBUG error: impact(4, "%s: Request 0x%lx: Closing client %d\n", SP_COMMAND_HEADER_NAMESPACE, pthread_self(), sock); close(sock); if(command) free(command); --(scp->client_count); return NULL; }
/*! * \brief Print the list of accessible SimplePost instances. * * \return true if all instances were enumerated successfully, false if not */ static bool __list_inst() { simplecmd_list_t sclp; // List of SimplePost Command instances char* address; // Address of the server unsigned short port; // Port the server is listening on char* version; // Server's version size_t failures = 0; // Number of instances that we failed to query simplecmd_list_inst(&sclp); for(simplecmd_list_t p = sclp; p; p = p->next) { if(simplecmd_get_version(p->inst_pid, &version) == 0) { impact(0, "%s: Failed to get the version of the %s instance with PID %d\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, p->inst_pid); ++failures; continue; } if(simplecmd_get_address(p->inst_pid, &address) == 0) { impact(0, "%s: Failed to get the address of the %s instance with PID %d\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, p->inst_pid); ++failures; free(version); continue; } port = simplecmd_get_port(p->inst_pid); if(port == 0) { impact(0, "%s: Failed to get the port of the %s instance with PID %d\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, p->inst_pid); ++failures; free(address); free(version); continue; } printf("[PID %d] %s %s serving files on %s:%hu\n", p->inst_pid, SP_MAIN_DESCRIPTION, version, address, port); free(address); free(version); } simplecmd_list_free(sclp); return (failures == 0); }
/*! * \brief Get the port the specified server is listening on. * * \param[in] server_pid Process identifier of the server to query * * \return the server's port number */ unsigned short simplecmd_get_port(pid_t server_pid) { int sock; // Socket descriptor unsigned short port; // Port the specified server is listening on char* buffer; // Port as a string (directly from the server) sock = __open_sock_by_pid(server_pid); if(sock < 0) return 0; __sock_recv(sock, __command_handlers[SP_COMMAND_GET_PORT].request, &buffer); if(buffer) { if(sscanf(buffer, "%hu", &port) != 1) { impact(0, "%s: %s: %s is not a port number\n", SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_HEADER_PROTOCOL_ERROR, buffer); port = 0; } free(buffer); } else { port = 0; } close(sock); return port; }
/* * CG_Fire_SpiralPattern */ static void CG_Fire_SpiralPattern( vec3_t start, vec3_t dir, int *seed, int ignore, int count, int spread, int range, void ( *impact )(trace_t *tr) ) { int i; float r; float u; trace_t trace, *water_trace; assert( seed ); for( i = 0; i < count; i++ ) { r = cos( *seed + i ) * spread * i; u = sin( *seed + i ) * spread * i; water_trace = GS_TraceBullet( &trace, start, dir, r, u, range, ignore, 0 ); if( water_trace ) { trace_t *tr = water_trace; if( !VectorCompare( tr->endpos, start ) ) CG_LeadWaterSplash( tr ); } if( trace.ent != -1 && !( trace.surfFlags & SURF_NOIMPACT ) ) impact( &trace ); if( water_trace ) CG_LeadBubbleTrail( &trace, water_trace->endpos ); } }
/*! * \brief Open a socket to the server with the specified process identifier. * * \note This functions prints error messages so its consumers don't have to. * * \param[in] server_pid Process identifier of the server * * \return an open socket descriptor if the specified PID belongs to a * compatible SimplePost server with an open local socket, -1 if POSIX open() * encounters an error, or -2 if this function encounters an error */ static int __open_sock_by_pid(pid_t server_pid) { int sock; // Socket descriptor struct sockaddr_un sock_addr; // Address to assign to the socket char sock_name[512]; // Name of the socket struct stat sock_status; // Status of the socket sprintf(sock_name, "%s/%s_sock_%d", SP_COMMAND_SOCK_DIR, SP_MAIN_SHORT_NAME, server_pid); if(stat(sock_name, &sock_status) == -1) { impact(0, "%s: Socket %s does not exist\n", SP_COMMAND_HEADER_NAMESPACE, sock_name); return -2; } if(S_ISSOCK(sock_status.st_mode) == 0) { impact(0, "%s: %s is not a socket\n", SP_COMMAND_HEADER_NAMESPACE, sock_name); return -2; } sock = socket(AF_UNIX, SOCK_STREAM, 0); if(sock == -1) { impact(0, "%s: Failed to open socket %s\n", SP_COMMAND_HEADER_NAMESPACE, sock_name); return -1; } memset(&sock_addr, 0, sizeof(struct sockaddr_un)); sock_addr.sun_family = AF_UNIX; strncpy(sock_addr.sun_path, sock_name, sizeof(sock_addr.sun_path) - 1); if(connect(sock, (struct sockaddr*) &sock_addr, sizeof(sock_addr)) == -1) { impact(0, "%s: Failed to connect to socket %s\n", SP_COMMAND_HEADER_NAMESPACE, sock_name); close(sock); return -1; } return sock; }
/*! * \brief Add a file to the specified server. * * \param[in] server_pid Process identifier of the server to act on * \param[in] file Name and path of the file to serve * \param[in] uri URI of the file to serve * \param[in] count Number of times the file should be served * * \return true if the file was successfully added to the server, false if * something went wrong (and the file was not added to the server) */ bool simplecmd_set_file( pid_t server_pid, const char* file, const char* uri, unsigned int count) { int sock; // Socket descriptor char buffer[512]; // Count as a string sock = __open_sock_by_pid(server_pid); if(sock < 0) return false; __sock_send(sock, __command_handlers[SP_COMMAND_SET_FILE].request, NULL); if(file) { impact(3, "%s: %s: Sending %s %s\n", SP_COMMAND_HEADER_NAMESPACE, __func__, SP_COMMAND_FILE_FILE, file); __sock_send(sock, SP_COMMAND_FILE_FILE, file); } if(count) { sprintf(buffer, "%u", count); impact(3, "%s: %s: Sending %s %s\n", SP_COMMAND_HEADER_NAMESPACE, __func__, SP_COMMAND_FILE_COUNT, buffer); __sock_send(sock, SP_COMMAND_FILE_COUNT, buffer); } if(uri) { impact(3, "%s: %s: Sending %s %s\n", SP_COMMAND_HEADER_NAMESPACE, __func__, SP_COMMAND_FILE_URI, uri); __sock_send(sock, SP_COMMAND_FILE_URI, uri); } close(sock); return true; }
/*! * \brief Stop accepting client commands. * * \param[in] scp Instance to act on * * \retval true the command server has been successfully killed * \retval false the command server is not running or could not be shut down */ bool simplecmd_deactivate(simplecmd_t scp) { if(scp->sock == -1) { impact(0, "%s: Server is not active\n", SP_COMMAND_HEADER_NAMESPACE); return false; } impact(1, "%s: Shutting down ...\n", SP_COMMAND_HEADER_NAMESPACE); scp->accpeting_clients = false; pthread_join(scp->accept_thread, NULL); #ifdef DEBUG impact(2, "%s: 0x%tu cleanup complete\n", SP_COMMAND_HEADER_NAMESPACE, scp->accept_thread); #endif // DEBUG return true; }
/*! * \brief Do we have a valid PID to a SimplePost instance? * * \param[in] args Arguments passed to this program * * \return true if the PID is valid, false if not * * \note This function should always be called after __resolve_pid()! */ static bool __is_pid_valid(const simplearg_t args) { if(args->pid == 0) { if(args->address && args->port) { impact(0, "%s: There is no %s instance bound to ADDRESS %s listening on PORT %hu\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, args->address, args->port); } else if(args->address) { impact(0, "%s: There is no %s instance bound to ADDRESS %s\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, args->address); } else if(args->port) { impact(0, "%s: There is no %s instance listening on PORT %hu\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, args->port); } else { impact(0, "%s: There are no other accessible %s instances\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION); } return false; } else if(args->options & SA_OPT_NEW) { impact(0, "%s: No %s PID may be given with the '--new' option\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION); return false; } return true; }
void CtcUnion::contract(IntervalVector& box) { IntervalVector savebox(box); IntervalVector result(IntervalVector::empty(box.size())); BitSet flags(BitSet::empty(Ctc::NB_OUTPUT_FLAGS)); BitSet impact(BitSet::all(nb_var)); // always set to "all" for the moment (to be improved later) for (int i=0; i<list.size(); i++) { if (i>0) box=savebox; flags.clear(); list[i].contract(box,impact,flags); result |= box; if (flags[INACTIVE]) { set_flag(INACTIVE); break; } } box = result; } // end namespace ibex
std::pair<int, float> calculate_impact (aabb<vector> body, vector motion, const collision_aabb& block) { vector impact (0, 0, 0); auto sa_int (sa_intersection(body, block)); if (!sa_intersects(sa_int)) return { -1, 0.0f }; int shortest_axis (-1); float shortest (std::numeric_limits<float>::max()); float shortest_impact (0); for (int axis (0); axis < 3; ++axis) { auto d (motion[axis]); if (d == 0) continue; // Pick the direction along this axis opposite to the motion int dir (axis * 2 + (motion[axis] > 0 ? 1 : 0)); int mask (1 << dir); // If there's no face exposed on this side, there's no collision // either. if ((block.open_sides & mask) == 0) continue; auto axis_impact ((d < 0 ? sa_int.first : sa_int.second)[axis]); auto dist (axis_impact / d); assert(dist > 0); if (dist > 0 && dist < shortest) { shortest_axis = axis; shortest = dist; shortest_impact = axis_impact; } } return std::make_pair(shortest_axis, -shortest_impact); }
/*! * \brief Free the given SimplePost command instance. * * \param[in] scp Instance to act on */ void simplecmd_free(simplecmd_t scp) { if(scp == NULL) return; if(scp->accpeting_clients) simplecmd_deactivate(scp); if(scp->sock != -1) { impact(2, "%s:%d: BUG! %s should have (directly or indirectly) closed the socket already!\n", __FILE__, __LINE__, __func__); close(scp->sock); } if(scp->sock_name) { remove(scp->sock_name); free(scp->sock_name); } }
/* * CG_FireBullet */ static void CG_FireBullet( int self, vec3_t start, vec3_t forward, int count, int spread, int seed, void ( *impact )(trace_t *tr /*, int impactnum*/) ) { int i; trace_t tr; vec3_t dir, axis[3]; qboolean takedamage; // calculate normal vectors VecToAngles( forward, dir ); AngleVectors( dir, axis[0], axis[1], axis[2] ); for( i = 0; i < count; i++ ) { CG_FireLead( self, start, axis, spread, spread, &seed, &tr ); takedamage = tr.ent && ( cg_entities[tr.ent].current.effects & EF_TAKEDAMAGE ); if( tr.fraction < 1.0f && !takedamage && !( tr.surfFlags & SURF_NOIMPACT ) ) impact( &tr ); } }
void Particle :: collisionEvent(std::shared_ptr<Object>& object) { if(object->solid()) { IOwnable* owned; if((owned = dynamic_cast<IOwnable*>(object.get()))) if(owner() && owned->owner() && owned->owner() != owner()) // diff owner? { std::string impact_fn; if(properties().getStringValue("events", "impact", impact_fn) && Filesystem::hasExtension(impact_fn, "ini")) // make sure event is not a script { std::shared_ptr<Object> impact(new Particle(impact_fn)); impact->pos(pos() + size()/2.0f - impact->size()/2.0f); world()->add(impact); } invalidate(); } } }
void CtcCompo::contract(IntervalVector& box) { // TODO: wrong algorithm here // if (incremental) { // for (int i=0; i<list.size(); i++) { // IntervalVector old_box(box); // impacts[i] |= impact; // // list[i].contract(box); // // for (int j=0; j<nb_var; j++) { // if (old_box[j].rel_distance(box[j])>ratio) // for (int i2=0; i2<list.size(); i2++) // if (i2!=i) impacts[i2].set(j); // } // } // return; // } bool inactive= true; BitSet flags(BitSet::empty(Ctc::NB_OUTPUT_FLAGS)); BitSet impact(BitSet::all(nb_var)); // always set to "all" for the moment (to be improved later) for (int i=0; i<list.size(); i++) { if (inactive) { flags.clear(); list[i].contract(box,impact,flags); if (!flags[INACTIVE]) inactive=false; } else { list[i].contract(box); } if (box.is_empty()) { set_flag(FIXPOINT); return; } } if (inactive) set_flag(INACTIVE); }
/*! * \brief Add the files to our SimplePost instance and start the HTTP server. * * \param[in] args Arguments passed to this program * * \return true if the HTTP server was started successfully, false if not */ static bool __start_httpd(const simplearg_t args) { httpd = simplepost_init(); if(httpd == NULL) { impact(2, "%s: %s: Failed to allocate memory for %s HTTP server instance\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_HEADER_MEMORY_ALLOC, SP_MAIN_DESCRIPTION); return false; } if(simplepost_bind(httpd, args->address, args->port) == 0) return false; for(simplefile_t p = args->files; p; p = p->next) { char* url; // URL of the file being served if(simplepost_serve_file(httpd, &url, p->file, p->uri, p->count) == 0) return false; free(url); } return true; }
/*! * \brief Resolve the PID of the SimplePost instance to connect to. * * \param[inout] args Arguments passed to this program * * \return true if the PID was resolved successfully, false if not * * \note This function will return false only if no SimplePost instance exists * with the given PID or if the stated arguments are invalid (or contradictory) * and no PID can be resolved. Use the return value as a sanity check before * attempting to use the PID. Although the various simplecmd methods WILL * catch the error and return properly if an invalid PID is given, it should * never get that far. This method's error messages are far more user-friendly. * * \note Just because this function returns true does not necessarily mean * that there is a PID, even if one was set from the command line. If the * "--new" argument was given, this function will clear the PID if one was set * and return true. */ static bool __resolve_pid(simplearg_t args) { if(args->options & SA_OPT_NEW) { args->pid = 0; } else if(args->pid) { pid_t pid = simplecmd_find_inst(args->address, args->port, args->pid); if(pid == 0) { impact(0, "%s: Found no %s command instance with PID %d\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, args->pid); return false; } } else { args->pid = simplecmd_find_inst(args->address, args->port, args->pid); } return true; }
bool collision(t_circle circle, t_rectangle brick[NB_BRICK]) { int i; t_bunny_position pos; i = 0; while (i < NB_BRICK) { pos.y = brick[i].pos.y; while (pos.y < (brick[i].pos.y + brick[i].height)) { pos.x = brick[i].pos.x; while (pos.x < (brick[i].pos.x + brick[i].width)) { if (impact(pos, circle) == true) return (true); pos.x++; } pos.y++; } i++; } return (false); }
/*! * \brief Add new files to be served to another SimplePost instance. * * \param[in] args Arguments passed to this program * * \return true if all files were added to the specified instance successfully, * false if not */ static bool __add_to_other_inst(const simplearg_t args) { char* address; // Destination server's address unsigned short port; // Destination server's port char buf[2048]; // String describing the file to add to the server size_t failures = 0; // The number of files we failed to add to the server impact(2, "%s: Trying to connect to the %s instance with PID %d ...\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, args->pid); if(simplecmd_get_address(args->pid, &address) == 0) { impact(0, "%s: Failed to get the ADDRESS of the %s instance with PID %d\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, args->pid); return false; } port = simplecmd_get_port(args->pid); if(port == 0) { impact(0, "%s: Failed to get the PORT of the %s instance with PID %d\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, args->pid); free(address); return false; } #ifdef DEBUG char* version; // Destination server's version if(simplecmd_get_version(args->pid, &version) == 0) { impact(0, "%s: Failed to get the version of the %s instance with PID %d\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, args->pid); free(address); return false; } impact(2, "%s: Serving FILESs on the %s %s instance with PID %d\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, version, args->pid); free(version); #endif // DEBUG for(simplefile_t p = args->files; p; p = p->next) { if(simplecmd_set_file(args->pid, p->file, p->uri, p->count) == false) { impact(0, "%s: Failed to add FILE %s to the %s instance with PID %d\n", SP_MAIN_HEADER_NAMESPACE, p->file, SP_MAIN_DESCRIPTION, args->pid); ++failures; } else { if(simplestr_get_serving_str(buf, sizeof(buf)/sizeof(buf[0]), p->file, address, port, p->uri, p->count) == 0) { impact(0, "%s: Failed to construct the description string for %s\n", SP_MAIN_HEADER_NAMESPACE, p->file); ++failures; continue; } impact(1, "[PID %d] %s\n", args->pid, buf); } } free(address); return (failures == 0); }
/*! * \brief Send the list of files that we are serving to the client. * * \param[in] scp Instance to act on * \param[in] sock Client socket * * \retval true the requested information was sent successfully * \retval false failed to respond to the request */ static bool __command_send_files(simplecmd_t scp, int sock) { char buffer[30]; // File count or index as a string simplepost_file_t files; // List of files being served size_t count; // Number of files being served size_t i = 0; // Index of the current file being sent count = simplepost_get_files(scp->spp, &files); impact(3, "%s: %s: Sending list of %zu files\n", SP_COMMAND_HEADER_NAMESPACE, __func__, count); if(sprintf(buffer, "%zu", count) <= 0) { simplepost_file_free(files); return false; } __sock_send(sock, NULL, buffer); for(simplepost_file_t p = files; p; p = p->next) { impact(3, "%s: %s: Sending %s %zu\n", SP_COMMAND_HEADER_NAMESPACE, __func__, SP_COMMAND_FILE_INDEX, i); if(sprintf(buffer, "%zu", i++) <= 0) { simplepost_file_free(files); return false; } __sock_send(sock, SP_COMMAND_FILE_INDEX, buffer); if(p->file) { impact(3, "%s: %s: Sending %s %s\n", SP_COMMAND_HEADER_NAMESPACE, __func__, SP_COMMAND_FILE_FILE, p->file); __sock_send(sock, SP_COMMAND_FILE_FILE, p->file); } if(p->count) { if(sprintf(buffer, "%u", p->count) <= 0) { impact(0, "%s: %s: Failed to buffer %s %u\n", SP_COMMAND_HEADER_NAMESPACE, __func__, SP_COMMAND_FILE_COUNT, p->count); simplepost_file_free(files); return false; } impact(3, "%s: %s: Sending %s %s\n", SP_COMMAND_HEADER_NAMESPACE, __func__, SP_COMMAND_FILE_COUNT, buffer); __sock_send(sock, SP_COMMAND_FILE_COUNT, buffer); } /* Always send the URL last. The reason for this is that only the FILE * and URL fields and required per-file. All others are optional. * Therefore to make sure that the optional fields are not skipped on * the client side, always send a required field last. */ if(p->url) { impact(3, "%s: %s: Sending %s %s\n", SP_COMMAND_HEADER_NAMESPACE, __func__, SP_COMMAND_FILE_URL, p->url); __sock_send(sock, SP_COMMAND_FILE_URL, p->url); } } simplepost_file_free(files); return true; }
void KeyboardCharacterMover::move(sf::RenderWindow &window, Character &character, Collisions &collisions, TilesMap &tilesMap, Camera &camera, Background &background, sf::Time elapsedTime) { // Check if we`re flying m_testRect = character.m_characterRect; m_testRect.top++; m_result = collisions.collidedY(m_testRect, character.m_digPower, tilesMap, m_blockPos); if(m_result == Collisions::NoCollision) m_flying = true; else m_flying = false; // If a direction is true, add or delete 13 to the velocity (x or y) to be able to move in that direction if(m_north) character.m_velocityY -= 13.0f; if(m_south) character.m_velocityY += 3.0f; // Only add 3 if m_south is true (because we'll add the gravity if(m_east) character.m_velocityX += 13.0f; if(m_west) character.m_velocityX -= 13.0f; // Add gravity (only if we're flying) if(m_flying) m_physic.addGravity(character.m_velocityY); // If east or west are false et their velocity is not equal to 0 if(!m_east && character.m_velocityX > 0) { character.m_velocityX = character.m_velocityX*97/100; // Reduce the velocity if(character.m_velocityX <= 15) // If the velocity is less than 15 set the velocity to 0 character.m_velocityX = 0; } if(!m_west && character.m_velocityX < 0) { character.m_velocityX = character.m_velocityX*97/100; // Reduce the velocity if(character.m_velocityX >= -15) // If the velocity is more than -15, set the velocity to 0 character.m_velocityX = 0; } // Check if the velocity are higher than the max if(character.m_velocityX > character.m_maxVelocity) character.m_velocityX = character.m_maxVelocity; if(character.m_velocityX < -character.m_maxVelocity) character.m_velocityX = -character.m_maxVelocity; if(character.m_velocityY < -character.m_maxVelocity) character.m_velocityY = -character.m_maxVelocity; if(character.m_velocityY > 2000) character.m_velocityY = 2000; // Check for collisions, if everything is ok: move the character. Else, check if we can dig m_testRect = character.m_characterRect; // Collisions in x axis m_testRect.left += elapsedTime.asSeconds()* character.m_velocityX; // Add x movement m_result = collisions.collidedX(m_testRect, character.m_digPower, tilesMap, m_blockPos); // Test // If there're no collision if(m_result == Collisions::NoCollision) { character.m_characterRect.left = m_testRect.left; // Move the character position camera.moveX(character.m_characterRect, tilesMap.getWorldSize()); // Move the camera position } // If we can dig else if(m_result == Collisions::Diggable) { // Only dig if we are not flying and if the the key is pressed if(m_blockPos.x < character.m_characterRect.left && m_west && !m_flying) { dig(window, character, tilesMap, camera, background, m_blockPos, KeyboardCharacterMover::WEST); return; } if(m_blockPos.x > character.m_characterRect.left && m_east && !m_flying) { dig(window, character, tilesMap, camera, background, m_blockPos, KeyboardCharacterMover::EAST); return; } } else { character.m_velocityX = 0; } // Collisions in y axis m_testRect.left = character.m_characterRect.left; // Because we don't care about the movement in x axis m_testRect.top += elapsedTime.asSeconds()* character.m_velocityY; // Add y movement m_result = collisions.collidedY(m_testRect, character.m_digPower, tilesMap, m_blockPos); // Test // If there's no collision if(m_result == Collisions::NoCollision) { character.m_characterRect.top = m_testRect.top; // Move the character position camera.moveY(character.m_characterRect, tilesMap.getWorldSize()); // Move the camera position } // If we can dig else if(m_result == Collisions::Diggable) { // Only dig if the the key is pressed, the block is under the character and the velocity in Y isn't too high if(m_blockPos.y > character.m_characterRect.top && m_south && character.m_velocityY <= 500) { m_flying = false; dig(window, character, tilesMap, camera, background, m_blockPos, KeyboardCharacterMover::SOUTH); } else if(m_blockPos.y > character.m_characterRect.top) { impact(character); } else { character.m_velocityY = 0; } } // If we collided but we can't dig else if(m_result == Collisions::BlockCollision && m_blockPos.y > character.m_characterRect.top) { impact(character); } // If we collided with the top or the end of the world (in which case we need to lose life) else if(m_result == Collisions::Collision) { if(!impact(character)) character.m_velocityY = 0; } else { // Set the velocity to 0 if we hit character.m_velocityY = 0; } // Set the image of the character if(character.m_velocityX > 0) { if(m_flying) character.setCharacterTexture("flyRight.png"); else character.setCharacterTexture("vehiculeRight.png"); if(!ServiceLocator::GetAudio()->isSoundPlaying("normal.ogg") && !m_flying) { ServiceLocator::GetAudio()->stopSounds(); ServiceLocator::GetAudio()->playSound("normal.ogg", 60, true); } else if(!ServiceLocator::GetAudio()->isSoundPlaying("fly.ogg") && m_flying) { ServiceLocator::GetAudio()->stopSounds(); ServiceLocator::GetAudio()->playSound("fly.ogg", 60, true); } } else if(character.m_velocityX < 0) { if(m_flying) character.setCharacterTexture("flyLeft.png"); else character.setCharacterTexture("vehiculeLeft.png"); if(!ServiceLocator::GetAudio()->isSoundPlaying("normal.ogg") && !m_flying) { ServiceLocator::GetAudio()->stopSounds(); ServiceLocator::GetAudio()->playSound("normal.ogg", 60, true); } else if(!ServiceLocator::GetAudio()->isSoundPlaying("fly.ogg") && m_flying) { ServiceLocator::GetAudio()->stopSounds(); ServiceLocator::GetAudio()->playSound("fly.ogg", 60, true); } } else if(character.m_velocityX == 0 && m_flying) { if(character.m_characterTextureName == "vehiculeLeft.png") character.setCharacterTexture("flyLeft.png"); else if(character.m_characterTextureName == "vehiculeRight.png") character.setCharacterTexture("flyRight.png"); if(!ServiceLocator::GetAudio()->isSoundPlaying("fly.ogg")) { ServiceLocator::GetAudio()->stopSounds(); ServiceLocator::GetAudio()->playSound("fly.ogg", 60, true); } } else if(character.m_velocityX == 0 && !m_flying) { if(character.m_characterTextureName == "flyLeft.png") character.setCharacterTexture("vehiculeLeft.png"); else if(character.m_characterTextureName == "flyRight.png") character.setCharacterTexture("vehiculeRight.png"); if(!ServiceLocator::GetAudio()->isSoundPlaying("normal.ogg")) { ServiceLocator::GetAudio()->stopSounds(); ServiceLocator::GetAudio()->playSound("normal.ogg", 60, true); } } }
void GS_TraceLaserBeam( trace_t *trace, vec3_t origin, vec3_t angles, float range, int ignore, int timeDelta, void ( *impact )( trace_t *tr, vec3_t dir ) ) { vec3_t from, dir, end; int mask = MASK_SHOT; int passthrough = ignore; entity_state_t *hit; vec3_t mins = { -0.5, -0.5, -0.5 }; vec3_t maxs = { 0.5, 0.5, 0.5 }; int hits[MAX_BEAM_HIT_ENTITIES]; int j, numhits; assert( trace ); AngleVectors( angles, dir, NULL, NULL ); VectorCopy( origin, from ); VectorMA( origin, range, dir, end ); trace->ent = 0; numhits = 0; while( trace->ent != -1 ) { module_Trace( trace, from, mins, maxs, end, passthrough, mask, timeDelta ); if( trace->ent != -1 ) { // prevent endless loops by checking whether we have already impacted this entity for( j = 0; j < numhits; j++ ) { if( trace->ent == hits[j] ) break; } if( j < numhits ) break; // callback impact if( impact ) impact( trace, dir ); // check for pass-through hit = module_GetEntityState( trace->ent, timeDelta ); if( trace->ent == 0 || !hit || hit->solid == SOLID_BMODEL ) // can't pass through brush models break; // if trapped inside solid, just forget about it if( trace->fraction == 0 || trace->allsolid || trace->startsolid ) break; // put a limit on number of hit entities if( numhits < MAX_BEAM_HIT_ENTITIES ) hits[numhits++] = trace->ent; else break; passthrough = trace->ent; VectorCopy( trace->endpos, from ); } } if( trace->ent != -1 ) // was interrupted by a brush model impact { } }
/*! * \brief Start accepting requests from clients. * * \param[in] p Instance to act on * * \return NULL */ static void* __accept_requests(void* p) { simplecmd_t scp = (simplecmd_t) p; // Properly cast SimplePost command handle int client_sock; // Socket the client connected on struct sockaddr_in client_name; // Name of the client socklen_t client_name_len; // Length of the client name structure pthread_t client_thread; // Handle of the client thread struct timespec timeout; // Maximum time to wait for a connection before checking the shutdown sentinel fd_set fds; // File descriptor set (for pselect() socket monitoring) scp->client_count = 0; scp->accpeting_clients = true; while(scp->accpeting_clients) { FD_ZERO(&fds); FD_SET(scp->sock, &fds); timeout.tv_sec = 2; timeout.tv_nsec = 0; switch(pselect(scp->sock + 1, &fds, NULL, NULL, &timeout, NULL)) { case -1: impact(0, "%s: Cannot accept connections on socket %d\n", SP_COMMAND_HEADER_NAMESPACE, scp->sock); scp->accpeting_clients = false; continue; case 0: continue; } client_name_len = sizeof(client_name); client_sock = accept(scp->sock, (struct sockaddr*) &client_name, &client_name_len); if(client_sock == -1) continue; struct simplecmd_request* scrp = (struct simplecmd_request*) malloc(sizeof(struct simplecmd_request)); if(scrp == NULL) { impact(0, "%s: %s: Failed to allocate memory for a new command request thread\n", SP_COMMAND_HEADER_NAMESPACE, SP_MAIN_HEADER_MEMORY_ALLOC); scp->accpeting_clients = false; continue; } scrp->scp = scp; scrp->client_sock = client_sock; if(pthread_create(&client_thread, NULL, &__process_request, (void*) scrp) == 0) { impact(2, "%s: Launched request processing thread 0x%lx for client %d\n", SP_COMMAND_HEADER_NAMESPACE, client_thread, client_sock); pthread_detach(client_thread); } else { impact(2, "%s: Failed to launch request processing thread for client %d\n", SP_COMMAND_HEADER_NAMESPACE, client_sock); close(scrp->client_sock); free(scrp); } } impact(2, "%s: Waiting for %zu clients to finish processing ...\n", SP_COMMAND_HEADER_NAMESPACE, scp->client_count); while(scp->client_count) usleep(1000); impact(4, "%s: Closing socket %d\n", SP_COMMAND_HEADER_NAMESPACE, scp->sock); close(scp->sock); scp->sock = -1; remove(scp->sock_name); return NULL; }
/*! * \brief Safely handle SIGINT by cleanly shutting down the server. * * \warning This function exits the program! * * \param[in] sig Signal to handle */ static void __server_terminal_interrupt(int sig) { impact(1, "\n"); // Terminate the ^C line __server_shutdown(sig); }
/*! * \brief Initialize the server. */ int main(int argc, char* argv[]) { simplearg_t args; // SimplePost arguments args = simplearg_init(); if(args == NULL) { impact(2, "%s: %s: Failed to allocate memory for %s arguments instance\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_HEADER_MEMORY_ALLOC, SP_MAIN_DESCRIPTION); return 0; } simplearg_parse(args, argc, argv); impact_level = args->verbosity; if(args->options & SA_OPT_ERROR) return 1; if(args->actions) { if(args->actions & SA_ACT_HELP) { __print_help(); goto no_error; } else if(args->actions & SA_ACT_VERSION) { __print_version(); goto no_error; } else if(args->actions & SA_ACT_LIST_INST) { if(__list_inst()) goto no_error; else goto error; } else if(args->actions & SA_ACT_LIST_FILES) { if(__resolve_pid(args) == false) goto error; if(__is_pid_valid(args) == false) goto error; if(__list_files(args)) goto no_error; else goto error; } else if(args->actions & SA_ACT_SHUTDOWN) { if(__resolve_pid(args) == false) goto error; if(__is_pid_valid(args) == false) goto error; if(__shutdown_inst(args) == false) goto error; goto no_error; } else { impact(0, "%s: BUG! Failed to handle action 0x%02X\n", __PRETTY_FUNCTION__, args->actions); goto error; } } if(__resolve_pid(args) == false) goto error; if(args->pid) { if(__add_to_other_inst(args)) goto no_error; else goto error; } if(args->options & SA_OPT_DAEMON) { impact(1, "%s: Daemonizing and forking to the background\n", SP_MAIN_HEADER_NAMESPACE); if(daemon(1, 0) == -1) { impact(0, "%s: Failed to daemonize %s: %s\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, strerror(errno)); goto error; } } if(__start_httpd(args) == false) goto error; signal(SIGPIPE, &__server_reset_pipe); signal(SIGINT, &__server_terminal_interrupt); signal(SIGTSTP, &__server_shutdown); signal(SIGQUIT, &__server_shutdown); signal(SIGTERM, &__server_shutdown); cmdd = simplecmd_init(); if(cmdd == NULL) { impact(2, "%s: %s: Failed to allocate memory for %s command server instance\n", SP_MAIN_HEADER_NAMESPACE, SP_MAIN_HEADER_MEMORY_ALLOC, SP_MAIN_DESCRIPTION); goto error; } simplecmd_activate(cmdd, httpd); simplepost_block_files(httpd); no_error: simplecmd_free(cmdd); simplepost_free(httpd); simplearg_free(args); return 0; error: simplecmd_free(cmdd); simplepost_free(httpd); simplearg_free(args); return 1; }
void GameScene::update() { Q_ASSERT(sender() == findChild<QTimer*>()); if(m_paused) return; GraphicsPlayerObject* player = nullptr; QList<AbstractGraphicsPlaneObject*> planes; for(auto item : items()) // find planes { switch(item->type()) { case PlayerType: player = qgraphicsitem_cast<GraphicsPlayerObject*>(item); case EnemyType: planes.append(dynamic_cast<AbstractGraphicsPlaneObject*>(item)); } } if(player && !player->isInvencible()) { Q_ASSERT(player == m_player); const auto playerRect = player->sceneBoundingRect(); for(auto plane : planes) { if(plane != player) { const auto enemyRect = plane->sceneBoundingRect(); if (playerRect.intersects(enemyRect)) player->impact(std::numeric_limits<qint32>::max()); } } } for(auto item : items()) { if(item->type() == BulletType || item->type() == EnemyBulletType) { const auto rect = item->boundingRect().translated(item->pos()); if(!sceneRect().contains(rect)) delete item; else { bool impacted = false; for(auto it = planes.begin(); it != planes.end() && !impacted; ++it) { const auto planeRect = (*it)->sceneBoundingRect(); auto plane = qgraphicsitem_cast< AbstractGraphicsPlaneObject*>(*it); const auto status = plane->status(); if(status == AbstractGraphicsPlaneObject::Status::Alive && planeRect.contains(rect)) { plane->impact(100); impacted = true; } } if(impacted) delete item; } } } if(--m_spawnEnemiesTicks == 0) // Spawn enemies { if(!(qrand() % 24)) // 1/25 spawnEnemies(GraphicsEnemyObject::EnemyType::Boss, true); else spawnEnemies(GraphicsEnemyObject::EnemyType::White, true); m_spawnEnemiesTicks = m_spawnEnemiesMaxTicks; } else if(m_spawnEnemiesTicks == m_spawnEnemiesMaxTicks / 2) { if(!(qrand() % 24)) // 1/25 spawnEnemies(GraphicsEnemyObject::EnemyType::Boss, false); else spawnEnemies(GraphicsEnemyObject::EnemyType::Green, false); } if(m_respawnTicks && --m_respawnTicks == 0) spawnPlayer(); QGraphicsScene::advance(); }
/*! * \brief Get a list of all SimplePost instances on the system with open sockets. * * \note This function has two very important exclusions. (1) First, it will * not include the socket created by this SimplePost instance in the resulting * list. (2) Second, it will only include sockets that we have read/write * access to. * * \param[out] sclp * \parblock * List of all open SimplePost sockets (excluding ours) * * If *sclp != NULL, you are responsible for freeing it. * \endparblock * * \return the number of instances in the list. If zero is returned, either a * memory allocation error occurred, or, more likely, there are no other * instances of SimplePost currently active */ size_t simplecmd_list_inst(simplecmd_list_t* sclp) { DIR* dp; // Directory handle struct dirent* ep; // Entity in the directory char suspect[512]; // Absolute path of the current entity int suspect_len; // Length of the current entity's absolute path struct stat suspect_status; // Status of the current entity char sock_name[512]; // Name of our socket regex_t regex; // Compiled SimplePost socket matching regular expression simplecmd_list_t tail; // Last element in the list size_t count = 0; // Number of items in the list tail = *sclp = NULL; // Failsafe dp = opendir(SP_COMMAND_SOCK_DIR); if(dp == NULL) { impact(0, "%s: Failed to open the command socket directory %s: %s\n", SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_SOCK_DIR, strerror(errno)); return 0; } sprintf(sock_name, "^%s_sock_[0-9]+$", SP_MAIN_SHORT_NAME); if(regcomp(®ex, sock_name, REG_EXTENDED | REG_NOSUB | REG_NEWLINE)) { impact(0, "%s: BUG! Failed to compile the socket matching regular expression\n", __PRETTY_FUNCTION__); closedir(dp); return 0; } sprintf(sock_name, "%s_sock_%d", SP_MAIN_SHORT_NAME, getpid()); while((ep = readdir(dp))) { suspect_len = snprintf(suspect, sizeof(suspect), "%s/%s", SP_COMMAND_SOCK_DIR, ep->d_name); if(suspect_len < 1 || (size_t) suspect_len >= sizeof(suspect)) { impact(0, "%s: Skipping %s/%s because only %zu of %d bytes are available in the buffer\n", SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_SOCK_DIR, ep->d_name, sizeof(suspect), suspect_len); continue; } if(stat(suspect, &suspect_status) == 0 && S_ISSOCK(suspect_status.st_mode) && access(suspect, R_OK | W_OK) == 0) { int regex_ret = regexec(®ex, ep->d_name, 0, NULL, 0); if(regex_ret == 0 && strcmp(sock_name, ep->d_name) != 0) { if(tail) { tail->next = simplecmd_list_init(); if(tail->next == NULL) { impact(0, "%s: %s: Failed to add a new element to the element list\n", SP_COMMAND_HEADER_NAMESPACE, SP_MAIN_HEADER_MEMORY_ALLOC); simplecmd_list_free(*sclp); *sclp = NULL; count = 0; break; } tail->next->prev = tail; tail = tail->next; } else { tail = *sclp = simplecmd_list_init(); if(tail == NULL) { impact(0, "%s:%d: Failed to initialize the list\n", __FILE__, __LINE__); break; } } count++; tail->sock_name = (char*) malloc(sizeof(char) * (strlen(suspect) + 1)); if(tail->sock_name == NULL) { impact(2, "%s: %s: Failed to allocate memory for socket name\n", SP_COMMAND_HEADER_NAMESPACE, SP_MAIN_HEADER_MEMORY_ALLOC); simplecmd_list_free(*sclp); *sclp = NULL; count = 0; break; } strcpy(tail->sock_name, suspect); const char* pid_ptr = suspect; while(isdigit(*pid_ptr) == 0) ++pid_ptr; sscanf(pid_ptr, "%d", &tail->inst_pid); impact(4, "%s: Found %s:%d socket %s\n", SP_COMMAND_HEADER_NAMESPACE, SP_MAIN_DESCRIPTION, tail->inst_pid, tail->sock_name); } else if(regex_ret != REG_NOMATCH) { char buffer[1024]; // regerror() error message regerror(regex_ret, ®ex, buffer, sizeof(buffer)/sizeof(buffer[0])); impact(0, "%s: %s\n", SP_COMMAND_HEADER_NAMESPACE, buffer); if(*sclp) { simplecmd_list_free(*sclp); *sclp = NULL; count = 0; } break; } } } regfree(®ex); closedir(dp); return count; }
/*! * \brief Receive a file and count from the client and add it our web server. * * \param[in] scp Instance to act on * \param[in] sock Client socket * * \retval true the requested information was sent successfully * \retval false failed to respond to the request */ static bool __command_recv_file(simplecmd_t scp, int sock) { char* url = NULL; // URL of the file being served char* file = NULL; // Name and path of the file to serve char* uri = NULL; // URI of the file to serve char* buffer = NULL; // Count or identifier string from the client unsigned int count; // Number of times the file should be served while(__sock_recv(sock, NULL, &buffer)) { if(buffer == NULL) goto error; impact(3, "%s: %s: Receiving %s\n", SP_COMMAND_HEADER_NAMESPACE, __func__, buffer); if(strcmp(buffer, SP_COMMAND_FILE_FILE) == 0) { free(buffer); buffer = NULL; if(file) { impact(0, "%s: %s: Received a second FILE\n", SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_HEADER_PROTOCOL_ERROR); goto error; } else if(__sock_recv(sock, NULL, &file) == 0) { impact(0, "%s: %s: Did not receive a FILE as expected\n", SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_HEADER_PROTOCOL_ERROR); goto error; } } else if(strcmp(buffer, SP_COMMAND_FILE_URI) == 0) { free(buffer); buffer = NULL; if(uri) { impact(0, "%s: %s: Received a second URI\n", SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_HEADER_PROTOCOL_ERROR); goto error; } else if(__sock_recv(sock, NULL, &uri) == 0) { impact(0, "%s: %s: Did not receive a URI as expected\n", SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_HEADER_PROTOCOL_ERROR); goto error; } } else if(strcmp(buffer, SP_COMMAND_FILE_COUNT) == 0) { free(buffer); buffer = NULL; if(__sock_recv(sock, NULL, &buffer) == 0) { impact(0, "%s: %s: Did not receive the COUNT as expected\n", SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_HEADER_PROTOCOL_ERROR); goto error; } if(sscanf(buffer, "%u", &count) == EOF) { impact(0, "%s: %s: %s is not a valid COUNT\n", SP_COMMAND_HEADER_NAMESPACE, SP_MAIN_HEADER_MEMORY_ALLOC, buffer); goto error; } free(buffer); buffer = NULL; } else { impact(3, "%s: %s: Invalid file identifier \"%s\"\n", SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_HEADER_PROTOCOL_ERROR, buffer); goto error; } } if(file == NULL) { impact(0, "%s: %s: Did not receive a FILE to serve\n", SP_COMMAND_HEADER_NAMESPACE, SP_COMMAND_HEADER_PROTOCOL_ERROR); goto error; } if(simplepost_serve_file(scp->spp, &url, file, uri, count) == 0) return false; free(buffer); free(uri); free(file); free(url); return true; error: free(buffer); free(uri); free(file); free(url); return false; }