Beispiel #1
0
	virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n)
	{
		ServerMap *map = &env->getServerMap();
		if (map->transforming_liquid_size() < 500)
			map->transforming_liquid_add(p);
		//if ((*map).m_transforming_liquid.size() < 500) (*map).m_transforming_liquid.push_back(p);
	}
Beispiel #2
0
// L-System tree LUA spawner
treegen::error spawn_ltree(ServerEnvironment *env, v3s16 p0, INodeDefManager *ndef, TreeDef tree_definition)
{
	ServerMap *map = &env->getServerMap();
	std::map<v3s16, MapBlock*> modified_blocks;
	ManualMapVoxelManipulator vmanip(map);
	v3s16 tree_blockp = getNodeBlockPos(p0);
	treegen::error e;

	vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,3,1));
	e = make_ltree (vmanip, p0, ndef, tree_definition);
	if (e != SUCCESS)
		return e;

	vmanip.blitBackAll(&modified_blocks);

	// update lighting
	std::map<v3s16, MapBlock*> lighting_modified_blocks;
	lighting_modified_blocks.insert(modified_blocks.begin(), modified_blocks.end());
	map->updateLighting(lighting_modified_blocks, modified_blocks);
	// Send a MEET_OTHER event
	MapEditEvent event;
	event.type = MEET_OTHER;
	for(std::map<v3s16, MapBlock*>::iterator
		i = modified_blocks.begin();
		i != modified_blocks.end(); ++i)
	{
		event.modified_blocks.insert(i->first);
	}
	map->dispatchEvent(&event);
	return SUCCESS;
}
Beispiel #3
0
int LuaVoxelManip::l_write_to_map(lua_State *L)
{
	MAP_LOCK_REQUIRED;

	LuaVoxelManip *o = checkobject(L, 1);
	bool update_light = !lua_isboolean(L, 2) || lua_toboolean(L, 2);
	GET_ENV_PTR;
	ServerMap *map = &(env->getServerMap());
	if (o->is_mapgen_vm || !update_light) {
		o->vm->blitBackAll(&(o->modified_blocks));
	} else {
		voxalgo::blit_back_with_light(map, o->vm,
			&(o->modified_blocks));
	}

	MapEditEvent event;
	event.type = MEET_OTHER;
	for (const auto &modified_block : o->modified_blocks)
		event.modified_blocks.insert(modified_block.first);

	map->dispatchEvent(&event);

	o->modified_blocks.clear();
	return 0;
}
Beispiel #4
0
bool EmergeThread::getBlockOrStartGen(v3s16 p, MapBlock **b,
	BlockMakeData *data, bool allow_gen)
{
#if !ENABLE_THREADS
	auto lock = map->m_nothread_locker.lock_unique_rec();
#endif

	MapBlock *block;
	{

	//envlock: usually takes <=1ms, sometimes 90ms or ~400ms to acquire
	//JMutexAutoLock envlock(m_server->m_env_mutex);


	// Attempt to load block
	block = map->getBlockNoCreateNoEx(p);
	if (!block || block->isDummy()) {
		EMERGE_DBG_OUT("not in memory, attempting to load from disk ag="<<allow_gen<<" block="<<block<<" p="<<p);
		block = map->loadBlock(p);
		if (block && block->isGenerated())
			map->prepareBlock(block);
	}
	}

	// If could not load and allowed to generate,
	// start generation inside this same envlock
	if (allow_gen && (!block)) {
		EMERGE_DBG_OUT("generating b="<<block);
		*b = block;
		return map->initBlockMake(data, p);
	}

	*b = block;
	return false;
}
Beispiel #5
0
bool EmergeThread::getBlockOrStartGen(v3s16 p, MapBlock **b, 
									BlockMakeData *data, bool allow_gen) {
	v2s16 p2d(p.X, p.Z);
	//envlock: usually takes <=1ms, sometimes 90ms or ~400ms to acquire
	JMutexAutoLock envlock(m_server->m_env_mutex); 
	
	// Load sector if it isn't loaded
	if (map->getSectorNoGenerateNoEx(p2d) == NULL)
		map->loadSectorMeta(p2d);

	// Attempt to load block
	MapBlock *block = map->getBlockNoCreateNoEx(p);
	if (!block || block->isDummy() || !block->isGenerated()) {
		EMERGE_DBG_OUT("not in memory, attempting to load from disk");
		block = map->loadBlock(p);
	}

	// If could not load and allowed to generate,
	// start generation inside this same envlock
	if (allow_gen && (block == NULL || !block->isGenerated())) {
		EMERGE_DBG_OUT("generating");
		*b = block;
		return map->initBlockMake(data, p);
	}
	
	*b = block;
	return false;
}
Beispiel #6
0
bool EmergeThread::getBlockOrStartGen(v3s16 p, MapBlock **b,
									BlockMakeData *data, bool allow_gen) {
	//envlock: usually takes <=1ms, sometimes 90ms or ~400ms to acquire
	//JMutexAutoLock envlock(m_server->m_env_mutex);

	// Attempt to load block
	MapBlock *block = map->getBlockNoCreateNoEx(p);
	if (!block || block->isDummy()) {
		EMERGE_DBG_OUT("not in memory, attempting to load from disk ag="<<allow_gen<<" block="<<block<<" p="<<p);
		block = map->loadBlock(p);
		if(block)
		{
// 			block->pushElementsToCircuit(m_circuit);
// 			m_circuit->processElementsQueue(*map, map->getNodeDefManager());
		}
		if (block && block->isGenerated())
			map->prepareBlock(block);
	}

	// If could not load and allowed to generate,
	// start generation inside this same envlock
	if (allow_gen && (!block)) {
		EMERGE_DBG_OUT("generating b="<<block);
		*b = block;
		return map->initBlockMake(data, p);
	}

	*b = block;
	return false;
}
Beispiel #7
0
	virtual void trigger(ServerEnvironment *env, v3POS p, MapNode n,
	                     u32 active_object_count, u32 active_object_count_wider, MapNode neighbor, bool activate) {
		ServerMap *map = &env->getServerMap();
		INodeDefManager *ndef = env->getGameDef()->ndef();
		int cold = ((ItemGroupList) ndef->get(neighbor).groups)["cold"];
		int freeze = ((ItemGroupList) ndef->get(n).groups)["freeze"];
		if (cold < freeze) {
			n.freeze_melt(ndef, -1);
			map->setNode(p, n);
		}
	}
