From bc4dc80c0166bd5c7f645bec1472101e4a9e20bb Mon Sep 17 00:00:00 2001 From: est31 Date: Fri, 15 Apr 2016 04:13:53 +0200 Subject: [PATCH 1/9] Mainmenu: Still support favorites if send_pre_v25_init is disabled @SmallJoker has noted a bug that servers from the (local) main menu favorites list can't be opened. This commit fixes the bug by disabling any main menu based protocol checks for servers from the favorite list. Also, it fixes a second bug that happens when a server from the public serverlist doesn't send its supported protocol versions, most likely because its running a minetest older than commit [1]. Then we have shown an error msg that the server has enforced one specific protocol version. This was most likely not the case. Of course, we can't do anything better than do an assumption on the protocol versions if they are not known. That assumption should however be closest to the most often occuring case as possible. Also, some little cleanups. [1]: 5a0ed780f56a5225b3d7c5f64099586e390e5f39 "Server: announce MIN/MAX protocol version supported to serverlist. Client: check serverlist" --- builtin/mainmenu/common.lua | 10 +++++++--- builtin/mainmenu/tab_multiplayer.lua | 30 ++++++++++++++++------------ builtin/mainmenu/tab_simple_main.lua | 12 +++++++---- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/builtin/mainmenu/common.lua b/builtin/mainmenu/common.lua index 3dd7d8b4a..62ab2b578 100644 --- a/builtin/mainmenu/common.lua +++ b/builtin/mainmenu/common.lua @@ -246,6 +246,7 @@ function asyncOnlineFavourites() }} end menudata.favorites = menudata.public_known + menudata.favorites_is_public = true core.handle_async( function(param) return core.get_favorites("online") @@ -257,6 +258,7 @@ function asyncOnlineFavourites() if favs[1] then menudata.public_known = favs menudata.favorites = menudata.public_known + menudata.favorites_is_public = true end core.event_handler("Refresh") end @@ -297,12 +299,14 @@ function is_server_protocol_compat_or_error(server_proto_min, server_proto_max) if not is_server_protocol_compat(server_proto_min, server_proto_max) then local server_prot_ver_info local client_prot_ver_info - if server_proto_min ~= server_proto_max then + local s_p_min = server_proto_min or 13 + local s_p_max = server_proto_max or 24 + if s_p_min ~= s_p_max then server_prot_ver_info = fgettext_ne("Server supports protocol versions between $1 and $2. ", - server_proto_min or 13, server_proto_max or 24) + s_p_min, s_p_max) else server_prot_ver_info = fgettext_ne("Server enforces protocol version $1. ", - server_proto_min or 13) + s_p_min) end if min_supp_proto ~= max_supp_proto then client_prot_ver_info= fgettext_ne("We support protocol versions between version $1 and $2.", diff --git a/builtin/mainmenu/tab_multiplayer.lua b/builtin/mainmenu/tab_multiplayer.lua index 06d8791f0..f3ba122fc 100644 --- a/builtin/mainmenu/tab_multiplayer.lua +++ b/builtin/mainmenu/tab_multiplayer.lua @@ -102,22 +102,22 @@ local function main_button_handler(tabview, fields, name, tabdata) local event = core.explode_table_event(fields["favourites"]) if event.type == "DCL" then if event.row <= #menudata.favorites then - if not is_server_protocol_compat_or_error(menudata.favorites[event.row].proto_min, - menudata.favorites[event.row].proto_max) then + local fav = menudata.favorites[event.row] + if menudata.favorites_is_public and + not is_server_protocol_compat_or_error( + fav.proto_min, fav.proto_max) then return true end - gamedata.address = menudata.favorites[event.row].address - gamedata.port = menudata.favorites[event.row].port + gamedata.address = fav.address + gamedata.port = fav.port gamedata.playername = fields["te_name"] if fields["te_pwd"] ~= nil then gamedata.password = fields["te_pwd"] end gamedata.selected_world = 0 - if menudata.favorites ~= nil then - gamedata.servername = menudata.favorites[event.row].name - gamedata.serverdescription = menudata.favorites[event.row].description - end + gamedata.servername = fav.name + gamedata.serverdescription = fav.description if gamedata.address ~= nil and gamedata.port ~= nil then @@ -188,6 +188,7 @@ local function main_button_handler(tabview, fields, name, tabdata) asyncOnlineFavourites() else menudata.favorites = core.get_favorites("local") + menudata.favorites_is_public = false end tabdata.fav_selected = nil return true @@ -197,7 +198,7 @@ local function main_button_handler(tabview, fields, name, tabdata) local current_favourite = core.get_table_index("favourites") if current_favourite == nil then return end core.delete_favorite(current_favourite) - menudata.favorites = order_favorite_list(core.get_favorites()) + menudata.favorites = core.get_favorites("local") tabdata.fav_selected = nil core.setting_set("address","") @@ -221,11 +222,13 @@ local function main_button_handler(tabview, fields, name, tabdata) menudata.favorites[fav_idx].address == fields["te_address"] and menudata.favorites[fav_idx].port == fields["te_port"] then - gamedata.servername = menudata.favorites[fav_idx].name - gamedata.serverdescription = menudata.favorites[fav_idx].description + local fav = menudata.favorites[fav_idx] + gamedata.servername = fav.name + gamedata.serverdescription = fav.description - if not is_server_protocol_compat_or_error(menudata.favorites[fav_idx].proto_min, - menudata.favorites[fav_idx].proto_max)then + if menudata.favorites_is_public and + not is_server_protocol_compat_or_error( + fav.proto_min, fav.proto_max) then return true end else @@ -252,6 +255,7 @@ local function on_change(type,old_tab,new_tab) asyncOnlineFavourites() else menudata.favorites = core.get_favorites("local") + menudata.favorites_is_public = false end end diff --git a/builtin/mainmenu/tab_simple_main.lua b/builtin/mainmenu/tab_simple_main.lua index b32418938..cb64b73f6 100644 --- a/builtin/mainmenu/tab_simple_main.lua +++ b/builtin/mainmenu/tab_simple_main.lua @@ -122,6 +122,7 @@ local function main_button_handler(tabview, fields, name, tabdata) asyncOnlineFavourites() else menudata.favorites = core.get_favorites("local") + menudata.favorites_is_public = false end return true end @@ -149,12 +150,14 @@ local function main_button_handler(tabview, fields, name, tabdata) if fav_idx ~= nil and fav_idx <= #menudata.favorites and menudata.favorites[fav_idx].address == fields["te_address"] and menudata.favorites[fav_idx].port == fields["te_port"] then + local fav = menudata.favorites[fav_idx] - gamedata.servername = menudata.favorites[fav_idx].name - gamedata.serverdescription = menudata.favorites[fav_idx].description + gamedata.servername = fav.name + gamedata.serverdescription = fav.description - if not is_server_protocol_compat_or_error(menudata.favorites[fav_idx].proto_min, - menudata.favorites[fav_idx].proto_max) then + if menudata.favorites_is_public and + not is_server_protocol_compat_or_error( + fav.proto_min, fav.proto_max) then return true end else @@ -192,6 +195,7 @@ local function on_activate(type,old_tab,new_tab) asyncOnlineFavourites() else menudata.favorites = core.get_favorites("local") + menudata.favorites_is_public = false end end From 855a305057a8a41d1e34520c4e88845872a01d6f Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Wed, 13 Apr 2016 23:10:37 -0700 Subject: [PATCH 2/9] falling: walk 4 additional diagonally down directions. This seems very little cost and matches the old behavior more closely. This will cause some more falling nodes to get added to falling clusters. With the efficiency of the algorithm, this really doesn't do much damage. --- builtin/game/falling.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/builtin/game/falling.lua b/builtin/game/falling.lua index cce8d4bf4..57bb98cfd 100644 --- a/builtin/game/falling.lua +++ b/builtin/game/falling.lua @@ -182,6 +182,10 @@ end -- Down first as likely case, but always before self. The same with sides. -- Up must come last, so that things above self will also fall all at once. local nodeupdate_neighbors = { + {x = -1, y = -1, z = 0}, + {x = 1, y = -1, z = 0}, + {x = 0, y = -1, z = -1}, + {x = 0, y = -1, z = 1}, {x = 0, y = -1, z = 0}, {x = -1, y = 0, z = 0}, {x = 1, y = 0, z = 0}, @@ -226,10 +230,10 @@ function nodeupdate(p) n = n - 1 -- If there's nothing left on the stack, and no -- more sides to walk to, we're done and can exit - if n == 0 and v == 7 then + if n == 0 and v == 11 then return end - until v < 7 + until v < 11 -- The next round walk the next neighbor in list. v = v + 1 else From fed5dd3b5d153bc38939298f37650062d11a7082 Mon Sep 17 00:00:00 2001 From: paramat Date: Sat, 16 Apr 2016 23:20:20 +0100 Subject: [PATCH 3/9] Mgv7: Combine mountain terrain generation with base terrain generation Previous mountain terrain generation was by necessity placing stone in air, this was removing air from any overgenerated structures such as tunnels, dungeons and large caves Moving it into the base terrain generation loop ensures that only 'ignore' is replaced generateRidgeTerrain: only return if node_max.Y < water_level - 16 Previously, if water level was set a few nodes above a mapchunk border the river channel was only partially excavated --- src/mapgen_v7.cpp | 144 ++++++++++++++++++++++------------------------ src/mapgen_v7.h | 7 +-- 2 files changed, 70 insertions(+), 81 deletions(-) diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index 069c34119..162bf068f 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -59,6 +59,8 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) //// amount of elements to skip for the next index //// for noise/height/biome maps (not vmanip) this->ystride = csize.X; + // 1-up 1-down overgeneration + this->zstride_1u1d = csize.X * (csize.Y + 2); // 1-down overgeneration this->zstride_1d = csize.X * (csize.Y + 1); @@ -263,10 +265,13 @@ void MapgenV7::makeChunk(BlockMakeData *data) // Make some noise calculateNoise(); - // Generate base terrain, mountains, and ridges with initial heightmaps + // Generate terrain and ridges with initial heightmaps s16 stone_surface_max_y = generateTerrain(); - // Create heightmap + if (spflags & MGV7_RIDGES) + generateRidgeTerrain(); + + // Update heightmap to include mountain terrain updateHeightmap(node_min, node_max); // Create biomemap at heightmap surface @@ -361,6 +366,11 @@ void MapgenV7::calculateNoise() noise_terrain_alt->perlinMap2D(x, z, persistmap); noise_height_select->perlinMap2D(x, z); + if (spflags & MGV7_MOUNTAINS) { + noise_mountain->perlinMap3D(x, y, z); + noise_mount_height->perlinMap2D(x, z); + } + if ((spflags & MGV7_RIDGES) && node_max.Y >= water_level) { noise_ridge->perlinMap3D(x, y, z); noise_ridge_uwater->perlinMap2D(x, z); @@ -369,9 +379,6 @@ void MapgenV7::calculateNoise() // Cave noises are calculated in generateCaves() // only if solid terrain is present in mapchunk - // Mountain noises are calculated in generateMountainTerrain() - // only if solid terrain surface dips into mapchunk - noise_filler_depth->perlinMap2D(x, z); noise_heat->perlinMap2D(x, z); noise_humidity->perlinMap2D(x, z); @@ -400,7 +407,7 @@ Biome *MapgenV7::getBiomeAtPoint(v3s16 p) return bmgr->getBiome(heat, humidity, groundlevel); } -//needs to be updated + float MapgenV7::baseTerrainLevelAtPoint(s16 x, s16 z) { float hselect = NoisePerlin2D(&noise_height_select->np, x, z, seed); @@ -455,100 +462,55 @@ bool MapgenV7::getMountainTerrainFromMap(int idx_xyz, int idx_xz, s16 y) int MapgenV7::generateTerrain() -{ - s16 stone_surface_min_y; - s16 stone_surface_max_y; - - generateBaseTerrain(&stone_surface_min_y, &stone_surface_max_y); - - if ((spflags & MGV7_MOUNTAINS) && stone_surface_min_y < node_max.Y) - stone_surface_max_y = generateMountainTerrain(stone_surface_max_y); - - if (spflags & MGV7_RIDGES) - generateRidgeTerrain(); - - return stone_surface_max_y; -} - - -void MapgenV7::generateBaseTerrain(s16 *stone_surface_min_y, s16 *stone_surface_max_y) { MapNode n_air(CONTENT_AIR); MapNode n_stone(c_stone); MapNode n_water(c_water_source); v3s16 em = vm->m_area.getExtent(); - s16 surface_min_y = MAX_MAP_GENERATION_LIMIT; - s16 surface_max_y = -MAX_MAP_GENERATION_LIMIT; - u32 index = 0; + s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT; + u32 index2d = 0; + bool mountain_flag = spflags & MGV7_MOUNTAINS; for (s16 z = node_min.Z; z <= node_max.Z; z++) - for (s16 x = node_min.X; x <= node_max.X; x++, index++) { - float surface_height = baseTerrainLevelFromMap(index); - s16 surface_y = (s16)surface_height; + for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { + s16 surface_y = baseTerrainLevelFromMap(index2d); + heightmap[index2d] = surface_y; // Create base terrain heightmap + ridge_heightmap[index2d] = surface_y; - heightmap[index] = surface_y; - ridge_heightmap[index] = surface_y; - - if (surface_y < surface_min_y) - surface_min_y = surface_y; - - if (surface_y > surface_max_y) - surface_max_y = surface_y; + if (surface_y > stone_surface_max_y) + stone_surface_max_y = surface_y; u32 vi = vm->m_area.index(x, node_min.Y - 1, z); + u32 index3d = (z - node_min.Z) * zstride_1u1d + (x - node_min.X); + for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { if (vm->m_data[vi].getContent() == CONTENT_IGNORE) { - if (y <= surface_y) - vm->m_data[vi] = n_stone; - else if (y <= water_level) + if (y <= surface_y) { + vm->m_data[vi] = n_stone; // Base terrain + } else if (mountain_flag && + getMountainTerrainFromMap(index3d, index2d, y)) { + vm->m_data[vi] = n_stone; // Mountain terrain + if (y > stone_surface_max_y) + stone_surface_max_y = y; + } else if (y <= water_level) { vm->m_data[vi] = n_water; - else + } else { vm->m_data[vi] = n_air; + } } vm->m_area.add_y(em, vi, 1); + index3d += ystride; } } - *stone_surface_min_y = surface_min_y; - *stone_surface_max_y = surface_max_y; -} - - -int MapgenV7::generateMountainTerrain(s16 ymax) -{ - noise_mountain->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); - noise_mount_height->perlinMap2D(node_min.X, node_min.Z); - - MapNode n_stone(c_stone); - u32 j = 0; - - for (s16 z = node_min.Z; z <= node_max.Z; z++) - for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { - u32 vi = vm->m_area.index(node_min.X, y, z); - for (s16 x = node_min.X; x <= node_max.X; x++) { - int index = (z - node_min.Z) * csize.X + (x - node_min.X); - content_t c = vm->m_data[vi].getContent(); - - if (getMountainTerrainFromMap(j, index, y) - && (c == CONTENT_AIR || c == c_water_source)) { - vm->m_data[vi] = n_stone; - if (y > ymax) - ymax = y; - } - - vi++; - j++; - } - } - - return ymax; + return stone_surface_max_y; } void MapgenV7::generateRidgeTerrain() { - if (node_max.Y < water_level) + if (node_max.Y < water_level - 16) return; MapNode n_water(c_water_source); @@ -562,7 +524,7 @@ void MapgenV7::generateRidgeTerrain() for (s16 x = node_min.X; x <= node_max.X; x++, index++, vi++) { int j = (z - node_min.Z) * csize.X + (x - node_min.X); - if (heightmap[j] < water_level - 16) + if (heightmap[j] < water_level - 16) // Use base terrain heightmap continue; float uwatern = noise_ridge_uwater->result[j] * 2; @@ -805,6 +767,36 @@ void MapgenV7::generateCaves(s16 max_stone_y) /////////////////////////////////////////////////////////////// +#if 0 +int MapgenV7::generateMountainTerrain(s16 ymax) +{ + MapNode n_stone(c_stone); + u32 j = 0; + + for (s16 z = node_min.Z; z <= node_max.Z; z++) + for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { + u32 vi = vm->m_area.index(node_min.X, y, z); + for (s16 x = node_min.X; x <= node_max.X; x++) { + int index = (z - node_min.Z) * csize.X + (x - node_min.X); + content_t c = vm->m_data[vi].getContent(); + + if (getMountainTerrainFromMap(j, index, y) + && (c == CONTENT_AIR || c == c_water_source)) { + vm->m_data[vi] = n_stone; + if (y > ymax) + ymax = y; + } + + vi++; + j++; + } + } + + return ymax; +} +#endif + + #if 0 void MapgenV7::carveRivers() { MapNode n_air(CONTENT_AIR), n_water_source(c_water_source); diff --git a/src/mapgen_v7.h b/src/mapgen_v7.h index 9fdecf592..57cb55a8a 100644 --- a/src/mapgen_v7.h +++ b/src/mapgen_v7.h @@ -59,6 +59,7 @@ public: BiomeManager *bmgr; int ystride; + int zstride_1u1d; int zstride_1d; u32 spflags; @@ -113,16 +114,12 @@ public: void calculateNoise(); - virtual int generateTerrain(); - void generateBaseTerrain(s16 *stone_surface_min_y, s16 *stone_surface_max_y); - int generateMountainTerrain(s16 ymax); + int generateTerrain(); void generateRidgeTerrain(); MgStoneType generateBiomes(float *heat_map, float *humidity_map); void dustTopNodes(); - //void addTopNodes(); - void generateCaves(s16 max_stone_y); }; From 65db88d24e65972b34da824743ba7dc6d307def0 Mon Sep 17 00:00:00 2001 From: kilbith Date: Mon, 18 Apr 2016 18:20:04 +0200 Subject: [PATCH 4/9] Mainmenu: Unify favorite servers with main serverlist --- builtin/mainmenu/common.lua | 26 ++-- builtin/mainmenu/tab_multiplayer.lua | 154 +++++++++---------- textures/base/pack/server_flags_favorite.png | Bin 0 -> 916 bytes 3 files changed, 85 insertions(+), 95 deletions(-) create mode 100644 textures/base/pack/server_flags_favorite.png diff --git a/builtin/mainmenu/common.lua b/builtin/mainmenu/common.lua index 62ab2b578..203b1382b 100644 --- a/builtin/mainmenu/common.lua +++ b/builtin/mainmenu/common.lua @@ -85,7 +85,7 @@ function order_favorite_list(list) end -------------------------------------------------------------------------------- -function render_favorite(spec,render_details) +function render_favorite(spec, is_favorite) local text = "" if spec.name ~= nil then @@ -105,13 +105,15 @@ function render_favorite(spec,render_details) end end - if not render_details then - return text - end - local details = "" local grey_out = not is_server_protocol_compat(spec.proto_min, spec.proto_max) + if is_favorite then + details = "1," + else + details = "0," + end + if spec.clients ~= nil and spec.clients_max ~= nil then local clients_color = '' local clients_percent = 100 * spec.clients / spec.clients_max @@ -253,15 +255,13 @@ function asyncOnlineFavourites() end, nil, function(result) - if core.setting_getbool("public_serverlist") then - local favs = order_favorite_list(result) - if favs[1] then - menudata.public_known = favs - menudata.favorites = menudata.public_known - menudata.favorites_is_public = true - end - core.event_handler("Refresh") + local favs = order_favorite_list(result) + if favs[1] then + menudata.public_known = favs + menudata.favorites = menudata.public_known + menudata.favorites_is_public = true end + core.event_handler("Refresh") end ) end diff --git a/builtin/mainmenu/tab_multiplayer.lua b/builtin/mainmenu/tab_multiplayer.lua index f3ba122fc..b5323fa99 100644 --- a/builtin/mainmenu/tab_multiplayer.lua +++ b/builtin/mainmenu/tab_multiplayer.lua @@ -20,65 +20,64 @@ local function get_formspec(tabview, name, tabdata) -- Update the cached supported proto info, -- it may have changed after a change by the settings menu. common_update_cached_supp_proto() + local fav_selected = menudata.favorites[tabdata.fav_selected] - local render_details = core.is_yes(core.setting_getbool("public_serverlist")) - local retval = - "label[7.75,-0.15;" .. fgettext("Address / Port :") .. "]" .. - "label[7.75,1.05;" .. fgettext("Name / Password :") .. "]" .. - "field[8,0.75;3.4,0.5;te_address;;" .. - core.formspec_escape(core.setting_get("address")) .. "]" .. - "field[11.25,0.75;1.3,0.5;te_port;;" .. - core.formspec_escape(core.setting_get("remote_port")) .. "]" .. - "checkbox[0,4.85;cb_public_serverlist;" .. fgettext("Public Serverlist") .. ";" .. - dump(core.setting_getbool("public_serverlist")) .. "]" - - if not core.setting_getbool("public_serverlist") then - retval = retval .. - "button[8,4.9;2,0.5;btn_delete_favorite;" .. fgettext("Delete") .. "]" - end - - retval = retval .. - "button[10,4.9;2,0.5;btn_mp_connect;" .. fgettext("Connect") .. "]" .. + "label[7.75,-0.15;" .. fgettext("Address / Port") .. "]" .. + "label[7.75,1.05;" .. fgettext("Name / Password") .. "]" .. + "field[8,0.75;3.3,0.5;te_address;;" .. + core.formspec_escape(core.setting_get("address")) .. "]" .. + "field[11.15,0.75;1.4,0.5;te_port;;" .. + core.formspec_escape(core.setting_get("remote_port")) .. "]" .. + "button[10.1,4.9;2,0.5;btn_mp_connect;" .. fgettext("Connect") .. "]" .. "field[8,1.95;2.95,0.5;te_name;;" .. - core.formspec_escape(core.setting_get("name")) .. "]" .. + core.formspec_escape(core.setting_get("name")) .. "]" .. "pwdfield[10.78,1.95;1.77,0.5;te_pwd;]" .. - "box[7.73,2.35;4.3,2.28;#999999]" .. - "textarea[8.1,2.4;4.26,2.6;;" - - if tabdata.fav_selected ~= nil and - menudata.favorites[tabdata.fav_selected] ~= nil and - menudata.favorites[tabdata.fav_selected].description ~= nil then - retval = retval .. - core.formspec_escape(menudata.favorites[tabdata.fav_selected].description,true) - end + "box[7.73,2.35;4.3,2.28;#999999]" - retval = retval .. - ";]" + if tabdata.fav_selected and fav_selected then + if gamedata.fav then + retval = retval .. "button[7.85,4.9;2.3,0.5;btn_delete_favorite;" .. + fgettext("Del. Favorite") .. "]" + end + if fav_selected.description then + retval = retval .. "textarea[8.1,2.4;4.26,2.6;;" .. + core.formspec_escape((gamedata.serverdescription or ""), true) .. ";]" + end + end --favourites - if render_details then - retval = retval .. "tablecolumns[" .. - "color,span=3;" .. - "text,align=right;" .. -- clients - "text,align=center,padding=0.25;" .. -- "/" - "text,align=right,padding=0.25;" .. -- clients_max - image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" .. - image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" .. - image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" .. - "color,span=1;" .. - "text,padding=1]" -- name - else - retval = retval .. "tablecolumns[text]" - end - retval = retval .. - "table[-0.15,-0.1;7.75,5;favourites;" + retval = retval .. "tablecolumns[" .. + image_column(fgettext("Favorite"), "favorite") .. ";" .. + "color,span=3;" .. + "text,align=right;" .. -- clients + "text,align=center,padding=0.25;" .. -- "/" + "text,align=right,padding=0.25;" .. -- clients_max + image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" .. + image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" .. + image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" .. + "color,span=1;" .. + "text,padding=1]" .. + "table[-0.15,-0.1;7.75,5.5;favourites;" if #menudata.favorites > 0 then - retval = retval .. render_favorite(menudata.favorites[1],render_details) - - for i=2,#menudata.favorites,1 do - retval = retval .. "," .. render_favorite(menudata.favorites[i],render_details) + local favs = core.get_favorites("local") + if #favs > 0 then + for i = 1, #favs do + for j = 1, #menudata.favorites do + if menudata.favorites[j].address == favs[i].address and + menudata.favorites[j].port == favs[i].port then + table.insert(menudata.favorites, i, table.remove(menudata.favorites, j)) + end + end + if favs[i].address ~= menudata.favorites[i].address then + table.insert(menudata.favorites, i, favs[i]) + end + end + end + retval = retval .. render_favorite(menudata.favorites[1], (#favs > 0)) + for i = 2, #menudata.favorites do + retval = retval .. "," .. render_favorite(menudata.favorites[i], (i <= #favs)) end end @@ -100,9 +99,10 @@ local function main_button_handler(tabview, fields, name, tabdata) if fields["favourites"] ~= nil then local event = core.explode_table_event(fields["favourites"]) + local fav = menudata.favorites[event.row] + if event.type == "DCL" then if event.row <= #menudata.favorites then - local fav = menudata.favorites[event.row] if menudata.favorites_is_public and not is_server_protocol_compat_or_error( fav.proto_min, fav.proto_max) then @@ -131,8 +131,18 @@ local function main_button_handler(tabview, fields, name, tabdata) if event.type == "CHG" then if event.row <= #menudata.favorites then - local address = menudata.favorites[event.row].address - local port = menudata.favorites[event.row].port + gamedata.fav = false + local favs = core.get_favorites("local") + local address = fav.address + local port = fav.port + gamedata.serverdescription = fav.description + + for i = 1, #favs do + if fav.address == favs[i].address and + fav.port == favs[i].port then + gamedata.fav = true + end + end if address ~= nil and port ~= nil then @@ -181,29 +191,16 @@ local function main_button_handler(tabview, fields, name, tabdata) return true end - if fields["cb_public_serverlist"] ~= nil then - core.setting_set("public_serverlist", fields["cb_public_serverlist"]) - - if core.setting_getbool("public_serverlist") then - asyncOnlineFavourites() - else - menudata.favorites = core.get_favorites("local") - menudata.favorites_is_public = false - end - tabdata.fav_selected = nil - return true - end - - if fields["btn_delete_favorite"] ~= nil then + if fields.btn_delete_favorite then local current_favourite = core.get_table_index("favourites") - if current_favourite == nil then return end + if not current_favourite then return end + core.delete_favorite(current_favourite) - menudata.favorites = core.get_favorites("local") + asyncOnlineFavourites() tabdata.fav_selected = nil - core.setting_set("address","") - core.setting_set("remote_port","30000") - + core.setting_set("address", "") + core.setting_set("remote_port", "30000") return true end @@ -247,16 +244,9 @@ local function main_button_handler(tabview, fields, name, tabdata) return false end -local function on_change(type,old_tab,new_tab) - if type == "LEAVE" then - return - end - if core.setting_getbool("public_serverlist") then - asyncOnlineFavourites() - else - menudata.favorites = core.get_favorites("local") - menudata.favorites_is_public = false - end +local function on_change(type, old_tab, new_tab) + if type == "LEAVE" then return end + asyncOnlineFavourites() end -------------------------------------------------------------------------------- diff --git a/textures/base/pack/server_flags_favorite.png b/textures/base/pack/server_flags_favorite.png new file mode 100644 index 0000000000000000000000000000000000000000..6a3fc5efe7ce3a9ffa0f2e0a800afdace65285c4 GIT binary patch literal 916 zcmV;F18e+=P)Ky5;j10^mHOxQ-`a%p0KmH*s0SF)_1|+})G695v z1~9NPXE6ANGPrrGS(%G4*n;HEL>L&{r5G5#{Xysf2p|*#z?wm>_`#seq^=ymAb5{~ z(MFjyN|!l>4JenV0W|wRiVg;V0Ac}?e}P(mG6*sJW)Nol$sqWji6NQAQk|cH;UNQq zm?DFdlZwxxuQ#Ji`5CT#`o!@5?;nQO3>*yKK=uIy5DUY9U;s%8>of4kaxgOg;$z`v z=V26;WM@+S1(XJc6vHD1wG?B11#O|FA6~xu!u*!;^WXPhKC#_-`uE?z|MdU?#Pan! z!&at$?17yA#_UY&Pk|b~0`Y60-j6`Pfb0N9jmTvNHh&%lF$OUn1_mCUe=BcGPTRw9 za?fjq`v3vN__m&b;mKnLTUiyB1p+}LN(`dFVEGC3C?j(4{DTm$iQ&(2~h3>gSMOm<6L<^ZgVCXR&d&Y15hNsV`X@@;p4ZCRX-O@ zd&E!=H1Z8d3Lt=({sCRc2}%Pj3|H?z_+Rzw^4C8MpMEefeEbf`2B2QX3n zK#EF$0Ad0q-G4wM|NRB4v19>x{TWc;>OY3hyZx$w literal 0 HcmV?d00001 From 8cf26bb0bbc94de437342c84c7b0854feb8957e8 Mon Sep 17 00:00:00 2001 From: kilbith Date: Mon, 18 Apr 2016 22:43:12 +0200 Subject: [PATCH 5/9] Mainmenu: Code cleaning --- builtin/mainmenu/common.lua | 150 +++++++++------------------ builtin/mainmenu/tab_multiplayer.lua | 102 ++++++++---------- 2 files changed, 95 insertions(+), 157 deletions(-) diff --git a/builtin/mainmenu/common.lua b/builtin/mainmenu/common.lua index 203b1382b..5bf39abd7 100644 --- a/builtin/mainmenu/common.lua +++ b/builtin/mainmenu/common.lua @@ -22,8 +22,7 @@ menudata = {} -------------------------------------------------------------------------------- -- Local cached values -------------------------------------------------------------------------------- -local min_supp_proto -local max_supp_proto +local min_supp_proto, max_supp_proto function common_update_cached_supp_proto() min_supp_proto = core.get_min_supp_proto() @@ -36,31 +35,24 @@ common_update_cached_supp_proto() -------------------------------------------------------------------------------- local function render_client_count(n) - if n > 99 then - return '99+' - elseif n >= 0 then - return tostring(n) - else - return '?' - end + if n > 99 then return '99+' + elseif n >= 0 then return tostring(n) + else return '?' end end local function configure_selected_world_params(idx) - local worldconfig = modmgr.get_worldconfig( - menudata.worldlist:get_list()[idx].path) - - if worldconfig.creative_mode ~= nil then + local worldconfig = modmgr.get_worldconfig(menudata.worldlist:get_list()[idx].path) + if worldconfig.creative_mode then core.setting_set("creative_mode", worldconfig.creative_mode) end - if worldconfig.enable_damage ~= nil then + if worldconfig.enable_damage then core.setting_set("enable_damage", worldconfig.enable_damage) end end -------------------------------------------------------------------------------- function image_column(tooltip, flagname) - return "image," .. - "tooltip=" .. core.formspec_escape(tooltip) .. "," .. + return "image,tooltip=" .. core.formspec_escape(tooltip) .. "," .. "0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," .. "1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_" .. flagname .. ".png") end @@ -69,13 +61,13 @@ end function order_favorite_list(list) local res = {} --orders the favorite list after support - for i=1,#list,1 do + for i = 1, #list do local fav = list[i] if is_server_protocol_compat(fav.proto_min, fav.proto_max) then res[#res + 1] = fav end end - for i=1,#list,1 do + for i = 1, #list do local fav = list[i] if not is_server_protocol_compat(fav.proto_min, fav.proto_max) then res[#res + 1] = fav @@ -87,21 +79,12 @@ end -------------------------------------------------------------------------------- function render_favorite(spec, is_favorite) local text = "" - - if spec.name ~= nil then + if spec.name then text = text .. core.formspec_escape(spec.name:trim()) - --- if spec.description ~= nil and --- core.formspec_escape(spec.description):trim() ~= "" then --- text = text .. " (" .. core.formspec_escape(spec.description) .. ")" --- end - else - if spec.address ~= nil then - text = text .. spec.address:trim() - - if spec.port ~= nil then - text = text .. ":" .. spec.port - end + elseif spec.address then + text = text .. spec.address:trim() + if spec.port then + text = text .. ":" .. spec.port end end @@ -114,33 +97,24 @@ function render_favorite(spec, is_favorite) details = "0," end - if spec.clients ~= nil and spec.clients_max ~= nil then + if spec.clients and spec.clients_max then local clients_color = '' local clients_percent = 100 * spec.clients / spec.clients_max -- Choose a color depending on how many clients are connected -- (relatively to clients_max) - if spec.clients == 0 then - clients_color = '' -- 0 players: default/white - elseif spec.clients == spec.clients_max then - clients_color = '#dd5b5b' -- full server: red (darker) - elseif clients_percent <= 60 then - clients_color = '#a1e587' -- 0-60%: green - elseif clients_percent <= 90 then - clients_color = '#ffdc97' -- 60-90%: yellow - else - clients_color = '#ffba97' -- 90-100%: orange + if grey_out then clients_color = '#aaaaaa' + elseif spec.clients == 0 then clients_color = '' -- 0 players: default/white + elseif clients_percent <= 60 then clients_color = '#a1e587' -- 0-60%: green + elseif clients_percent <= 90 then clients_color = '#ffdc97' -- 60-90%: yellow + elseif clients_percent == 100 then clients_color = '#dd5b5b' -- full server: red (darker) + else clients_color = '#ffba97' -- 90-100%: orange end - if grey_out then - clients_color = '#aaaaaa' - end + details = details .. clients_color .. ',' .. + render_client_count(spec.clients) .. ',/,' .. + render_client_count(spec.clients_max) .. ',' - details = details .. - clients_color .. ',' .. - render_client_count(spec.clients) .. ',' .. - '/,' .. - render_client_count(spec.clients_max) .. ',' elseif grey_out then details = details .. '#aaaaaa,?,/,?,' else @@ -191,56 +165,36 @@ end -------------------------------------------------------------------------------- function menu_render_worldlist() local retval = "" - local current_worldlist = menudata.worldlist:get_list() - for i,v in ipairs(current_worldlist) do - if retval ~= "" then - retval = retval .."," - end - + for i, v in ipairs(current_worldlist) do + if retval ~= "" then retval = retval .. "," end retval = retval .. core.formspec_escape(v.name) .. - " \\[" .. core.formspec_escape(v.gameid) .. "\\]" + " \\[" .. core.formspec_escape(v.gameid) .. "\\]" end return retval end -------------------------------------------------------------------------------- -function menu_handle_key_up_down(fields,textlist,settingname) - if fields["key_up"] then - local oldidx = core.get_textlist_index(textlist) - - if oldidx ~= nil and oldidx > 1 then - local newidx = oldidx -1 - core.setting_set(settingname, - menudata.worldlist:get_raw_index(newidx)) - - configure_selected_world_params(newidx) +function menu_handle_key_up_down(fields, textlist, settingname) + local oldidx, newidx = core.get_textlist_index(textlist) + if fields.key_up or fields.key_down then + if fields.key_up and oldidx and oldidx > 1 then + newidx = oldidx - 1 + elseif fields.key_down and oldidx and + oldidx < menudata.worldlist:size() then + newidx = oldidx + 1 end + core.setting_set(settingname, menudata.worldlist:get_raw_index(newidx)) + configure_selected_world_params(newidx) return true end - - if fields["key_down"] then - local oldidx = core.get_textlist_index(textlist) - - if oldidx ~= nil and oldidx < menudata.worldlist:size() then - local newidx = oldidx + 1 - core.setting_set(settingname, - menudata.worldlist:get_raw_index(newidx)) - - configure_selected_world_params(newidx) - end - - return true - end - return false end -------------------------------------------------------------------------------- function asyncOnlineFavourites() - if not menudata.public_known then menudata.public_known = {{ name = fgettext("Loading..."), @@ -267,24 +221,18 @@ function asyncOnlineFavourites() end -------------------------------------------------------------------------------- -function text2textlist(xpos,ypos,width,height,tl_name,textlen,text,transparency) - local textlines = core.splittext(text,textlen) +function text2textlist(xpos, ypos, width, height, tl_name, textlen, text, transparency) + local textlines = core.splittext(text, textlen) + local retval = "textlist[" .. xpos .. "," .. ypos .. ";" .. width .. + "," .. height .. ";" .. tl_name .. ";" - local retval = "textlist[" .. xpos .. "," .. ypos .. ";" - .. width .. "," .. height .. ";" - .. tl_name .. ";" - - for i=1, #textlines, 1 do - textlines[i] = textlines[i]:gsub("\r","") + for i = 1, #textlines do + textlines[i] = textlines[i]:gsub("\r", "") retval = retval .. core.formspec_escape(textlines[i]) .. "," end retval = retval .. ";0;" - - if transparency then - retval = retval .. "true" - end - + if transparency then retval = retval .. "true" end retval = retval .. "]" return retval @@ -297,10 +245,10 @@ end -------------------------------------------------------------------------------- function is_server_protocol_compat_or_error(server_proto_min, server_proto_max) if not is_server_protocol_compat(server_proto_min, server_proto_max) then - local server_prot_ver_info - local client_prot_ver_info + local server_prot_ver_info, client_prot_ver_info local s_p_min = server_proto_min or 13 local s_p_max = server_proto_max or 24 + if s_p_min ~= s_p_max then server_prot_ver_info = fgettext_ne("Server supports protocol versions between $1 and $2. ", s_p_min, s_p_max) @@ -329,7 +277,7 @@ function menu_worldmt(selected, setting, value) local filename = world.path .. DIR_DELIM .. "world.mt" local world_conf = Settings(filename) - if value ~= nil then + if value then if not world_conf:write() then core.log("error", "Failed to write world config file") end @@ -347,7 +295,7 @@ function menu_worldmt_legacy(selected) local modes_names = {"creative_mode", "enable_damage", "server_announce"} for _, mode_name in pairs(modes_names) do local mode_val = menu_worldmt(selected, mode_name) - if mode_val ~= nil then + if mode_val then core.setting_set(mode_name, mode_val) else menu_worldmt(selected, mode_name, core.setting_get(mode_name)) diff --git a/builtin/mainmenu/tab_multiplayer.lua b/builtin/mainmenu/tab_multiplayer.lua index b5323fa99..00150f26d 100644 --- a/builtin/mainmenu/tab_multiplayer.lua +++ b/builtin/mainmenu/tab_multiplayer.lua @@ -81,7 +81,7 @@ local function get_formspec(tabview, name, tabdata) end end - if tabdata.fav_selected ~= nil then + if tabdata.fav_selected then retval = retval .. ";" .. tabdata.fav_selected .. "]" else retval = retval .. ";0]" @@ -92,13 +92,13 @@ end -------------------------------------------------------------------------------- local function main_button_handler(tabview, fields, name, tabdata) - if fields["te_name"] ~= nil then - gamedata.playername = fields["te_name"] - core.setting_set("name", fields["te_name"]) + if fields.te_name then + gamedata.playername = fields.te_name + core.setting_set("name", fields.te_name) end - if fields["favourites"] ~= nil then - local event = core.explode_table_event(fields["favourites"]) + if fields.favourites then + local event = core.explode_table_event(fields.favourites) local fav = menudata.favorites[event.row] if event.type == "DCL" then @@ -108,21 +108,22 @@ local function main_button_handler(tabview, fields, name, tabdata) fav.proto_min, fav.proto_max) then return true end + gamedata.address = fav.address gamedata.port = fav.port - gamedata.playername = fields["te_name"] - if fields["te_pwd"] ~= nil then - gamedata.password = fields["te_pwd"] - end + gamedata.playername = fields.te_name gamedata.selected_world = 0 + if fields.te_pwd then + gamedata.password = fields.te_pwd + end + gamedata.servername = fav.name gamedata.serverdescription = fav.description - if gamedata.address ~= nil and - gamedata.port ~= nil then - core.setting_set("address",gamedata.address) - core.setting_set("remote_port",gamedata.port) + if gamedata.address and gamedata.port then + core.setting_set("address", gamedata.address) + core.setting_set("remote_port", gamedata.port) core.start() end end @@ -144,47 +145,41 @@ local function main_button_handler(tabview, fields, name, tabdata) end end - if address ~= nil and - port ~= nil then - core.setting_set("address",address) - core.setting_set("remote_port",port) + if address and port then + core.setting_set("address", address) + core.setting_set("remote_port", port) end - tabdata.fav_selected = event.row end - return true end end - if fields["key_up"] ~= nil or - fields["key_down"] ~= nil then - + if fields.key_up or fields.key_down then local fav_idx = core.get_table_index("favourites") + local fav = menudata.favorites[fav_idx] - if fav_idx ~= nil then - if fields["key_up"] ~= nil and fav_idx > 1 then - fav_idx = fav_idx -1 - else if fields["key_down"] and fav_idx < #menudata.favorites then - fav_idx = fav_idx +1 - end end + if fav_idx then + if fields.key_up and fav_idx > 1 then + fav_idx = fav_idx - 1 + elseif fields.key_down and fav_idx < #menudata.favorites then + fav_idx = fav_idx + 1 + end else fav_idx = 1 end - - if menudata.favorites == nil or - menudata.favorites[fav_idx] == nil then + + if not menudata.favorites or not fav then tabdata.fav_selected = 0 return true end - - local address = menudata.favorites[fav_idx].address - local port = menudata.favorites[fav_idx].port - if address ~= nil and - port ~= nil then - core.setting_set("address",address) - core.setting_set("remote_port",port) + local address = fav.address + local port = fav.port + + if address and port then + core.setting_set("address", address) + core.setting_set("remote_port", port) end tabdata.fav_selected = fav_idx @@ -204,22 +199,19 @@ local function main_button_handler(tabview, fields, name, tabdata) return true end - if (fields["btn_mp_connect"] ~= nil or - fields["key_enter"] ~= nil) and fields["te_address"] ~= nil and - fields["te_port"] ~= nil then - - gamedata.playername = fields["te_name"] - gamedata.password = fields["te_pwd"] - gamedata.address = fields["te_address"] - gamedata.port = fields["te_port"] - + if (fields.btn_mp_connect or fields.key_enter) and fields.te_address and fields.te_port then + gamedata.playername = fields.te_name + gamedata.password = fields.te_pwd + gamedata.address = fields.te_address + gamedata.port = fields.te_port + gamedata.selected_world = 0 local fav_idx = core.get_table_index("favourites") + local fav = menudata.favorites[fav_idx] - if fav_idx ~= nil and fav_idx <= #menudata.favorites and - menudata.favorites[fav_idx].address == fields["te_address"] and - menudata.favorites[fav_idx].port == fields["te_port"] then + if fav_idx and fav_idx <= #menudata.favorites and + fav.address == fields.te_address and + fav.port == fields.te_port then - local fav = menudata.favorites[fav_idx] gamedata.servername = fav.name gamedata.serverdescription = fav.description @@ -233,10 +225,8 @@ local function main_button_handler(tabview, fields, name, tabdata) gamedata.serverdescription = "" end - gamedata.selected_world = 0 - - core.setting_set("address", fields["te_address"]) - core.setting_set("remote_port",fields["te_port"]) + core.setting_set("address", fields.te_address) + core.setting_set("remote_port", fields.te_port) core.start() return true From a60aa8e226584b97d0be0d26688b302dfddf7125 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Tue, 19 Apr 2016 15:47:14 -0700 Subject: [PATCH 6/9] Fix timer initialization. This fixes the problem that the first timer tick is an overrun and causes all timers to expire immediately. replaces #4003 --- builtin/game/misc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/game/misc.lua b/builtin/game/misc.lua index 4f58710d0..de41cfc91 100644 --- a/builtin/game/misc.lua +++ b/builtin/game/misc.lua @@ -6,7 +6,7 @@ local jobs = {} local time = 0.0 -local last = 0.0 +local last = core.get_us_time() / 1000000 core.register_globalstep(function(dtime) local new = core.get_us_time() / 1000000 From 9b437088dfff0303c99f70848f8f404b16ed1e55 Mon Sep 17 00:00:00 2001 From: paramat Date: Wed, 20 Apr 2016 07:24:14 +0100 Subject: [PATCH 7/9] Textures: Replace menu background fallback dirt_bg.png with empty sky texture --- builtin/mainmenu/textures.lua | 4 ++-- textures/base/pack/dirt_bg.png | Bin 82 -> 0 bytes textures/base/pack/menu_bg.png | Bin 0 -> 124 bytes 3 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 textures/base/pack/dirt_bg.png create mode 100644 textures/base/pack/menu_bg.png diff --git a/builtin/mainmenu/textures.lua b/builtin/mainmenu/textures.lua index 075f38ee0..dadbb093e 100644 --- a/builtin/mainmenu/textures.lua +++ b/builtin/mainmenu/textures.lua @@ -179,7 +179,7 @@ function mm_texture.set_dirt_bg() end end - --use base pack - local minimalpath = defaulttexturedir .. "dirt_bg.png" + -- Use universal fallback texture in textures/base/pack + local minimalpath = defaulttexturedir .. "menu_bg.png" core.set_background("background", minimalpath, true, 128) end diff --git a/textures/base/pack/dirt_bg.png b/textures/base/pack/dirt_bg.png deleted file mode 100644 index 29df43912305a909c9cb66e80d7c39a27cb2b5ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!D3?x-;bCrM;Lx4|+tM`h|P#}}n)5S5QA}%>0 bMTL`*f!TmT(LDN%6iAV$tDnm{r-UW|6~+%S diff --git a/textures/base/pack/menu_bg.png b/textures/base/pack/menu_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..ed7e34f61625c8bca81bfee04d6996686ddbb787 GIT binary patch literal 124 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!D3?x-;bCrM;bAV5XYtOD Date: Thu, 21 Apr 2016 08:58:29 +0100 Subject: [PATCH 8/9] Biomes: Make dust fallback 'ignore' to fix y = 63 lighting The shadow bug at y = 63 was caused by dark air being placed as dust, when the biome dust was unspecified it was falling back to 'air' In dustTopNodes only dust == 'ignore' will disable dust placement --- src/mg_biome.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mg_biome.cpp b/src/mg_biome.cpp index 055ce0198..9ab8d06cc 100644 --- a/src/mg_biome.cpp +++ b/src/mg_biome.cpp @@ -56,7 +56,7 @@ BiomeManager::BiomeManager(IGameDef *gamedef) : b->m_nodenames.push_back("mapgen_water_source"); b->m_nodenames.push_back("mapgen_water_source"); b->m_nodenames.push_back("mapgen_river_water_source"); - b->m_nodenames.push_back("air"); + b->m_nodenames.push_back("ignore"); m_ndef->pendNodeResolve(b); add(b); @@ -138,5 +138,5 @@ void Biome::resolveNodeNames() getIdFromNrBacklog(&c_water_top, "mapgen_water_source", CONTENT_AIR); getIdFromNrBacklog(&c_water, "mapgen_water_source", CONTENT_AIR); getIdFromNrBacklog(&c_river_water, "mapgen_river_water_source", CONTENT_AIR); - getIdFromNrBacklog(&c_dust, "air", CONTENT_IGNORE); + getIdFromNrBacklog(&c_dust, "ignore", CONTENT_IGNORE); } From c350cfb50b3bf81c075a80307adb15393ea773d0 Mon Sep 17 00:00:00 2001 From: Ekdohibs Date: Thu, 21 Apr 2016 10:45:42 +0200 Subject: [PATCH 9/9] Make logging use a fixed-length buffer to avoid race conditions. Previously, race conditions occurred inside logging, that caused segfaults because a thread was trying to use an old pointer that was freed when the string was reallocated. Using a fixed-length buffer avoids this, at the cost of cutting too long messages over seveal lines. --- src/log.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/log.cpp b/src/log.cpp index 600e715c1..589cfd909 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -34,9 +34,13 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include +const int BUFFER_LENGTH = 256; + class StringBuffer : public std::streambuf { public: - StringBuffer() {} + StringBuffer() { + buffer_index = 0; + } int overflow(int c); virtual void flush(const std::string &buf) = 0; @@ -44,7 +48,8 @@ public: void push_back(char c); private: - std::string buffer; + char buffer[BUFFER_LENGTH]; + int buffer_index; }; @@ -338,11 +343,18 @@ std::streamsize StringBuffer::xsputn(const char *s, std::streamsize n) void StringBuffer::push_back(char c) { if (c == '\n' || c == '\r') { - if (!buffer.empty()) - flush(buffer); - buffer.clear(); + if (buffer_index) + flush(std::string(buffer, buffer_index)); + buffer_index = 0; } else { - buffer.push_back(c); + int index = buffer_index; + buffer[index++] = c; + if (index >= BUFFER_LENGTH) { + flush(std::string(buffer, buffer_index)); + buffer_index = 0; + } else { + buffer_index = index; + } } }