Players are left on server while server is running. No passwords yet.

This commit is contained in:
Perttu Ahola 2011-01-15 03:28:19 +02:00
parent cfaa15895a
commit 3fb0d2fb65
9 changed files with 312 additions and 174 deletions

@ -568,7 +568,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
our_peer_id = m_con.GetPeerID(); our_peer_id = m_con.GetPeerID();
} }
// Cancel if we don't have a peer id // Cancel if we don't have a peer id
if(our_peer_id == PEER_ID_NEW){ if(our_peer_id == PEER_ID_INEXISTENT){
dout_client<<DTIME<<"TOCLIENT_PLAYERPOS cancelled: " dout_client<<DTIME<<"TOCLIENT_PLAYERPOS cancelled: "
"we have no peer id" "we have no peer id"
<<std::endl; <<std::endl;
@ -634,7 +634,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
our_peer_id = m_con.GetPeerID(); our_peer_id = m_con.GetPeerID();
} }
// Cancel if we don't have a peer id // Cancel if we don't have a peer id
if(our_peer_id == PEER_ID_NEW){ if(our_peer_id == PEER_ID_INEXISTENT){
dout_client<<DTIME<<"TOCLIENT_PLAYERINFO cancelled: " dout_client<<DTIME<<"TOCLIENT_PLAYERINFO cancelled: "
"we have no peer id" "we have no peer id"
<<std::endl; <<std::endl;
@ -1410,7 +1410,7 @@ void Client::sendPlayerPos()
} }
// Set peer id if not set already // Set peer id if not set already
if(myplayer->peer_id == PEER_ID_NEW) if(myplayer->peer_id == PEER_ID_INEXISTENT)
myplayer->peer_id = our_peer_id; myplayer->peer_id = our_peer_id;
// Check that an existing peer_id is the same as the connection's // Check that an existing peer_id is the same as the connection's
assert(myplayer->peer_id == our_peer_id); assert(myplayer->peer_id == our_peer_id);

