Skip to content

Commit 672e0e3

Browse files
authored
Address exploit of container dump module (#1550)
* Address exploit of container dump module * Update market chest exchange values * Replace kill mechanic with stun mechanic * Separate vehicle penalty logic in configs * Change default config
1 parent fb573c0 commit 672e0e3

File tree

3 files changed

+145
-69
lines changed

3 files changed

+145
-69
lines changed

config.lua

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -590,11 +590,11 @@ storage.config = {
590590
market_provides_chests = true,
591591
-- What market provides
592592
offers = {
593-
['coal'] = 2,
594-
['copper-ore'] = 2,
595-
['iron-ore'] = 2,
596-
['stone'] = 2,
597-
['uranium-ore'] = 10,
593+
['coal'] = 5,
594+
['copper-ore'] = 5,
595+
['iron-ore'] = 5,
596+
['stone'] = 5,
597+
['uranium-ore'] = 25,
598598
},
599599
-- What market requests
600600
requests = {

features/gui/experience.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ local function on_entity_died(event)
484484

485485
-- stuff killed by the player force, but not the player
486486
if force and force.name == 'player' then
487-
if cause and (cause.name == 'artillery-turret' or cause.name == 'gun-turret' or cause.name == 'laser-turret' or cause.name == 'flamethrower-turret') then
487+
if cause and cause.valid and (cause.name == 'artillery-turret' or cause.name == 'gun-turret' or cause.name == 'laser-turret' or cause.name == 'flamethrower-turret') then
488488
exp = config.XP['enemy_killed'] * (config.alien_experience_modifiers[entity_name] or 1)
489489
floating_text_position = cause.position
490490
else
Lines changed: 139 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
local Event = require 'utils.event'
22
local Global = require 'utils.global'
33
local math = require 'utils.math'
4+
local Token = require 'utils.token'
5+
local Task = require 'utils.task'
46

57
local floor = math.floor
68
local max = math.max
79

810
local chest = defines.inventory.chest
11+
local stun_sticker_duration = 3 -- seconds
912

1013
local died_entities = {}
1114

@@ -18,89 +21,162 @@ Global.register(
1821

1922
local Public = {}
2023

24+
local cause_by_type = {
25+
['character'] = function(cause)
26+
return cause.player
27+
end,
28+
['car'] = function(cause)
29+
local d = cause.get_driver()
30+
if d then
31+
return (d.object_name == 'LuaEntity') and d.player or d
32+
else
33+
return cause.last_user
34+
end
35+
end,
36+
['spider-vehicle'] = function(cause)
37+
local d = cause.get_driver()
38+
if d then
39+
return (d.object_name == 'LuaEntity') and d.player or d
40+
else
41+
return cause.last_user
42+
end
43+
end,
44+
['land-mine'] = function(cause)
45+
return cause.last_user
46+
end,
47+
}
48+
49+
local stun_player_callback
50+
stun_player_callback = Token.register(function(data)
51+
local entity = data.entity
52+
if not entity.valid then
53+
return
54+
end
55+
56+
local time_to_live = data.time_to_live
57+
if time_to_live <= 0 then
58+
return
59+
end
60+
61+
data.time_to_live = time_to_live - stun_sticker_duration
62+
entity.surface.create_entity {
63+
name = 'stun-sticker',
64+
target = entity,
65+
position = entity.position,
66+
}
67+
Task.set_timeout(stun_sticker_duration, stun_player_callback, data)
68+
end)
69+
70+
---@param config table
71+
---@field entity_name? string, resource to be spawned (default: coal)
72+
---@field time_penalty? number, time lost by the player when misbehaving (default: 18s, 0 to apply none)
73+
---@field spare_vehicle? boolean, saves the involved vehicle, if any (default: false)
2174
Public.register = function(config)
2275
local entity_name = config.entity_name or 'coal'
23-
Event.add(
24-
defines.events.on_entity_died,
25-
function(event)
26-
local entity = event.entity
76+
local time_penalty = config.time_penalty or 18
77+
local spare_vehicle = config.spare_vehicle or false
2778

28-
if not entity.valid then
29-
return
30-
end
79+
Event.add(defines.events.on_entity_died, function(event)
80+
local entity = event.entity
3181

32-
local type = entity.type
33-
if type ~= 'container' and type ~= 'logistic-container' then
34-
return
35-
end
82+
if not entity.valid then
83+
return
84+
end
3685

37-
local inventory = entity.get_inventory(chest)
38-
if not inventory or not inventory.valid then
39-
return
40-
end
86+
local type = entity.type
87+
if type ~= 'container' and type ~= 'logistic-container' then
88+
return
89+
end
4190

42-
local count = 0
43-
local deadlock_stack_size = (settings.startup['deadlock-stack-size'] or {}).value or 1
44-
local contents = inventory.get_contents()
45-
for _, item_stack in pairs(contents) do
46-
local real_count
47-
if item_stack.name:sub(1, #'deadlock-stack') == 'deadlock-stack' then
48-
real_count = item_stack.count * deadlock_stack_size
49-
else
50-
real_count = item_stack.count
51-
end
52-
53-
count = count + real_count
54-
end
91+
local inventory = entity.get_inventory(chest)
92+
if not inventory or not inventory.valid then
93+
return
94+
end
5595

56-
if count == 0 then
57-
return
96+
local count = 0
97+
local deadlock_stack_size = (settings.startup['deadlock-stack-size'] or {}).value or 1
98+
local contents = inventory.get_contents()
99+
for _, item_stack in pairs(contents) do
100+
local real_count
101+
if item_stack.name:sub(1, #'deadlock-stack') == 'deadlock-stack' then
102+
real_count = item_stack.count * deadlock_stack_size
103+
else
104+
real_count = item_stack.count
58105
end
59106

60-
local area = entity.bounding_box
61-
local left_top, right_bottom = area.left_top, area.right_bottom
62-
local x1, y1 = floor(left_top.x), floor(left_top.y)
63-
local x2, y2 = floor(right_bottom.x), floor(right_bottom.y)
107+
count = count + real_count
108+
end
109+
110+
if count == 0 then
111+
return
112+
end
113+
114+
local area = entity.bounding_box
115+
local left_top, right_bottom = area.left_top, area.right_bottom
116+
local x1, y1 = floor(left_top.x), floor(left_top.y)
117+
local x2, y2 = floor(right_bottom.x), floor(right_bottom.y)
64118

65-
local size_x = x2 - x1 + 1
66-
local size_y = y2 - y1 + 1
67-
local amount = floor(count / (size_x * size_y))
68-
amount = max(amount, 1)
119+
local size_x = x2 - x1 + 1
120+
local size_y = y2 - y1 + 1
121+
local amount = floor(count / (size_x * size_y))
122+
amount = max(amount, 1)
69123

70-
local create_entity = entity.surface.create_entity
124+
local create_entity = entity.surface.create_entity
71125

72-
for x = x1, x2 do
73-
for y = y1, y2 do
74-
create_entity({name = entity_name, position = {x, y}, amount = amount})
75-
end
126+
for x = x1, x2 do
127+
for y = y1, y2 do
128+
create_entity({name = entity_name, position = {x, y}, amount = amount})
76129
end
130+
end
77131

78-
died_entities[entity.unit_number] = true
132+
died_entities[entity.unit_number] = true
133+
134+
local cause = event.cause
135+
if not (cause and cause.valid and cause.force and cause.force.name == 'player') then
136+
return
79137
end
80-
)
81-
82-
Event.add(
83-
defines.events.on_post_entity_died,
84-
function(event)
85-
local unit_number = event.unit_number
86-
if not unit_number then
87-
return
88-
end
89138

90-
if not died_entities[unit_number] then
91-
return
92-
end
139+
local handler = cause_by_type[cause.type]
140+
local actor = handler and handler(cause)
141+
if not (actor and actor.valid) then
142+
return
143+
end
93144

94-
died_entities[unit_number] = nil
145+
local character = actor.character
146+
if not (character and character.valid) then
147+
return
148+
end
95149

96-
local ghost = event.ghost
97-
if not ghost or not ghost.valid then
98-
return
99-
end
150+
actor.print('The ore fights back!', { color = { 255, 128, 0 } })
151+
Task.set_timeout_in_ticks(1, stun_player_callback, {
152+
entity = character,
153+
time_to_live = time_penalty,
154+
})
100155

101-
ghost.destroy()
156+
if (not spare_vehicle) and (cause.type == 'car' or cause.type == 'spider-vehicle') then
157+
cause.die('neutral')
102158
end
103-
)
159+
end)
160+
161+
Event.add(defines.events.on_post_entity_died, function(event)
162+
local unit_number = event.unit_number
163+
if not unit_number then
164+
return
165+
end
166+
167+
if not died_entities[unit_number] then
168+
return
169+
end
170+
171+
died_entities[unit_number] = nil
172+
173+
local ghost = event.ghost
174+
if not ghost or not ghost.valid then
175+
return
176+
end
177+
178+
ghost.destroy()
179+
end)
104180
end
105181

106182
return Public

0 commit comments

Comments
 (0)