1+ package com .cells .commands ;
2+
3+ import java .util .EnumSet ;
4+
5+ import javax .annotation .Nonnull ;
6+
7+ import net .minecraft .command .CommandBase ;
8+ import net .minecraft .command .ICommandSender ;
9+ import net .minecraft .entity .player .EntityPlayerMP ;
10+ import net .minecraft .server .MinecraftServer ;
11+ import net .minecraft .tileentity .TileEntity ;
12+ import net .minecraft .util .EnumFacing ;
13+ import net .minecraft .util .math .BlockPos ;
14+ import net .minecraft .util .math .RayTraceResult ;
15+ import net .minecraft .util .math .Vec3d ;
16+ import net .minecraft .util .text .TextComponentTranslation ;
17+
18+ import appeng .api .parts .IPart ;
19+ import appeng .api .parts .IPartHost ;
20+ import appeng .api .parts .SelectedPart ;
21+ import appeng .api .util .AEPartLocation ;
22+
23+ import com .cells .network .sync .ResourceType ;
24+ import com .cells .parts .subnetproxy .PartSubnetProxyBack ;
25+ import com .cells .parts .subnetproxy .PartSubnetProxyFront ;
26+
27+
28+ public class InspectSubnetProxyCommand extends CommandBase {
29+
30+ private static final double REACH_DISTANCE = 5.0D ;
31+
32+ @ Override
33+ @ Nonnull
34+ public String getName () {
35+ return "inspectSubnetProxy" ;
36+ }
37+
38+ @ Override
39+ @ Nonnull
40+ public String getUsage (@ Nonnull ICommandSender sender ) {
41+ return "commands.cells.inspect_subnet_proxy.usage" ;
42+ }
43+
44+ @ Override
45+ public int getRequiredPermissionLevel () {
46+ return 0 ;
47+ }
48+
49+ @ Override
50+ public void execute (@ Nonnull MinecraftServer server , @ Nonnull ICommandSender sender , @ Nonnull String [] args ) {
51+ if (!(sender .getCommandSenderEntity () instanceof EntityPlayerMP )) {
52+ sender .sendMessage (new TextComponentTranslation ("commands.cells.inspect_slots.not_player" ));
53+ return ;
54+ }
55+
56+ EntityPlayerMP player = (EntityPlayerMP ) sender .getCommandSenderEntity ();
57+ RayTraceResult hit = rayTrace (player );
58+ if (hit == null || hit .typeOfHit != RayTraceResult .Type .BLOCK ) {
59+ sender .sendMessage (new TextComponentTranslation ("commands.cells.inspect_slots.no_block" ));
60+ return ;
61+ }
62+
63+ BlockPos hitPos = hit .getBlockPos ();
64+ TileEntity te = player .world .getTileEntity (hitPos );
65+ if (te == null ) {
66+ sender .sendMessage (new TextComponentTranslation (
67+ "commands.cells.inspect_slots.no_tile" , hitPos .getX (), hitPos .getY (), hitPos .getZ ()));
68+ return ;
69+ }
70+
71+ TargetedProxy target = resolveTarget (te , hit );
72+ if (target == null ) {
73+ sender .sendMessage (new TextComponentTranslation ("commands.cells.inspect_subnet_proxy.no_proxy" ));
74+ return ;
75+ }
76+
77+ if (target .targetedBack ) {
78+ sender .sendMessage (new TextComponentTranslation (
79+ "commands.cells.inspect_subnet_proxy.back_header" ,
80+ hitPos .getX (),
81+ hitPos .getY (),
82+ hitPos .getZ (),
83+ player .world .provider .getDimension (),
84+ player .world .provider .getDimensionType ().getName (),
85+ target .back .getSide ().getFacing ()));
86+
87+ if (target .front == null ) {
88+ sender .sendMessage (new TextComponentTranslation ("commands.cells.inspect_subnet_proxy.no_front" ));
89+ return ;
90+ }
91+ }
92+
93+ PartSubnetProxyFront .ProxyDiagnosticSnapshot snapshot = target .front .getDiagnosticSnapshot ();
94+ BlockPos frontPos = snapshot .pos != null ? snapshot .pos : hitPos ;
95+ EnumFacing frontSide = snapshot .side != null ? snapshot .side : hit .sideHit ;
96+
97+ if (!target .targetedBack ) {
98+ sender .sendMessage (new TextComponentTranslation (
99+ "commands.cells.inspect_subnet_proxy.front_header" ,
100+ frontPos .getX (),
101+ frontPos .getY (),
102+ frontPos .getZ (),
103+ snapshot .dimensionId ,
104+ snapshot .dimensionName ,
105+ frontSide ));
106+ } else {
107+ sender .sendMessage (new TextComponentTranslation (
108+ "commands.cells.inspect_subnet_proxy.linked_front" ,
109+ frontPos .getX (),
110+ frontPos .getY (),
111+ frontPos .getZ (),
112+ frontSide ));
113+ }
114+
115+ sender .sendMessage (new TextComponentTranslation (
116+ "commands.cells.inspect_subnet_proxy.state" ,
117+ boolText (snapshot .powered ),
118+ boolText (snapshot .active ),
119+ boolText (snapshot .paired ),
120+ boolText (snapshot .ownOriginVisible ),
121+ formatHash (snapshot .structureHash )));
122+
123+ sender .sendMessage (new TextComponentTranslation (
124+ "commands.cells.inspect_subnet_proxy.channels" ,
125+ describeEnabledChannels (snapshot .enabledChannels ),
126+ snapshot .priority ,
127+ boolText (snapshot .hasInsertionCard ),
128+ boolText (snapshot .insertionActive ),
129+ snapshot .filterMode .name (),
130+ boolText (snapshot .fuzzyEnabled ),
131+ boolText (snapshot .inverterEnabled )));
132+
133+ sender .sendMessage (new TextComponentTranslation (
134+ "commands.cells.inspect_subnet_proxy.grids" ,
135+ formatHash (snapshot .frontGridHash ),
136+ formatHash (snapshot .backGridHash ),
137+ snapshot .exposedOriginCount ,
138+ snapshot .visiblePeerCount ,
139+ snapshot .totalPeerCount ,
140+ snapshot .itemLocalCells ,
141+ snapshot .fluidLocalCells ,
142+ snapshot .gasLocalCells ,
143+ snapshot .essentiaLocalCells ));
144+
145+ if (snapshot .lastFault == null ) {
146+ sender .sendMessage (new TextComponentTranslation ("commands.cells.inspect_subnet_proxy.last_fault.none" ));
147+ return ;
148+ }
149+
150+ sender .sendMessage (new TextComponentTranslation (
151+ "commands.cells.inspect_subnet_proxy.last_fault" ,
152+ snapshot .lastFault .lastObservedTick ,
153+ snapshot .lastFault .occurrenceCount ,
154+ snapshot .lastFault .channelName ,
155+ snapshot .lastFault .requestDescription ,
156+ snapshot .lastFault .requestedAmount ,
157+ snapshot .lastFault .extractedAmount ,
158+ snapshot .lastFault .visibleAmount ,
159+ snapshot .lastFault .actionName ,
160+ formatHash (snapshot .lastFault .structureHash )));
161+ }
162+
163+ private static TargetedProxy resolveTarget (TileEntity te , RayTraceResult hit ) {
164+ if (!(te instanceof IPartHost )) return null ;
165+
166+ IPartHost host = (IPartHost ) te ;
167+ SelectedPart selected = host .selectPartGlobal (hit .hitVec );
168+ IPart part = selected .part ;
169+
170+ if (!(part instanceof PartSubnetProxyFront ) && !(part instanceof PartSubnetProxyBack ) && hit .sideHit != null ) {
171+ part = host .getPart (AEPartLocation .fromFacing (hit .sideHit ));
172+ }
173+
174+ if (part instanceof PartSubnetProxyFront ) {
175+ PartSubnetProxyFront front = (PartSubnetProxyFront ) part ;
176+ return new TargetedProxy (front , front .findBackPart (), false );
177+ }
178+
179+ if (part instanceof PartSubnetProxyBack ) {
180+ PartSubnetProxyBack back = (PartSubnetProxyBack ) part ;
181+ return new TargetedProxy (back .findFrontPart (), back , true );
182+ }
183+
184+ return null ;
185+ }
186+
187+ private static RayTraceResult rayTrace (EntityPlayerMP player ) {
188+ Vec3d start = player .getPositionEyes (1.0F );
189+ Vec3d lookVec = player .getLookVec ();
190+ Vec3d end = start .add (lookVec .scale (REACH_DISTANCE ));
191+
192+ return player .world .rayTraceBlocks (start , end , false , false , true );
193+ }
194+
195+ private static String boolText (boolean value ) {
196+ return value ? "yes" : "no" ;
197+ }
198+
199+ private static String formatHash (int hash ) {
200+ return String .format ("%08X" , hash );
201+ }
202+
203+ private static String describeEnabledChannels (EnumSet <ResourceType > channels ) {
204+ if (channels .isEmpty ()) return "none" ;
205+
206+ StringBuilder description = new StringBuilder ();
207+ for (ResourceType channel : channels ) {
208+ if (description .length () > 0 ) description .append (", " );
209+
210+ description .append (channel .name ());
211+ }
212+
213+ return description .toString ();
214+ }
215+
216+ private static class TargetedProxy {
217+
218+ private final PartSubnetProxyFront front ;
219+ private final PartSubnetProxyBack back ;
220+ private final boolean targetedBack ;
221+
222+ private TargetedProxy (PartSubnetProxyFront front , PartSubnetProxyBack back , boolean targetedBack ) {
223+ this .front = front ;
224+ this .back = back ;
225+ this .targetedBack = targetedBack ;
226+ }
227+ }
228+ }
0 commit comments