Beispiel #8
0
MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata,
	std::map<v3s16, MapBlock *> *modified_blocks)
{
	//MutexAutoLock envlock(m_server->m_env_mutex);
	ScopeProfiler sp(g_profiler,
		"EmergeThread: after Mapgen::makeChunk", SPT_AVG);

	/*
		Perform post-processing on blocks (invalidate lighting, queue liquid
		transforms, etc.) to finish block make
	*/
	m_map->finishBlockMake(bmdata, modified_blocks);

	MapBlock *block = m_map->getBlockNoCreateNoEx(pos, false, true);
	if (!block) {
		errorstream << "EmergeThread::finishGen: Couldn't grab block we "
			"just generated: " << PP(pos) << std::endl;
		return NULL;
	}

	v3s16 minp = bmdata->blockpos_min * MAP_BLOCKSIZE;
	v3s16 maxp = bmdata->blockpos_max * MAP_BLOCKSIZE +
				 v3s16(1,1,1) * (MAP_BLOCKSIZE - 1);

	// Ignore map edit events, they will not need to be sent
	// to anybody because the block hasn't been sent to anybody

/* thread unsafe
	MapEditEventAreaIgnorer ign(
		&m_server->m_ignore_map_edit_events_area,
		VoxelArea(minp, maxp));
*/

	/*
		Run Lua on_generated callbacks
	*/
	try {
		MAP_NOTHREAD_LOCK(m_map);
		m_server->getScriptIface()->environment_OnGenerated(
			minp, maxp, m_mapgen->blockseed);
	} catch (LuaError &e) {
		m_server->setAsyncFatalError("Lua: " + std::string(e.what()));
	}

	EMERGE_DBG_OUT("ended up with: " << analyze_block(block));

	/*
		Activate the block
	*/
	m_server->m_env->activateBlock(block, 0);

	return block;
}
Beispiel #9
0
	virtual void trigger(ServerEnvironment *env, v3POS p, MapNode n,
	                     u32 active_object_count, u32 active_object_count_wider, MapNode neighbor, bool activate) {
		ServerMap *map = &env->getServerMap();
		INodeDefManager *ndef = env->getGameDef()->ndef();
		int hot = ((ItemGroupList) ndef->get(neighbor).groups)["hot"];
		int melt = ((ItemGroupList) ndef->get(n).groups)["melt"];
		if (hot > melt) {
			n.freeze_melt(ndef, +1);
			map->setNode(p, n);
			env->nodeUpdate(p, 2);
		}
	}
Beispiel #10
0
	virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n)
	{
		INodeDefManager *ndef = env->getGameDef()->ndef();
		ServerMap *map = &env->getServerMap();
		
		MapNode n_top = map->getNodeNoEx(p+v3s16(0,1,0));
		if(!ndef->get(n_top).light_propagates ||
				ndef->get(n_top).isLiquid())
		{
			n.setContent(ndef->getId("dirt"));
			map->addNodeWithEvent(p, n);
		}
	}
