@@ -130,156 +130,160 @@ public AnimatedFrame(ItemFrame baseFrame, Vector3DDouble firstCorner, Vector3DDo
130130
131131 @ Override
132132 public void run () {
133- if (!imageLoaded ) {
134- MapManager mapManager = ((MapManagerPlugin ) Bukkit .getPluginManager ().getPlugin ("MapManager" )).getMapManager ();
135- try {
136- File cacheDir = new File (new File (plugin .getDataFolder (), "cache" ), this .name );
137- if (!cacheDir .exists ()) {
138- cacheDir .mkdirs ();
139-
140- plugin .getLogger ().info ("Generating image data for " + getName () + "..." );
141-
142- File file = plugin .frameManager .downloadOrGetImage (this .imageSource );
143- GifDecoder decoder = new GifDecoder ();
144- decoder .read (new FileInputStream (file ));
145-
146- if ((this .length = decoder .getFrameCount ()) <= 0 ) {
147- plugin .getLogger ().info ("Animation length for '" + getName () + "' is zero. Creating non-animated image." );
148- this .length = 1 ;
149-
150- BufferedImage image = ImageIO .read (file );
151- if (image == null ) {
152- throw new RuntimeException ("Failed to read the given image. Please make sure you're using a valid source" );
133+ try {
134+ if (!imageLoaded ) {
135+ MapManager mapManager = ((MapManagerPlugin ) Bukkit .getPluginManager ().getPlugin ("MapManager" )).getMapManager ();
136+ try {
137+ File cacheDir = new File (new File (plugin .getDataFolder (), "cache" ), this .name );
138+ if (!cacheDir .exists ()) {
139+ cacheDir .mkdirs ();
140+
141+ plugin .getLogger ().info ("Generating image data for " + getName () + "..." );
142+
143+ File file = plugin .frameManager .downloadOrGetImage (this .imageSource );
144+ GifDecoder decoder = new GifDecoder ();
145+ decoder .read (new FileInputStream (file ));
146+
147+ if ((this .length = decoder .getFrameCount ()) <= 0 ) {
148+ plugin .getLogger ().info ("Animation length for '" + getName () + "' is zero. Creating non-animated image." );
149+ this .length = 1 ;
150+
151+ BufferedImage image = ImageIO .read (file );
152+ if (image == null ) {
153+ throw new RuntimeException ("Failed to read the given image. Please make sure you're using a valid source" );
154+ }
155+ image = scaleImage (image );
156+ MapWrapper mapWrapper = mapManager .wrapMultiImage (image , this .height , this .width );
157+ this .frameDelays = new int [] { 500 };
158+ this .mapWrappers = new MapWrapper [] { mapWrapper };
159+ image .flush ();
160+
161+ File cacheFile = new File (cacheDir , this .name + "_0.afc" );
162+ cacheFile .createNewFile ();
163+ try (FileOutputStream out = new FileOutputStream (cacheFile )) {
164+ out .write (Ints .toByteArray (500 ));
165+ ArrayImage .writeMultiToSream (((MultiWrapper ) mapWrapper ).getMultiContent (), out );
166+ }
167+ } else {
168+ this .frameDelays = new int [this .length ];
169+ this .mapWrappers = new MapWrapper [this .length ];
170+ for (int i = 0 ; i < this .length ; i ++) {
171+ plugin .getLogger ().info ("Generating Frame " + (i + 1 ) + "/" + this .length + " for " + getName () + "..." );
172+
173+ BufferedImage image = scaleImage (decoder .getFrame (i ));
174+ int delay = decoder .getDelay (i );
175+ if (delay == 0 ) {
176+ plugin .getLogger ().warning ("Frame has no delay information, falling back to default (" + plugin .defaultDelay + ")" );
177+ delay = plugin .defaultDelay ;
178+ }
179+ this .frameDelays [i ] = delay ;
180+ MapWrapper wrapper = mapManager .wrapMultiImage (image , this .height , this .width );
181+ this .mapWrappers [i ] = wrapper ;
182+ image .flush ();
183+
184+ File cacheFile = new File (cacheDir , this .name + "_" + i + ".afc" );
185+ cacheFile .createNewFile ();
186+ try (FileOutputStream out = new FileOutputStream (cacheFile )) {
187+ out .write (Ints .toByteArray (delay ));
188+ ArrayImage .writeMultiToSream (((MultiWrapper ) wrapper ).getMultiContent (), out );
189+ }
190+ }
153191 }
154- image = scaleImage (image );
155- MapWrapper mapWrapper = mapManager .wrapMultiImage (image , this .height , this .width );
156- this .frameDelays = new int [] { 500 };
157- this .mapWrappers = new MapWrapper [] { mapWrapper };
158- image .flush ();
159-
160- File cacheFile = new File (cacheDir , this .name + "_0.afc" );
161- cacheFile .createNewFile ();
162- try (FileOutputStream out = new FileOutputStream (cacheFile )) {
163- out .write (Ints .toByteArray (500 ));
164- ArrayImage .writeMultiToSream (((MultiWrapper ) mapWrapper ).getMultiContent (), out );
192+
193+ // Reset all images
194+ for (Object object : decoder .frames ) {
195+ ((GifDecoder .GifFrame ) object ).image .flush ();
165196 }
197+ decoder .frames .clear ();
198+
166199 } else {
200+ plugin .getLogger ().info ("Reading " + getName () + " from cache..." );
201+
202+ String [] fileList = cacheDir .list ();
203+ this .length = fileList .length ;
167204 this .frameDelays = new int [this .length ];
168205 this .mapWrappers = new MapWrapper [this .length ];
169- for (int i = 0 ; i < this .length ; i ++) {
170- plugin .getLogger ().info ("Generating Frame " + (i + 1 ) + "/" + this .length + " for " + getName () + "..." );
171206
172- BufferedImage image = scaleImage (decoder .getFrame (i ));
173- int delay = decoder .getDelay (i );
174- if (delay == 0 ) {
175- plugin .getLogger ().warning ("Frame has no delay information, falling back to default (" + plugin .defaultDelay + ")" );
176- delay = plugin .defaultDelay ;
177- }
178- this .frameDelays [i ] = delay ;
179- MapWrapper wrapper = mapManager .wrapMultiImage (image , this .height , this .width );
180- this .mapWrappers [i ] = wrapper ;
181- image .flush ();
207+ for (int i = 0 ; i < this .length ; i ++) {
208+ plugin .getLogger ().info ("Reading Frame " + (i + 1 ) + "/" + this .length + " of " + getName () + "..." );
182209
183210 File cacheFile = new File (cacheDir , this .name + "_" + i + ".afc" );
184211 cacheFile .createNewFile ();
185- try (FileOutputStream out = new FileOutputStream (cacheFile )) {
186- out .write (Ints .toByteArray (delay ));
187- ArrayImage .writeMultiToSream (((MultiWrapper ) wrapper ).getMultiContent (), out );
212+ try (FileInputStream in = new FileInputStream (cacheFile )) {
213+ byte [] lengthBytes = new byte [4 ];
214+ in .read (lengthBytes , 0 , 4 );
215+ this .frameDelays [i ] = Ints .fromByteArray (lengthBytes );
216+
217+ ArrayImage [][] images = ArrayImage .readMultiFromStream (in );
218+ this .mapWrappers [i ] = mapManager .wrapMultiImage (images );
219+ } catch (IOException readE ) {
220+ throw new RuntimeException ("Your cached frame data appears to be invalid. Please delete the plugins/AnimatedFrames/cache directory and restart your server" , readE );
188221 }
189222 }
190223 }
191224
192- // Reset all images
193- for (Object object : decoder .frames ) {
194- ((GifDecoder .GifFrame ) object ).image .flush ();
195- }
196- decoder .frames .clear ();
197-
198- } else {
199- plugin .getLogger ().info ("Reading " + getName () + " from cache..." );
200-
201- String [] fileList = cacheDir .list ();
202- this .length = fileList .length ;
203- this .frameDelays = new int [this .length ];
204- this .mapWrappers = new MapWrapper [this .length ];
205-
206- for (int i = 0 ; i < this .length ; i ++) {
207- plugin .getLogger ().info ("Reading Frame " + (i + 1 ) + "/" + this .length + " of " + getName () + "..." );
208-
209- File cacheFile = new File (cacheDir , this .name + "_" + i + ".afc" );
210- cacheFile .createNewFile ();
211- try (FileInputStream in = new FileInputStream (cacheFile )) {
212- byte [] lengthBytes = new byte [4 ];
213- in .read (lengthBytes , 0 , 4 );
214- this .frameDelays [i ] = Ints .fromByteArray (lengthBytes );
215-
216- ArrayImage [][] images = ArrayImage .readMultiFromStream (in );
217- this .mapWrappers [i ] = mapManager .wrapMultiImage (images );
218- } catch (IOException readE ) {
219- throw new RuntimeException ("Your cached frame data appears to be invalid. Please delete the plugins/AnimatedFrames/cache directory and restart your server" , readE );
220- }
221- }
225+ imageLoaded = true ;
226+ } catch (IOException e ) {
227+ plugin .getLogger ().log (Level .SEVERE , "Failed to load image '" + getName () + "'" , e );
228+ throw new RuntimeException ("Failed to load image" );
222229 }
223-
224- imageLoaded = true ;
225- } catch (IOException e ) {
226- plugin .getLogger ().log (Level .SEVERE , "Failed to load image '" + getName () + "'" , e );
227- throw new RuntimeException ("Failed to load image" );
228230 }
229- }
230231
231- while (!this .playing ) {
232- try {
233- Thread .sleep (1000 );
234- } catch (InterruptedException e ) {
235- plugin .getLogger ().warning ("playing-delay for '" + getName () + "' has been interrupted" );
236- return ;
237- }
238- }
239-
240- if (AnimatedFramesPlugin .synchronizedStart ) {
241- while (System .currentTimeMillis () < AnimatedFramesPlugin .synchronizedTime ) {
232+ while (!this .playing ) {
242233 try {
243- Thread .sleep (1 );
234+ Thread .sleep (1000 );
244235 } catch (InterruptedException e ) {
245- plugin .getLogger ().warning ("synchronized start delay for '" + getName () + "' has been interrupted" );
236+ plugin .getLogger ().warning ("playing- delay for '" + getName () + "' has been interrupted" );
246237 return ;
247238 }
248239 }
249- }
250240
251- while (this .playing && this .plugin .isEnabled ()) {
252- if (startCallback != null ) {
253- startCallback .call (null );
254- startCallback = null ;
255- }
256-
257- if (timeSinceLastRefresh ++ > 10000 ) {
258- timeSinceLastRefresh = 0 ;
259- refresh ();
260- }
261- if (delayTicks ++ >= this .frameDelays [this .currentFrame ]) {
262- delayTicks = 0 ;
263- if (Bukkit .getOnlinePlayers ().isEmpty ()) {
241+ if (AnimatedFramesPlugin .synchronizedStart ) {
242+ while (System .currentTimeMillis () < AnimatedFramesPlugin .synchronizedTime ) {
264243 try {
265- Thread .sleep (2000 );
244+ Thread .sleep (1 );
266245 } catch (InterruptedException e ) {
267- plugin .getLogger ().warning ("Animation thread for " + getName () + " interrupted" );
246+ plugin .getLogger ().warning ("synchronized start delay for '" + getName () + "' has been interrupted" );
247+ return ;
268248 }
269- continue ;
249+ }
250+ }
251+
252+ while (this .playing && this .plugin .isEnabled ()) {
253+ if (startCallback != null ) {
254+ startCallback .call (null );
255+ startCallback = null ;
270256 }
271257
272- displayCurrentFrame ();
258+ if (timeSinceLastRefresh ++ > 10000 ) {
259+ timeSinceLastRefresh = 0 ;
260+ refresh ();
261+ }
262+ if (delayTicks ++ >= this .frameDelays [this .currentFrame ]) {
263+ delayTicks = 0 ;
264+ if (Bukkit .getOnlinePlayers ().isEmpty ()) {
265+ try {
266+ Thread .sleep (2000 );
267+ } catch (InterruptedException e ) {
268+ plugin .getLogger ().warning ("Animation thread for " + getName () + " interrupted" );
269+ }
270+ continue ;
271+ }
273272
274- this .currentFrame ++;
275- if (this .currentFrame >= this .length ) { this .currentFrame = 0 ; }
276- }
277- try {
278- Thread .sleep (1 );
279- } catch (InterruptedException e ) {
280- plugin .getLogger ().log (Level .WARNING , "Frame interrupted" , e );
281- }
273+ displayCurrentFrame ();
282274
275+ this .currentFrame ++;
276+ if (this .currentFrame >= this .length ) { this .currentFrame = 0 ; }
277+ }
278+ try {
279+ Thread .sleep (1 );
280+ } catch (InterruptedException e ) {
281+ plugin .getLogger ().log (Level .WARNING , "Frame interrupted" , e );
282+ }
283+
284+ }
285+ } catch (Throwable e ) {
286+ throw new RuntimeException ("Unexpected exception in AnimatedFrame " + name , e );
283287 }
284288 }
285289
@@ -468,7 +472,7 @@ public boolean isClickable() {
468472
469473 @ Override
470474 public void handleClick (Player player , CursorPosition position , int action ) {
471- this .clickEvents .stream ().filter (e -> e .contains (position .x , position .y )).forEach (e -> e .executeFor (player ,this .plugin ));
475+ this .clickEvents .stream ().filter (e -> e .contains (position .x , position .y )).forEach (e -> e .executeFor (player , this .plugin ));
472476 }
473477
474478 @ Override
0 commit comments