IrrlichtDevice *device,
const char *playername,
const std::string &password,
+ const std::string &address_name,
MapDrawControl &control,
IWritableTextureSource *tsrc,
IWritableShaderSource *shsrc,
),
m_particle_manager(&m_env),
m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, ipv6, this),
+ m_address_name(address_name),
m_device(device),
m_camera(NULL),
+ m_minimap(NULL),
m_minimap_disabled_by_server(false),
m_server_ser_ver(SER_FMT_VER_INVALID),
m_proto_ver(0),
m_animation_time(0),
m_crack_level(-1),
m_crack_pos(0,0,0),
+ m_last_chat_message_sent(time(NULL)),
+ m_chat_message_allowance(5.0f),
m_map_seed(0),
m_password(password),
m_chosen_auth_mech(AUTH_MECHANISM_NONE),
// Add local player
m_env.setLocalPlayer(new LocalPlayer(this, playername));
- m_minimap = new Minimap(device, this);
+ if (g_settings->getBool("enable_minimap")) {
+ m_minimap = new Minimap(device, this);
+ }
m_cache_save_interval = g_settings->getU16("server_map_save_interval");
m_modding_enabled = g_settings->getBool("enable_client_modding");
if (!string_allowed(mod.name, MODNAME_ALLOWED_CHARS)) {
throw ModError("Error loading mod \"" + mod.name +
"\": Mod name does not follow naming conventions: "
- "Only chararacters [a-z0-9_] are allowed.");
+ "Only characters [a-z0-9_] are allowed.");
}
std::string script_path = mod.path + DIR_DELIM + "init.lua";
infostream << " [" << padStringRight(mod.name, 12) << "] [\""
delete m_minimap;
}
-void Client::connect(Address address,
- const std::string &address_name,
- bool is_local_server)
+void Client::connect(Address address, bool is_local_server)
{
DSTACK(FUNCTION_NAME);
- initLocalMapSaving(address, address_name, is_local_server);
+ initLocalMapSaving(address, m_address_name, is_local_server);
m_con.SetTimeoutMs(0);
m_con.Connect(address);
}
}
+ /*
+ Send pending messages on out chat queue
+ */
+ if (!m_out_chat_queue.empty() && canSendChatMessage()) {
+ sendChatMessage(m_out_chat_queue.front());
+ m_out_chat_queue.pop();
+ }
+
/*
Handle environment
*/
// Step environment
m_env.step(dtime);
+ m_sound->step(dtime);
/*
Get events
delete r.mesh;
}
- if (do_mapper_update)
+ if (m_minimap && do_mapper_update)
m_minimap->addBlock(r.p, minimap_mapblock);
if (r.ack_block_to_server) {
Send(&pkt);
}
+bool Client::canSendChatMessage() const
+{
+ u32 now = time(NULL);
+ float time_passed = now - m_last_chat_message_sent;
+
+ float virt_chat_message_allowance = m_chat_message_allowance + time_passed *
+ (CLIENT_CHAT_MESSAGE_LIMIT_PER_10S / 8.0f);
+
+ if (virt_chat_message_allowance < 1.0f)
+ return false;
+
+ return true;
+}
+
void Client::sendChatMessage(const std::wstring &message)
{
- NetworkPacket pkt(TOSERVER_CHAT_MESSAGE, 2 + message.size() * sizeof(u16));
+ const s16 max_queue_size = g_settings->getS16("max_out_chat_queue_size");
+ if (canSendChatMessage()) {
+ u32 now = time(NULL);
+ float time_passed = now - m_last_chat_message_sent;
+ m_last_chat_message_sent = time(NULL);
- pkt << message;
+ m_chat_message_allowance += time_passed * (CLIENT_CHAT_MESSAGE_LIMIT_PER_10S / 8.0f);
+ if (m_chat_message_allowance > CLIENT_CHAT_MESSAGE_LIMIT_PER_10S)
+ m_chat_message_allowance = CLIENT_CHAT_MESSAGE_LIMIT_PER_10S;
- Send(&pkt);
+ m_chat_message_allowance -= 1.0f;
+
+ NetworkPacket pkt(TOSERVER_CHAT_MESSAGE, 2 + message.size() * sizeof(u16));
+
+ pkt << message;
+
+ Send(&pkt);
+ } else if (m_out_chat_queue.size() < (u16) max_queue_size || max_queue_size == -1) {
+ m_out_chat_queue.push(message);
+ } else {
+ infostream << "Could not queue chat message because maximum out chat queue size ("
+ << max_queue_size << ") is reached." << std::endl;
+ }
+}
+
+void Client::clearOutChatQueue()
+{
+ m_out_chat_queue = std::queue<std::wstring>();
}
void Client::sendChangePassword(const std::string &oldpassword,
float Client::getCurRate()
{
- return ( m_con.getLocalStat(con::CUR_INC_RATE) +
+ return (m_con.getLocalStat(con::CUR_INC_RATE) +
m_con.getLocalStat(con::CUR_DL_RATE));
}
{
return porting::path_user + DIR_DELIM + "client" + DIR_DELIM + "mod_storage";
}
-