Beispiel #11
0
	virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n)
	{
		INodeDefManager *ndef = env->getGameDef()->ndef();
		ServerMap *map = &env->getServerMap();
		
		MapNode n_top = map->getNodeNoEx(p+v3s16(0,1,0));
		if(ndef->get(n_top).light_propagates &&
				!ndef->get(n_top).isLiquid() &&
				n_top.getLightBlend(env->getDayNightRatio(), ndef) >= 13)
		{
			n.setContent(ndef->getId("dirt_with_grass"));
			map->addNodeWithEvent(p, n);
		}
	}
Beispiel #12
0
	virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
			u32 active_object_count, u32 active_object_count_wider)
	{
		INodeDefManager *ndef = env->getGameDef()->ndef();
		ServerMap *map = &env->getServerMap();
		
		MapNode n_below = map->getNodeNoEx(p - v3s16(0, 1, 0));
		if (n_below.getContent() != c_dirt &&
			n_below.getContent() != c_dirt_with_grass)
			return;
			
		bool is_jungle_tree = n.getContent() == c_junglesapling;
		
		actionstream <<"A " << (is_jungle_tree ? "jungle " : "")
				<< "sapling grows into a tree at "
				<< PP(p) << std::endl;

		std::map<v3s16, MapBlock*> modified_blocks;
		v3s16 tree_p = p;
		ManualMapVoxelManipulator vmanip(map);
		v3s16 tree_blockp = getNodeBlockPos(tree_p);
		vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,1,1));
		
		if (is_jungle_tree) {
			treegen::make_jungletree(vmanip, tree_p, ndef, myrand());
		} else {
			bool is_apple_tree = myrand() % 4 == 0;
			treegen::make_tree(vmanip, tree_p, is_apple_tree, ndef, myrand());
		}
		
		vmanip.blitBackAll(&modified_blocks);

		// update lighting
		std::map<v3s16, MapBlock*> lighting_modified_blocks;
		lighting_modified_blocks.insert(modified_blocks.begin(), modified_blocks.end());
		map->updateLighting(lighting_modified_blocks, modified_blocks);

		// Send a MEET_OTHER event
		MapEditEvent event;
		event.type = MEET_OTHER;
//		event.modified_blocks.insert(modified_blocks.begin(), modified_blocks.end());
		for(std::map<v3s16, MapBlock*>::iterator
			i = modified_blocks.begin();
			i != modified_blocks.end(); ++i)
		{
			event.modified_blocks.insert(i->first);
		}
		map->dispatchEvent(&event);
	}
Beispiel #13
0
	/*! Add a ServerSession to the manager; takes ownership of the object
	  \param what ServerSession to add
	  \return true if successful */
	bool add(ServerSessionBase *what)
	{
		if (!what || !what->_server_sock)
			throw f8Exception("bad or missing server socket");
		_servermap.insert({*what->_server_sock, what});
		return true;
	}
Beispiel #14
0
	/*! Check to see if there are any waiting inbound connections on any of the managed servers. Will only
		return the first ServerSession; select should be called continually to process all waiting sockets.
	  \param timeout timespan (us, default 250 ms) to wait before returning (will return immediately if connection available)
	  \return pointer to ServerSession that is ready to accept a connection or nullptr if timeout with none */
	ServerSessionBase *select(const Poco::Timespan& timeout=Poco::Timespan(250000)) const
	{
		Poco::Net::Socket::SocketList readList, writeList, exceptList;
		for (auto& pp : _servermap)
			readList.push_back(pp.first);
		return Poco::Net::Socket::select(readList, writeList, exceptList, timeout) && !readList.empty()
			? _servermap.find(readList[0])->second : nullptr;
	}
Beispiel #15
0
	virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
			u32 active_object_count, u32 active_object_count_wider)
	{
		if(active_object_count_wider != 0)
			return;

		INodeDefManager *ndef = env->getGameDef()->ndef();
		ServerMap *map = &env->getServerMap();

		v3s16 p1 = p + v3s16(0,1,0);
		MapNode n1a = map->getNodeNoEx(p1+v3s16(0,0,0));
		if(n1a.getLightBlend(env->getDayNightRatio(), ndef) <= 3){
			MapNode n1b = map->getNodeNoEx(p1+v3s16(0,1,0));
			if(n1a.getContent() == CONTENT_AIR &&
					n1b.getContent() == CONTENT_AIR)
			{
				v3f pos = intToFloat(p1, BS);
				int i = myrand()%5;
				if(i == 0 || i == 1){
					actionstream<<"A dungeon master spawns at "
							<<PP(p1)<<std::endl;
					Settings properties;
					getMob_dungeon_master(properties);
					ServerActiveObject *obj = new MobV2SAO(
							env, pos, &properties);
					env->addActiveObject(obj);
				} else if(i == 2 || i == 3){
					actionstream<<"Rats spawn at "
							<<PP(p1)<<std::endl;
					for(int j=0; j<3; j++){
						ServerActiveObject *obj = new RatSAO(
								env, pos);
						env->addActiveObject(obj);
					}
				} else {
					actionstream<<"An oerkki spawns at "
							<<PP(p1)<<std::endl;
					ServerActiveObject *obj = new Oerkki1SAO(
							env, pos);
					env->addActiveObject(obj);
				}
			}
		}
	}