@ -497,7 +497,7 @@ Connection::Connection(
m_protocol_id = protocol_id; m_protocol_id = protocol_id;
m_max_packet_size = max_packet_size; m_max_packet_size = max_packet_size;
m_timeout = timeout; m_timeout = timeout;
m_peer_id = PEER_ID_NEW; m_peer_id = PEER_ID_INEXISTENT;
//m_waiting_new_peer_id = false; //m_waiting_new_peer_id = false;
m_indentation = 0; m_indentation = 0;
m_peerhandler = peerhandler; m_peerhandler = peerhandler;
@ -534,8 +534,8 @@ void Connection::Connect(Address address)
m_socket.Bind(0); m_socket.Bind(0);
// Send a dummy packet to server with peer_id = PEER_ID_NEW // Send a dummy packet to server with peer_id = PEER_ID_INEXISTENT
m_peer_id = PEER_ID_NEW; m_peer_id = PEER_ID_INEXISTENT;
SharedBuffer<u8> data(0); SharedBuffer<u8> data(0);
Send(PEER_ID_SERVER, 0, data, true); Send(PEER_ID_SERVER, 0, data, true);
@ -568,7 +568,7 @@ bool Connection::Connected()
if(node == NULL) if(node == NULL)
return false; return false;
if(m_peer_id == PEER_ID_NEW) if(m_peer_id == PEER_ID_INEXISTENT)
return false; return false;
return true; return true;
@ -643,7 +643,7 @@ SharedBuffer<u8> Channel::ProcessPacket(
con->PrintInfo(); con->PrintInfo();
dout_con<<"Got new peer id: "<<peer_id_new<<"... "<<std::endl; dout_con<<"Got new peer id: "<<peer_id_new<<"... "<<std::endl;
if(con->GetPeerID() != PEER_ID_NEW) if(con->GetPeerID() != PEER_ID_INEXISTENT)
{ {
con->PrintInfo(derr_con); con->PrintInfo(derr_con);
derr_con<<"WARNING: Not changing" derr_con<<"WARNING: Not changing"
@ -951,7 +951,7 @@ u32 Connection::Receive(u16 &peer_id, u8 *data, u32 datasize)
throw InvalidIncomingDataException("Channel doesn't exist"); throw InvalidIncomingDataException("Channel doesn't exist");
} }
if(peer_id == PEER_ID_NEW) if(peer_id == PEER_ID_INEXISTENT)
{ {
/* /*
Somebody is trying to send stuff to us with no peer id. Somebody is trying to send stuff to us with no peer id.
@ -994,7 +994,7 @@ u32 Connection::Receive(u16 &peer_id, u8 *data, u32 datasize)
/* /*
The peer was not found in our lists. Add it. The peer was not found in our lists. Add it.
*/ */
if(peer_id == PEER_ID_NEW) if(peer_id == PEER_ID_INEXISTENT)
{ {
// Somebody wants to make a new connection // Somebody wants to make a new connection
@ -1016,7 +1016,7 @@ u32 Connection::Receive(u16 &peer_id, u8 *data, u32 datasize)
} }
PrintInfo(); PrintInfo();
dout_con<<"Receive(): Got a packet with peer_id=PEER_ID_NEW," dout_con<<"Receive(): Got a packet with peer_id=PEER_ID_INEXISTENT,"
" giving peer_id="<<peer_id_new<<std::endl; " giving peer_id="<<peer_id_new<<std::endl;
// Create a peer // Create a peer
@ -1042,7 +1042,7 @@ u32 Connection::Receive(u16 &peer_id, u8 *data, u32 datasize)
if(node == NULL) if(node == NULL)
{ {
// Peer not found // Peer not found
// This means that the peer id of the sender is not PEER_ID_NEW // This means that the peer id of the sender is not PEER_ID_INEXISTENT
// and it is invalid. // and it is invalid.
PrintInfo(derr_con); PrintInfo(derr_con);
derr_con<<"Receive(): Peer not found"<<std::endl; derr_con<<"Receive(): Peer not found"<<std::endl;

@ -209,7 +209,7 @@ channel:
Only channels 0, 1 and 2 exist. Only channels 0, 1 and 2 exist.
*/ */
#define BASE_HEADER_SIZE 7 #define BASE_HEADER_SIZE 7
#define PEER_ID_NEW 0 #define PEER_ID_INEXISTENT 0
#define PEER_ID_SERVER 1 #define PEER_ID_SERVER 1
#define CHANNEL_COUNT 3 #define CHANNEL_COUNT 3
/* /*

@ -243,11 +243,44 @@ Player * Environment::getPlayer(u16 peer_id)
return NULL; return NULL;
} }
Player * Environment::getPlayer(const char *name)
{
for(core::list<Player*>::Iterator i = m_players.begin();
i != m_players.end(); i++)
{
Player *player = *i;
if(strcmp(player->getName(), name) == 0)
return player;
}
return NULL;
}
core::list<Player*> Environment::getPlayers() core::list<Player*> Environment::getPlayers()
{ {
return m_players; return m_players;
} }
core::list<Player*> Environment::getPlayers(bool ignore_disconnected)
{
core::list<Player*> newlist;
for(core::list<Player*>::Iterator
i = m_players.begin();
i != m_players.end(); i++)
{
Player *player = *i;
if(ignore_disconnected)
{
// Ignore disconnected players
if(player->peer_id == 0)
continue;
}
newlist.push_back(player);
}
return newlist;
}
void Environment::printPlayers(std::ostream &o) void Environment::printPlayers(std::ostream &o)
{ {
o<<"Players in environment:"<<std::endl; o<<"Players in environment:"<<std::endl;

@ -59,7 +59,9 @@ public:
LocalPlayer * getLocalPlayer(); LocalPlayer * getLocalPlayer();
#endif #endif
Player * getPlayer(u16 peer_id); Player * getPlayer(u16 peer_id);
Player * getPlayer(const char *name);
core::list<Player*> getPlayers(); core::list<Player*> getPlayers();
core::list<Player*> getPlayers(bool ignore_disconnected);
void printPlayers(std::ostream &o); void printPlayers(std::ostream &o);
#ifndef SERVER #ifndef SERVER

@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
Player::Player(): Player::Player():
touching_ground(false), touching_ground(false),
in_water(false), in_water(false),
peer_id(PEER_ID_NEW), peer_id(PEER_ID_INEXISTENT),
m_speed(0,0,0), m_speed(0,0,0),
m_position(0,0,0) m_position(0,0,0)
{ {

@ -97,8 +97,9 @@ public:
virtual void updateLight(u8 light_at_pos) {}; virtual void updateLight(u8 light_at_pos) {};
virtual bool isClientConnected() { return false; } // NOTE: Use peer_id == 0 for disconnected
virtual void setClientConnected(bool) {} /*virtual bool isClientConnected() { return false; }
virtual void setClientConnected(bool) {}*/
bool touching_ground; bool touching_ground;
bool in_water; bool in_water;
@ -118,8 +119,9 @@ protected:
class ServerRemotePlayer : public Player class ServerRemotePlayer : public Player
{ {
public: public:
ServerRemotePlayer(bool client_connected): /*ServerRemotePlayer(bool client_connected):
m_client_connected(client_connected) m_client_connected(client_connected)*/
ServerRemotePlayer()
{ {
} }
virtual ~ServerRemotePlayer() virtual ~ServerRemotePlayer()
@ -135,7 +137,7 @@ public:
{ {
} }
virtual bool isClientConnected() /*virtual bool isClientConnected()
{ {
return m_client_connected; return m_client_connected;
} }
@ -145,7 +147,7 @@ public:
} }
// This // This
bool m_client_connected; bool m_client_connected;*/
private: private:
}; };

@ -294,6 +294,8 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
Player *player = server->m_env.getPlayer(peer_id); Player *player = server->m_env.getPlayer(peer_id);
assert(player != NULL);
v3f playerpos = player->getPosition(); v3f playerpos = player->getPosition();
v3f playerspeed = player->getSpeed(); v3f playerspeed = player->getSpeed();
@ -605,7 +607,8 @@ void RemoteClient::SendObjectData(
Get and write player data Get and write player data
*/ */
core::list<Player*> players = server->m_env.getPlayers(); // Get connected players
core::list<Player*> players = server->m_env.getPlayers(true);
// Write player count // Write player count
u16 playercount = players.size(); u16 playercount = players.size();
@ -656,6 +659,8 @@ void RemoteClient::SendObjectData(
Player *player = server->m_env.getPlayer(peer_id); Player *player = server->m_env.getPlayer(peer_id);
assert(player);
v3f playerpos = player->getPosition(); v3f playerpos = player->getPosition();
v3f playerspeed = player->getSpeed(); v3f playerspeed = player->getSpeed();
@ -847,7 +852,8 @@ PlayerInfo::PlayerInfo()
void PlayerInfo::PrintLine(std::ostream *s) void PlayerInfo::PrintLine(std::ostream *s)
{ {
(*s)<<id<<": \""<<name<<"\" (" (*s)<<id<<": ";
(*s)<<"\""<<name<<"\" ("
<<position.X<<","<<position.Y <<position.X<<","<<position.Y
<<","<<position.Z<<") "; <<","<<position.Z<<") ";
address.print(s); address.print(s);
@ -910,13 +916,13 @@ Server::~Server()
i = m_clients.getIterator(); i = m_clients.getIterator();
i.atEnd() == false; i++) i.atEnd() == false; i++)
{ {
u16 peer_id = i.getNode()->getKey(); /*// Delete player
// NOTE: These are removed by env destructor
// Delete player
{ {
u16 peer_id = i.getNode()->getKey();
JMutexAutoLock envlock(m_env_mutex); JMutexAutoLock envlock(m_env_mutex);
m_env.removePlayer(peer_id); m_env.removePlayer(peer_id);
} }*/
// Delete client // Delete client
delete i.getNode()->getValue(); delete i.getNode()->getValue();
@ -1420,19 +1426,43 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
Set up player Set up player
*/ */
Player *player = m_env.getPlayer(peer_id); // Get player name
const u32 playername_size = 20;
char playername[playername_size];
for(u32 i=0; i<playername_size-1; i++)
{
playername[i] = data[3+i];
}
playername[playername_size-1] = 0;
// Get player
Player *player = emergePlayer(playername, "");
//Player *player = m_env.getPlayer(peer_id);
// If a client is already connected to the player, cancel
if(player->peer_id != 0)
{
derr_server<<DTIME<<"Server: peer_id="<<peer_id
<<" tried to connect to "
"an already connected player (peer_id="
<<player->peer_id<<")"<<std::endl;
return;
}
// Set client of player
player->peer_id = peer_id;
// Check if player doesn't exist // Check if player doesn't exist
if(player == NULL) if(player == NULL)
throw con::InvalidIncomingDataException throw con::InvalidIncomingDataException
("Server::ProcessData(): INIT: Player doesn't exist"); ("Server::ProcessData(): INIT: Player doesn't exist");
// update name if it was supplied /*// update name if it was supplied
if(datasize >= 20+3) if(datasize >= 20+3)
{ {
data[20+3-1] = 0; data[20+3-1] = 0;
player->updateName((const char*)&data[3]); player->updateName((const char*)&data[3]);
} }*/
// Now answer with a TOCLIENT_INIT // Now answer with a TOCLIENT_INIT
@ -1488,9 +1518,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
assert(client->peer_id == i.getNode()->getKey()); assert(client->peer_id == i.getNode()->getKey());
if(client->serialization_version == SER_FMT_VER_INVALID) if(client->serialization_version == SER_FMT_VER_INVALID)
continue; continue;
// Get player
Player *player = m_env.getPlayer(client->peer_id);
// Get name of player // Get name of player
std::wstring name = L"unknown"; std::wstring name = L"unknown";
Player *player = m_env.getPlayer(client->peer_id);
if(player != NULL) if(player != NULL)
name = narrow_to_wide(player->getName()); name = narrow_to_wide(player->getName());
// Add name to information string // Add name to information string
@ -2394,15 +2425,17 @@ core::list<PlayerInfo> Server::getPlayerInfo()
PlayerInfo info; PlayerInfo info;
Player *player = *i; Player *player = *i;
try{ try{
con::Peer *peer = m_con.GetPeer(player->peer_id); con::Peer *peer = m_con.GetPeer(player->peer_id);
// Copy info from peer to info struct
info.id = peer->id; info.id = peer->id;
info.address = peer->address; info.address = peer->address;
info.avg_rtt = peer->avg_rtt; info.avg_rtt = peer->avg_rtt;
} }
catch(con::PeerNotFoundException &e) catch(con::PeerNotFoundException &e)
{ {
// Outdated peer info // Set dummy peer info
info.id = 0; info.id = 0;
info.address = Address(0,0,0,0,0); info.address = Address(0,0,0,0,0);
info.avg_rtt = 0.0; info.avg_rtt = 0.0;
@ -2470,7 +2503,8 @@ void Server::SendPlayerInfos()
//JMutexAutoLock envlock(m_env_mutex); //JMutexAutoLock envlock(m_env_mutex);
core::list<Player*> players = m_env.getPlayers(); // Get connected players
core::list<Player*> players = m_env.getPlayers(true);
u32 player_count = players.getSize(); u32 player_count = players.getSize();
u32 datasize = 2+(2+PLAYERNAME_SIZE)*player_count; u32 datasize = 2+(2+PLAYERNAME_SIZE)*player_count;
@ -2922,78 +2956,86 @@ RemoteClient* Server::getClient(u16 peer_id)
return n->getValue(); return n->getValue();
} }
void Server::UpdateBlockWaterPressure(MapBlock *block, Player *Server::emergePlayer(const char *name, const char *password)
core::map<v3s16, MapBlock*> &modified_blocks)
{ {
MapVoxelManipulator v(&m_env.getMap());
v.m_disable_water_climb =
g_settings.getBool("disable_water_climb");
VoxelArea area(block->getPosRelative(),
block->getPosRelative() + v3s16(1,1,1)*(MAP_BLOCKSIZE-1));
try
{
v.updateAreaWaterPressure(area, m_flow_active_nodes);
}
catch(ProcessingLimitException &e)
{
dstream<<"Processing limit reached (1)"<<std::endl;
}
v.blitBack(modified_blocks);
}
void Server::handlePeerChange(PeerChange &c)
{
JMutexAutoLock envlock(m_env_mutex);
JMutexAutoLock conlock(m_con_mutex);
if(c.type == PEER_ADDED)
{
/* /*
Add Try to get an existing player
*/ */
Player *player = m_env.getPlayer(name);
// Error check if(player != NULL)
core::map<u16, RemoteClient*>::Node *n;
n = m_clients.find(c.peer_id);
// The client shouldn't already exist
assert(n == NULL);
// Create client
RemoteClient *client = new RemoteClient();
client->peer_id = c.peer_id;
m_clients.insert(client->peer_id, client);
// Create player
{ {
Player *player = m_env.getPlayer(c.peer_id); // Got one.
return player;
}
// The player shouldn't already exist /*
assert(player == NULL); Create a new player
*/
player = new ServerRemotePlayer(true); {
player->peer_id = c.peer_id; player = new ServerRemotePlayer();
//player->peer_id = c.peer_id;
player->peer_id = PEER_ID_INEXISTENT;
player->updateName(name);
/* /*
Set player position Set player position
*/ */
#if 0
// We're going to throw the player to this position // We're going to throw the player to this position
//v2s16 nodepos(29990,29990); //v2s16 nodepos(29990,29990);
//v2s16 nodepos(9990,9990); //v2s16 nodepos(9990,9990);
v2s16 nodepos(0,0); v2s16 nodepos(0,0);
v2s16 sectorpos = getNodeSectorPos(nodepos); v2s16 sectorpos = getNodeSectorPos(nodepos);
// Get zero sector (it could have been unloaded to disk) // Get sector
m_env.getMap().emergeSector(sectorpos); m_env.getMap().emergeSector(sectorpos);
// Get ground height at origin // Get ground height at point
f32 groundheight = m_env.getMap().getGroundHeight(nodepos, true); f32 groundheight = m_env.getMap().getGroundHeight(nodepos, true);
// The sector should have been generated -> groundheight exists // The sector should have been generated -> groundheight exists
assert(groundheight > GROUNDHEIGHT_VALID_MINVALUE); assert(groundheight > GROUNDHEIGHT_VALID_MINVALUE);
// Don't go underwater // Don't go underwater
if(groundheight < WATER_LEVEL) if(groundheight < WATER_LEVEL)
groundheight = WATER_LEVEL; groundheight = WATER_LEVEL;
#endif
#if 1
v2s16 nodepos;
f32 groundheight = 0;
// Try to find a good place a few times
for(s32 i=0; i<100; i++)
{
s32 range = 1 + i*5;
// We're going to try to throw the player to this position
nodepos = v2s16(-range/2 + (myrand()%range),
-range/2 + (myrand()%range));
v2s16 sectorpos = getNodeSectorPos(nodepos);
// Get sector
m_env.getMap().emergeSector(sectorpos);
// Get ground height at point
groundheight = m_env.getMap().getGroundHeight(nodepos, true);
// The sector should have been generated -> groundheight exists
assert(groundheight > GROUNDHEIGHT_VALID_MINVALUE);
// Don't go underwater
if(groundheight < WATER_LEVEL)
continue;
// Don't go inside ground
try{
v3s16 footpos(nodepos.X, groundheight+1, nodepos.Y);
v3s16 headpos(nodepos.X, groundheight+2, nodepos.Y);
if(m_env.getMap().getNode(footpos).d != CONTENT_AIR
|| m_env.getMap().getNode(headpos).d != CONTENT_AIR)
{
// In ground
continue;
}
}catch(InvalidPositionException &e)
{
// Ignore invalid position
continue;
}
// Found a good place
break;
}
#endif
player->setPosition(intToFloat(v3s16( player->setPosition(intToFloat(v3s16(
nodepos.X, nodepos.X,
@ -3103,7 +3145,54 @@ void Server::handlePeerChange(PeerChange &c)
assert(r == true); assert(r == true);
}*/ }*/
} }
return player;
} }
}
void Server::UpdateBlockWaterPressure(MapBlock *block,
core::map<v3s16, MapBlock*> &modified_blocks)
{
MapVoxelManipulator v(&m_env.getMap());
v.m_disable_water_climb =
g_settings.getBool("disable_water_climb");
VoxelArea area(block->getPosRelative(),
block->getPosRelative() + v3s16(1,1,1)*(MAP_BLOCKSIZE-1));
try
{
v.updateAreaWaterPressure(area, m_flow_active_nodes);
}
catch(ProcessingLimitException &e)
{
dstream<<"Processing limit reached (1)"<<std::endl;
}
v.blitBack(modified_blocks);
}
void Server::handlePeerChange(PeerChange &c)
{
JMutexAutoLock envlock(m_env_mutex);
JMutexAutoLock conlock(m_con_mutex);
if(c.type == PEER_ADDED)
{
/*
Add
*/
// Error check
core::map<u16, RemoteClient*>::Node *n;
n = m_clients.find(c.peer_id);
// The client shouldn't already exist
assert(n == NULL);
// Create client
RemoteClient *client = new RemoteClient();
client->peer_id = c.peer_id;
m_clients.insert(client->peer_id, client);
} // PEER_ADDED } // PEER_ADDED
else if(c.type == PEER_REMOVED) else if(c.type == PEER_REMOVED)
@ -3133,9 +3222,15 @@ void Server::handlePeerChange(PeerChange &c)
message += L" (timed out)"; message += L" (timed out)";
} }
// Delete player /*// Delete player
{ {
m_env.removePlayer(c.peer_id); m_env.removePlayer(c.peer_id);
}*/
// Set player client disconnected
{
Player *player = m_env.getPlayer(c.peer_id);
player->peer_id = 0;
} }
// Delete client // Delete client

@ -425,6 +425,12 @@ private:
// When called, connection mutex should be locked // When called, connection mutex should be locked
RemoteClient* getClient(u16 peer_id); RemoteClient* getClient(u16 peer_id);
// Gets a player from memory or creates one.
// Caller should check isClientConnected() and set it appropriately.
//
// Call with env and con locked.
Player *emergePlayer(const char *name, const char *password);
/* /*
Update water pressure. Update water pressure.
This also adds suitable nodes to active_nodes. This also adds suitable nodes to active_nodes.