summaryrefslogtreecommitdiff
path: root/src/server.cpp
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2010-12-23 22:35:53 +0200
committerPerttu Ahola <celeron55@gmail.com>2010-12-23 22:35:53 +0200
commit10b06419ab454e8931a9b6502029bc298e8bce35 (patch)
treef8dedc838957537e0ee9efc627c695afccb3c9f2 /src/server.cpp
parent61b5a353849f8c8a188c4f91c1aa89c9e7a1d10a (diff)
downloadminetest-10b06419ab454e8931a9b6502029bc298e8bce35.tar.gz
minetest-10b06419ab454e8931a9b6502029bc298e8bce35.tar.bz2
minetest-10b06419ab454e8931a9b6502029bc298e8bce35.zip
changes to handing of digging (non backwards-compatible i guess)
Diffstat (limited to 'src/server.cpp')
-rw-r--r--src/server.cpp239
1 files changed, 232 insertions, 7 deletions
diff --git a/src/server.cpp b/src/server.cpp
index 8b063b60d..d7bd22668 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -355,8 +355,10 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
{
SharedPtr<JMutexAutoLock> lock(m_time_from_building.getLock());
m_time_from_building.m_value += dtime;
- if(m_time_from_building.m_value
- < FULL_BLOCK_SEND_ENABLE_MIN_TIME_FROM_BUILDING)
+ /*if(m_time_from_building.m_value
+ < FULL_BLOCK_SEND_ENABLE_MIN_TIME_FROM_BUILDING)*/
+ if(m_time_from_building.m_value < g_settings.getFloat(
+ "full_block_send_enable_min_time_from_building"))
{
maximum_simultaneous_block_sends
= LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS;
@@ -1188,7 +1190,7 @@ void Server::AsyncRunStep()
NOTE: Some of this could be moved to RemoteClient
*/
-
+#if 0
{
JMutexAutoLock envlock(m_env_mutex);
JMutexAutoLock conlock(m_con_mutex);
@@ -1208,7 +1210,10 @@ void Server::AsyncRunStep()
client->m_dig_time_remaining -= dtime;
if(client->m_dig_time_remaining > 0)
+ {
+ client->m_time_from_building.set(0.0);
continue;
+ }
v3s16 p_under = client->m_dig_position;
@@ -1287,6 +1292,7 @@ void Server::AsyncRunStep()
v.blitBack(modified_blocks);
}
}
+#endif
// Send object positions
{
@@ -1493,6 +1499,20 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
m_time_of_day.get());
m_con.Send(peer->id, 0, data, true);
}
+
+ // Send information about joining in chat
+ {
+ std::wstring name = L"unknown";
+ Player *player = m_env.getPlayer(peer_id);
+ if(player != NULL)
+ name = narrow_to_wide(player->getName());
+
+ std::wstring message;
+ message += L"*** ";
+ message += name;
+ message += L" joined game";
+ BroadcastChatMessage(message);
+ }
return;
}
@@ -1688,7 +1708,12 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
*/
if(action == 0)
{
+ /*
+ NOTE: This can be used in the future to check if
+ somebody is cheating, by checking the timing.
+ */
+#if 0
u8 content;
try
@@ -1728,7 +1753,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// Reset build time counter
getClient(peer->id)->m_time_from_building.set(0.0);
-
+#endif
} // action == 0
/*
@@ -1736,12 +1761,118 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
*/
else if(action == 2)
{
+#if 0
RemoteClient *client = getClient(peer->id);
JMutexAutoLock digmutex(client->m_dig_mutex);
client->m_dig_tool_item = -1;
+#endif
}
/*
+ 3: Digging completed
+ */
+ if(action == 3)
+ {
+ // Mandatory parameter; actually used for nothing
+ core::map<v3s16, MapBlock*> modified_blocks;
+
+ u8 material;
+
+ try
+ {
+ // Get material at position
+ material = m_env.getMap().getNode(p_under).d;
+ // If it's not diggable, do nothing
+ if(content_diggable(material) == false)
+ {
+ derr_server<<"Server: Not finishing digging: Node not diggable"
+ <<std::endl;
+ return;
+ }
+ }
+ catch(InvalidPositionException &e)
+ {
+ derr_server<<"Server: Not finishing digging: Node not found"
+ <<std::endl;
+ return;
+ }
+
+ //TODO: Send to only other clients
+
+ /*
+ Send the removal to all other clients
+ */
+
+ // Create packet
+ u32 replysize = 8;
+ SharedBuffer<u8> reply(replysize);
+ writeU16(&reply[0], TOCLIENT_REMOVENODE);
+ writeS16(&reply[2], p_under.X);
+ writeS16(&reply[4], p_under.Y);
+ writeS16(&reply[6], p_under.Z);
+
+ for(core::map<u16, RemoteClient*>::Iterator
+ i = m_clients.getIterator();
+ i.atEnd() == false; i++)
+ {
+ // Get client and check that it is valid
+ RemoteClient *client = i.getNode()->getValue();
+ assert(client->peer_id == i.getNode()->getKey());
+ if(client->serialization_version == SER_FMT_VER_INVALID)
+ continue;
+
+ // Don't send if it's the same one
+ if(peer_id == client->peer_id)
+ continue;
+
+ // Send as reliable
+ m_con.Send(client->peer_id, 0, reply, true);
+ }
+
+ /*
+ Update and send inventory
+ */
+
+ if(g_settings.getBool("creative_mode") == false)
+ {
+ // Add to inventory and send inventory
+ InventoryItem *item = new MaterialItem(material, 1);
+ player->inventory.addItem("main", item);
+ SendInventory(player->peer_id);
+ }
+
+ /*
+ Remove the node
+ (this takes some time so it is done after the quick stuff)
+ */
+ m_env.getMap().removeNodeAndUpdate(p_under, modified_blocks);
+
+ /*
+ Update water
+ */
+
+ // Update water pressure around modification
+ // This also adds it to m_flow_active_nodes if appropriate
+
+ MapVoxelManipulator v(&m_env.getMap());
+ v.m_disable_water_climb =
+ g_settings.getBool("disable_water_climb");
+
+ VoxelArea area(p_under-v3s16(1,1,1), p_under+v3s16(1,1,1));
+
+ try
+ {
+ v.updateAreaWaterPressure(area, m_flow_active_nodes);
+ }
+ catch(ProcessingLimitException &e)
+ {
+ dstream<<"Processing limit reached (1)"<<std::endl;
+ }
+
+ v.blitBack(modified_blocks);
+ }
+
+ /*
1: place block
*/
else if(action == 1)
@@ -1948,6 +2079,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
}
} // action == 1
+
/*
Catch invalid actions
*/
@@ -2100,6 +2232,57 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
<<std::endl;
}
}
+ else if(command == TOSERVER_CHAT_MESSAGE)
+ {
+ /*
+ u16 command
+ u16 length
+ wstring message
+ */
+ u8 buf[6];
+ std::string datastring((char*)&data[2], datasize-2);
+ std::istringstream is(datastring, std::ios_base::binary);
+
+ // Read stuff
+ is.read((char*)buf, 2);
+ u16 len = readU16(buf);
+
+ std::wstring message;
+ for(u16 i=0; i<len; i++)
+ {
+ is.read((char*)buf, 2);
+ message += (wchar_t)readU16(buf);
+ }
+
+ dstream<<"CHAT: "<<wide_to_narrow(message)<<std::endl;
+
+ /*
+ Send the message to all other clients
+ */
+ for(core::map<u16, RemoteClient*>::Iterator
+ i = m_clients.getIterator();
+ i.atEnd() == false; i++)
+ {
+ // Get client and check that it is valid
+ RemoteClient *client = i.getNode()->getValue();
+ assert(client->peer_id == i.getNode()->getKey());
+ if(client->serialization_version == SER_FMT_VER_INVALID)
+ continue;
+
+ // Don't send if it's the same one
+ if(peer_id == client->peer_id)
+ continue;
+
+ // Get player name of this client
+ std::wstring name = L"unknown";
+ Player *player = m_env.getPlayer(client->peer_id);
+ if(player != NULL)
+ name = narrow_to_wide(player->getName());
+
+ SendChatMessage(client->peer_id,
+ std::wstring(L"<")+name+L"> "+message);
+ }
+ }
else
{
derr_server<<"WARNING: Server::ProcessData(): Ignoring "
@@ -2401,8 +2584,6 @@ void Server::SendInventory(u16 peer_id)
{
DSTACK(__FUNCTION_NAME);
- //JMutexAutoLock envlock(m_env_mutex);
-
Player* player = m_env.getPlayer(peer_id);
/*
@@ -2464,12 +2645,56 @@ void Server::SendInventory(u16 peer_id)
writeU16(&data[0], TOCLIENT_INVENTORY);
memcpy(&data[2], s.c_str(), s.size());
- //JMutexAutoLock conlock(m_con_mutex);
+ // Send as reliable
+ m_con.Send(peer_id, 0, data, true);
+}
+void Server::SendChatMessage(u16 peer_id, const std::wstring &message)
+{
+ DSTACK(__FUNCTION_NAME);
+
+ std::ostringstream os(std::ios_base::binary);
+ u8 buf[12];
+
+ // Write command
+ writeU16(buf, TOCLIENT_CHAT_MESSAGE);
+ os.write((char*)buf, 2);
+
+ // Write length
+ writeU16(buf, message.size());
+ os.write((char*)buf, 2);
+
+ // Write string
+ for(u32 i=0; i<message.size(); i++)
+ {
+ u16 w = message[i];
+ writeU16(buf, w);
+ os.write((char*)buf, 2);
+ }
+
+ // Make data buffer
+ std::string s = os.str();
+ SharedBuffer<u8> data((u8*)s.c_str(), s.size());
// Send as reliable
m_con.Send(peer_id, 0, data, true);
}
+void Server::BroadcastChatMessage(const std::wstring &message)
+{
+ for(core::map<u16, RemoteClient*>::Iterator
+ i = m_clients.getIterator();
+ i.atEnd() == false; i++)
+ {
+ // Get client and check that it is valid
+ RemoteClient *client = i.getNode()->getValue();
+ assert(client->peer_id == i.getNode()->getKey());
+ if(client->serialization_version == SER_FMT_VER_INVALID)
+ continue;
+
+ SendChatMessage(client->peer_id, message);
+ }
+}
+
void Server::SendBlocks(float dtime)
{
DSTACK(__FUNCTION_NAME);