Beispiel #16
0
EmergeAction EmergeThread::getBlockOrStartGen(
	v3s16 pos, bool allow_gen, MapBlock **block, BlockMakeData *bmdata)
{
	//MutexAutoLock envlock(m_server->m_env_mutex);

	{
	MAP_NOTHREAD_LOCK(m_map);
	// 1). Attempt to fetch block from memory
	*block = m_map->getBlockNoCreateNoEx(pos, false, true);
	}
	if (*block && !(*block)->isDummy() && (*block)->isGenerated())
		return EMERGE_FROM_MEMORY;

	{
	MAP_NOTHREAD_LOCK(m_map);
	// 2). Attempt to load block from disk
	*block = m_map->loadBlock(pos);
	}

	if (*block && (*block)->isGenerated())
	{
		MAP_NOTHREAD_LOCK(m_map);
		m_map->prepareBlock(*block);
		return EMERGE_FROM_DISK;
	}

	{
	MAP_NOTHREAD_LOCK(m_map);
	// 3). Attempt to start generation
	if (allow_gen && m_map->initBlockMake(pos, bmdata))
		return EMERGE_GENERATED;
	}

/*
	verbosestream << "EmergeThread::getBlockOrStartGen : cancel pos=" << pos << " block="<< *block;
	if (*block)
		verbosestream << "dummy=" << (*block)->isDummy() << " generated="<< (*block)->isGenerated();
	verbosestream << std::endl;
*/

	// All attempts failed; cancel this block emerge
	return EMERGE_CANCELLED;
}
Beispiel #17
0
	virtual void trigger(ServerEnvironment *env, v3POS p, MapNode n,
	                     u32 active_object_count, u32 active_object_count_wider, MapNode neighbor, bool activate) {
		ServerMap *map = &env->getServerMap();
		INodeDefManager *ndef = env->getGameDef()->ndef();

		float heat = map->updateBlockHeat(env, p);
		//heater = rare
		content_t c = map->getNodeTry(p - v3POS(0,  -1, 0 )).getContent(); // top
		//more chance to freeze if air at top
		static int water_level = g_settings->getS16("water_level");
		bool top_liquid = ndef->get(n).liquid_type > LIQUID_NONE && p.Y > water_level;
		int freeze = ((ItemGroupList) ndef->get(n).groups)["freeze"];
		if (heat <= freeze - 1 && ((!top_liquid && (activate || (heat <= freeze - 50))) || heat <= freeze - 50 ||
		                           (myrand_range(freeze - 50, heat) <= (freeze + (top_liquid ? -42 : c == CONTENT_AIR ? -10 : -40))))) {
			content_t c_self = n.getContent();
			// making freeze not annoying, do not freeze random blocks in center of ocean
			// todo: any block not water (dont freeze _source near _flowing)
			bool allow = activate || heat < freeze - 40;
			// todo: make for(...)
			if (!allow) {
				c = map->getNodeTry(p - v3POS(0,  1, 0 )).getContent(); // below
				if (c == CONTENT_AIR || c == CONTENT_IGNORE)
					if (ndef->get(n.getContent()).liquid_type == LIQUID_FLOWING || ndef->get(n.getContent()).liquid_type == LIQUID_SOURCE)
						return; // do not freeze when falling
				if (c != c_self && c != CONTENT_IGNORE) allow = 1;
				if (!allow) {
					c = map->getNodeTry(p - v3POS(1,  0, 0 )).getContent(); // right
					if (c != c_self && c != CONTENT_IGNORE) allow = 1;
					if (!allow) {
						c = map->getNodeTry(p - v3POS(-1, 0, 0 )).getContent(); // left
						if (c != c_self && c != CONTENT_IGNORE) allow = 1;
						if (!allow) {
							c = map->getNodeTry(p - v3POS(0,  0, 1 )).getContent(); // back
							if (c != c_self && c != CONTENT_IGNORE) allow = 1;
							if (!allow) {
								c = map->getNodeTry(p - v3POS(0,  0, -1)).getContent(); // front
								if (c != c_self && c != CONTENT_IGNORE) allow = 1;
							}
						}
					}
				}
			}
			if (allow) {
				n.freeze_melt(ndef, -1);
				map->setNode(p, n);
			}
		}
	}
