WSLUA_CONSTRUCTOR Dir_open(lua_State* L) { /* Opens a directory and returns a `Dir` object representing the files in the directory. @code for filename in Dir.open(path) do ... end @endcode */ #define WSLUA_ARG_Dir_open_PATHNAME 1 /* The pathname of the directory. */ #define WSLUA_OPTARG_Dir_open_EXTENSION 2 /* If given, only files with this extension will be returned. */ const char* dirname = luaL_checkstring(L,WSLUA_ARG_Dir_open_PATHNAME); const char* extension = luaL_optstring(L,WSLUA_OPTARG_Dir_open_EXTENSION,NULL); Dir dir; char* dirname_clean; dirname_clean = wslua_get_actual_filename(dirname); if (!dirname_clean) { WSLUA_ARG_ERROR(Dir_open,PATHNAME,"directory does not exist"); return 0; } if (!test_for_directory(dirname_clean)) { g_free(dirname_clean); WSLUA_ARG_ERROR(Dir_open,PATHNAME, "must be a directory"); return 0; } dir = (Dir)g_malloc(sizeof(struct _wslua_dir)); dir->dir = g_dir_open(dirname_clean, 0, dir->dummy); g_free(dirname_clean); dir->ext = extension ? g_strdup(extension) : NULL; dir->dummy = (GError **)g_malloc(sizeof(GError *)); *(dir->dummy) = NULL; if (dir->dir == NULL) { g_free(dir->dummy); g_free(dir); WSLUA_ARG_ERROR(Dir_open,PATHNAME,"could not open directory"); return 0; } pushDir(L,dir); WSLUA_RETURN(1); /* the `Dir` object. */ }
void Bot::TouchedJumppad(const edict_t *jumppad) { // jumppad->s.origin2 contains initial push velocity Vec3 pushDir(jumppad->s.origin2); pushDir.NormalizeFast(); float relaxedFlightSeconds = 0; float zDotFactor = pushDir.Dot(&axis_identity[AXIS_UP]); if (zDotFactor > 0) { // Start to find landing area when vertical velocity is close to zero. // This may be wrong for Q3-like horizontal jumppads, // but its unlikely to see this kind of triggers in the QF game. relaxedFlightSeconds = 0.90f * jumppad->s.origin2[2] / (level.gravity + 0.0001f); } // Otherwise (for some weird jumppad that pushes dow) start to find landing area immediately jumppadMovementState.jumppadMoveTimeout = level.time + (unsigned)(1000.0f * relaxedFlightSeconds); jumppadMovementState.hasTouchedJumppad = true; jumppadMovementState.jumppadTarget = Vec3(jumppad->target_ent->s.origin); }
WSLUA_CONSTRUCTOR Dir_open(lua_State* L) { /* Usage: for filename in Dir.open(path) do ... end */ #define WSLUA_ARG_Dir_open_PATHNAME 1 /* The pathname of the directory */ #define WSLUA_OPTARG_Dir_open_EXTENSION 2 /* If given, only file with this extension will be returned */ const char* dirname = luaL_checkstring(L,WSLUA_ARG_Dir_open_PATHNAME); const char* extension = luaL_optstring(L,WSLUA_OPTARG_Dir_open_EXTENSION,NULL); Dir dir; char* dirname_clean; if (!dirname) WSLUA_ARG_ERROR(Dir_open,PATHNAME,"must be a string"); dirname_clean = wslua_get_actual_filename(dirname); if (!dirname_clean) WSLUA_ARG_ERROR(Dir_open,PATHNAME,"directory does not exist"); if (!test_for_directory(dirname_clean)) { g_free(dirname_clean); WSLUA_ARG_ERROR(Dir_open,PATHNAME, "must be a directory"); } dir = g_malloc(sizeof(struct _wslua_dir)); dir->dir = OPENDIR_OP(dirname_clean); g_free(dirname_clean); dir->ext = extension ? g_strdup(extension) : NULL; dir->dummy = g_malloc(sizeof(GError *)); *(dir->dummy) = NULL; if (dir->dir == NULL) { g_free(dir->dummy); g_free(dir); WSLUA_ARG_ERROR(Dir_open,PATHNAME,"could not open directory"); } pushDir(L,dir); WSLUA_RETURN(1); /* the Dir object */ }
signed char do_restore(nwBackupParms * parms, char * remote_name, char * local_dir, char * logfile) { char ctrl_file_name[L_tmpnam]; FILE * ctrl_file; dirStack_t dstack; dirStruct_t dummy_curr_dir; fileStruct_t dummy_curr_file; nwBackupCodes nw_rc = SUCCESS; int do_restore_rc = 0; int path_eostr; char current_file_name[FILENAME_MAX]; char * path, * path_and_file, * unix_path, \ * unix_path_and_file, * file_buffer, * in_buffer; uint8_t * ctrl_buffer; path = malloc(129 * 4); file_buffer = malloc(FILE_BUF_SIZE); in_buffer = malloc(OUTBUF_SIZE); ctrl_buffer = malloc(BUFSIZ); /* Should be more than enough... handle dynamically sizing it later. */ //dummy_outbuf = calloc(OUTBUF_SIZE, 1); //This doesn't set the first and third byte //to zero! if(path == NULL || file_buffer == NULL || in_buffer == NULL || ctrl_buffer == NULL) { fprintf(stderr, "Could not allocate memory for path or file buffers!\n"); return -1; } /* Don't bother freeing till end of program- if error, program will terminate soon anyway! */ path_and_file = path + 129; unix_path = path_and_file + 129; unix_path_and_file = unix_path + 129; if(initDirStack(&dstack)) { fprintf(stderr, "Directory Stack Initialization failed!\n"); return -2; } if(!strcpy(path, local_dir)) /* if(strncpy(path, argv[1], DIR_MAX_PATH + 1) >= (DIR_MAX_PATH + 1)) */ { /* Shouldn't fail... but Heartbleed convinces me to code defensively. */ fprintf(stderr, "Specified path name is too long...\n" "Actually if we're got this error on DOS, we have more serious\n" "trouble than just a bad path!\n"); } path_eostr = strlen(path); if(path[path_eostr - 1] == 92) { /* Backslash */ path[path_eostr - 1] = '\0'; local_dir[path_eostr - 1] = '\0'; /* We will need local dir again! */ path_eostr--; /* path_eostr now points to the root path's NULL terminator. */ } //full_unix_path = malloc(strlen(parms-> strlen(remote_name) + ); /* If doing an absolute-path restore, the first push should be deferred until the control file header is read. */ if(pushDir(&dstack, &dummy_curr_dir, path)) { fprintf(stderr, "Initial directory push failed!\n"); return -3; } if(tmpnam(ctrl_file_name) == NULL) { fprintf(stderr, "Attempt to allocate tmpnam() for receiving CONTROL failed!\n"); return -4; } ctrl_file = fopen(ctrl_file_name, "wb+"); if(ctrl_file == NULL) { fprintf(stderr, "Attempt to open temp file for receiving CONTROL failed!\n"); return -5; } nw_rc = initRemote(parms); if(nw_rc != SUCCESS) { do_restore_rc = -6; } nw_rc = chDirRemote(remote_name); if(!(nw_rc == SUCCESS)) { do_restore_rc = -7; } if(!do_restore_rc) { /* Grab the control file from the server */ fprintf(stderr, "Receiving control file from the server (no retry)...\n"); setvbuf(ctrl_file, file_buffer, _IOFBF, FILE_BUF_SIZE); if(restore_file(ctrl_file, "CONTROL.NFO", in_buffer, OUTBUF_SIZE)) { fprintf(stderr, "Couldn't receive control file (%s) to the server. Supply" "the control file manually (not implemented) and try again.\n", ctrl_file_name); do_restore_rc = -8; } else { /* Control file was successfully grabbed. We can continue. */ ctrlEntryType_t entry_type; int8_t all_dirs_restored = 0; unsigned int attr, time, date; long unsigned int size; fprintf(stderr, "Control file received successfully from the server.\n"); fclose(ctrl_file); /* Assume this doesn't fail for now */ ctrl_file = fopen(ctrl_file_name, "rb"); entry_type = getNextEntry(ctrl_file, ctrl_buffer, BUFSIZ); while(!all_dirs_restored && do_restore_rc == 0) { FILE * curr_file; int temp; switch(entry_type) { case CTRL_HEADER: /* For now, absolute-path restores are disabled. Restores are relative to the directory in which the program is invoked. In effect, this code does nothing! */ //parseHeaderEntry(ctrl_buffer, path); /* if(pushDir(&dstack, &dummy_curr_dir, path)) { fprintf(stderr, "Initial directory push failed!\n"); do_restore_rc = -16; } */ fprintf(stderr, "Root directory: %s\n", path); break; case CTRL_DIR: temp = parseDirEntry(ctrl_buffer, current_file_name, &attr, &time, &date, &size); /* Change to snprintf soon */ sprintf(path_and_file, "%s\\%s", path, current_file_name); strcpy(path, path_and_file); unix_path[0] = '\0'; /* Skip the leading separator for now... */ if(createUnixName(unix_path, &path[path_eostr + 1]) == NULL) { fprintf(stderr, "Unix directory name creation failed!\n"); do_restore_rc = -9; break; } /* fprintf(stderr, "Return code: %d Curr directory: %s, Attr: %hu\nUnix name: %s\n",\ temp, path, attr, unix_path); */ if(_mkdir(path)) { fprintf(stderr, "Directory creation failed (%s)!\n", path); do_restore_rc = -10; } else { int dos_handle; fprintf(stderr, "Directory created: %s\n", path); if(_dos_open(path, O_RDONLY, &dos_handle)) { fprintf(stderr, "Warning: Could not open directory to set attributes!\n"); } else { if(_dos_setftime(dos_handle, date, time)) { fprintf(stderr, "Warning: Could not reset date/time on directory %s!\n", path); } _dos_close(dos_handle); if(_dos_setfileattr(path_and_file, attr)) { fprintf(stderr, "Warning: Could not set attributes on directory %s!\n", path); } } } //getchar(); break; case CTRL_FILE: /* Should not cause buffer overflow, since sizeof(current_file_name) set to FILENAME_MAX */ temp = parseFileEntry(ctrl_buffer, current_file_name, &attr, &time, &date, &size); /* Skip the leading separator for now... */ sprintf(path_and_file, "%s\\%s", path, current_file_name); if(!strcmp(path, local_dir)) { /* Don't copy a separator if the path is at the root... otherwise the server won't find the file and/or think the file is at the server's root! */ strcpy(unix_path_and_file, current_file_name); } else { sprintf(unix_path_and_file, "%s/%s", unix_path, current_file_name); } /* fprintf(stderr, "Return code: %d Curr directory: %s, Attr: %hu, Time %hu, Date %hu, Size %lu\n" \ "Unix directory: %s\n", temp, path_and_file, attr, time, date, size, unix_path_and_file); */ /* Receive file scope block. */ { int retry_count = 0; int8_t local_error = 0, rcv_done = 0; fprintf(stderr, "Receiving file %s...\n", unix_path_and_file); while(!rcv_done && !local_error && retry_count <= 3) { int8_t rcv_remote_rc; if(retry_count) { fprintf(stderr, "Retrying operation... (%d)\n", rcv_remote_rc); } curr_file = fopen(path_and_file, "wb"); setvbuf(curr_file, file_buffer, _IOFBF, FILE_BUF_SIZE); rcv_remote_rc = restore_file(curr_file, unix_path_and_file, in_buffer, OUTBUF_SIZE); //rcv_remote_rc = 0; fclose(curr_file); /* Close the file no matter what */ switch(rcv_remote_rc) { case 0: rcv_done = 1; break; case -2: fprintf(stderr, "Read error on file: %s! Not continuing.", path_and_file); local_error = 1; /* Local file error. */ break; case -1: /* Recoverable error. */ default: break; } retry_count++; } if(local_error) { /* If file error, we need to break out. */ do_restore_rc = -11; } else if(retry_count > 3) { do_restore_rc = -12; } else { /* File receive ok, try setting attributes now. */ int dos_handle; if(_dos_open(path_and_file, O_RDONLY, &dos_handle)) { fprintf(stderr, "Warning: Could not open file to set attributes!\n"); } else { if(_dos_setftime(dos_handle, date, time)) { fprintf(stderr, "Warning: Could not reset date/time on file %s!\n", path_and_file); } _dos_close(dos_handle); if(_dos_setfileattr(path_and_file, attr)) { fprintf(stderr, "Warning: Could not set attributes on file %s!\n", path_and_file); } } } } break; case CTRL_CDUP: /* Remove the deepest directory of the path, as long as we are not back at the invocation directory. */ //fprintf(stderr, "CDUP occurred.\n"); if(strcmp(path, local_dir)) { char * separator = strrchr(path, 92); if(separator != NULL) { /* Two characters need to be set to null because */ (* separator) = '\0'; //fprintf(stderr, "Path was stripped. ); } fprintf(stderr, "Directory change. New path is: %s\n", path); /* Skip the leading separator for now... we need to recreate the unix path in case a directory does not follow next! */ if(createUnixName(unix_path, &path[path_eostr + 1]) == NULL) { fprintf(stderr, "Unix directory name creation failed!\n"); do_restore_rc = -13; break; } //getchar(); } break; case CTRL_EOF: all_dirs_restored = 1; fprintf(stderr, "End of control file.\n"); break; default: fprintf(stderr, "Unexpected data from control file!\n"); do_restore_rc = -14; break; } entry_type = getNextEntry(ctrl_file, ctrl_buffer, BUFSIZ); fprintf(stderr, "\n"); } } } if(do_restore_rc) { fprintf(stderr, "Full restore failed with status code %d.\n", do_restore_rc); } else { fprintf(stderr, "Full restore completed successfully.\n"); } fclose(ctrl_file); closeRemote(); remove(ctrl_file_name); return do_restore_rc; }
////////////////////////////////////////////////////////////////////////// // NOTE: This function must be thread-safe. Before adding stuff contact MarcoC. void CVehicleMovementStdBoat::ProcessMovement(const float deltaTime) { FUNCTION_PROFILER( GetISystem(), PROFILE_GAME ); static const float fWaterLevelMaxDiff = 0.15f; // max allowed height difference between propeller center and water level static const float fSubmergedMin = 0.01f; static const float fMinSpeedForTurn = 0.5f; // min speed so that turning becomes possible if (m_bNetSync) m_netActionSync.UpdateObject(this); CryAutoCriticalSection lk(m_lock); CVehicleMovementBase::ProcessMovement(deltaTime); IEntity* pEntity = m_pVehicle->GetEntity(); IPhysicalEntity* pPhysics = pEntity->GetPhysics(); SVehiclePhysicsStatus* physStatus = &m_physStatus[k_physicsThread]; assert(pPhysics); float frameTime = min(deltaTime, 0.1f); if (abs(m_movementAction.power) < 0.001f) m_movementAction.power = 0.f; if (abs(m_movementAction.rotateYaw) < 0.001f) m_movementAction.rotateYaw = 0.f; Matrix34 wTM( physStatus->q ); wTM.AddTranslation( physStatus->pos ); Matrix34 wTMInv = wTM.GetInvertedFast(); Vec3 localVel = wTMInv.TransformVector( physStatus->v ); Vec3 localW = wTMInv.TransformVector( physStatus->w ); const Vec3 xAxis = wTM.GetColumn0(); const Vec3 yAxis = wTM.GetColumn1(); const Vec3 zAxis = wTM.GetColumn2(); // check if propeller is in water Vec3 worldPropPos = wTM * m_pushOffset; float waterLevelWorld = gEnv->p3DEngine->GetWaterLevel( &worldPropPos ); float fWaterLevelDiff = worldPropPos.z - waterLevelWorld; bool submerged = physStatus->submergedFraction > fSubmergedMin; m_inWater = submerged && fWaterLevelDiff < fWaterLevelMaxDiff; float speed = physStatus->v.len2() > 0.001f ? physStatus->v.len() : 0.f; float speedRatio = min(1.f, speed/(m_maxSpeed*m_factorMaxSpeed)); float absPedal = abs(m_movementAction.power); float absSteer = abs(m_movementAction.rotateYaw); // wave stuff float waveFreq = 1.f; waveFreq += 3.f*speedRatio; float waveTimerPrev = m_waveTimer; m_waveTimer += frameTime*waveFreq; // new randomized amount for this oscillation if (m_waveTimer >= gf_PI && waveTimerPrev < gf_PI) m_waveRandomMult = cry_random(0.0f, 1.0f); if (m_waveTimer >= 2*gf_PI) m_waveTimer -= 2*gf_PI; float kx = m_waveIdleStrength.x*(m_waveRandomMult+0.3f) * (1.f-speedRatio + m_waveSpeedMult*speedRatio); float ky = m_waveIdleStrength.y * (1.f - 0.5f*absPedal - 0.5f*absSteer); Vec3 waveLoc = m_massOffset; waveLoc.y += speedRatio*min(0.f, m_pushOffset.y-m_massOffset.y); waveLoc = wTM * waveLoc; bool visible = m_pVehicle->GetGameObject()->IsProbablyVisible(); bool doWave = visible && submerged && physStatus->submergedFraction < 0.99f; if (doWave && !m_isEnginePowered) m_pVehicle->NeedsUpdate(IVehicle::eVUF_AwakePhysics); if (m_isEnginePowered || (visible && !m_pVehicle->IsProbablyDistant())) { if (doWave && (m_isEnginePowered || g_pGameCVars->v_rockBoats)) { pe_action_impulse waveImp; waveImp.angImpulse.x = Boosting() ? 0.f : sinf(m_waveTimer) * frameTime * m_Inertia.x * kx; if (isneg(waveImp.angImpulse.x)) waveImp.angImpulse.x *= (1.f - min(1.f, 2.f*speedRatio)); // less amplitude for negative impulse waveImp.angImpulse.y = sinf(m_waveTimer-0.5f*gf_PI) * frameTime * m_Inertia.y * ky; waveImp.angImpulse.z = 0.f; waveImp.angImpulse = wTM.TransformVector(waveImp.angImpulse); waveImp.point = waveLoc; if (!m_movementAction.isAI) pPhysics->Action(&waveImp, 1); } } // ~wave stuff if (!m_isEnginePowered) return; pe_action_impulse linearImp, angularImp, dampImp, liftImp; float turnAccel = 0, turnAccelNorm = 0; if (m_inWater) { // Lateral damping if (m_lateralDamping>0.f) { pe_action_impulse impulse; impulse.impulse = - physStatus->mass * xAxis * (localVel.x * (frameTime * m_lateralDamping)/(1.f + frameTime*m_lateralDamping)); pPhysics->Action(&impulse, 1); } // optional lifting (catamarans) if (m_velLift > 0.f) { if (localVel.y > m_velLift && !IsLifted()) Lift(true); else if (localVel.y < m_velLift && IsLifted()) Lift(false); } if (Boosting() && IsLifted()) { // additional lift force liftImp.impulse = Vec3(0,0,physStatus->mass*frameTime*(localVel.y/(m_velMax*m_factorMaxSpeed))*3.f); liftImp.point = wTM * m_massOffset; pPhysics->Action(&liftImp, 1); } // apply driving force float a = m_movementAction.power; if (sgn(a)*sgn(localVel.y) > 0) { // reduce acceleration with increasing speed float ratio = (localVel.y > 0.f) ? localVel.y/(m_velMax*m_factorMaxSpeed) : -localVel.y/(m_velMaxReverse*m_factorMaxSpeed); a = (ratio>1.f) ? 0.f : sgn(a)*min(abs(a), 1.f-((1.f-m_accelVelMax)*sqr(ratio))); } if (a != 0) { if (sgn(a) * sgn(localVel.y) < 0) // "braking" a *= m_accelCoeff; else a = max(a, -m_pedalLimitReverse); Vec3 pushDir(FORWARD_DIRECTION); // apply force downwards a bit for more realistic response if (a > 0) pushDir = Quat_tpl<float>::CreateRotationAA( DEG2RAD(m_pushTilt), Vec3(-1,0,0) ) * pushDir; pushDir = wTM.TransformVector( pushDir ); linearImp.impulse = pushDir * physStatus->mass * a * m_accel * m_factorAccel * frameTime; linearImp.point = m_pushOffset; linearImp.point.x = m_massOffset.x; linearImp.point = wTM * linearImp.point; pPhysics->Action(&linearImp, 1); } float roll = (float)__fsel(zAxis.z - 0.2f, xAxis.z / (frameTime + frameTime*frameTime), 0.f); // Roll damping (with a exp. time constant of 1 sec) // apply steering if (m_movementAction.rotateYaw != 0) { if (abs(localVel.y) < fMinSpeedForTurn){ // if forward speed too small, no turning possible turnAccel = 0; } else { int iDir = m_movementAction.power != 0.f ? sgn(m_movementAction.power) : sgn(localVel.y); turnAccelNorm = m_movementAction.rotateYaw * iDir * max(1.f, m_turnVelocityMult * speedRatio); // steering and current w in same direction? int sgnSteerW = sgn(m_movementAction.rotateYaw) * iDir * sgn(-localW.z); if (sgnSteerW < 0) { // "braking" turnAccelNorm *= m_turnAccelCoeff; } else { // reduce turn vel towards max float maxRatio = 1.f - 0.15f*min(1.f, abs(localW.z)/m_turnRateMax); turnAccelNorm = sgn(turnAccelNorm) * min(abs(turnAccelNorm), maxRatio); } turnAccel = turnAccelNorm * m_turnAccel; //roll = 0.2f * turnAccel; // slight roll } } // Use the centripetal acceleration to determine the amount of roll float centripetalAccel = clamp_tpl(speed * localW.z, -10.f, +10.f); roll -= (1.f - 2.f*fabsf(xAxis.z)) * m_rollAccel * centripetalAccel; // Always damp rotation! turnAccel += localW.z * m_turnDamping; if (turnAccel != 0) { Vec3& angImp = angularImp.angImpulse; angImp.x = 0.f; angImp.y = roll * frameTime * m_Inertia.y; angImp.z = -turnAccel * frameTime * m_Inertia.z; angImp = wTM.TransformVector( angImp ); pPhysics->Action(&angularImp, 1); } if (abs(localVel.x) > 0.01f) { // lateral force Vec3& cornerForce = dampImp.impulse; cornerForce.x = -localVel.x * m_cornerForceCoeff * physStatus->mass * frameTime; cornerForce.y = 0.f; cornerForce.z = 0.f; if (m_cornerTilt != 0) cornerForce = Quat_tpl<float>::CreateRotationAA( sgn(localVel.x)*DEG2RAD(m_cornerTilt), Vec3(0,1,0) ) * cornerForce; dampImp.impulse = wTM.TransformVector(cornerForce); dampImp.point = m_cornerOffset; dampImp.point.x = m_massOffset.x; dampImp.point = wTM.TransformPoint( dampImp.point ); pPhysics->Action(&dampImp, 1); } } EjectionTest(deltaTime); if (!m_pVehicle->GetStatus().doingNetPrediction) { if (m_bNetSync && m_netActionSync.PublishActions( CNetworkMovementStdBoat(this) )) CHANGED_NETWORK_STATE(m_pVehicle, CNetworkMovementStdBoat::CONTROLLED_ASPECT ); } }