2
2
import java .io .IOException ;
3
3
import java .io .InputStream ;
4
4
import java .lang .reflect .Method ;
5
+ import java .util .ArrayList ;
5
6
import java .util .HashMap ;
6
7
import java .util .HashSet ;
8
+ import java .util .List ;
7
9
import java .util .Map ;
8
10
import java .util .Set ;
9
11
import java .util .logging .Level ;
18
20
import org .bukkit .configuration .file .FileConfiguration ;
19
21
import org .bukkit .entity .AnimalTamer ;
20
22
import org .bukkit .entity .Entity ;
23
+ import org .bukkit .entity .Horse ;
24
+ import org .bukkit .entity .LivingEntity ;
21
25
import org .bukkit .entity .Ocelot ;
22
26
import org .bukkit .entity .Player ;
23
27
import org .bukkit .entity .Skeleton ;
28
+ import org .bukkit .entity .Horse .Variant ;
24
29
import org .bukkit .entity .Skeleton .SkeletonType ;
25
30
import org .bukkit .entity .Villager ;
26
31
import org .bukkit .entity .Villager .Profession ;
@@ -64,6 +69,9 @@ public class DynmapMobsPlugin extends JavaPlugin {
64
69
static String nmspackage ;
65
70
Method gethandle ;
66
71
72
+ int updates_per_tick = 20 ;
73
+ int vupdates_per_tick = 20 ;
74
+
67
75
HashMap <String , Integer > lookup_cache = new HashMap <String , Integer >();
68
76
HashMap <String , Integer > vlookup_cache = new HashMap <String , Integer >();
69
77
@@ -183,8 +191,7 @@ private static class MobMapping {
183
191
new MobMapping ("squid" , "org.bukkit.entity.Squid" , "Squid" ),
184
192
new MobMapping ("villager" , "org.bukkit.entity.Villager" , "Villager" ),
185
193
new MobMapping ("golem" , "org.bukkit.entity.IronGolem" , "Iron Golem" ),
186
- new MobMapping ("vanillahorse" , "org.bukkit.entity.Animals" , "Horse" , "net.minecraft.server.EntityHorse" )
187
- //TODO: once CB is fixed - new MobMapping("vanillahorse", "org.bukkit.entity.Horse", "Horse")
194
+ new MobMapping ("vanillahorse" , "org.bukkit.entity.Horse" , "Horse" )
188
195
};
189
196
private MobMapping configvehicles [] = {
190
197
// Explosive Minecart
@@ -210,47 +217,53 @@ public static void info(String msg) {
210
217
public static void severe (String msg ) {
211
218
log .log (Level .SEVERE , msg );
212
219
}
213
-
214
220
215
221
private class MobUpdate implements Runnable {
222
+ Map <Integer ,Marker > newmap = new HashMap <Integer ,Marker >(); /* Build new map */
223
+ ArrayList <World > worldsToDo = null ;
224
+ List <LivingEntity > mobsToDo = null ;
225
+ int mobIndex = 0 ;
226
+ World curWorld = null ;
227
+
216
228
public void run () {
217
- if (!stop ) {
218
- updateMobs ();
219
- getServer ().getScheduler ().scheduleSyncDelayedTask (DynmapMobsPlugin .this , new MobUpdate (), updperiod );
229
+ if (stop || (mobs == null ) || (mobs .length == 0 ) || (set == null )) {
230
+ return ;
220
231
}
221
- }
222
- }
223
-
224
- private class VehicleUpdate implements Runnable {
225
- public void run () {
226
- if (!stop ) {
227
- updateVehicles ();
228
- getServer ().getScheduler ().scheduleSyncDelayedTask (DynmapMobsPlugin .this , new VehicleUpdate (), vupdperiod );
232
+ // If needed, prime world list
233
+ if (worldsToDo == null ) {
234
+ worldsToDo = new ArrayList <World >(getServer ().getWorlds ());
229
235
}
230
- }
231
- }
232
-
233
- private Map <Integer , Marker > mobicons = new HashMap <Integer , Marker >();
234
- private Map <Integer , Marker > vehicleicons = new HashMap <Integer , Marker >();
235
-
236
- private int findNext (int idx , String mobid ) {
237
- idx ++;
238
- if ((idx < mobs .length ) && mobs [idx ].mobid .equals (mobid )) {
239
- return idx ;
240
- }
241
- else {
242
- return mobs .length ;
243
- }
244
- }
245
- /* Update mob population and position */
246
- private void updateMobs () {
247
- if ((mobs == null ) || (mobs .length == 0 ) || (set == null )) {
248
- return ;
249
- }
250
- Map <Integer ,Marker > newmap = new HashMap <Integer ,Marker >(); /* Build new map */
251
-
252
- for (World w : getServer ().getWorlds ()) {
253
- for (Entity le : w .getLivingEntities ()) {
236
+ while (mobsToDo == null ) {
237
+ if (worldsToDo .isEmpty ()) {
238
+ /* Now, review old map - anything left is gone */
239
+ for (Marker oldm : mobicons .values ()) {
240
+ oldm .deleteMarker ();
241
+ }
242
+ /* And replace with new map */
243
+ mobicons = newmap ;
244
+ // Schedule next run
245
+ getServer ().getScheduler ().scheduleSyncDelayedTask (DynmapMobsPlugin .this , new MobUpdate (), updperiod );
246
+ return ;
247
+ }
248
+ else {
249
+ curWorld = worldsToDo .remove (0 ); // Get next world
250
+ mobsToDo = curWorld .getLivingEntities (); // Get living entities
251
+ mobIndex = 0 ;
252
+ if ((mobsToDo != null ) && mobsToDo .isEmpty ()) {
253
+ mobsToDo = null ;
254
+ }
255
+ }
256
+ }
257
+ // Process up to limit per tick
258
+ for (int cnt = 0 ; cnt < updates_per_tick ; cnt ++) {
259
+ if (mobIndex >= mobsToDo .size ()) {
260
+ mobsToDo = null ;
261
+ break ;
262
+ }
263
+ // Get next entity
264
+ LivingEntity le = mobsToDo .get (mobIndex );
265
+ mobIndex ++;
266
+
254
267
int i ;
255
268
256
269
/* See if entity is mob we care about */
@@ -354,10 +367,28 @@ else if(mobs[i].mobid.equals("villager")) {
354
367
}
355
368
}
356
369
else if (mobs [i ].mobid .equals ("vanillahorse" )) { /* Check for rider */
370
+ Horse h = (Horse )le ;
371
+ Variant hv = h .getVariant ();
372
+ switch (hv ) {
373
+ case DONKEY :
374
+ label = "Donkey" ;
375
+ break ;
376
+ case MULE :
377
+ label = "Mule" ;
378
+ break ;
379
+ case UNDEAD_HORSE :
380
+ label = "Undead Horse" ;
381
+ break ;
382
+ case SKELETON_HORSE :
383
+ label = "Skeleton Horse" ;
384
+ break ;
385
+ default :
386
+ break ;
387
+ }
357
388
if (le .getPassenger () != null ) { /* Has passenger? */
358
389
Entity e = le .getPassenger ();
359
390
if (e instanceof Player ) {
360
- label = mobs [ i ]. label + " (" + ((Player )e ).getName () + ")" ;
391
+ label = label + " (" + ((Player )e ).getName () + ")" ;
361
392
}
362
393
}
363
394
}
@@ -381,7 +412,6 @@ else if(mobs[i].mobid.equals("vanillahorse")) { /* Check for rider */
381
412
continue ;
382
413
}
383
414
}
384
-
385
415
/* See if we already have marker */
386
416
double x = Math .round (loc .getX () / res ) * res ;
387
417
double y = Math .round (loc .getY () / res ) * res ;
@@ -394,35 +424,66 @@ else if(inc_coord) {
394
424
label = label + " [" + (int )x + "," + (int )y + "," + (int )z + "]" ;
395
425
}
396
426
if (m == null ) { /* Not found? Need new one */
397
- m = set .createMarker ("mob" +le .getEntityId (), label , w .getName (), x , y , z , mobs [i ].icon , false );
427
+ m = set .createMarker ("mob" +le .getEntityId (), label , curWorld .getName (), x , y , z , mobs [i ].icon , false );
398
428
}
399
429
else { /* Else, update position if needed */
400
- m .setLocation (w .getName (), x , y , z );
430
+ m .setLocation (curWorld .getName (), x , y , z );
401
431
m .setLabel (label );
402
432
m .setMarkerIcon (mobs [i ].icon );
403
433
}
404
434
newmap .put (le .getEntityId (), m ); /* Add to new map */
405
435
}
436
+ getServer ().getScheduler ().scheduleSyncDelayedTask (DynmapMobsPlugin .this , this , 1 );
406
437
}
407
- /* Now, review old map - anything left is gone */
408
- for (Marker oldm : mobicons .values ()) {
409
- oldm .deleteMarker ();
410
- }
411
- /* And replace with new map */
412
- mobicons = newmap ;
413
438
}
414
439
415
- /* Update vehicle population and position */
416
- private void updateVehicles () {
417
- if ((vehicles == null ) || (vehicles .length == 0 ) || (vset == null )) {
418
- return ;
419
- }
440
+ private class VehicleUpdate implements Runnable {
420
441
Map <Integer ,Marker > newmap = new HashMap <Integer ,Marker >(); /* Build new map */
421
-
422
- for (World w : getServer ().getWorlds ()) {
423
- for (Entity le : w .getEntitiesByClasses (org .bukkit .entity .Vehicle .class )) {
424
- int i ;
442
+ ArrayList <World > worldsToDo = null ;
443
+ List <Entity > vehiclesToDo = null ;
444
+ int vehiclesIndex = 0 ;
445
+ World curWorld = null ;
446
+
447
+ public void run () {
448
+ if (stop || (vehicles == null ) || (vehicles .length == 0 ) || (vset == null )) {
449
+ return ;
450
+ }
451
+ // If needed, prime world list
452
+ if (worldsToDo == null ) {
453
+ worldsToDo = new ArrayList <World >(getServer ().getWorlds ());
454
+ }
455
+ while (vehiclesToDo == null ) {
456
+ if (worldsToDo .isEmpty ()) {
457
+ /* Now, review old map - anything left is gone */
458
+ for (Marker oldm : vehicleicons .values ()) {
459
+ oldm .deleteMarker ();
460
+ }
461
+ /* And replace with new map */
462
+ vehicleicons = newmap ;
463
+ // Schedule next run
464
+ getServer ().getScheduler ().scheduleSyncDelayedTask (DynmapMobsPlugin .this , new VehicleUpdate (), vupdperiod );
465
+ return ;
466
+ }
467
+ else {
468
+ curWorld = worldsToDo .remove (0 ); // Get next world
469
+ vehiclesToDo = new ArrayList <Entity >(curWorld .getEntitiesByClasses (org .bukkit .entity .Vehicle .class )); // Get vehicles
470
+ vehiclesIndex = 0 ;
471
+ if ((vehiclesToDo != null ) && vehiclesToDo .isEmpty ()) {
472
+ vehiclesToDo = null ;
473
+ }
474
+ }
475
+ }
476
+ // Process up to limit per tick
477
+ for (int cnt = 0 ; cnt < vupdates_per_tick ; cnt ++) {
478
+ if (vehiclesIndex >= vehiclesToDo .size ()) {
479
+ vehiclesToDo = null ;
480
+ break ;
481
+ }
482
+ // Get next entity
483
+ Entity le = vehiclesToDo .get (vehiclesIndex );
484
+ vehiclesIndex ++;
425
485
486
+ int i ;
426
487
/* See if entity is vehicle we care about */
427
488
String clsid = null ;
428
489
if (gethandle != null ) {
@@ -468,7 +529,7 @@ else if(gethandle != null) {
468
529
label = vehicles [i ].label ;
469
530
}
470
531
Location loc = le .getLocation ();
471
- if (w .isChunkLoaded (loc .getBlockX () >> 4 , loc .getBlockZ () >> 4 ) == false ) {
532
+ if (curWorld .isChunkLoaded (loc .getBlockX () >> 4 , loc .getBlockZ () >> 4 ) == false ) {
472
533
continue ;
473
534
}
474
535
Block blk = null ;
@@ -484,7 +545,6 @@ else if(gethandle != null) {
484
545
continue ;
485
546
}
486
547
}
487
-
488
548
/* See if we already have marker */
489
549
double x = Math .round (loc .getX () / res ) * res ;
490
550
double y = Math .round (loc .getY () / res ) * res ;
@@ -496,22 +556,30 @@ else if(vinc_coord) {
496
556
label = label + " [" + (int )x + "," + (int )y + "," + (int )z + "]" ;
497
557
}
498
558
if (m == null ) { /* Not found? Need new one */
499
- m = vset .createMarker ("vehicle" +le .getEntityId (), label , w .getName (), x , y , z , vehicles [i ].icon , false );
559
+ m = vset .createMarker ("vehicle" +le .getEntityId (), label , curWorld .getName (), x , y , z , vehicles [i ].icon , false );
500
560
}
501
561
else { /* Else, update position if needed */
502
- m .setLocation (w .getName (), x , y , z );
562
+ m .setLocation (curWorld .getName (), x , y , z );
503
563
m .setLabel (label );
504
564
m .setMarkerIcon (vehicles [i ].icon );
505
565
}
506
566
newmap .put (le .getEntityId (), m ); /* Add to new map */
507
567
}
568
+ getServer ().getScheduler ().scheduleSyncDelayedTask (DynmapMobsPlugin .this , this , 1 );
508
569
}
509
- /* Now, review old map - anything left is gone */
510
- for (Marker oldm : vehicleicons .values ()) {
511
- oldm .deleteMarker ();
570
+ }
571
+
572
+ private Map <Integer , Marker > mobicons = new HashMap <Integer , Marker >();
573
+ private Map <Integer , Marker > vehicleicons = new HashMap <Integer , Marker >();
574
+
575
+ private int findNext (int idx , String mobid ) {
576
+ idx ++;
577
+ if ((idx < mobs .length ) && mobs [idx ].mobid .equals (mobid )) {
578
+ return idx ;
579
+ }
580
+ else {
581
+ return mobs .length ;
512
582
}
513
- /* And replace with new map */
514
- vehicleicons = newmap ;
515
583
}
516
584
517
585
private class OurServerListener implements Listener {
@@ -672,6 +740,7 @@ private void activate() {
672
740
double per = cfg .getDouble ("update.period" , 5.0 );
673
741
if (per < 2.0 ) per = 2.0 ;
674
742
updperiod = (long )(per *20.0 );
743
+ updates_per_tick = cfg .getInt ("update.mobs-per-tick" , 20 );
675
744
stop = false ;
676
745
getServer ().getScheduler ().scheduleSyncDelayedTask (this , new MobUpdate (), updperiod );
677
746
info ("Enable layer for mobs" );
@@ -738,6 +807,7 @@ private void activate() {
738
807
double per = cfg .getDouble ("update.vehicleperiod" , 5.0 );
739
808
if (per < 2.0 ) per = 2.0 ;
740
809
vupdperiod = (long )(per *20.0 );
810
+ vupdates_per_tick = cfg .getInt ("update.vehicles-per-tick" , 20 );
741
811
stop = false ;
742
812
getServer ().getScheduler ().scheduleSyncDelayedTask (this , new VehicleUpdate (), vupdperiod / 3 );
743
813
info ("Enable layer for vehicles" );
0 commit comments