4949import  org .spongepowered .api .event .SpongeEventFactory ;
5050import  org .spongepowered .api .event .entity .SpawnEntityEvent ;
5151import  org .spongepowered .api .plugin .PluginContainer ;
52+ import  org .spongepowered .api .util .Tuple ;
5253import  org .spongepowered .api .world .BlockChangeFlag ;
5354import  org .spongepowered .api .world .World ;
5455import  org .spongepowered .asm .util .PrettyPrinter ;
@@ -98,12 +99,15 @@ public final class PhaseTracker {
9899        */ 
99100    };
100101
101-     private  final  CauseStack  stack  = new  CauseStack ();
102+     private  final  PhaseStack  stack  = new  PhaseStack ();
102103
103104    @ Nullable  private  PhaseData  currentProcessingState  = null ;
104105
105106    public  final  boolean  isVerbose  = SpongeImpl .getGlobalConfig ().getConfig ().getCauseTracker ().isVerbose ();
106107    public  final  boolean  verboseErrors  = SpongeImpl .getGlobalConfig ().getConfig ().getCauseTracker ().verboseErrors ();
108+     private  boolean  hasPrintedEmptyOnce  = false ;
109+     private  boolean  hasPrintedAboutRunnawayPhases  = false ;
110+     private  List <Tuple <IPhaseState <?>, IPhaseState <?>>> completedIncorrectStates  = new  ArrayList <>();
107111
108112    private  PhaseTracker () {
109113        // We cannot have two instances ever. ever ever. 
@@ -118,7 +122,7 @@ public static PhaseTracker getInstance() {
118122
119123    // ----------------- STATE ACCESS ---------------------------------- 
120124
121-     public   void  switchToPhase (IPhaseState <?> state , PhaseContext <?> phaseContext ) {
125+     void  switchToPhase (IPhaseState <?> state , PhaseContext <?> phaseContext ) {
122126        checkNotNull (state , "State cannot be null!" );
123127        checkNotNull (state .getPhase (), "Phase cannot be null!" );
124128        checkNotNull (phaseContext , "PhaseContext cannot be null!" );
@@ -139,28 +143,6 @@ public void switchToPhase(IPhaseState<?> state, PhaseContext<?> phaseContext) {
139143        this .stack .push (state , phaseContext );
140144    }
141145
142-     public  void  switchToPhase (PhaseData  phaseData ) {
143-         checkNotNull (phaseData .state , "State cannot be null!" );
144-         checkNotNull (phaseData .state .getPhase (), "Phase cannot be null!" );
145-         checkNotNull (phaseData .context , "PhaseContext cannot be null!" );
146-         checkArgument (phaseData .context .isComplete (), "PhaseContext must be complete!" );
147- 
148-         final  IPhaseState <?> currentState  = this .stack .peek ().state ;
149-         if  (this .isVerbose ) {
150-             if  (this .stack .size () > 6  && !currentState .isExpectedForReEntrance ()) {
151-                 // This printing is to detect possibilities of a phase not being cleared properly 
152-                 // and resulting in a "runaway" phase state accumulation. 
153-                 printRunawayPhase (phaseData .state , phaseData .context );
154-             }
155-             if  (!currentState .canSwitchTo (phaseData .state ) && phaseData .state  != GeneralPhase .Post .UNWINDING  && currentState  == GeneralPhase .Post .UNWINDING ) {
156-                 // This is to detect incompatible phase switches. 
157-                 printPhaseIncompatibility (currentState , phaseData .state );
158-             }
159-         }
160- 
161-         this .stack .push (phaseData .state , phaseData .context );
162-     }
163- 
164146    /** 
165147     * Used when exception occurs during the main body of a phase. 
166148     * Avoids running the normal unwinding code 
@@ -222,6 +204,10 @@ public void completePhase(IPhaseState<?> prevState) {
222204    }
223205
224206    private  void  printRunnawayPhaseCompletion (IPhaseState <?> state ) {
207+         if  (!this .isVerbose  && !this .hasPrintedAboutRunnawayPhases ) {
208+             // Avoiding spam logs. 
209+             return ;
210+         }
225211        final  PrettyPrinter  printer  = new  PrettyPrinter (60 );
226212        printer .add ("Completing Phase" ).centre ().hr ();
227213        printer .addWrapped (50 , "Detecting a runaway phase! Potentially a problem where something isn't completing a phase!!!" );
@@ -234,6 +220,9 @@ private void printRunnawayPhaseCompletion(IPhaseState<?> state) {
234220        printer .add ();
235221        generateVersionInfo (printer );
236222        printer .trace (System .err , SpongeImpl .getLogger (), Level .ERROR );
223+         if  (!this .isVerbose ) {
224+             this .hasPrintedAboutRunnawayPhases  = true ;
225+         }
237226    }
238227
239228    public  void  generateVersionInfo (PrettyPrinter  printer ) {
@@ -245,6 +234,17 @@ public void generateVersionInfo(PrettyPrinter printer) {
245234    }
246235
247236    private  void  printIncorrectPhaseCompletion (IPhaseState <?> prevState , IPhaseState <?> state ) {
237+         if  (!this .isVerbose  && !this .completedIncorrectStates .isEmpty ()) {
238+             for  (Tuple <IPhaseState <?>, IPhaseState <?>> tuple  : this .completedIncorrectStates ) {
239+                 if  ((tuple .getFirst ().equals (prevState )
240+                         && tuple .getSecond ().equals (state ))) {
241+                     // we've already printed once about the previous state and the current state 
242+                     // being completed incorrectly. only print it once. 
243+                     return ;
244+                 }
245+             }
246+         }
247+ 
248248        PrettyPrinter  printer  = new  PrettyPrinter (60 ).add ("Completing incorrect phase" ).centre ().hr ()
249249                .addWrapped (50 , "Sponge's tracking system is very dependent on knowing when" 
250250                        + "a change to any world takes place, however, we are attempting" 
@@ -260,9 +260,19 @@ private void printIncorrectPhaseCompletion(IPhaseState<?> prevState, IPhaseState
260260        printer .add ();
261261        generateVersionInfo (printer );
262262        printer .trace (System .err , SpongeImpl .getLogger (), Level .ERROR );
263+         if  (!this .isVerbose ) {
264+             this .completedIncorrectStates .add (new  Tuple <>(prevState , state ));
265+         }
263266    }
264267
265268    private  void  printEmptyStackOnCompletion () {
269+         if  (!this .isVerbose  && this .hasPrintedEmptyOnce ) {
270+             // We want to only mention it once that we are completing an 
271+             // empty state, of course something is bound to break, but 
272+             // we don't want to spam megabytes worth of log files just 
273+             // because of it. 
274+             return ;
275+         }
266276        final  PrettyPrinter  printer  = new  PrettyPrinter (60 ).add ("Unexpectedly Completing An Empty Stack" ).centre ().hr ()
267277                .addWrapped (50 , "Sponge's tracking system is very dependent on knowing when" 
268278                                + "a change to any world takes place, however, we have been told" 
@@ -274,9 +284,16 @@ private void printEmptyStackOnCompletion() {
274284                .add ();
275285        generateVersionInfo (printer );
276286        printer .trace (System .err , SpongeImpl .getLogger (), Level .ERROR );
287+         if  (!this .isVerbose ) {
288+             this .hasPrintedEmptyOnce  = true ;
289+         }
277290    }
278291
279292    private  void  printRunawayPhase (IPhaseState <?> state , PhaseContext <?> context ) {
293+         if  (!this .isVerbose  && !this .hasPrintedAboutRunnawayPhases ) {
294+             // Avoiding spam logs. 
295+             return ;
296+         }
280297        final  PrettyPrinter  printer  = new  PrettyPrinter (40 );
281298        printer .add ("Switching Phase" ).centre ().hr ();
282299        printer .addWrapped (50 , "Detecting a runaway phase! Potentially a problem where something isn't completing a phase!!!" );
@@ -290,9 +307,22 @@ private void printRunawayPhase(IPhaseState<?> state, PhaseContext<?> context) {
290307        printer .add ();
291308        generateVersionInfo (printer );
292309        printer .trace (System .err , SpongeImpl .getLogger (), Level .ERROR );
310+         if  (!this .isVerbose ) {
311+             this .hasPrintedAboutRunnawayPhases  = true ;
312+         }
293313    }
294314
295315    private  void  printPhaseIncompatibility (IPhaseState <?> currentState , IPhaseState <?> incompatibleState ) {
316+         if  (!this .isVerbose  && !this .completedIncorrectStates .isEmpty ()) {
317+             for  (Tuple <IPhaseState <?>, IPhaseState <?>> tuple  : this .completedIncorrectStates ) {
318+                 if  ((tuple .getFirst ().equals (currentState )
319+                         && tuple .getSecond ().equals (incompatibleState ))) {
320+                     // we've already printed once about the previous state and the current state 
321+                     // being completed incorrectly. only print it once. 
322+                     return ;
323+                 }
324+             }
325+         }
296326        PrettyPrinter  printer  = new  PrettyPrinter (80 );
297327        printer .add ("Switching Phase" ).centre ().hr ();
298328        printer .add ("Phase incompatibility detected! Attempting to switch to an invalid phase!" );
@@ -307,13 +337,16 @@ private void printPhaseIncompatibility(IPhaseState<?> currentState, IPhaseState<
307337        printer .add ();
308338        generateVersionInfo (printer );
309339        printer .trace (System .err , SpongeImpl .getLogger (), Level .ERROR );
340+         if  (!this .isVerbose ) {
341+             this .completedIncorrectStates .add (Tuple .of (currentState , incompatibleState ));
342+         }
310343    }
311344
312345    public  void  printMessageWithCaughtException (String  header , String  subHeader , Throwable  e ) {
313346        this .printMessageWithCaughtException (header , subHeader , this .getCurrentState (), this .getCurrentContext (), e );
314347    }
315348
316-     public  void  printMessageWithCaughtException (String  header , String  subHeader , IPhaseState <?> state , PhaseContext <?> context , Throwable  t ) {
349+     private  void  printMessageWithCaughtException (String  header , String  subHeader , IPhaseState <?> state , PhaseContext <?> context , Throwable  t ) {
317350        final  PrettyPrinter  printer  = new  PrettyPrinter (40 );
318351        printer .add (header ).centre ().hr ()
319352                .add ("%s %s" , subHeader , state )
@@ -328,7 +361,7 @@ public void printMessageWithCaughtException(String header, String subHeader, IPh
328361        printer .trace (System .err , SpongeImpl .getLogger (), Level .ERROR );
329362    }
330363
331-     public   String  dumpStack () {
364+     String  dumpStack () {
332365        if  (this .stack .isEmpty ()) {
333366            return  "[Empty stack]" ;
334367        }
@@ -356,10 +389,6 @@ public PhaseContext<?> getCurrentContext() {
356389        return  this .stack .peekContext ();
357390    }
358391
359-     public  PhaseData  getCurrentProcessingPhase () {
360-         return  this .currentProcessingState  == null  ? CauseStack .EMPTY_DATA  : this .currentProcessingState ;
361-     }
362- 
363392    // --------------------- DELEGATED WORLD METHODS ------------------------- 
364393
365394    /** 
0 commit comments