/*
-Minetest-c55
-Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
#include "map.h"
#include "inventory.h"
#include "ban.h"
+#include "hud.h"
#include "gamedef.h"
#include "serialization.h" // For SER_FMT_VER_INVALID
#include "mods.h"
#include "util/string.h"
#include "rollback_interface.h" // Needed for rollbackRevertActions()
#include <list> // Needed for rollbackRevertActions()
+#include <algorithm>
+
+#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
struct LuaState;
typedef struct lua_State lua_State;
class EventManager;
class PlayerSAO;
class IRollbackManager;
+class EmergeManager;
+//struct HudElement;
class ServerError : public std::exception
{
*/
v3f findSpawnPos(ServerMap &map);
-/*
- A structure containing the data needed for queueing the fetching
- of blocks.
-*/
-struct QueuedBlockEmerge
-{
- v3s16 pos;
- // key = peer_id, value = flags
- core::map<u16, u8> peer_ids;
-};
-/*
- This is a thread-safe class.
-*/
-class BlockEmergeQueue
+class MapEditEventIgnorer
{
public:
- BlockEmergeQueue()
- {
- m_mutex.Init();
- }
-
- ~BlockEmergeQueue()
+ MapEditEventIgnorer(bool *flag):
+ m_flag(flag)
{
- JMutexAutoLock lock(m_mutex);
-
- core::list<QueuedBlockEmerge*>::Iterator i;
- for(i=m_queue.begin(); i!=m_queue.end(); i++)
- {
- QueuedBlockEmerge *q = *i;
- delete q;
- }
+ if(*m_flag == false)
+ *m_flag = true;
+ else
+ m_flag = NULL;
}
- /*
- peer_id=0 adds with nobody to send to
- */
- void addBlock(u16 peer_id, v3s16 pos, u8 flags)
+ ~MapEditEventIgnorer()
{
- DSTACK(__FUNCTION_NAME);
-
- JMutexAutoLock lock(m_mutex);
-
- if(peer_id != 0)
+ if(m_flag)
{
- /*
- Find if block is already in queue.
- If it is, update the peer to it and quit.
- */
- core::list<QueuedBlockEmerge*>::Iterator i;
- for(i=m_queue.begin(); i!=m_queue.end(); i++)
- {
- QueuedBlockEmerge *q = *i;
- if(q->pos == pos)
- {
- q->peer_ids[peer_id] = flags;
- return;
- }
- }
+ assert(*m_flag);
+ *m_flag = false;
}
-
- /*
- Add the block
- */
- QueuedBlockEmerge *q = new QueuedBlockEmerge;
- q->pos = pos;
- if(peer_id != 0)
- q->peer_ids[peer_id] = flags;
- m_queue.push_back(q);
}
- // Returned pointer must be deleted
- // Returns NULL if queue is empty
- QueuedBlockEmerge * pop()
- {
- JMutexAutoLock lock(m_mutex);
-
- core::list<QueuedBlockEmerge*>::Iterator i = m_queue.begin();
- if(i == m_queue.end())
- return NULL;
- QueuedBlockEmerge *q = *i;
- m_queue.erase(i);
- return q;
- }
+private:
+ bool *m_flag;
+};
- u32 size()
+class MapEditEventAreaIgnorer
+{
+public:
+ MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a):
+ m_ignorevariable(ignorevariable)
{
- JMutexAutoLock lock(m_mutex);
- return m_queue.size();
+ if(m_ignorevariable->getVolume() == 0)
+ *m_ignorevariable = a;
+ else
+ m_ignorevariable = NULL;
}
- u32 peerItemCount(u16 peer_id)
+ ~MapEditEventAreaIgnorer()
{
- JMutexAutoLock lock(m_mutex);
-
- u32 count = 0;
-
- core::list<QueuedBlockEmerge*>::Iterator i;
- for(i=m_queue.begin(); i!=m_queue.end(); i++)
+ if(m_ignorevariable)
{
- QueuedBlockEmerge *q = *i;
- if(q->peer_ids.find(peer_id) != NULL)
- count++;
+ assert(m_ignorevariable->getVolume() != 0);
+ *m_ignorevariable = VoxelArea();
}
-
- return count;
}
private:
- core::list<QueuedBlockEmerge*> m_queue;
- JMutex m_mutex;
+ VoxelArea *m_ignorevariable;
};
class Server;
void * Thread();
};
-class EmergeThread : public SimpleThread
-{
- Server *m_server;
-
-public:
-
- EmergeThread(Server *server):
- SimpleThread(),
- m_server(server)
- {
- }
-
- void * Thread();
-
- void trigger()
- {
- setRun(true);
- if(IsRunning() == false)
- {
- Start();
- }
- }
-};
-
struct PlayerInfo
{
u16 id;
pos = a_pos;
peer_id = a_peer_id;
}
- bool operator < (PrioritySortedBlockTransfer &other)
+ bool operator < (const PrioritySortedBlockTransfer &other) const
{
return priority < other.priority;
}
dtime is used for resetting send radius at slow interval
*/
void GetNextBlocks(Server *server, float dtime,
- core::array<PrioritySortedBlockTransfer> &dest);
+ std::vector<PrioritySortedBlockTransfer> &dest);
void GotBlock(v3s16 p);
void SentBlock(v3s16 p);
void SetBlockNotSent(v3s16 p);
- void SetBlocksNotSent(core::map<v3s16, MapBlock*> &blocks);
+ void SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks);
s32 SendingCount()
{
List of active objects that the client knows of.
Value is dummy.
*/
- core::map<u16, bool> m_known_objects;
+ std::set<u16> m_known_objects;
private:
/*
Key is position, value is dummy.
No MapBlock* is stored here because the blocks can get deleted.
*/
- core::map<v3s16, bool> m_blocks_sent;
+ std::set<v3s16> m_blocks_sent;
s16 m_nearest_unsent_d;
v3s16 m_last_center;
float m_nearest_unsent_reset_timer;
Block is removed when GOTBLOCKS is received.
Value is time from sending. (not used at the moment)
*/
- core::map<v3s16, float> m_blocks_sending;
+ std::map<v3s16, float> m_blocks_sending;
/*
Count of excess GotBlocks().
void Receive();
void ProcessData(u8 *data, u32 datasize, u16 peer_id);
- core::list<PlayerInfo> getPlayerInfo();
+ std::list<PlayerInfo> getPlayerInfo();
// Environment must be locked when called
void setTimeOfDay(u32 time)
}
// Envlock and conlock should be locked when calling this
- void notifyPlayer(const char *name, const std::wstring msg);
+ void notifyPlayer(const char *name, const std::wstring msg, const bool prepend);
void notifyPlayers(const std::wstring msg);
+ void spawnParticle(const char *playername,
+ v3f pos, v3f velocity, v3f acceleration,
+ float expirationtime, float size,
+ bool collisiondetection, std::string texture);
+
+ void spawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
+ float expirationtime, float size,
+ bool collisiondetection, std::string texture);
+
+ u32 addParticleSpawner(const char *playername,
+ u16 amount, float spawntime,
+ v3f minpos, v3f maxpos,
+ v3f minvel, v3f maxvel,
+ v3f minacc, v3f maxacc,
+ float minexptime, float maxexptime,
+ float minsize, float maxsize,
+ bool collisiondetection, std::string texture);
+
+ u32 addParticleSpawnerAll(u16 amount, float spawntime,
+ v3f minpos, v3f maxpos,
+ v3f minvel, v3f maxvel,
+ v3f minacc, v3f maxacc,
+ float minexptime, float maxexptime,
+ float minsize, float maxsize,
+ bool collisiondetection, std::string texture);
+
+ void deleteParticleSpawner(const char *playername, u32 id);
+ void deleteParticleSpawnerAll(u32 id);
void queueBlockEmerge(v3s16 blockpos, bool allow_generate);
// Envlock should be locked when using the rollback manager
IRollbackManager *getRollbackManager(){ return m_rollback; }
- //TODO: determine what should be locked when accessing the emerge manager
+ //TODO: determine what (if anything) should be locked to access EmergeManager
EmergeManager *getEmergeManager(){ return m_emerge; }
// actions: time-reversed list
IWritableCraftDefManager* getWritableCraftDefManager();
const ModSpec* getModSpec(const std::string &modname);
- void getModNames(core::list<std::string> &modlist);
+ void getModNames(std::list<std::string> &modlist);
std::string getBuiltinLuaPath();
std::string getWorldPath(){ return m_path_world; }
}
bool showFormspec(const char *name, const std::string &formspec, const std::string &formname);
+
+ u32 hudAdd(Player *player, HudElement *element);
+ bool hudRemove(Player *player, u32 id);
+ bool hudChange(Player *player, u32 id, HudElementStat stat, void *value);
+ bool hudSetFlags(Player *player, u32 flags, u32 mask);
+
private:
// con::PeerHandler implementation.
Static send methods
*/
+ static void SendMovement(con::Connection &con, u16 peer_id);
static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
static void SendAccessDenied(con::Connection &con, u16 peer_id,
const std::wstring &reason);
static void SendDeathscreen(con::Connection &con, u16 peer_id,
bool set_camera_point_target, v3f camera_point_target);
static void SendItemDef(con::Connection &con, u16 peer_id,
- IItemDefManager *itemdef);
+ IItemDefManager *itemdef, u16 protocol_version);
static void SendNodeDef(con::Connection &con, u16 peer_id,
INodeDefManager *nodedef, u16 protocol_version);
void SendPlayerPrivileges(u16 peer_id);
void SendPlayerInventoryFormspec(u16 peer_id);
void SendShowFormspecMessage(u16 peer_id, const std::string formspec, const std::string formname);
+ void SendHUDAdd(u16 peer_id, u32 id, HudElement *form);
+ void SendHUDRemove(u16 peer_id, u32 id);
+ void SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value);
+ void SendHUDSetFlags(u16 peer_id, u32 flags, u32 mask);
+
/*
Send a node removal/addition event to all clients except ignore_id.
Additionally, if far_players!=NULL, players further away than
*/
// Envlock and conlock should be locked when calling these
void sendRemoveNode(v3s16 p, u16 ignore_id=0,
- core::list<u16> *far_players=NULL, float far_d_nodes=100);
+ std::list<u16> *far_players=NULL, float far_d_nodes=100);
void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
- core::list<u16> *far_players=NULL, float far_d_nodes=100);
+ std::list<u16> *far_players=NULL, float far_d_nodes=100);
void setBlockNotSent(v3s16 p);
// Environment and Connection must be locked when called
void fillMediaCache();
void sendMediaAnnouncement(u16 peer_id);
void sendRequestedMedia(u16 peer_id,
- const core::list<MediaRequest> &tosend);
+ const std::list<MediaRequest> &tosend);
void sendDetachedInventory(const std::string &name, u16 peer_id);
void sendDetachedInventoryToAll(const std::string &name);
void sendDetachedInventories(u16 peer_id);
+ // Adds a ParticleSpawner on peer with peer_id
+ void SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime,
+ v3f minpos, v3f maxpos,
+ v3f minvel, v3f maxvel,
+ v3f minacc, v3f maxacc,
+ float minexptime, float maxexptime,
+ float minsize, float maxsize,
+ bool collisiondetection, std::string texture, u32 id);
+
+ // Adds a ParticleSpawner on all peers
+ void SendAddParticleSpawnerAll(u16 amount, float spawntime,
+ v3f minpos, v3f maxpos,
+ v3f minvel, v3f maxvel,
+ v3f minacc, v3f maxacc,
+ float minexptime, float maxexptime,
+ float minsize, float maxsize,
+ bool collisiondetection, std::string texture, u32 id);
+
+ // Deletes ParticleSpawner on a single client
+ void SendDeleteParticleSpawner(u16 peer_id, u32 id);
+
+ // Deletes ParticleSpawner on all clients
+ void SendDeleteParticleSpawnerAll(u32 id);
+
+ // Spawns particle on single client
+ void SendSpawnParticle(u16 peer_id,
+ v3f pos, v3f velocity, v3f acceleration,
+ float expirationtime, float size,
+ bool collisiondetection, std::string texture);
+
+ // Spawns particle on all clients
+ void SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
+ float expirationtime, float size,
+ bool collisiondetection, std::string texture);
+
/*
Something random
*/
// Some timers
float m_liquid_transform_timer;
+ float m_liquid_transform_every;
float m_print_info_timer;
+ float m_masterserver_timer;
float m_objectdata_timer;
float m_emergethread_trigger_timer;
float m_savemap_timer;
con::Connection m_con;
JMutex m_con_mutex;
// Connected clients (behind the con mutex)
- core::map<u16, RemoteClient*> m_clients;
+ std::map<u16, RemoteClient*> m_clients;
+ u16 m_clients_number; //for announcing masterserver
// Bann checking
BanManager m_banmanager;
// The server mainly operates in this thread
ServerThread m_thread;
- // This thread fetches and generates map
- EmergeThread m_emergethread;
- // Queue of block coordinates to be processed by the emerge thread
- BlockEmergeQueue m_emerge_queue;
/*
Time related stuff
*/
// Mod parent directory paths
- core::list<std::string> m_modspaths;
+ std::list<std::string> m_modspaths;
bool m_shutdown_requested;
*/
// key = name
std::map<std::string, Inventory*> m_detached_inventories;
+
+ /*
+ Particles
+ */
+ std::vector<u32> m_particlespawner_ids;
};
/*