Skip to content

Commit 13262d9

Browse files
committed
Add command that forces resync of all replicables for player
1 parent 492d42f commit 13262d9

File tree

7 files changed

+145
-61
lines changed

7 files changed

+145
-61
lines changed

Essentials/Commands/DeleteModule.cs

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,52 @@ namespace Essentials
1313
[Category("delete")]
1414
public class DeleteModule : CommandModule
1515
{
16+
[Command("grids notype", "Delete all grids that don't have a block of the given type")]
17+
[Permission(MyPromoteLevel.SpaceMaster)]
18+
public void DeleteByType(string type, bool scanOnly = true)
19+
{
20+
var count = 0;
21+
foreach (var grid in MyEntities.GetEntities().OfType<MyCubeGrid>())
22+
{
23+
if (ShouldRemove(grid))
24+
{
25+
if (!scanOnly)
26+
grid.Close();
27+
count++;
28+
}
29+
}
30+
31+
Context.Respond($"{(scanOnly ? "Found" : "Deleted")} {count} grids missing the block subtype '{type}'.");
32+
33+
bool ShouldRemove(MyCubeGrid grid)
34+
{
35+
foreach (var block in grid.GetBlocks())
36+
{
37+
var id = block.BlockDefinition.Id.TypeId.ToString();
38+
if (string.Compare(id, type, StringComparison.InvariantCultureIgnoreCase) == 0)
39+
return false;
40+
}
41+
42+
return true;
43+
}
44+
}
45+
1646
[Command("grids nosubtype", "Delete all grids that don't have a block of the given subtype.")]
1747
[Permission(MyPromoteLevel.SpaceMaster)]
18-
public void DeleteBySubtype(string subtype)
48+
public void DeleteBySubtype(string subtype, bool scanOnly = true)
1949
{
2050
var count = 0;
2151
foreach (var grid in MyEntities.GetEntities().OfType<MyCubeGrid>())
2252
{
2353
if (ShouldRemove(grid))
2454
{
25-
grid.Close();
55+
if (!scanOnly)
56+
grid.Close();
2657
count++;
2758
}
2859
}
2960

30-
Context.Respond($"Deleted {count} grids missing the block subtype '{subtype}'.");
61+
Context.Respond($"{(scanOnly ? "Found" : "Deleted")} {count} grids missing the block subtype '{subtype}'.");
3162

3263
bool ShouldRemove(MyCubeGrid grid)
3364
{
@@ -44,7 +75,7 @@ bool ShouldRemove(MyCubeGrid grid)
4475

4576
[Command("grids ownedby", "Delete grids that the given player owns the majority of.")]
4677
[Permission(MyPromoteLevel.SpaceMaster)]
47-
public void DeleteByOwner(string name)
78+
public void DeleteByOwner(string name, bool scanOnly = true)
4879
{
4980
var player = Utilities.GetPlayerByNameOrId(name);
5081
if (player == null)
@@ -62,42 +93,44 @@ public void DeleteByOwner(string name)
6293
count++;
6394
}
6495
}
65-
66-
Context.Respond($"Deleted {count} grids owned by '{name}.'");
96+
97+
Context.Respond($"{(scanOnly ? "Found" : "Deleted")} {count} grids owned by '{name}.'");
6798
}
6899

69100
[Command("grids blockslessthan", "Delete grids with fewer than X blocks.")]
70101
[Permission(MyPromoteLevel.SpaceMaster)]
71-
public void DeleteBlocksLessThan(int minBlocks)
102+
public void DeleteBlocksLessThan(int minBlocks, bool scanOnly = true)
72103
{
73104
var count = 0;
74105
foreach (var grid in MyEntities.GetEntities().OfType<MyCubeGrid>())
75106
{
76107
if (grid.BlocksCount < minBlocks)
77108
{
78-
grid.Close();
109+
if (!scanOnly)
110+
grid.Close();
79111
count++;
80112
}
81113
}
82114

83-
Context.Respond($"Deleted {count} grids with less than {minBlocks} blocks.");
115+
Context.Respond($"{(scanOnly ? "Found" : "Deleted")} {count} grids with less than {minBlocks} blocks.");
84116
}
85117

86118
[Command("grids blocksgreaterthan", "Delete grids with greater than X blocks.")]
87119
[Permission(MyPromoteLevel.SpaceMaster)]
88-
public void DeleteBlocksGreaterThan(int maxBlocks)
120+
public void DeleteBlocksGreaterThan(int maxBlocks, bool scanOnly = true)
89121
{
90122
var count = 0;
91123
foreach (var grid in MyEntities.GetEntities().OfType<MyCubeGrid>())
92124
{
93125
if (grid.BlocksCount > maxBlocks)
94126
{
95-
grid.Close();
127+
if (!scanOnly)
128+
grid.Close();
96129
count++;
97130
}
98131
}
99132

100-
Context.Respond($"Deleted {count} grids with greater than {maxBlocks} blocks.");
133+
Context.Respond($"{(scanOnly ? "Found" : "Deleted")} {count} grids with greater than {maxBlocks} blocks.");
101134
}
102135

103136
[Command("floating", "Delete all floating objects.")]

Essentials/Commands/EntityModule.cs

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,67 @@
11
using System;
2+
using System.Collections;
23
using System.Collections.Generic;
34
using System.Linq;
5+
using System.Reflection;
46
using System.Text;
57
using System.Threading.Tasks;
8+
using Sandbox;
9+
using Sandbox.Engine.Multiplayer;
610
using Sandbox.Game.Entities;
11+
using Sandbox.Game.World;
712
using Sandbox.ModAPI;
813
using Torch.Commands;
914
using Torch.Commands.Permissions;
15+
using VRage.Collections;
1016
using VRage.Game.Entity;
1117
using VRage.Game.ModAPI;
1218
using VRage.ModAPI;
19+
using VRage.Network;
20+
using VRage.Replication;
1321
using VRageMath;
1422

1523
namespace Essentials
1624
{
17-
[Category("entity")]
25+
[Category("entities")]
1826
public class EntityModule : CommandModule
1927
{
28+
[Command("refresh", "Resyncs all entities for the player running the command.")]
29+
[Permission(MyPromoteLevel.None)]
30+
public void Refresh2()
31+
{
32+
if (Context.Player == null)
33+
return;
34+
35+
var playerEndpoint = new Endpoint(Context.Player.SteamUserId, 0);
36+
var replicationServer = (MyReplicationServer)MyMultiplayer.ReplicationLayer;
37+
var clientDataDict = typeof(MyReplicationServer).GetField("m_clientStates", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(replicationServer) as IDictionary;
38+
object clientData;
39+
try
40+
{
41+
clientData = clientDataDict[playerEndpoint];
42+
}
43+
catch
44+
{
45+
return;
46+
}
47+
48+
var clientReplicables = clientData.GetType().GetField("Replicables").GetValue(clientData) as MyConcurrentDictionary<IMyReplicable, MyReplicableClientData>;
49+
var removeForClientMethod = typeof(MyReplicationServer).GetMethod("RemoveForClient", BindingFlags.Instance | BindingFlags.NonPublic);
50+
var forceReplicableMethod = typeof(MyReplicationServer).GetMethod("ForceReplicable", BindingFlags.Instance | BindingFlags.NonPublic, null, new[] {typeof(IMyReplicable), typeof(Endpoint)}, null);
51+
52+
var replicableList = new List<IMyReplicable>(clientReplicables.Count);
53+
foreach (var pair in clientReplicables)
54+
replicableList.Add(pair.Key);
55+
56+
foreach (var replicable in replicableList)
57+
{
58+
removeForClientMethod.Invoke(replicationServer, new object[] {replicable, playerEndpoint, clientData, true});
59+
forceReplicableMethod.Invoke(replicationServer, new object[] {replicable, playerEndpoint});
60+
}
61+
62+
Context.Respond($"Forced replication of {replicableList.Count} entities.");
63+
}
64+
2065
[Command("stop", "Stops an entity from moving")]
2166
[Permission(MyPromoteLevel.SpaceMaster)]
2267
public void Stop(string entityName)
@@ -79,24 +124,6 @@ public void Find(string name)
79124
[Permission(MyPromoteLevel.SpaceMaster)]
80125
public void Teleport(string destination, string entityToMove = null)
81126
{
82-
/*
83-
IMyEntity targetEntity;
84-
IMyEntity destEntity;
85-
switch (Context.Args.Count)
86-
{
87-
case 1:
88-
targetEntity = Context.Player.Controller.ControlledEntity.Entity;
89-
Utilities.TryGetEntityByNameOrId(Context.Args[0], out destEntity);
90-
break;
91-
case 2:
92-
Utilities.TryGetEntityByNameOrId(Context.Args[0], out targetEntity);
93-
Utilities.TryGetEntityByNameOrId(Context.Args[1], out destEntity);
94-
break;
95-
default:
96-
Context.Respond("Wrong number of arguments.");
97-
return;
98-
}*/
99-
100127
Utilities.TryGetEntityByNameOrId(destination, out IMyEntity destEntity);
101128

102129
IMyEntity targetEntity;

Essentials/Commands/GridModule.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
namespace Essentials
1717
{
18-
[Category("grid")]
18+
[Category("grids")]
1919
public class GridModule : CommandModule
2020
{
2121
[Command("setowner", "Sets grid ownership to the given player or ID.", "Usage: setowner <grid> <newowner>")]

Essentials/Commands/VoxelModule.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using Sandbox.Engine.Multiplayer;
7+
using Sandbox.Engine.Voxels;
8+
using Sandbox.Game.Entities;
9+
using Sandbox.Game.Replication;
10+
using Torch.Commands;
11+
using VRage.Game.ModAPI;
12+
using VRage.ModAPI;
13+
using VRage.Network;
14+
using VRage.Voxels;
15+
using Parallel = ParallelTasks.Parallel;
16+
17+
namespace Essentials.Commands
18+
{
19+
[Category("voxels")]
20+
public class VoxelModule : CommandModule
21+
{
22+
[Command("reset all", "Resets all voxel maps.")]
23+
public void ResetAll()
24+
{
25+
var voxelMaps = MyEntities.GetEntities().Select(x => x as IMyVoxelBase);
26+
27+
Console.WriteLine(voxelMaps.Count());
28+
var count = 0;
29+
//Parallel.ForEach(voxelMaps, map =>
30+
try
31+
{
32+
foreach (var map in voxelMaps)
33+
{
34+
if (map?.StorageName == null || ((MyStorageBase)map.Storage).DataProvider == null)
35+
continue;
36+
37+
map.Storage.Reset(MyStorageDataTypeFlags.All);
38+
((MyReplicationServer)MyMultiplayer.ReplicationLayer).ForceClientRefresh((MyVoxelBase)map);
39+
count++;
40+
}
41+
}
42+
catch (Exception e)
43+
{
44+
Console.WriteLine($"{e.Message}\n{e.StackTrace}");
45+
}
46+
47+
Context.Respond($"Reset {count} voxel maps.");
48+
}
49+
}
50+
}

Essentials/Essentials.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129
<Reference Include="WindowsBase" />
130130
</ItemGroup>
131131
<ItemGroup>
132+
<Compile Include="Commands\VoxelModule.cs" />
132133
<Compile Include="Commands\WorldModule.cs" />
133134
<Compile Include="EssentialsConfig.cs" />
134135
<Compile Include="Commands\DeleteModule.cs" />

Essentials/EssentialsControl.xaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,5 @@
77
mc:Ignorable="d"
88
d:DesignHeight="300" d:DesignWidth="300">
99
<StackPanel>
10-
<TextBlock Text="WPF Control Test"/>
11-
<Button Content="Click Meh"></Button>
1210
</StackPanel>
1311
</UserControl>

Essentials/EssentialsPlugin.cs

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,16 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
6-
using System.Windows.Controls;
1+
using System.Windows.Controls;
72
using Torch;
8-
using Torch.API;
93
using Torch.API.Plugins;
104

115
namespace Essentials
126
{
13-
[Plugin("Essentials", "1.1", "cbfdd6ab-4cda-4544-a201-f73efa3d46c0")]
7+
[Plugin("Essentials", "1.2", "cbfdd6ab-4cda-4544-a201-f73efa3d46c0")]
148
public class EssentialsPlugin : TorchPluginBase, IWpfPlugin
159
{
1610
private EssentialsControl _control;
1711
private Persistent<EssentialsConfig> _config;
1812

1913
/// <inheritdoc />
2014
public UserControl GetControl() => _control ?? (_control = new EssentialsControl());
21-
22-
/// <inheritdoc />
23-
public override void Init(ITorchBase torch)
24-
{
25-
base.Init(torch);
26-
27-
}
28-
29-
/// <inheritdoc />
30-
public override void Update()
31-
{
32-
33-
}
34-
35-
/// <inheritdoc />
36-
public override void Dispose()
37-
{
38-
39-
}
4015
}
4116
}

0 commit comments

Comments
 (0)