//Falling physics loop bool Physics::updateFall() { uint32_t listSize = fallSimList.size(); for (int32_t simIt = listSize-1; simIt >= 0; simIt--) { bool hitGround = false; double timeInSec = (microTime()-fallSimList[simIt].startTime)/1000000.0; fallSimList[simIt].ticks++; const double gravity = 9.81; double offset = 0.5*gravity*timeInSec*timeInSec; int blockOffset = fallSimList[simIt].pos.y() - fallSimList[simIt].lastY; if(blockOffset != (int)offset) { for(int ypos = fallSimList[simIt].lastY-1; ypos >= fallSimList[simIt].lastY-((int)offset-blockOffset);ypos--) { uint8_t block, meta; ServerInstance->map(map)->getBlock(fallSimList[simIt].pos.x(),ypos,fallSimList[simIt].pos.z(), &block, &meta); fallSimList[simIt].lastY--; switch (block) { case BLOCK_AIR: case BLOCK_WATER: case BLOCK_STATIONARY_WATER: case BLOCK_LAVA: case BLOCK_STATIONARY_LAVA: case BLOCK_SNOW: break; //If we hit ground default: { ServerInstance->map(map)->setBlock(fallSimList[simIt].pos.x(),ypos+1,fallSimList[simIt].pos.z(), fallSimList[simIt].block, 0); ServerInstance->map(map)->sendBlockChange(fallSimList[simIt].pos.x(),ypos+1,fallSimList[simIt].pos.z(), fallSimList[simIt].block, 0); //Despawn entity Packet pkt = Protocol::destroyEntity(fallSimList[simIt].EID); const int chunk_x = blockToChunk(fallSimList[simIt].pos.x()); const int chunk_z = blockToChunk(fallSimList[simIt].pos.z()); const ChunkMap::const_iterator it = ServerInstance->map(map)->chunks.find(Coords(chunk_x, chunk_z)); if (it != ServerInstance->map(map)->chunks.end()) { it->second->sendPacket(pkt); } //Erase from the simulation list fallSimList.erase(fallSimList.begin()+simIt); hitGround = true; break; } } if(hitGround) { break; } } } } return true; }
//Falling physics loop bool Physics::updateFall() { uint32_t listSize = fallSimList.size(); for (int32_t simIt = listSize-1; simIt >= 0; simIt--) { Falling& f = fallSimList[simIt]; double timeInSec = (microTime()-f.startTime)/1000000.0; f.ticks++; const double gravity = 9.81; double offset = 0.5*gravity*timeInSec*timeInSec; int blockOffset = f.pos.y() - f.lastY; if(blockOffset != (int)offset) { /// not necessary, doesn't optimize much int yStart = f.pos.y(); int x = f.pos.x(); int z = f.pos.z(); int ypos = f.lastY; f.lastY = yStart-(int)offset; for(; ypos >= f.lastY; ypos--) { uint8_t block, meta; map->getBlock(x,ypos,z, &block, &meta); switch (block) { case BLOCK_AIR: case BLOCK_WATER: case BLOCK_STATIONARY_WATER: case BLOCK_LAVA: case BLOCK_STATIONARY_LAVA: case BLOCK_SNOW: break; //If we hit ground default: { map->setBlock(x, ++ypos, z, f.block, 0); map->sendBlockChange(x, ypos, z, f.block, 0); //Despawn entity Packet pkt = Protocol::destroyEntity(f.EID); const int chunk_x = blockToChunk(x); const int chunk_z = blockToChunk(z); const ChunkMap::const_iterator it = map->chunks.find(Coords(chunk_x, chunk_z)); if (it != map->chunks.end()) { it->second->sendPacket(pkt); } //Erase from the simulation list fallSimList.erase(fallSimList.begin()+simIt); goto breakout; } } } } breakout: continue; } return true; }
int main(void) { double d,dd; MICRO_TIME tim; TimeStart(&tim); int i=1; while(/*!kbhit()*/i<1e3) { d = microTime(); // usleep(1E6); dd = microTime() - d; //d = dd*(dd+1.0)/(dd-1.0); printf("[%d] Time in microseconds: %lf = %lf s\n",i, dd,dd/1E6); i++; } printf("%lf sec\n",TimeStop(&tim)/1E6); return(0); }
void MethodState_Delete(tThread *pThread, tMethodState **ppMethodState) { tMethodState *pThis = *ppMethodState; #ifdef GEN_COMBINED_OPCODES if (pThis->pJIT != pThis->pMethod->pJITted) { // Only decrease call-stack count if it's been using the combined JIT pThis->pMethod->callStackCount--; } if (pThis->pCaller != NULL) { // Add a call to the method being returned to. // This is neccesary to give a more correct 'usage heuristic' to long-running // methods that call lots of other methods. AddCall(pThis->pCaller->pMethod); } #endif #ifdef DIAG_METHOD_CALLS pThis->pMethod->totalTime += microTime() - pThis->startTime; #endif // If this MethodState is a Finalizer, then let the heap know this Finalizer has been run if (pThis->finalizerThis != NULL) { Heap_UnmarkFinalizer(pThis->finalizerThis); } if (pThis->pDelegateParams != NULL) { free(pThis->pDelegateParams); } // Note that the way the stack free funtion works means that only the 1st allocated chunk // needs to be free'd, as this function just sets the current allocation offset to the address given. Thread_StackFree(pThread, pThis); *ppMethodState = NULL; }
tMethodState* MethodState_Direct(tThread *pThread, tMD_MethodDef *pMethod, tMethodState *pCaller, U32 isInternalNewObjCall) { tMethodState *pThis; if (!pMethod->isFilled) { tMD_TypeDef *pTypeDef; pTypeDef = MetaData_GetTypeDefFromMethodDef(pMethod); MetaData_Fill_TypeDef(pTypeDef, NULL, NULL); } pThis = (tMethodState*)Thread_StackAlloc(pThread, sizeof(tMethodState)); pThis->finalizerThis = NULL; pThis->pCaller = pCaller; pThis->pMetaData = pMethod->pMetaData; pThis->pMethod = pMethod; if (pMethod->pJITted == NULL) { // If method has not already been JITted JIT_Prepare(pMethod, 0); } pThis->pJIT = pMethod->pJITted; pThis->ipOffset = 0; pThis->pEvalStack = (PTR)Thread_StackAlloc(pThread, pThis->pMethod->pJITted->maxStack); pThis->stackOfs = 0; pThis->isInternalNewObjCall = isInternalNewObjCall; pThis->pNextDelegate = NULL; pThis->pDelegateParams = NULL; pThis->pParamsLocals = (PTR)Thread_StackAlloc(pThread, pMethod->parameterStackSize + pMethod->pJITted->localsStackSize); memset(pThis->pParamsLocals, 0, pMethod->parameterStackSize + pMethod->pJITted->localsStackSize); #ifdef GEN_COMBINED_OPCODES AddCall(pMethod); /*if (combinedJITSize < GEN_COMBINED_OPCODES_MAX_MEMORY) { if (pMethod->genCallCount > GEN_COMBINED_OPCODES_CALL_TRIGGER) { if (pMethod->pJITtedCombined == NULL) { JIT_Prepare(pMethod, 1); combinedJITSize += pMethod->pJITtedCombined->opsMemSize; } } }*/ if (pMethod->pJITtedCombined == NULL && pMethod->genCallCount >= GEN_COMBINED_OPCODES_CALL_TRIGGER && (pMethod->pNextHighestCalls == NULL || pMethod->pPrevHighestCalls == NULL || pMethod->pPrevHighestCalls->pJITtedCombined != NULL || (combinedJITSize < GEN_COMBINED_OPCODES_MAX_MEMORY && pMethod->pNextHighestCalls->pJITtedCombined != NULL))) { // Do a combined JIT, if there's enough room after removing combined JIT from previous if (combinedJITSize > GEN_COMBINED_OPCODES_MAX_MEMORY) { // Remove the least-called function's combined JIT tMD_MethodDef *pToRemove = pMethod; while (pToRemove->pPrevHighestCalls != NULL && pToRemove->pPrevHighestCalls->pJITtedCombined != NULL) { pToRemove = pToRemove->pPrevHighestCalls; } if (pToRemove != pMethod) { RemoveCombinedJIT(pToRemove); } } if (combinedJITSize < GEN_COMBINED_OPCODES_MAX_MEMORY) { // If there's enough room, then create new combined JIT AddCombinedJIT(pMethod); } } // See if there is a combined opcode JIT ready to use if (pMethod->pJITtedCombined != NULL) { pThis->pJIT = pMethod->pJITtedCombined; pMethod->callStackCount++; } #endif #ifdef DIAG_METHOD_CALLS // Keep track of the number of times this method is called pMethod->callCount++; pThis->startTime = microTime(); #endif return pThis; }
//Minecart physics loop bool Physics::updateMinecart() { std::vector<MinecartData> &minecarts = ServerInstance->map(map)->minecarts; uint32_t listSize = minecarts.size(); for (int32_t simIt = 0; simIt < listSize; simIt++) { //Check if the cart is suppose to move if(minecarts[simIt].speed.x() != 0 || minecarts[simIt].speed.y() != 0 || minecarts[simIt].speed.z() != 0) { uint64_t timeNow = microTime(); double timeDiff = (timeNow-minecarts[simIt].timestamp*1.0)/1000000.0; //s minecarts[simIt].timestamp = timeNow; vec diff = vec(int8_t(float(minecarts[simIt].speed.x())*(timeDiff)), int8_t(float(minecarts[simIt].speed.y())*(timeDiff)), int8_t(float(minecarts[simIt].speed.z())*(timeDiff)) ); minecarts[simIt].pos = vec(minecarts[simIt].pos.x()+diff.x(), minecarts[simIt].pos.y()+diff.y(), minecarts[simIt].pos.z()+diff.z()); vec blockPos = vec((int)(minecarts[simIt].pos.x()/32), (int)(minecarts[simIt].pos.y()/32), (int)(minecarts[simIt].pos.z()/32)); uint8_t block, meta; ServerInstance->map(map)->getBlock(blockPos.x(), blockPos.y(), blockPos.z(), &block, &meta); bool changed = false; if(block == BLOCK_AIR) { minecarts[simIt].pos.y() -= 32; changed = true; } else if((minecarts[simIt].lastBlock.x() != blockPos.x() || minecarts[simIt].lastBlock.y() != blockPos.y() || minecarts[simIt].lastBlock.z() != blockPos.z()) && block == BLOCK_MINECART_TRACKS) { minecarts[simIt].lastBlock = blockPos; if((meta == FLAT_NS && minecarts[simIt].speed.x() != 0) || (meta == FLAT_EW && minecarts[simIt].speed.z() != 0)) { } else { //z = north //-x = east //Going west if(minecarts[simIt].speed.x() > 0 && meta == CORNER_NW) { minecarts[simIt].speed.z() = -minecarts[simIt].speed.x(); minecarts[simIt].speed.x() = 0; changed = true; } //Going west else if(minecarts[simIt].speed.x() > 0 && meta == CORNER_SW) { minecarts[simIt].speed.z() = minecarts[simIt].speed.x(); minecarts[simIt].speed.x() = 0; changed = true; } //Going east else if(minecarts[simIt].speed.x() < 0 && meta == CORNER_NE) { minecarts[simIt].speed.z() = minecarts[simIt].speed.x(); minecarts[simIt].speed.x() = 0; changed = true; } //Going east else if(minecarts[simIt].speed.x() < 0 && meta == CORNER_SE) { minecarts[simIt].speed.z() = -minecarts[simIt].speed.x(); minecarts[simIt].speed.x() = 0; changed = true; } //Going north else if(minecarts[simIt].speed.z() > 0 && meta == CORNER_NW) { minecarts[simIt].speed.x() = -minecarts[simIt].speed.z(); minecarts[simIt].speed.z() = 0; changed = true; } //Going north else if(minecarts[simIt].speed.z() > 0 && meta == CORNER_NE) { minecarts[simIt].speed.x() = minecarts[simIt].speed.z(); minecarts[simIt].speed.z() = 0; changed = true; } //Going south else if(minecarts[simIt].speed.z() < 0 && meta == CORNER_SE) { minecarts[simIt].speed.x() = -minecarts[simIt].speed.z(); minecarts[simIt].speed.z() = 0; changed = true; } //Going south else if(minecarts[simIt].speed.z() < 0 && meta == CORNER_SW) { minecarts[simIt].speed.x() = minecarts[simIt].speed.z(); minecarts[simIt].speed.z() = 0; changed = true; } } } else { //minecarts[simIt].pos.y() += 32; //changed = true; } //Signal clients about the new pos Packet pkt; if(changed) { minecarts[simIt].pos.x() = blockPos.x()*32; minecarts[simIt].pos.y() = blockPos.y()*32; minecarts[simIt].pos.z() = blockPos.z()*32; pkt = Protocol::entityTeleport(minecarts[simIt].EID, (minecarts[simIt].pos.x()+16.0)/32.0, (minecarts[simIt].pos.y()+16.0)/32.0, (minecarts[simIt].pos.z()+16.0)/32.0, 0, 0); } else { pkt = Protocol::entityRelativeMove(minecarts[simIt].EID,(int8_t)diff.x(),(int8_t)diff.y(),(int8_t)diff.z()); } User::sendAll(pkt); } } return true; }
Mineserver::Mineserver(int args, char **argarray) : argv(argarray), argc(args), m_socketlisten (0), m_saveInterval (0), m_lastSave (std::time(NULL)), m_pvp_enabled (false), m_damage_enabled(false), m_only_helmets (false), m_running (false), m_eventBase (NULL), // core modules m_config (new Config()), m_screen (new CliScreen()), m_logger (new Logger()), m_plugin (NULL), m_chat (NULL), m_furnaceManager(NULL), m_packetHandler (NULL), m_inventory (NULL), m_mobs (NULL) { pthread_mutex_init(&m_validation_mutex,NULL); ServerInstance = this; InitSignals(); std::srand((uint32_t)std::time(NULL)); initPRNG(); std::string cfg; std::vector<std::string> overrides; for (int i = 1; i < argc; i++) { const std::string arg(argv[i]); switch (arg[0]) { case '-': // option // we have only '-h' and '--help' now, so just return with help printHelp(0); throw CoreException(); case '+': // override overrides.push_back(arg.substr(1)); break; default: // otherwise, it is config file if (!cfg.empty()) throw CoreException("Only single CONFIG_FILE argument is allowed!"); cfg = arg; break; } } const std::string path_exe = "./"; // If config file is provided as an argument if (!cfg.empty()) { std::cout << "Searching for configuration file..." << std::endl; if (fileExists(cfg)) { const std::pair<std::string, std::string> fullpath = pathOfFile(cfg); cfg = fullpath.first + PATH_SEPARATOR + fullpath.second; this->config()->config_path = fullpath.first; } else { std::cout << "Config not found...\n";; cfg.clear(); } } if (cfg.empty()) { if (fileExists(path_exe + PATH_SEPARATOR + CONFIG_FILE)) { cfg = path_exe + PATH_SEPARATOR + CONFIG_FILE; this->config()->config_path = path_exe; } else { std::cout << "Config not found\n"; } } // load config Config &configvar = *this->config(); if (!configvar.load(cfg)) { throw CoreException("Could not load config!"); } m_plugin = new Plugin(); LOG2(INFO, "Using config: " + cfg); if (overrides.size()) { std::stringstream override_config; for (size_t i = 0; i < overrides.size(); i++) { LOG2(INFO, "Overriden: " + overrides[i]); override_config << overrides[i] << ';' << std::endl; } // override config if (!configvar.load(override_config)) throw CoreException("Error when parsing overrides: maybe you forgot to doublequote string values?"); } memset(&m_listenEvent, 0, sizeof(event)); initConstants(); // Write PID to file std::ofstream pid_out((config()->sData("system.pid_file")).c_str()); if (!pid_out.fail()) { pid_out << getpid(); } pid_out.close(); init_plugin_api(); if (config()->bData("system.interface.use_cli")) { // Init our Screen screen()->init(VERSION); } LOG2(INFO, "Welcome to Mineserver v" + VERSION); LOG2(INFO, "Using zlib "+std::string(ZLIB_VERSION)+" libevent "+std::string(event_get_version())); LOG2(INFO, "Generating RSA key pair for protocol encryption"); //Protocol encryption srand(microTime()); if((rsa = RSA_generate_key(1024, 17, 0, 0)) == NULL) { LOG2(INFO, "KEY GENERATION FAILED!"); exit(1); } LOG2(INFO, "RSA key pair generated."); /* Get ASN.1 format public key */ x=X509_new(); pk=EVP_PKEY_new(); EVP_PKEY_assign_RSA(pk,rsa); X509_set_version(x,0); X509_set_pubkey(x,pk); int len; unsigned char *buf; buf = NULL; len = i2d_X509(x, &buf); //Glue + jesus tape, dont ask - Fador publicKey = std::string((char *)(buf+28),len-36); OPENSSL_free(buf); /* END key fetching */ const std::string temp_nums="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890=-"; const std::string temp_hex="0123456789abcdef"; for(int i = 0; i < 4; i++) { encryptionBytes += (char)(temp_nums[rand()%temp_nums.size()]); } for(int i = 0; i < 16; i++) { serverID += (char)(temp_hex[rand()%temp_hex.size()]); } LOG2(INFO, "ServerID: " + serverID); if(!m_config->bData("system.user_validation")) { serverID = "-"; } MapGen* mapgen = new MapGen(); MapGen* nethergen = new NetherGen(); MapGen* heavengen = new HeavenGen(); MapGen* biomegen = new BiomeGen(); MapGen* eximgen = new EximGen(); m_mapGenNames.push_back(mapgen); m_mapGenNames.push_back(nethergen); m_mapGenNames.push_back(heavengen); m_mapGenNames.push_back(biomegen); m_mapGenNames.push_back(eximgen); m_saveInterval = m_config->iData("map.save_interval"); m_only_helmets = m_config->bData("system.armour.helmet_strict"); m_pvp_enabled = m_config->bData("system.pvp.enabled"); m_damage_enabled = m_config->bData("system.damage.enabled"); const char* key = "map.storage.nbt.directories"; // Prefix for worlds config if (m_config->has(key) && (m_config->type(key) == CONFIG_NODE_LIST)) { std::list<std::string> tmp = m_config->mData(key)->keys(); int n = 0; for (std::list<std::string>::const_iterator it = tmp.begin(); it != tmp.end(); ++it) { m_map.push_back(new Map()); Physics* phy = new Physics; phy->map = n; m_physics.push_back(phy); RedstoneSimulation* red = new RedstoneSimulation; red->map = n; m_redstone.push_back(red); int k = m_config->iData((std::string(key) + ".") + (*it)); if ((uint32_t)k >= m_mapGenNames.size()) { std::ostringstream s; s << "Error! Mapgen number " << k << " in config. " << m_mapGenNames.size() << " Mapgens known"; LOG2(INFO, s.str()); } // WARNING: if k is too big this will be an access error! -- louisdx MapGen* m = m_mapGenNames[k]; m_mapGen.push_back(m); n++; } } else { LOG2(WARNING, "Cannot find map.storage.nbt.directories.*"); } if (m_map.size() == 0) throw CoreException("No worlds in Config"); m_chat = new Chat; m_furnaceManager = new FurnaceManager; m_packetHandler = new PacketHandler; m_inventory = new Inventory(m_config->sData("system.path.data") + '/' + "recipes", ".recipe", "ENABLED_RECIPES.cfg"); m_mobs = new Mobs; } // End Mineserver constructor
//Falling physics loop bool Physics::updateEntity() { uint32_t listSize = entitySimList.size(); std::vector<uint32_t> toRem; for (int32_t simIt = listSize-1; simIt >= 0; simIt--) { simulationEntity& f = entitySimList[simIt]; double timeInSec = (microTime()-f.startTime)/1000000.0; double lasttimeInSec = (f.lastTime-f.startTime)/1000000.0; f.lastTime = microTime(); f.ticks++; const double gravity = -13.5;//9.81; //Calculate offset when x and z velocity stays the same and y velocity has gravity to deal with double offset_x = f.startPos.vel_x*timeInSec; double offset_z = f.startPos.vel_z*timeInSec; double offset_y = 0.5*gravity*timeInSec*timeInSec+f.startPos.vel_y*timeInSec; entity_position newPos; newPos.x = offset_x+f.startPos.x; newPos.z = offset_z+f.startPos.z; newPos.y = offset_y+f.startPos.y; entity_position diffPos; diffPos.x = newPos.x-f.pos.x; diffPos.z = newPos.z-f.pos.z; diffPos.y = newPos.y-f.pos.y; //Loop all blocks between current point and last point. Just simple linear interpolation for(double i = 0; i < 1.0; i+= 1.0/sqrt(diffPos.x*diffPos.x+diffPos.y*diffPos.y+diffPos.z*diffPos.z)) { //Check for the block uint8_t block,meta; map->getBlock((int)(f.pos.x+diffPos.x*i-0.5),(int)(f.pos.y+diffPos.y*i),(int)(f.pos.z+diffPos.z*i-0.5),&block, &meta); //When hitting _something_, turn it to glass and destroy the entity if(block != BLOCK_AIR) { map->sendBlockChange((int)(f.pos.x+diffPos.x*i-0.5), (int)(f.pos.y+diffPos.y*i), (int)(f.pos.z+diffPos.z*i-0.5), BLOCK_GLASS, 0); //Add to "to-remove" list toRem.push_back(f.EID); break; } } f.pos.x = newPos.x; f.pos.z = newPos.z; f.pos.y = newPos.y; f.pos.vel_y = gravity*timeInSec+f.startPos.vel_y; /* Packet pkt = Protocol::entityVelocity(f.EID,(int16_t)(f.pos.vel_x*8000.0/20), (int16_t)(f.pos.vel_y*8000.0/20), (int16_t)(f.pos.vel_z*8000.0/20)); pkt << Protocol::entityTeleport(f.EID, f.pos.x, f.pos.y, f.pos.z,0,0); User::sendAll(pkt); */ } for(int32_t i = 0; i < toRem.size(); i++) { for (int32_t simIt = entitySimList.size()-1; simIt >= 0; simIt--) { if(entitySimList[simIt].EID == toRem[i]) { Packet pkt = Protocol::destroyEntity(toRem[i]); User::sendAll(pkt); entitySimList.erase(entitySimList.begin()+simIt); break; } } } return true; }