Beispiel #18
0
	virtual void trigger(ServerEnvironment *env, v3POS p, MapNode n,
	                     u32 active_object_count, u32 active_object_count_wider, MapNode neighbor, bool activate) {
		ServerMap *map = &env->getServerMap();
		INodeDefManager *ndef = env->getGameDef()->ndef();
		float heat = map->updateBlockHeat(env, p);
		content_t c = map->getNodeTry(p - v3POS(0,  -1, 0 )).getContent(); // top
		int melt = ((ItemGroupList) ndef->get(n).groups)["melt"];
		if (heat >= melt + 1 && (activate || heat >= melt + 40 ||
		                         ((myrand_range(heat, melt + 40)) >= (c == CONTENT_AIR ? melt + 10 : melt + 20)))) {
			if (ndef->get(n.getContent()).liquid_type == LIQUID_FLOWING || ndef->get(n.getContent()).liquid_type == LIQUID_SOURCE) {
				c = map->getNodeTry(p - v3POS(0,  1, 0 )).getContent(); // below
				if (c == CONTENT_AIR || c == CONTENT_IGNORE)
					return; // do not melt when falling (dirt->dirt_with_grass on air)
			}
			n.freeze_melt(ndef, +1);
			map->setNode(p, n);
			env->nodeUpdate(p, 2); //enable after making FAST nodeupdate
		}
	}
Beispiel #19
0
	/*! Check to see if there are any waiting inbound connections on any of the managed servers. Will add
		all ServerSession pointers to the supplied vector for all waiting sockets found.
	  \param result vector to place results in; will empty before polling
	  \param timeout timespan (us, default 250 ms) to wait before returning (will return immediately if connection available)
	  \return number of active ServerSockets returned in vector */
	size_t select_l(std::vector<ServerSessionBase *>& result, const Poco::Timespan& timeout=Poco::Timespan(250000)) const
	{
		result.clear();
		Poco::Net::Socket::SocketList readList, writeList, exceptList;
		for (auto& pp : _servermap)
			readList.push_back(pp.first);
		if (Poco::Net::Socket::select(readList, writeList, exceptList, timeout) && !readList.empty())
			std::for_each(readList.begin(), readList.end(), [&](decltype(readList)::value_type& pp)
				{ result.push_back(_servermap.find(pp)->second); });
		return result.size();
	}
Beispiel #20
0
	virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
			u32 active_object_count, u32 active_object_count_wider)
	{
		if(active_object_count_wider != 0)
			return;

		INodeDefManager *ndef = env->getGameDef()->ndef();
		ServerMap *map = &env->getServerMap();
		
		v3s16 p1 = p + v3s16(myrand_range(-2, 2),
				0, myrand_range(-2, 2));
		MapNode n1 = map->getNodeNoEx(p1);
		MapNode n1b = map->getNodeNoEx(p1+v3s16(0,-1,0));
		if(n1b.getContent() == ndef->getId("dirt_with_grass") &&
				n1.getContent() == CONTENT_AIR)
		{
			v3f pos = intToFloat(p1, BS);
			ServerActiveObject *obj = new RatSAO(env, pos);
			env->addActiveObject(obj);
		}
	}
Beispiel #21
0
	virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
			u32 active_object_count, u32 active_object_count_wider)
	{
		INodeDefManager *ndef = env->getGameDef()->ndef();
		ServerMap *map = &env->getServerMap();
		
		actionstream<<"A sapling grows into a tree at "
				<<PP(p)<<std::endl;

		core::map<v3s16, MapBlock*> modified_blocks;
		v3s16 tree_p = p;
		ManualMapVoxelManipulator vmanip(map);
		v3s16 tree_blockp = getNodeBlockPos(tree_p);
		vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,1,1));
		bool is_apple_tree = myrand()%4 == 0;
		mapgen::make_tree(vmanip, tree_p, is_apple_tree, ndef);
		vmanip.blitBackAll(&modified_blocks);

		// update lighting
		core::map<v3s16, MapBlock*> lighting_modified_blocks;
		for(core::map<v3s16, MapBlock*>::Iterator
			i = modified_blocks.getIterator();
			i.atEnd() == false; i++)
		{
			lighting_modified_blocks.insert(i.getNode()->getKey(), i.getNode()->getValue());
		}
		map->updateLighting(lighting_modified_blocks, modified_blocks);

		// Send a MEET_OTHER event
		MapEditEvent event;
		event.type = MEET_OTHER;
		for(core::map<v3s16, MapBlock*>::Iterator
			i = modified_blocks.getIterator();
			i.atEnd() == false; i++)
		{
			v3s16 p = i.getNode()->getKey();
			event.modified_blocks.insert(p, true);
		}
		map->dispatchEvent(&event);
	}
