More protection from un-initialized player crashes

This commit is contained in:
stujones11 2017-04-13 19:47:43 +01:00
parent b4283f6e60
commit de2c47f334
4 changed files with 51 additions and 35 deletions

View File

@ -14,8 +14,29 @@ armor = {
default.get_hotbar_bg(0, 4.7).. default.get_hotbar_bg(0, 4.7)..
"list[current_player;main;0,4.7;8,1;]".. "list[current_player;main;0,4.7;8,1;]"..
"list[current_player;main;0,5.85;8,3;8]", "list[current_player;main;0,5.85;8,3;8]",
def = {}, def = setmetatable({}, {
textures = {}, __index = function()
return setmetatable({
groups = setmetatable({}, {
__index = function()
return 0
end})
}, {
__index = function()
return 0
end
})
end,
}),
textures = setmetatable({}, {
__index = function()
return setmetatable({}, {
__index = function()
return "blank.png"
end
})
end
}),
default_skin = "character", default_skin = "character",
materials = { materials = {
wood = "group:wood", wood = "group:wood",
@ -199,6 +220,7 @@ armor.init_player_armor = function(self, player)
self:run_callbacks("on_equip", player, stack) self:run_callbacks("on_equip", player, stack)
end end
self.def[name] = { self.def[name] = {
init_time = minetest.get_gametime(),
level = 0, level = 0,
state = 0, state = 0,
count = 0, count = 0,
@ -464,15 +486,15 @@ armor.get_preview = function(self, name)
end end
armor.get_armor_formspec = function(self, name, listring) armor.get_armor_formspec = function(self, name, listring)
if armor.def[name].init_time == 0 then
return "label[0,0;Armor not initialized!]"
end
local formspec = armor.formspec.. local formspec = armor.formspec..
"list[detached:"..name.."_armor;armor;0,0.5;2,3;]" "list[detached:"..name.."_armor;armor;0,0.5;2,3;]"
if listring == true then if listring == true then
formspec = formspec.."listring[current_player;main]".. formspec = formspec.."listring[current_player;main]"..
"listring[detached:"..name.."_armor;armor]" "listring[detached:"..name.."_armor;armor]"
end end
if not armor.def[name] or not armor.textures[name] then
return formspec
end
formspec = formspec:gsub("armor_preview", armor.textures[name].preview) formspec = formspec:gsub("armor_preview", armor.textures[name].preview)
formspec = formspec:gsub("armor_level", armor.def[name].level) formspec = formspec:gsub("armor_level", armor.def[name].level)
for _, attr in pairs(self.attributes) do for _, attr in pairs(self.attributes) do

View File

@ -139,7 +139,7 @@ end)
minetest.register_on_joinplayer(function(player) minetest.register_on_joinplayer(function(player)
default.player_set_model(player, "3d_armor_character.b3d") default.player_set_model(player, "3d_armor_character.b3d")
if armor:init_player_armor(player) == false then if armor:init_player_armor(player) == false then
table.insert(pending_players, {player, 0}) pending_players[player] = 0
end end
end) end)
@ -149,11 +149,7 @@ minetest.register_on_leaveplayer(function(player)
armor.def[name] = nil armor.def[name] = nil
armor.textures[name] = nil armor.textures[name] = nil
end end
for i, con in pairs(pending_players) do pending_players[player] = nil
if player == con[1] then
table.remove(pending_players, i)
end
end
end) end)
if armor.config.drop == true or armor.config.destroy == true then if armor.config.drop == true or armor.config.destroy == true then
@ -209,7 +205,7 @@ if armor.config.punch_damage == true then
minetest.register_on_punchplayer(function(player, hitter, minetest.register_on_punchplayer(function(player, hitter,
time_from_last_punch, tool_capabilities) time_from_last_punch, tool_capabilities)
local name = player:get_player_name() local name = player:get_player_name()
if name and armor.def[name] then if name then
armor:punch(player, hitter, time_from_last_punch, tool_capabilities) armor:punch(player, hitter, time_from_last_punch, tool_capabilities)
last_punch_time[name] = minetest.get_gametime() last_punch_time[name] = minetest.get_gametime()
end end
@ -219,8 +215,8 @@ end
minetest.register_on_player_hpchange(function(player, hp_change) minetest.register_on_player_hpchange(function(player, hp_change)
if player and hp_change < 0 then if player and hp_change < 0 then
local name = player:get_player_name() local name = player:get_player_name()
if name and armor.def[name] then if name then
local heal = armor.def[name].heal or 0 local heal = armor.def[name].heal
heal = heal * armor.config.heal_multiplier heal = heal * armor.config.heal_multiplier
if heal >= math.random(100) then if heal >= math.random(100) then
hp_change = 0 hp_change = 0
@ -238,15 +234,15 @@ end, true)
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
timer = timer + dtime timer = timer + dtime
if timer > armor.config.init_delay then if timer > armor.config.init_delay then
for i, con in pairs(pending_players) do for player, count in pairs(pending_players) do
local remove = armor:init_player_armor(con[1]) == true local remove = armor:init_player_armor(player) == true
con[2] = con[2] + 1 pending_players[player] = count + 1
if remove == false and con[2] > armor.config.init_times then if remove == false and count > armor.config.init_times then
minetest.log("warning", "3d_armor: Failed to initialize player") minetest.log("warning", "3d_armor: Failed to initialize player")
remove = true remove = true
end end
if remove == true then if remove == true then
table.remove(pending_players, i) pending_players[player] = nil
end end
end end
timer = 0 timer = 0
@ -281,7 +277,7 @@ if armor.config.water_protect == true or armor.config.fire_protect == true then
end end
-- water breathing -- water breathing
if armor.config.water_protect == true then if armor.config.water_protect == true then
if armor.def[name] and armor.def[name].water > 0 and if armor.def[name].water > 0 and
player:get_breath() < 10 then player:get_breath() < 10 then
player:set_breath(10) player:set_breath(10)
end end

View File

@ -27,10 +27,11 @@ unified_inventory.register_page("armor", {
get_formspec = function(player, perplayer_formspec) get_formspec = function(player, perplayer_formspec)
local fy = perplayer_formspec.formspec_y local fy = perplayer_formspec.formspec_y
local name = player:get_player_name() local name = player:get_player_name()
if armor.def[name].init_time == 0 then
return {formspec="label[0,0;Armor not initialized!]"}
end
local formspec = "background[0.06,"..fy..";7.92,7.52;3d_armor_ui_form.png]".. local formspec = "background[0.06,"..fy..";7.92,7.52;3d_armor_ui_form.png]"..
"label[0,0;Armor]" "label[0,0;Armor]"..
if armor.def[name] then
formspec = formspec..
"list[detached:"..name.."_armor;armor;0,"..fy..";2,3;]".. "list[detached:"..name.."_armor;armor;0,"..fy..";2,3;]"..
"image[2.5,"..(fy - 0.25)..";2,4;"..armor.textures[name].preview.."]".. "image[2.5,"..(fy - 0.25)..";2,4;"..armor.textures[name].preview.."]"..
"label[5.0,"..(fy + 0.0)..";"..S("Level")..": "..armor.def[name].level.."]".. "label[5.0,"..(fy + 0.0)..";"..S("Level")..": "..armor.def[name].level.."]"..
@ -45,7 +46,6 @@ unified_inventory.register_page("armor", {
formspec = formspec.."label[5.0,"..(fy + 1.5)..";".. formspec = formspec.."label[5.0,"..(fy + 1.5)..";"..
S("Radiation")..": "..armor.def[name].groups["radiation"].."]" S("Radiation")..": "..armor.def[name].groups["radiation"].."]"
end end
end
return {formspec=formspec} return {formspec=formspec}
end, end,
}) })

View File

@ -57,11 +57,9 @@ wieldview.update_wielded_item = function(self, player)
if self.wielded_item[name] == item then if self.wielded_item[name] == item then
return return
end end
if armor.textures[name] then
armor.textures[name].wielditem = self:get_item_texture(item) armor.textures[name].wielditem = self:get_item_texture(item)
armor:update_player_visuals(player) armor:update_player_visuals(player)
end end
end
self.wielded_item[name] = item self.wielded_item[name] = item
end end