Skip to content

Commit 19306df

Browse files
authored
Merge pull request #386 from sp00ktober/master
fix newly introduced multithread issue by locking access
2 parents fdf5afa + 150125a commit 19306df

File tree

1 file changed

+111
-40
lines changed

1 file changed

+111
-40
lines changed

NebulaWorld/Factory/PowerTowerManager.cs

Lines changed: 111 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using NebulaModel.Logger;
22
using System.Collections.Concurrent;
33
using System.Collections.Generic;
4+
using System.Threading;
45

56
namespace NebulaWorld.Factory
67
{
@@ -129,13 +130,27 @@ public static int GetExtraDemand(int PlanetId, int NetId)
129130

130131
if(Energy.TryGetValue(PlanetId, out var mapping))
131132
{
132-
for(int i = 0; i < mapping.Count; i++)
133+
if(Monitor.TryEnter(mapping, 100))
133134
{
134-
if(mapping[i].NetId == NetId)
135+
try
136+
{
137+
for (int i = 0; i < mapping.Count; i++)
138+
{
139+
if (mapping[i].NetId == NetId)
140+
{
141+
return mapping[i].ExtraPower;
142+
}
143+
}
144+
}
145+
finally
135146
{
136-
return mapping[i].ExtraPower;
147+
Monitor.Exit(mapping);
137148
}
138149
}
150+
else
151+
{
152+
Log.Warn($"PowerTower: cant wait longer for threading lock, PowerTowers will be desynced!");
153+
}
139154
}
140155

141156
return 0;
@@ -152,25 +167,39 @@ public static void RemExtraDemand(int PlanetId, int NetId, int NodeId)
152167
PlanetFactory factory = GameMain.galaxy.PlanetById(PlanetId).factory;
153168
PowerSystem pSystem = factory?.powerSystem;
154169

155-
for(int j = 0; j < mapping[i].NodeId.Count; j++)
170+
if(Monitor.TryEnter(mapping, 100))
156171
{
157-
if(mapping[i].NodeId[j] == NodeId)
172+
try
158173
{
159-
if (factory != null && pSystem != null)
174+
for (int j = 0; j < mapping[i].NodeId.Count; j++)
160175
{
161-
mapping[i].ExtraPower -= pSystem.nodePool[NodeId].workEnergyPerTick;
162-
}
163-
else
164-
{
165-
mapping[i].ExtraPower -= mapping[i].ExtraPower / mapping[i].NodeId.Count;
176+
if (mapping[i].NodeId[j] == NodeId)
177+
{
178+
if (factory != null && pSystem != null)
179+
{
180+
mapping[i].ExtraPower -= pSystem.nodePool[NodeId].workEnergyPerTick;
181+
}
182+
else
183+
{
184+
mapping[i].ExtraPower -= mapping[i].ExtraPower / mapping[i].NodeId.Count;
185+
}
186+
187+
mapping[i].Activated[j]--;
188+
AddRequested(PlanetId, NetId, NodeId, false, true);
189+
190+
break;
191+
}
166192
}
167-
168-
mapping[i].Activated[j]--;
169-
AddRequested(PlanetId, NetId, NodeId, false, true);
170-
171-
break;
193+
}
194+
finally
195+
{
196+
Monitor.Exit(mapping);
172197
}
173198
}
199+
else
200+
{
201+
Log.Warn($"PowerTower: cant wait longer for threading lock, PowerTowers will be desynced!");
202+
}
174203

175204
if (mapping[i].ExtraPower < 0)
176205
{
@@ -187,38 +216,66 @@ public static void AddExtraDemand(int PlanetId, int NetId, int NodeId, int Power
187216
{
188217
for(int i = 0; i < mapping.Count; i++)
189218
{
190-
if(mapping[i].NetId == NetId)
219+
if(Monitor.TryEnter(mapping, 100))
191220
{
192-
bool foundNodeId = false;
193-
for(int j = 0; j < mapping[i].NodeId.Count; j++)
221+
try
194222
{
195-
if(mapping[i].NodeId[j] == NodeId)
223+
if (mapping[i].NetId == NetId)
196224
{
197-
foundNodeId = true;
198-
mapping[i].Activated[j]++;
199-
mapping[i].ExtraPower += PowerAmount;
200-
break;
225+
bool foundNodeId = false;
226+
for (int j = 0; j < mapping[i].NodeId.Count; j++)
227+
{
228+
if (mapping[i].NodeId[j] == NodeId)
229+
{
230+
foundNodeId = true;
231+
mapping[i].Activated[j]++;
232+
mapping[i].ExtraPower += PowerAmount;
233+
break;
234+
}
235+
}
236+
237+
if (!foundNodeId)
238+
{
239+
mapping[i].NodeId.Add(NodeId);
240+
mapping[i].Activated.Add(1);
241+
mapping[i].ExtraPower += PowerAmount;
242+
}
243+
244+
return;
201245
}
202246
}
203-
204-
if (!foundNodeId)
247+
finally
205248
{
206-
mapping[i].NodeId.Add(NodeId);
207-
mapping[i].Activated.Add(1);
208-
mapping[i].ExtraPower += PowerAmount;
249+
Monitor.Exit(mapping);
209250
}
210-
211-
return;
251+
}
252+
else
253+
{
254+
Log.Warn($"PowerTower: cant wait longer for threading lock, PowerTowers will be desynced!");
212255
}
213256
}
214257

215-
EnergyMapping map = new PowerTowerManager.EnergyMapping();
216-
map.NetId = NetId;
217-
map.NodeId.Add(NodeId);
218-
map.Activated.Add(1);
219-
map.ExtraPower = PowerAmount;
258+
if(Monitor.TryEnter(mapping, 100))
259+
{
260+
try
261+
{
262+
EnergyMapping map = new PowerTowerManager.EnergyMapping();
263+
map.NetId = NetId;
264+
map.NodeId.Add(NodeId);
265+
map.Activated.Add(1);
266+
map.ExtraPower = PowerAmount;
220267

221-
mapping.Add(map);
268+
mapping.Add(map);
269+
}
270+
finally
271+
{
272+
Monitor.Exit(mapping);
273+
}
274+
}
275+
else
276+
{
277+
Log.Warn($"PowerTower: cant wait longer for threading lock, PowerTowers will be desynced!");
278+
}
222279
}
223280
else
224281
{
@@ -243,13 +300,27 @@ public static void UpdateAllAnimations(int PlanetId)
243300
{
244301
if(Energy.TryGetValue(PlanetId, out var mapping))
245302
{
246-
for(int i = 0; i < mapping.Count; i++)
303+
if(Monitor.TryEnter(mapping, 100))
247304
{
248-
for(int j = 0; j < mapping[i].Activated.Count; j++)
305+
try
306+
{
307+
for (int i = 0; i < mapping.Count; i++)
308+
{
309+
for (int j = 0; j < mapping[i].Activated.Count; j++)
310+
{
311+
UpdateAnimation(PlanetId, mapping[i].NetId, mapping[i].NodeId[j], mapping[i].Activated[j] > 0 ? 1 : 0);
312+
}
313+
}
314+
}
315+
finally
249316
{
250-
UpdateAnimation(PlanetId, mapping[i].NetId, mapping[i].NodeId[j], mapping[i].Activated[j] > 0 ? 1 : 0);
317+
Monitor.Exit(mapping);
251318
}
252319
}
320+
else
321+
{
322+
Log.Warn($"PowerTower: cant wait longer for threading lock, PowerTowers will be desynced!");
323+
}
253324
}
254325
}
255326

0 commit comments

Comments
 (0)