Beispiel #22
0
EmergeAction EmergeThread::getBlockOrStartGen(
	v3s16 pos, bool allow_gen, MapBlock **block, BlockMakeData *bmdata)
{
	MutexAutoLock envlock(m_server->m_env_mutex);

	// 1). Attempt to fetch block from memory
	*block = m_map->getBlockNoCreateNoEx(pos);
	if (*block && !(*block)->isDummy() && (*block)->isGenerated())
		return EMERGE_FROM_MEMORY;

	// 2). Attempt to load block from disk
	*block = m_map->loadBlock(pos);
	if (*block && (*block)->isGenerated())
		return EMERGE_FROM_DISK;

	// 3). Attempt to start generation
	if (allow_gen && m_map->initBlockMake(pos, bmdata))
		return EMERGE_GENERATED;

	// All attempts failed; cancel this block emerge
	return EMERGE_CANCELLED;
}
Beispiel #23
0
int main(int argc, char const *[])
{
	std::string str="123456";
	std::cout<<str<<std::endl;
	typedef std::map<std::string, CacheServer> ServerMap;
	ServerMap servers;
	Consistent::HashRing<std::string,std::string,SdbmHash> ring(4,SdbmHash());

	//Create some cache servers
	servers["cach1.example.com"]=CacheServer();
	servers["cach2.example.com"]=CacheServer();
	servers["cach3.example.com"]=CacheServer();

	//Add their host names to the hash ring
	for (ServerMap::const_iterator it = servers.begin();it != servers.end(); ++it) {
		std::cout << "Adding " << it->first << " with hash " << ring.AddNode(it->first) <<std::endl;
	}

	//Store some data
	const char* fruits[] = {"apple","pear","banana","orange","cherry","apricot"};
	const char* colours[] = {"red","green","yellow","orange","black","pink"};
	const unsigned int numfruits = sizeof(fruits)/sizeof(char*);
	//std::cout<< "sizeof(fruits):" <<sizeof(fruits) << " sizeof (char*):" <<sizeof(char*) <<std::endl; 
	for (unsigned int f = 0; f<numfruits;f++) {
		std::string host = ring.GetNode(fruits[f]);
		std::cout << "Storing " <<fruits[f] << " on server " <<host <<std::endl;
		servers[host].Put(fruits[f],colours[f]);
	}

	//Read it back
	for (unsigned int f = 0; f< numfruits; f++) {
		std::string host = ring.GetNode(fruits[f]);
		std::string colour =servers[host].Get(fruits[f]);
		std::cout << "Found " << fruits[f] << " on server "<< host << " (" <<colour << ")" <<std::endl;
	}
	return 0;
}
Beispiel #24
0
	virtual void trigger(ServerEnvironment *env, v3POS p, MapNode n,
	                     u32 active_object_count, u32 active_object_count_wider, MapNode neighbor, bool activate) {
		ServerMap *map = &env->getServerMap();
		if (map->transforming_liquid_size() > map->m_liquid_step_flow)
			return;
		if (   map->getNodeTry(p - v3POS(0,  1, 0 )).getContent() != CONTENT_AIR  // below
		        && map->getNodeTry(p - v3POS(1,  0, 0 )).getContent() != CONTENT_AIR  // right
		        && map->getNodeTry(p - v3POS(-1, 0, 0 )).getContent() != CONTENT_AIR  // left
		        && map->getNodeTry(p - v3POS(0,  0, 1 )).getContent() != CONTENT_AIR  // back
		        && map->getNodeTry(p - v3POS(0,  0, -1)).getContent() != CONTENT_AIR  // front
		   )
			return;
		map->transforming_liquid_push_back(p);
	}
Beispiel #25
0
	/// Dtor.
	virtual ~ServerManager()
		{ std::for_each (_servermap.begin(), _servermap.end(), [](decltype(_servermap)::value_type& pp){ delete pp.second; }); }
Beispiel #26
0
void *EmergeThread::Thread() {
	ThreadStarted();
	log_register_thread("EmergeThread" + itos(id));
	DSTACK(__FUNCTION_NAME);
	BEGIN_DEBUG_EXCEPTION_HANDLER

	v3s16 last_tried_pos(-32768,-32768,-32768); // For error output
	v3s16 p;
	u8 flags = 0;

	map    = (ServerMap *)&(m_server->m_env->getMap());
	emerge = m_server->m_emerge;
	mapgen = emerge->mapgen[id];
	enable_mapgen_debug_info = emerge->mapgen_debug_info;

	porting::setThreadName("EmergeThread");

	while (!StopRequested())
	try {
		if (!popBlockEmerge(&p, &flags)) {
			qevent.wait();
			continue;
		}

		last_tried_pos = p;
		if (blockpos_over_limit(p))
			continue;

		bool allow_generate = flags & BLOCK_EMERGE_ALLOWGEN;
		EMERGE_DBG_OUT("p=" PP(p) " allow_generate=" << allow_generate);

		/*
			Try to fetch block from memory or disk.
			If not found and asked to generate, initialize generator.
		*/
		BlockMakeData data;
		MapBlock *block = NULL;
		std::map<v3s16, MapBlock *> modified_blocks;

		if (getBlockOrStartGen(p, &block, &data, allow_generate) && mapgen) {
			{
				ScopeProfiler sp(g_profiler, "EmergeThread: Mapgen::makeChunk", SPT_AVG);
				TimeTaker t("mapgen::make_block()");

				mapgen->makeChunk(&data);

				if (enable_mapgen_debug_info == false)
					t.stop(true); // Hide output
			}

			{
				//envlock: usually 0ms, but can take either 30 or 400ms to acquire
				JMutexAutoLock envlock(m_server->m_env_mutex);
				ScopeProfiler sp(g_profiler, "EmergeThread: after "
						"Mapgen::makeChunk (envlock)", SPT_AVG);

				map->finishBlockMake(&data, modified_blocks);

				block = map->getBlockNoCreateNoEx(p);
				if (block) {
					/*
						Do some post-generate stuff
					*/
					v3s16 minp = data.blockpos_min * MAP_BLOCKSIZE;
					v3s16 maxp = data.blockpos_max * MAP_BLOCKSIZE +
								 v3s16(1,1,1) * (MAP_BLOCKSIZE - 1);

					// Ignore map edit events, they will not need to be sent
					// to anybody because the block hasn't been sent to anybody
					MapEditEventAreaIgnorer
						ign(&m_server->m_ignore_map_edit_events_area,
						VoxelArea(minp, maxp));
					try {  // takes about 90ms with -O1 on an e3-1230v2
						m_server->getScriptIface()->environment_OnGenerated(
								minp, maxp, emerge->getBlockSeed(minp));
					} catch(LuaError &e) {
						m_server->setAsyncFatalError(e.what());
					}

					EMERGE_DBG_OUT("ended up with: " << analyze_block(block));

					m_server->m_env->activateBlock(block, 0);
				}
			}
		}

		/*
			Set sent status of modified blocks on clients
		*/
		// Add the originally fetched block to the modified list
		if (block)
			modified_blocks[p] = block;

		if (modified_blocks.size() > 0) {
			m_server->SetBlocksNotSent(modified_blocks);
		}
	}
	catch (VersionMismatchException &e) {
		std::ostringstream err;
		err << "World data version mismatch in MapBlock "<<PP(last_tried_pos)<<std::endl;
		err << "----"<<std::endl;
		err << "\""<<e.what()<<"\""<<std::endl;
		err << "See debug.txt."<<std::endl;
		err << "World probably saved by a newer version of Minetest."<<std::endl;
		m_server->setAsyncFatalError(err.str());
	}
	catch (SerializationError &e) {
		std::ostringstream err;
		err << "Invalid data in MapBlock "<<PP(last_tried_pos)<<std::endl;
		err << "----"<<std::endl;
		err << "\""<<e.what()<<"\""<<std::endl;
		err << "See debug.txt."<<std::endl;
		err << "You can ignore this using [ignore_world_load_errors = true]."<<std::endl;
		m_server->setAsyncFatalError(err.str());
	}

	END_DEBUG_EXCEPTION_HANDLER(errorstream)
	log_deregister_thread();
	return NULL;
}
void LuaEntitySAO::step(float dtime, bool send_recommended)
{
	if(!m_properties_sent)
	{
		m_properties_sent = true;
		std::string str = getPropertyPacket();
		// create message and add to list
		ActiveObjectMessage aom(getId(), true, str);
		m_messages_out.push(aom);
	}

	// If attached, check that our parent is still there. If it isn't, detach.
	if(m_attachment_parent_id && !isAttached())
	{
		m_attachment_parent_id = 0;
		m_attachment_bone = "";
		m_attachment_position = v3f(0,0,0);
		m_attachment_rotation = v3f(0,0,0);
		sendPosition(false, true);
	}

	m_last_sent_position_timer += dtime;

	// Each frame, parent position is copied if the object is attached, otherwise it's calculated normally
	// If the object gets detached this comes into effect automatically from the last known origin
	if(isAttached())
	{
		v3f pos = m_env->getActiveObject(m_attachment_parent_id)->getBasePosition();
		m_base_position = pos;
		m_velocity = v3f(0,0,0);
		m_acceleration = v3f(0,0,0);
	}
	else
	{
		if(m_prop.physical){
			aabb3f box = m_prop.collisionbox;
			box.MinEdge *= BS;
			box.MaxEdge *= BS;
			collisionMoveResult moveresult;
			f32 pos_max_d = BS*0.25; // Distance per iteration
			v3f p_pos = m_base_position;
			v3f p_velocity = m_velocity;
			v3f p_acceleration = m_acceleration;
			moveresult = collisionMoveSimple(m_env, m_env->getGameDef(),
					pos_max_d, box, m_prop.stepheight, dtime,
					&p_pos, &p_velocity, p_acceleration,
					this, m_prop.collideWithObjects);

			// Apply results
			m_base_position = p_pos;
			m_velocity = p_velocity;
			m_acceleration = p_acceleration;
		} else {
			m_base_position += dtime * m_velocity + 0.5 * dtime
					* dtime * m_acceleration;
			m_velocity += dtime * m_acceleration;
		}

		if((m_prop.automatic_face_movement_dir) &&
				(fabs(m_velocity.Z) > 0.001 || fabs(m_velocity.X) > 0.001))
		{
			float optimal_yaw = atan2(m_velocity.Z,m_velocity.X) * 180 / M_PI
					+ m_prop.automatic_face_movement_dir_offset;
			float max_rotation_delta =
					dtime * m_prop.automatic_face_movement_max_rotation_per_sec;

			if ((m_prop.automatic_face_movement_max_rotation_per_sec > 0) &&
				(fabs(m_yaw - optimal_yaw) > max_rotation_delta)) {

				m_yaw = optimal_yaw < m_yaw ? m_yaw - max_rotation_delta : m_yaw + max_rotation_delta;
			} else {
				m_yaw = optimal_yaw;
			}
		}
	}

	if(m_registered){
		m_env->getScriptIface()->luaentity_Step(m_id, dtime);
	}

	// Remove LuaEntity beyond terrain edges
	{
		ServerMap *map = dynamic_cast<ServerMap *>(&m_env->getMap());
		assert(map);
		if (!m_pending_deactivation &&
				map->saoPositionOverLimit(m_base_position)) {
			infostream << "Remove SAO " << m_id << "(" << m_init_name
				<< "), outside of limits" << std::endl;
			m_pending_deactivation = true;
			m_removed = true;
			return;
		}
	}

	if(send_recommended == false)
		return;

	if(!isAttached())
	{
		// TODO: force send when acceleration changes enough?
		float minchange = 0.2*BS;
		if(m_last_sent_position_timer > 1.0){
			minchange = 0.01*BS;
		} else if(m_last_sent_position_timer > 0.2){
			minchange = 0.05*BS;
		}
		float move_d = m_base_position.getDistanceFrom(m_last_sent_position);
		move_d += m_last_sent_move_precision;
		float vel_d = m_velocity.getDistanceFrom(m_last_sent_velocity);
		if(move_d > minchange || vel_d > minchange ||
				fabs(m_yaw - m_last_sent_yaw) > 1.0){
			sendPosition(true, false);
		}
	}

	if(m_armor_groups_sent == false){
		m_armor_groups_sent = true;
		std::string str = gob_cmd_update_armor_groups(
				m_armor_groups);
		// create message and add to list
		ActiveObjectMessage aom(getId(), true, str);
		m_messages_out.push(aom);
	}

	if(m_animation_sent == false){
		m_animation_sent = true;
		std::string str = gob_cmd_update_animation(
			m_animation_range, m_animation_speed, m_animation_blend, m_animation_loop);
		// create message and add to list
		ActiveObjectMessage aom(getId(), true, str);
		m_messages_out.push(aom);
	}

	if(m_bone_position_sent == false){
		m_bone_position_sent = true;
		for (UNORDERED_MAP<std::string, core::vector2d<v3f> >::const_iterator
				ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){
			std::string str = gob_cmd_update_bone_position((*ii).first,
					(*ii).second.X, (*ii).second.Y);
			// create message and add to list
			ActiveObjectMessage aom(getId(), true, str);
			m_messages_out.push(aom);
		}
	}

	if(m_attachment_sent == false){
		m_attachment_sent = true;
		std::string str = gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation);
		// create message and add to list
		ActiveObjectMessage aom(getId(), true, str);
		m_messages_out.push(aom);
	}
}