Fixes a bunch of warnings and typos
This commit is contained in:
		
							
								
								
									
										61
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								pom.xml
									
									
									
									
									
								
							@@ -12,25 +12,6 @@
 | 
				
			|||||||
    </properties>
 | 
					    </properties>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <build>
 | 
					    <build>
 | 
				
			||||||
        <resources>
 | 
					 | 
				
			||||||
            <resource>
 | 
					 | 
				
			||||||
                <directory>src/main/resources</directory>
 | 
					 | 
				
			||||||
                <filtering>true</filtering>
 | 
					 | 
				
			||||||
                <includes>
 | 
					 | 
				
			||||||
                    <include>*.yml</include>
 | 
					 | 
				
			||||||
                    <include>*.txt</include>
 | 
					 | 
				
			||||||
                </includes>
 | 
					 | 
				
			||||||
            </resource>
 | 
					 | 
				
			||||||
            <resource>
 | 
					 | 
				
			||||||
                <directory>src/main/resources</directory>
 | 
					 | 
				
			||||||
                <filtering>false</filtering>
 | 
					 | 
				
			||||||
                <excludes>
 | 
					 | 
				
			||||||
                    <exclude>*.yml</exclude>
 | 
					 | 
				
			||||||
                    <exclude>*.txt</exclude>
 | 
					 | 
				
			||||||
                </excludes>
 | 
					 | 
				
			||||||
            </resource>
 | 
					 | 
				
			||||||
        </resources>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        <plugins>
 | 
					        <plugins>
 | 
				
			||||||
            <plugin>
 | 
					            <plugin>
 | 
				
			||||||
                <groupId>org.apache.maven.plugins</groupId>
 | 
					                <groupId>org.apache.maven.plugins</groupId>
 | 
				
			||||||
@@ -41,7 +22,43 @@
 | 
				
			|||||||
                    <target>16</target>
 | 
					                    <target>16</target>
 | 
				
			||||||
                </configuration>
 | 
					                </configuration>
 | 
				
			||||||
            </plugin>
 | 
					            </plugin>
 | 
				
			||||||
 | 
					            <plugin>
 | 
				
			||||||
 | 
					                <groupId>org.apache.maven.plugins</groupId>
 | 
				
			||||||
 | 
					                <artifactId>maven-shade-plugin</artifactId>
 | 
				
			||||||
 | 
					                <version>3.3.0</version>
 | 
				
			||||||
 | 
					                <executions>
 | 
				
			||||||
 | 
					                    <execution>
 | 
				
			||||||
 | 
					                        <phase>package</phase>
 | 
				
			||||||
 | 
					                        <goals>
 | 
				
			||||||
 | 
					                            <goal>shade</goal>
 | 
				
			||||||
 | 
					                        </goals>
 | 
				
			||||||
 | 
					                        <configuration>
 | 
				
			||||||
 | 
					                            <createDependencyReducedPom>false</createDependencyReducedPom>
 | 
				
			||||||
 | 
					                            <relocations>
 | 
				
			||||||
 | 
					                                <relocation>
 | 
				
			||||||
 | 
					                                    <pattern>org.jetbrains.annotations</pattern>
 | 
				
			||||||
 | 
					                                    <shadedPattern>net.knarcraft.placeholdersigns.lib.annotations</shadedPattern>
 | 
				
			||||||
 | 
					                                </relocation>
 | 
				
			||||||
 | 
					                            </relocations>
 | 
				
			||||||
 | 
					                            <filters>
 | 
				
			||||||
 | 
					                                <filter>
 | 
				
			||||||
 | 
					                                    <artifact>org.jetbrains:annotations</artifact>
 | 
				
			||||||
 | 
					                                    <includes>
 | 
				
			||||||
 | 
					                                        <include>org/jetbrains/annotations/**</include>
 | 
				
			||||||
 | 
					                                    </includes>
 | 
				
			||||||
 | 
					                                </filter>
 | 
				
			||||||
 | 
					                            </filters>
 | 
				
			||||||
 | 
					                        </configuration>
 | 
				
			||||||
 | 
					                    </execution>
 | 
				
			||||||
 | 
					                </executions>
 | 
				
			||||||
 | 
					            </plugin>
 | 
				
			||||||
        </plugins>
 | 
					        </plugins>
 | 
				
			||||||
 | 
					        <resources>
 | 
				
			||||||
 | 
					            <resource>
 | 
				
			||||||
 | 
					                <directory>src/main/resources</directory>
 | 
				
			||||||
 | 
					                <filtering>true</filtering>
 | 
				
			||||||
 | 
					            </resource>
 | 
				
			||||||
 | 
					        </resources>
 | 
				
			||||||
    </build>
 | 
					    </build>
 | 
				
			||||||
    <repositories>
 | 
					    <repositories>
 | 
				
			||||||
        <repository>
 | 
					        <repository>
 | 
				
			||||||
@@ -79,5 +96,11 @@
 | 
				
			|||||||
            <version>3.3.3</version>
 | 
					            <version>3.3.3</version>
 | 
				
			||||||
            <scope>provided</scope>
 | 
					            <scope>provided</scope>
 | 
				
			||||||
        </dependency>
 | 
					        </dependency>
 | 
				
			||||||
 | 
					        <dependency>
 | 
				
			||||||
 | 
					            <groupId>org.jetbrains</groupId>
 | 
				
			||||||
 | 
					            <artifactId>annotations</artifactId>
 | 
				
			||||||
 | 
					            <version>24.0.1</version>
 | 
				
			||||||
 | 
					            <scope>compile</scope>
 | 
				
			||||||
 | 
					        </dependency>
 | 
				
			||||||
    </dependencies>
 | 
					    </dependencies>
 | 
				
			||||||
</project>
 | 
					</project>
 | 
				
			||||||
@@ -2,50 +2,82 @@ package org.dynmap.factions;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import org.bukkit.configuration.file.FileConfiguration;
 | 
					import org.bukkit.configuration.file.FileConfiguration;
 | 
				
			||||||
import org.dynmap.markers.MarkerIcon;
 | 
					import org.dynmap.markers.MarkerIcon;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AreaStyle {
 | 
					/**
 | 
				
			||||||
 | 
					 * A style usable to mark a faction area
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param strokeColor   <p>The color of the outer stroke</p>
 | 
				
			||||||
 | 
					 * @param strokeOpacity <p>The opacity of the outer stroke</p>
 | 
				
			||||||
 | 
					 * @param strokeWeight  <p>The weight (priority) of the stroke</p>
 | 
				
			||||||
 | 
					 * @param fillColor     <p>The color of the filled-in area</p>
 | 
				
			||||||
 | 
					 * @param fillOpacity   <p>The opacity of the filled-in area</p>
 | 
				
			||||||
 | 
					 * @param homeMarker    <p>The name of the icon to use for marking faction homes</p>
 | 
				
			||||||
 | 
					 * @param homeIcon      <p>The icon to use for marking faction homes</p>
 | 
				
			||||||
 | 
					 * @param boost
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public record AreaStyle(String strokeColor, double strokeOpacity, int strokeWeight, String fillColor,
 | 
				
			||||||
 | 
					                        double fillOpacity, String homeMarker, MarkerIcon homeIcon, boolean boost) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final String strokecolor;
 | 
					    /**
 | 
				
			||||||
    final double strokeopacity;
 | 
					     * Instantiates a new area style
 | 
				
			||||||
    final int strokeweight;
 | 
					     *
 | 
				
			||||||
    final String fillcolor;
 | 
					     * @param dynmapFactionsPlugin <p>An instance of the dynmap factions plugin</p>
 | 
				
			||||||
    final double fillopacity;
 | 
					     * @param cfg                  <p>The configuration to read</p>
 | 
				
			||||||
    final String homemarker;
 | 
					     * @param path                 <p>The path of the area style to load from the config</p>
 | 
				
			||||||
    MarkerIcon homeicon;
 | 
					     * @param def                  <p>The default area style to use for missing values</p>
 | 
				
			||||||
    final boolean boost;
 | 
					     */
 | 
				
			||||||
 | 
					    public AreaStyle(@NotNull DynmapFactionsPlugin dynmapFactionsPlugin, @NotNull FileConfiguration cfg,
 | 
				
			||||||
    AreaStyle(DynmapFactionsPlugin dynmapFactionsPlugin, FileConfiguration cfg, String path, AreaStyle def) {
 | 
					                     @NotNull String path, @NotNull AreaStyle def) {
 | 
				
			||||||
        strokecolor = cfg.getString(path + ".strokeColor", def.strokecolor);
 | 
					        this(cfg.getString(path + ".strokeColor", def.strokeColor),
 | 
				
			||||||
        strokeopacity = cfg.getDouble(path + ".strokeOpacity", def.strokeopacity);
 | 
					                cfg.getDouble(path + ".strokeOpacity", def.strokeOpacity),
 | 
				
			||||||
        strokeweight = cfg.getInt(path + ".strokeWeight", def.strokeweight);
 | 
					                cfg.getInt(path + ".strokeWeight", def.strokeWeight),
 | 
				
			||||||
        fillcolor = cfg.getString(path + ".fillColor", def.fillcolor);
 | 
					                cfg.getString(path + ".fillColor", def.fillColor),
 | 
				
			||||||
        fillopacity = cfg.getDouble(path + ".fillOpacity", def.fillopacity);
 | 
					                cfg.getDouble(path + ".fillOpacity", def.fillOpacity),
 | 
				
			||||||
        homemarker = cfg.getString(path + ".homeicon", def.homemarker);
 | 
					                cfg.getString(path + ".homeIcon", def.homeMarker),
 | 
				
			||||||
        if (homemarker != null) {
 | 
					                getHomeIcon(dynmapFactionsPlugin, cfg.getString(path + ".homeIcon", def.homeMarker)),
 | 
				
			||||||
            homeicon = dynmapFactionsPlugin.markerapi.getMarkerIcon(homemarker);
 | 
					                cfg.getBoolean(path + ".boost", def.boost));
 | 
				
			||||||
            if (homeicon == null) {
 | 
					 | 
				
			||||||
                DynmapFactionsPlugin.severe("Invalid homeicon: " + homemarker);
 | 
					 | 
				
			||||||
                homeicon = dynmapFactionsPlugin.markerapi.getMarkerIcon("blueicon");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        boost = cfg.getBoolean(path + ".boost", def.boost);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    AreaStyle(DynmapFactionsPlugin dynmapFactionsPlugin, FileConfiguration cfg, String path) {
 | 
					    /**
 | 
				
			||||||
        strokecolor = cfg.getString(path + ".strokeColor", "#FF0000");
 | 
					     * Instantiates a new area style
 | 
				
			||||||
        strokeopacity = cfg.getDouble(path + ".strokeOpacity", 0.8);
 | 
					     *
 | 
				
			||||||
        strokeweight = cfg.getInt(path + ".strokeWeight", 3);
 | 
					     * @param dynmapFactionsPlugin <p>An instance of the dynmap factions plugin</p>
 | 
				
			||||||
        fillcolor = cfg.getString(path + ".fillColor", "#FF0000");
 | 
					     * @param cfg                  <p>The configuration to read</p>
 | 
				
			||||||
        fillopacity = cfg.getDouble(path + ".fillOpacity", 0.35);
 | 
					     * @param path                 <p>The path of the area style to load from the config</p>
 | 
				
			||||||
        homemarker = cfg.getString(path + ".homeicon", null);
 | 
					     */
 | 
				
			||||||
        if (homemarker != null) {
 | 
					    public AreaStyle(@NotNull DynmapFactionsPlugin dynmapFactionsPlugin, @NotNull FileConfiguration cfg,
 | 
				
			||||||
            homeicon = dynmapFactionsPlugin.markerapi.getMarkerIcon(homemarker);
 | 
					                     @NotNull String path) {
 | 
				
			||||||
            if (homeicon == null) {
 | 
					        this(cfg.getString(path + ".strokeColor", "#FF0000"),
 | 
				
			||||||
                DynmapFactionsPlugin.severe("Invalid homeicon: " + homemarker);
 | 
					                cfg.getDouble(path + ".strokeOpacity", 0.8),
 | 
				
			||||||
                homeicon = dynmapFactionsPlugin.markerapi.getMarkerIcon("blueicon");
 | 
					                cfg.getInt(path + ".strokeWeight", 3),
 | 
				
			||||||
 | 
					                cfg.getString(path + ".fillColor", "#FF0000"),
 | 
				
			||||||
 | 
					                cfg.getDouble(path + ".fillOpacity", 0.35),
 | 
				
			||||||
 | 
					                cfg.getString(path + ".homeIcon", null),
 | 
				
			||||||
 | 
					                getHomeIcon(dynmapFactionsPlugin, cfg.getString(path + ".homeIcon", null)),
 | 
				
			||||||
 | 
					                cfg.getBoolean(path + ".boost", false));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Gets the icon to use for marking a faction home
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param dynmapFactionsPlugin <p>An instance of the dynmap factions plugin</p>
 | 
				
			||||||
 | 
					     * @param homeMarker           <p>The name of the marker to get</p>
 | 
				
			||||||
 | 
					     * @return <p>The marker, or null if it does not exist</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @Nullable
 | 
				
			||||||
 | 
					    private static MarkerIcon getHomeIcon(@NotNull DynmapFactionsPlugin dynmapFactionsPlugin,
 | 
				
			||||||
 | 
					                                          @Nullable String homeMarker) {
 | 
				
			||||||
 | 
					        MarkerIcon homeIcon = null;
 | 
				
			||||||
 | 
					        if (homeMarker != null) {
 | 
				
			||||||
 | 
					            homeIcon = dynmapFactionsPlugin.markerAPI.getMarkerIcon(homeMarker);
 | 
				
			||||||
 | 
					            if (homeIcon == null) {
 | 
				
			||||||
 | 
					                DynmapFactionsPlugin.severe("Invalid home icon: " + homeMarker);
 | 
				
			||||||
 | 
					                homeIcon = dynmapFactionsPlugin.markerAPI.getMarkerIcon("blueicon");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        boost = cfg.getBoolean(path + ".boost", false);
 | 
					        return homeIcon;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,28 @@
 | 
				
			|||||||
package org.dynmap.factions;
 | 
					package org.dynmap.factions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A representation of the directions that make sense in a Dynmap context
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
public enum Direction {
 | 
					public enum Direction {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    XPLUS,
 | 
					    /**
 | 
				
			||||||
    ZPLUS,
 | 
					     * The positive X direction
 | 
				
			||||||
    XMINUS,
 | 
					     */
 | 
				
			||||||
    ZMINUS
 | 
					    POSITIVE_X,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The positive Z direction
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    POSITIVE_Z,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The negative x direction
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    NEGATIVE_X,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The negative z direction
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    NEGATIVE_Z
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,16 +14,18 @@ import org.bukkit.event.EventPriority;
 | 
				
			|||||||
import org.bukkit.event.Listener;
 | 
					import org.bukkit.event.Listener;
 | 
				
			||||||
import org.bukkit.event.server.PluginEnableEvent;
 | 
					import org.bukkit.event.server.PluginEnableEvent;
 | 
				
			||||||
import org.bukkit.plugin.Plugin;
 | 
					import org.bukkit.plugin.Plugin;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class DynmapFactionsListener implements Listener {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OurServerListener implements Listener {
 | 
					 | 
				
			||||||
    private final DynmapFactionsPlugin dynmapFactionsPlugin;
 | 
					    private final DynmapFactionsPlugin dynmapFactionsPlugin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public OurServerListener(DynmapFactionsPlugin dynmapFactionsPlugin) {
 | 
					    public DynmapFactionsListener(DynmapFactionsPlugin dynmapFactionsPlugin) {
 | 
				
			||||||
        this.dynmapFactionsPlugin = dynmapFactionsPlugin;
 | 
					        this.dynmapFactionsPlugin = dynmapFactionsPlugin;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler
 | 
					    @EventHandler
 | 
				
			||||||
    public void onPluginEnable(PluginEnableEvent event) {
 | 
					    public void onPluginEnable(@NotNull PluginEnableEvent event) {
 | 
				
			||||||
        Plugin p = event.getPlugin();
 | 
					        Plugin p = event.getPlugin();
 | 
				
			||||||
        String name = p.getDescription().getName();
 | 
					        String name = p.getDescription().getName();
 | 
				
			||||||
        if (name.equals("dynmap") || name.equals("Factions")) {
 | 
					        if (name.equals("dynmap") || name.equals("Factions")) {
 | 
				
			||||||
@@ -34,33 +36,33 @@ class OurServerListener implements Listener {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler(priority = EventPriority.MONITOR)
 | 
					    @EventHandler(priority = EventPriority.MONITOR)
 | 
				
			||||||
    public void onFPlayerJoin(EventFactionsMembershipChange event) {
 | 
					    public void onFPlayerJoin(@NotNull EventFactionsMembershipChange event) {
 | 
				
			||||||
        if (event.isCancelled()) {
 | 
					        if (event.isCancelled()) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (dynmapFactionsPlugin.playersets) {
 | 
					        if (dynmapFactionsPlugin.playerSets) {
 | 
				
			||||||
            Faction f = event.getNewFaction();
 | 
					            Faction f = event.getNewFaction();
 | 
				
			||||||
            dynmapFactionsPlugin.requestUpdatePlayerSet(f.getId());
 | 
					            dynmapFactionsPlugin.requestUpdatePlayerSet(f.getId());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler(priority = EventPriority.MONITOR)
 | 
					    @EventHandler(priority = EventPriority.MONITOR)
 | 
				
			||||||
    public void onFactionCreate(EventFactionsCreate event) {
 | 
					    public void onFactionCreate(@NotNull EventFactionsCreate event) {
 | 
				
			||||||
        if (event.isCancelled()) {
 | 
					        if (event.isCancelled()) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (dynmapFactionsPlugin.playersets) {
 | 
					        if (dynmapFactionsPlugin.playerSets) {
 | 
				
			||||||
            dynmapFactionsPlugin.requestUpdatePlayerSet(event.getFactionId());
 | 
					            dynmapFactionsPlugin.requestUpdatePlayerSet(event.getFactionId());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        requestUpdateFactions();
 | 
					        requestUpdateFactions();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler(priority = EventPriority.MONITOR)
 | 
					    @EventHandler(priority = EventPriority.MONITOR)
 | 
				
			||||||
    public void onFactionDisband(EventFactionsDisband event) {
 | 
					    public void onFactionDisband(@NotNull EventFactionsDisband event) {
 | 
				
			||||||
        if (event.isCancelled()) {
 | 
					        if (event.isCancelled()) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (dynmapFactionsPlugin.playersets) {
 | 
					        if (dynmapFactionsPlugin.playerSets) {
 | 
				
			||||||
            Faction f = event.getFaction();
 | 
					            Faction f = event.getFaction();
 | 
				
			||||||
            dynmapFactionsPlugin.requestUpdatePlayerSet(f.getId());
 | 
					            dynmapFactionsPlugin.requestUpdatePlayerSet(f.getId());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -68,7 +70,7 @@ class OurServerListener implements Listener {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler(priority = EventPriority.MONITOR)
 | 
					    @EventHandler(priority = EventPriority.MONITOR)
 | 
				
			||||||
    public void onFactionRename(EventFactionsNameChange event) {
 | 
					    public void onFactionRename(@NotNull EventFactionsNameChange event) {
 | 
				
			||||||
        if (event.isCancelled()) {
 | 
					        if (event.isCancelled()) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -76,7 +78,7 @@ class OurServerListener implements Listener {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler(priority = EventPriority.MONITOR)
 | 
					    @EventHandler(priority = EventPriority.MONITOR)
 | 
				
			||||||
    public void onFactionRename(EventFactionsWarpAdd event) {
 | 
					    public void onFactionRename(@NotNull EventFactionsWarpAdd event) {
 | 
				
			||||||
        if (event.isCancelled()) {
 | 
					        if (event.isCancelled()) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -84,7 +86,7 @@ class OurServerListener implements Listener {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler(priority = EventPriority.MONITOR)
 | 
					    @EventHandler(priority = EventPriority.MONITOR)
 | 
				
			||||||
    public void onFactionRename(EventFactionsWarpRemove event) {
 | 
					    public void onFactionRename(@NotNull EventFactionsWarpRemove event) {
 | 
				
			||||||
        if (event.isCancelled()) {
 | 
					        if (event.isCancelled()) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -92,7 +94,7 @@ class OurServerListener implements Listener {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler(priority = EventPriority.MONITOR)
 | 
					    @EventHandler(priority = EventPriority.MONITOR)
 | 
				
			||||||
    public void onFactionRename(EventFactionsChunksChange event) {
 | 
					    public void onFactionRename(@NotNull EventFactionsChunksChange event) {
 | 
				
			||||||
        if (event.isCancelled()) {
 | 
					        if (event.isCancelled()) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -101,10 +103,11 @@ class OurServerListener implements Listener {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private void requestUpdateFactions() {
 | 
					    private void requestUpdateFactions() {
 | 
				
			||||||
        if (DynmapFactionsPlugin.instance.pending == null) {
 | 
					        if (DynmapFactionsPlugin.instance.pending == null) {
 | 
				
			||||||
            FactionsUpdate upd = new FactionsUpdate(DynmapFactionsPlugin.instance);
 | 
					            FactionsUpdate factionsUpdate = new FactionsUpdate(DynmapFactionsPlugin.instance,
 | 
				
			||||||
            upd.runonce = true;
 | 
					                    DynmapFactionsPlugin.instance.getConfig());
 | 
				
			||||||
            DynmapFactionsPlugin.instance.pending = upd;
 | 
					            factionsUpdate.runonce = true;
 | 
				
			||||||
            Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(DynmapFactionsPlugin.instance, upd, 20);
 | 
					            DynmapFactionsPlugin.instance.pending = factionsUpdate;
 | 
				
			||||||
 | 
					            Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(DynmapFactionsPlugin.instance, factionsUpdate, 20);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1,16 +1,8 @@
 | 
				
			|||||||
package org.dynmap.factions;
 | 
					package org.dynmap.factions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.massivecraft.factions.Factions;
 | 
					 | 
				
			||||||
import com.massivecraft.factions.entity.BoardColl;
 | 
					 | 
				
			||||||
import com.massivecraft.factions.entity.Faction;
 | 
					import com.massivecraft.factions.entity.Faction;
 | 
				
			||||||
import com.massivecraft.factions.entity.FactionColl;
 | 
					import com.massivecraft.factions.entity.FactionColl;
 | 
				
			||||||
import com.massivecraft.factions.entity.MFlag;
 | 
					 | 
				
			||||||
import com.massivecraft.factions.entity.MFlagColl;
 | 
					 | 
				
			||||||
import com.massivecraft.factions.entity.MPlayer;
 | 
					import com.massivecraft.factions.entity.MPlayer;
 | 
				
			||||||
import com.massivecraft.factions.entity.Warp;
 | 
					 | 
				
			||||||
import com.massivecraft.massivecore.ps.PS;
 | 
					 | 
				
			||||||
import com.massivecraft.massivecore.store.EntityInternalMap;
 | 
					 | 
				
			||||||
import org.bukkit.ChatColor;
 | 
					 | 
				
			||||||
import org.bukkit.configuration.ConfigurationSection;
 | 
					import org.bukkit.configuration.ConfigurationSection;
 | 
				
			||||||
import org.bukkit.configuration.file.FileConfiguration;
 | 
					import org.bukkit.configuration.file.FileConfiguration;
 | 
				
			||||||
import org.bukkit.plugin.Plugin;
 | 
					import org.bukkit.plugin.Plugin;
 | 
				
			||||||
@@ -20,17 +12,12 @@ import org.dynmap.DynmapAPI;
 | 
				
			|||||||
import org.dynmap.markers.AreaMarker;
 | 
					import org.dynmap.markers.AreaMarker;
 | 
				
			||||||
import org.dynmap.markers.Marker;
 | 
					import org.dynmap.markers.Marker;
 | 
				
			||||||
import org.dynmap.markers.MarkerAPI;
 | 
					import org.dynmap.markers.MarkerAPI;
 | 
				
			||||||
import org.dynmap.markers.MarkerIcon;
 | 
					 | 
				
			||||||
import org.dynmap.markers.MarkerSet;
 | 
					import org.dynmap.markers.MarkerSet;
 | 
				
			||||||
import org.dynmap.markers.PlayerSet;
 | 
					import org.dynmap.markers.PlayerSet;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.IOException;
 | 
					 | 
				
			||||||
import java.util.ArrayDeque;
 | 
					 | 
				
			||||||
import java.util.ArrayList;
 | 
					 | 
				
			||||||
import java.util.Collection;
 | 
					 | 
				
			||||||
import java.util.HashMap;
 | 
					import java.util.HashMap;
 | 
				
			||||||
import java.util.HashSet;
 | 
					import java.util.HashSet;
 | 
				
			||||||
import java.util.LinkedList;
 | 
					 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
import java.util.Set;
 | 
					import java.util.Set;
 | 
				
			||||||
@@ -40,33 +27,36 @@ import java.util.logging.Logger;
 | 
				
			|||||||
public class DynmapFactionsPlugin extends JavaPlugin {
 | 
					public class DynmapFactionsPlugin extends JavaPlugin {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static Logger log;
 | 
					    private static Logger log;
 | 
				
			||||||
    private static final String DEF_INFOWINDOW = "<div class=\"infowindow\"><span style=\"font-size:120%;\">%regionname%</span><br />Flags<br /><span style=\"font-weight:bold;\">%flags%</span></div>";
 | 
					 | 
				
			||||||
    Plugin dynmap;
 | 
					    Plugin dynmap;
 | 
				
			||||||
    DynmapAPI api;
 | 
					    DynmapAPI api;
 | 
				
			||||||
    MarkerAPI markerapi;
 | 
					    MarkerAPI markerAPI;
 | 
				
			||||||
    Plugin factions;
 | 
					    Plugin factions;
 | 
				
			||||||
    Factions factapi;
 | 
					    boolean playerSets;
 | 
				
			||||||
    boolean playersets;
 | 
					    Map<String, AreaMarker> factionAreaMarkers = new HashMap<>();
 | 
				
			||||||
 | 
					    Map<String, Marker> factionMarkers = new HashMap<>();
 | 
				
			||||||
    int blocksize;
 | 
					    AreaStyle defaultStyle;
 | 
				
			||||||
 | 
					    Map<String, AreaStyle> customStyle;
 | 
				
			||||||
 | 
					    int blockSize;
 | 
				
			||||||
    MarkerSet set;
 | 
					    MarkerSet set;
 | 
				
			||||||
    long updperiod;
 | 
					    long updatePeriod;
 | 
				
			||||||
    boolean use3d;
 | 
					
 | 
				
			||||||
    String infowindow;
 | 
					 | 
				
			||||||
    AreaStyle defstyle;
 | 
					 | 
				
			||||||
    Map<String, AreaStyle> cusstyle;
 | 
					 | 
				
			||||||
    Set<String> visible;
 | 
					    Set<String> visible;
 | 
				
			||||||
    Set<String> hidden;
 | 
					    Set<String> hidden;
 | 
				
			||||||
    boolean stop;
 | 
					    boolean stop;
 | 
				
			||||||
    static DynmapFactionsPlugin instance;
 | 
					    static DynmapFactionsPlugin instance;
 | 
				
			||||||
 | 
					    private boolean reload = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void onLoad() {
 | 
					    public void onLoad() {
 | 
				
			||||||
        log = this.getLogger();
 | 
					        log = this.getLogger();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static void info(String msg) {
 | 
					    /**
 | 
				
			||||||
 | 
					     * Logs an info message
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param msg <p>The message to log</p>
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static void info(@NotNull String msg) {
 | 
				
			||||||
        log.log(Level.INFO, msg);
 | 
					        log.log(Level.INFO, msg);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -74,391 +64,47 @@ public class DynmapFactionsPlugin extends JavaPlugin {
 | 
				
			|||||||
        log.log(Level.SEVERE, msg);
 | 
					        log.log(Level.SEVERE, msg);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void requestUpdatePlayerSet(String factid) {
 | 
					    void requestUpdatePlayerSet(String factionId) {
 | 
				
			||||||
        if (playersets) {
 | 
					        if (playerSets) {
 | 
				
			||||||
            getServer().getScheduler().scheduleSyncDelayedTask(this, new PlayerSetUpdate(this, factid));
 | 
					            getServer().getScheduler().scheduleSyncDelayedTask(this, new PlayerSetUpdate(this, factionId));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    FactionsUpdate pending = null;
 | 
					    FactionsUpdate pending = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void updatePlayerSet(String factid) {
 | 
					    void updatePlayerSet(String factionId) {
 | 
				
			||||||
        /* If Wilderness or other unassociated factions (guid-style ID), skip */
 | 
					        /* If Wilderness or other unassociated factions (guid-style ID), skip */
 | 
				
			||||||
        if (factid.indexOf('-') >= 0) {
 | 
					        if (factionId.indexOf('-') >= 0) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Set<String> plids = new HashSet<>();
 | 
					        Set<String> playerIds = new HashSet<>();
 | 
				
			||||||
        FactionColl fc = FactionColl.get();
 | 
					        FactionColl fc = FactionColl.get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Faction f = fc.getByName(factid);    /* Get faction */
 | 
					        Faction f = fc.getByName(factionId);    /* Get faction */
 | 
				
			||||||
        if (f != null) {
 | 
					        if (f != null) {
 | 
				
			||||||
            List<MPlayer> ps = f.getMPlayers();
 | 
					            List<MPlayer> ps = f.getMPlayers();
 | 
				
			||||||
            for (MPlayer fp : ps) {
 | 
					            for (MPlayer fp : ps) {
 | 
				
			||||||
                plids.add(fp.getId());
 | 
					                playerIds.add(fp.getId());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            factid = f.getId();
 | 
					            factionId = f.getId();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        String setid = "factions." + factid;
 | 
					        String setId = "factions." + factionId;
 | 
				
			||||||
        PlayerSet set = markerapi.getPlayerSet(setid);  /* See if set exists */
 | 
					        PlayerSet set = markerAPI.getPlayerSet(setId);  /* See if set exists */
 | 
				
			||||||
        if ((set == null) && (f != null)) {
 | 
					        if ((set == null) && (f != null)) {
 | 
				
			||||||
            set = markerapi.createPlayerSet(setid, true, plids, false);
 | 
					            set = markerAPI.createPlayerSet(setId, true, playerIds, false);
 | 
				
			||||||
            info("Added player visibility set '" + setid + "' for faction " + factid);
 | 
					            info("Added player visibility set '" + setId + "' for faction " + factionId);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (f != null) {
 | 
					        if (f != null) {
 | 
				
			||||||
            set.setPlayers(plids);
 | 
					            set.setPlayers(playerIds);
 | 
				
			||||||
        } else if (set != null) {
 | 
					        } else if (set != null) {
 | 
				
			||||||
            set.deleteSet();
 | 
					            set.deleteSet();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private Map<String, AreaMarker> resareas = new HashMap<>();
 | 
					 | 
				
			||||||
    private Map<String, Marker> resmark = new HashMap<>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private String formatInfoWindow(Faction fact) {
 | 
					 | 
				
			||||||
        String v = "<div class=\"regioninfo\">" + infowindow + "</div>";
 | 
					 | 
				
			||||||
        v = v.replace("%regionname%", ChatColor.stripColor(fact.getName()));
 | 
					 | 
				
			||||||
        v = v.replace("%description%", ChatColor.stripColor(fact.getDescription()));
 | 
					 | 
				
			||||||
        MPlayer adm = fact.getLeader();
 | 
					 | 
				
			||||||
        v = v.replace("%playerowners%", (adm != null) ? adm.getName() : "");
 | 
					 | 
				
			||||||
        StringBuilder res = new StringBuilder();
 | 
					 | 
				
			||||||
        for (MPlayer r : fact.getMPlayers()) {
 | 
					 | 
				
			||||||
            if (!res.isEmpty()) {
 | 
					 | 
				
			||||||
                res.append(", ");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            res.append(r.getName());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        v = v.replace("%playermembers%", res.toString());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        v = v.replace("%nation%", ChatColor.stripColor(fact.getName()));
 | 
					 | 
				
			||||||
        /* Build flags */
 | 
					 | 
				
			||||||
        StringBuilder flgs = new StringBuilder();
 | 
					 | 
				
			||||||
        for (MFlag ff : MFlagColl.get().getAll()) {
 | 
					 | 
				
			||||||
            flgs.append("<br/>").append(ff.getName()).append(": ").append(fact.getFlag(ff));
 | 
					 | 
				
			||||||
            v = v.replace("%flag." + ff.getName() + "%", fact.getFlag(ff) ? "true" : "false");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        v = v.replace("%flags%", flgs.toString());
 | 
					 | 
				
			||||||
        return v;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private boolean isVisible(String id, String worldname) {
 | 
					 | 
				
			||||||
        if ((visible != null) && (!visible.isEmpty())) {
 | 
					 | 
				
			||||||
            if ((!visible.contains(id)) && (!visible.contains("world:" + worldname))) {
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if ((hidden != null) && (!hidden.isEmpty())) {
 | 
					 | 
				
			||||||
            return !hidden.contains(id) && !hidden.contains("world:" + worldname);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private void addStyle(String resid, AreaMarker m) {
 | 
					 | 
				
			||||||
        AreaStyle as = cusstyle.get(resid);
 | 
					 | 
				
			||||||
        if (as == null) {
 | 
					 | 
				
			||||||
            as = defstyle;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        int sc = 0xFF0000;
 | 
					 | 
				
			||||||
        int fc = 0xFF0000;
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            sc = Integer.parseInt(as.strokecolor.substring(1), 16);
 | 
					 | 
				
			||||||
            fc = Integer.parseInt(as.fillcolor.substring(1), 16);
 | 
					 | 
				
			||||||
        } catch (NumberFormatException ignored) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        m.setLineStyle(as.strokeweight, as.strokeopacity, sc);
 | 
					 | 
				
			||||||
        m.setFillStyle(as.fillopacity, fc);
 | 
					 | 
				
			||||||
        m.setBoostFlag(as.boost);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private MarkerIcon getMarkerIcon(String factname, Faction fact) {
 | 
					 | 
				
			||||||
        AreaStyle as = cusstyle.get(factname);
 | 
					 | 
				
			||||||
        if (as == null) {
 | 
					 | 
				
			||||||
            as = defstyle;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return as.homeicon;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Find all contiguous blocks, set in target and clear in source
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private int floodFillTarget(TileFlags src, TileFlags dest, int x, int y) {
 | 
					 | 
				
			||||||
        int cnt = 0;
 | 
					 | 
				
			||||||
        ArrayDeque<int[]> stack = new ArrayDeque<>();
 | 
					 | 
				
			||||||
        stack.push(new int[]{x, y});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        while (!stack.isEmpty()) {
 | 
					 | 
				
			||||||
            int[] nxt = stack.pop();
 | 
					 | 
				
			||||||
            x = nxt[0];
 | 
					 | 
				
			||||||
            y = nxt[1];
 | 
					 | 
				
			||||||
            if (src.getFlag(x, y)) { /* Set in src */
 | 
					 | 
				
			||||||
                src.setFlag(x, y, false);   /* Clear source */
 | 
					 | 
				
			||||||
                dest.setFlag(x, y, true);   /* Set in destination */
 | 
					 | 
				
			||||||
                cnt++;
 | 
					 | 
				
			||||||
                if (src.getFlag(x + 1, y)) {
 | 
					 | 
				
			||||||
                    stack.push(new int[]{x + 1, y});
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                if (src.getFlag(x - 1, y)) {
 | 
					 | 
				
			||||||
                    stack.push(new int[]{x - 1, y});
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                if (src.getFlag(x, y + 1)) {
 | 
					 | 
				
			||||||
                    stack.push(new int[]{x, y + 1});
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                if (src.getFlag(x, y - 1)) {
 | 
					 | 
				
			||||||
                    stack.push(new int[]{x, y - 1});
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return cnt;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Handle specific faction on specific world */
 | 
					 | 
				
			||||||
    private void handleFactionOnWorld(String factname, Faction fact, String world, LinkedList<FactionBlock> blocks, Map<String, AreaMarker> newmap, Map<String, Marker> newmark) {
 | 
					 | 
				
			||||||
        double[] x;
 | 
					 | 
				
			||||||
        double[] z;
 | 
					 | 
				
			||||||
        int poly_index = 0; /* Index of polygon for given faction */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* Build popup */
 | 
					 | 
				
			||||||
        String desc = formatInfoWindow(fact);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* Handle areas */
 | 
					 | 
				
			||||||
        if (isVisible(factname, world)) {
 | 
					 | 
				
			||||||
            if (blocks.isEmpty()) {
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            LinkedList<FactionBlock> nodevals = new LinkedList<>();
 | 
					 | 
				
			||||||
            TileFlags curblks = new TileFlags();
 | 
					 | 
				
			||||||
            /* Loop through blocks: set flags on blockmaps */
 | 
					 | 
				
			||||||
            for (FactionBlock b : blocks) {
 | 
					 | 
				
			||||||
                curblks.setFlag(b.x(), b.z(), true); /* Set flag for block */
 | 
					 | 
				
			||||||
                nodevals.addLast(b);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            /* Loop through until we don't find more areas */
 | 
					 | 
				
			||||||
            while (nodevals != null) {
 | 
					 | 
				
			||||||
                LinkedList<FactionBlock> ournodes = null;
 | 
					 | 
				
			||||||
                LinkedList<FactionBlock> newlist = null;
 | 
					 | 
				
			||||||
                TileFlags ourblks = null;
 | 
					 | 
				
			||||||
                int minx = Integer.MAX_VALUE;
 | 
					 | 
				
			||||||
                int minz = Integer.MAX_VALUE;
 | 
					 | 
				
			||||||
                for (FactionBlock node : nodevals) {
 | 
					 | 
				
			||||||
                    int nodex = node.x();
 | 
					 | 
				
			||||||
                    int nodez = node.z();
 | 
					 | 
				
			||||||
                    /* If we need to start shape, and this block is not part of one yet */
 | 
					 | 
				
			||||||
                    if ((ourblks == null) && curblks.getFlag(nodex, nodez)) {
 | 
					 | 
				
			||||||
                        ourblks = new TileFlags();  /* Create map for shape */
 | 
					 | 
				
			||||||
                        ournodes = new LinkedList<>();
 | 
					 | 
				
			||||||
                        floodFillTarget(curblks, ourblks, nodex, nodez);   /* Copy shape */
 | 
					 | 
				
			||||||
                        ournodes.add(node); /* Add it to our node list */
 | 
					 | 
				
			||||||
                        minx = nodex;
 | 
					 | 
				
			||||||
                        minz = nodez;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    /* If shape found, and we're in it, add to our node list */
 | 
					 | 
				
			||||||
                    else if ((ourblks != null) && ourblks.getFlag(nodex, nodez)) {
 | 
					 | 
				
			||||||
                        ournodes.add(node);
 | 
					 | 
				
			||||||
                        if (nodex < minx) {
 | 
					 | 
				
			||||||
                            minx = nodex;
 | 
					 | 
				
			||||||
                            minz = nodez;
 | 
					 | 
				
			||||||
                        } else if ((nodex == minx) && (nodez < minz)) {
 | 
					 | 
				
			||||||
                            minz = nodez;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    } else {  /* Else, keep it in the list for the next polygon */
 | 
					 | 
				
			||||||
                        if (newlist == null) {
 | 
					 | 
				
			||||||
                            newlist = new LinkedList<>();
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        newlist.add(node);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                nodevals = newlist; /* Replace list (null if no more to process) */
 | 
					 | 
				
			||||||
                if (ourblks != null) {
 | 
					 | 
				
			||||||
                    /* Trace outline of blocks - start from minx, minz going to x+ */
 | 
					 | 
				
			||||||
                    int cur_x = minx;
 | 
					 | 
				
			||||||
                    int cur_z = minz;
 | 
					 | 
				
			||||||
                    Direction dir = Direction.XPLUS;
 | 
					 | 
				
			||||||
                    ArrayList<int[]> linelist = new ArrayList<>();
 | 
					 | 
				
			||||||
                    linelist.add(new int[]{minx, minz}); // Add start point
 | 
					 | 
				
			||||||
                    while ((cur_x != minx) || (cur_z != minz) || (dir != Direction.ZMINUS)) {
 | 
					 | 
				
			||||||
                        switch (dir) {
 | 
					 | 
				
			||||||
                            case XPLUS: /* Segment in X+ direction */
 | 
					 | 
				
			||||||
                                if (!ourblks.getFlag(cur_x + 1, cur_z)) { /* Right turn? */
 | 
					 | 
				
			||||||
                                    linelist.add(new int[]{cur_x + 1, cur_z}); /* Finish line */
 | 
					 | 
				
			||||||
                                    dir = Direction.ZPLUS;  /* Change direction */
 | 
					 | 
				
			||||||
                                } else if (!ourblks.getFlag(cur_x + 1, cur_z - 1)) {  /* Straight? */
 | 
					 | 
				
			||||||
                                    cur_x++;
 | 
					 | 
				
			||||||
                                } else {  /* Left turn */
 | 
					 | 
				
			||||||
                                    linelist.add(new int[]{cur_x + 1, cur_z}); /* Finish line */
 | 
					 | 
				
			||||||
                                    dir = Direction.ZMINUS;
 | 
					 | 
				
			||||||
                                    cur_x++;
 | 
					 | 
				
			||||||
                                    cur_z--;
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                                break;
 | 
					 | 
				
			||||||
                            case ZPLUS: /* Segment in Z+ direction */
 | 
					 | 
				
			||||||
                                if (!ourblks.getFlag(cur_x, cur_z + 1)) { /* Right turn? */
 | 
					 | 
				
			||||||
                                    linelist.add(new int[]{cur_x + 1, cur_z + 1}); /* Finish line */
 | 
					 | 
				
			||||||
                                    dir = Direction.XMINUS;  /* Change direction */
 | 
					 | 
				
			||||||
                                } else if (!ourblks.getFlag(cur_x + 1, cur_z + 1)) {  /* Straight? */
 | 
					 | 
				
			||||||
                                    cur_z++;
 | 
					 | 
				
			||||||
                                } else {  /* Left turn */
 | 
					 | 
				
			||||||
                                    linelist.add(new int[]{cur_x + 1, cur_z + 1}); /* Finish line */
 | 
					 | 
				
			||||||
                                    dir = Direction.XPLUS;
 | 
					 | 
				
			||||||
                                    cur_x++;
 | 
					 | 
				
			||||||
                                    cur_z++;
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                                break;
 | 
					 | 
				
			||||||
                            case XMINUS: /* Segment in X- direction */
 | 
					 | 
				
			||||||
                                if (!ourblks.getFlag(cur_x - 1, cur_z)) { /* Right turn? */
 | 
					 | 
				
			||||||
                                    linelist.add(new int[]{cur_x, cur_z + 1}); /* Finish line */
 | 
					 | 
				
			||||||
                                    dir = Direction.ZMINUS;  /* Change direction */
 | 
					 | 
				
			||||||
                                } else if (!ourblks.getFlag(cur_x - 1, cur_z + 1)) {  /* Straight? */
 | 
					 | 
				
			||||||
                                    cur_x--;
 | 
					 | 
				
			||||||
                                } else {  /* Left turn */
 | 
					 | 
				
			||||||
                                    linelist.add(new int[]{cur_x, cur_z + 1}); /* Finish line */
 | 
					 | 
				
			||||||
                                    dir = Direction.ZPLUS;
 | 
					 | 
				
			||||||
                                    cur_x--;
 | 
					 | 
				
			||||||
                                    cur_z++;
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                                break;
 | 
					 | 
				
			||||||
                            case ZMINUS: /* Segment in Z- direction */
 | 
					 | 
				
			||||||
                                if (!ourblks.getFlag(cur_x, cur_z - 1)) { /* Right turn? */
 | 
					 | 
				
			||||||
                                    linelist.add(new int[]{cur_x, cur_z}); /* Finish line */
 | 
					 | 
				
			||||||
                                    dir = Direction.XPLUS;  /* Change direction */
 | 
					 | 
				
			||||||
                                } else if (!ourblks.getFlag(cur_x - 1, cur_z - 1)) {  /* Straight? */
 | 
					 | 
				
			||||||
                                    cur_z--;
 | 
					 | 
				
			||||||
                                } else {  /* Left turn */
 | 
					 | 
				
			||||||
                                    linelist.add(new int[]{cur_x, cur_z}); /* Finish line */
 | 
					 | 
				
			||||||
                                    dir = Direction.XMINUS;
 | 
					 | 
				
			||||||
                                    cur_x--;
 | 
					 | 
				
			||||||
                                    cur_z--;
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                                break;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    /* Build information for specific area */
 | 
					 | 
				
			||||||
                    String polyid = factname + "__" + world + "__" + poly_index;
 | 
					 | 
				
			||||||
                    int sz = linelist.size();
 | 
					 | 
				
			||||||
                    x = new double[sz];
 | 
					 | 
				
			||||||
                    z = new double[sz];
 | 
					 | 
				
			||||||
                    for (int i = 0; i < sz; i++) {
 | 
					 | 
				
			||||||
                        int[] line = linelist.get(i);
 | 
					 | 
				
			||||||
                        x[i] = (double) line[0] * (double) blocksize;
 | 
					 | 
				
			||||||
                        z[i] = (double) line[1] * (double) blocksize;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    /* Find existing one */
 | 
					 | 
				
			||||||
                    AreaMarker m = resareas.remove(polyid); /* Existing area? */
 | 
					 | 
				
			||||||
                    if (m == null) {
 | 
					 | 
				
			||||||
                        m = set.createAreaMarker(polyid, factname, false, world, x, z, false);
 | 
					 | 
				
			||||||
                        if (m == null) {
 | 
					 | 
				
			||||||
                            info("error adding area marker " + polyid);
 | 
					 | 
				
			||||||
                            return;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        m.setCornerLocations(x, z); /* Replace corner locations */
 | 
					 | 
				
			||||||
                        m.setLabel(factname);   /* Update label */
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    m.setDescription(desc); /* Set popup */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    /* Set line and fill properties */
 | 
					 | 
				
			||||||
                    addStyle(factname, m);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    /* Add to map */
 | 
					 | 
				
			||||||
                    newmap.put(polyid, m);
 | 
					 | 
				
			||||||
                    poly_index++;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Update Factions information */
 | 
					 | 
				
			||||||
    void updateFactions() {
 | 
					 | 
				
			||||||
        Map<String, AreaMarker> newmap = new HashMap<>(); /* Build new map */
 | 
					 | 
				
			||||||
        Map<String, Marker> newmark = new HashMap<>(); /* Build new map */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* Parse into faction centric mapping, split by world */
 | 
					 | 
				
			||||||
        Map<String, FactionBlocks> blocks_by_faction = new HashMap<>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        FactionColl fc = FactionColl.get();
 | 
					 | 
				
			||||||
        Collection<Faction> facts = fc.getAll();
 | 
					 | 
				
			||||||
        for (Faction fact : facts) {
 | 
					 | 
				
			||||||
            Set<PS> chunks = BoardColl.get().getChunks(fact);
 | 
					 | 
				
			||||||
            String fid = fc.getUniverse() + "_" + fact.getId();
 | 
					 | 
				
			||||||
            FactionBlocks factblocks = blocks_by_faction.get(fid); /* Look up faction */
 | 
					 | 
				
			||||||
            if (factblocks == null) {    /* Create faction block if first time */
 | 
					 | 
				
			||||||
                factblocks = new FactionBlocks();
 | 
					 | 
				
			||||||
                blocks_by_faction.put(fid, factblocks);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            for (PS cc : chunks) {
 | 
					 | 
				
			||||||
                String world = cc.getWorld();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                /* Get block set for given world */
 | 
					 | 
				
			||||||
                LinkedList<FactionBlock> blocks = factblocks.blocks.computeIfAbsent(world, k -> new LinkedList<>());
 | 
					 | 
				
			||||||
                FactionBlock fb = new FactionBlock(cc.getChunkX(), cc.getChunkZ());
 | 
					 | 
				
			||||||
                blocks.add(fb); /* Add to list */
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        /* Loop through factions */
 | 
					 | 
				
			||||||
        for (Faction fact : facts) {
 | 
					 | 
				
			||||||
            String factname = ChatColor.stripColor(fact.getName());
 | 
					 | 
				
			||||||
            String fid = fc.getUniverse() + "_" + fact.getId();
 | 
					 | 
				
			||||||
            FactionBlocks factblocks = blocks_by_faction.get(fid); /* Look up faction */
 | 
					 | 
				
			||||||
            if (factblocks == null) {
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /* Loop through each world that faction has blocks on */
 | 
					 | 
				
			||||||
            for (Map.Entry<String, LinkedList<FactionBlock>> worldblocks : factblocks.blocks.entrySet()) {
 | 
					 | 
				
			||||||
                handleFactionOnWorld(factname, fact, worldblocks.getKey(), worldblocks.getValue(), newmap, newmark);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            factblocks.blocks.clear();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /* Now, add marker for home location */
 | 
					 | 
				
			||||||
            EntityInternalMap<Warp> warps = fact.getWarps();
 | 
					 | 
				
			||||||
            Warp home = null;
 | 
					 | 
				
			||||||
            for (String warp : warps.keySet()) {
 | 
					 | 
				
			||||||
                if (warp.equalsIgnoreCase("home")) {
 | 
					 | 
				
			||||||
                    home = warps.get(warp);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (home == null) {
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            PS homeloc = home.getLocation();
 | 
					 | 
				
			||||||
            if (homeloc != null) {
 | 
					 | 
				
			||||||
                String markid = fc.getUniverse() + "_" + factname + "__home";
 | 
					 | 
				
			||||||
                MarkerIcon ico = getMarkerIcon(factname, fact);
 | 
					 | 
				
			||||||
                if (ico != null) {
 | 
					 | 
				
			||||||
                    Marker homeMarker = resmark.remove(markid);
 | 
					 | 
				
			||||||
                    String lbl = factname + " [home]";
 | 
					 | 
				
			||||||
                    if (homeMarker == null) {
 | 
					 | 
				
			||||||
                        homeMarker = set.createMarker(markid, lbl, homeloc.getWorld(),
 | 
					 | 
				
			||||||
                                homeloc.getLocationX(), homeloc.getLocationY(), homeloc.getLocationZ(), ico, false);
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        homeMarker.setLocation(homeloc.getWorld(), homeloc.getLocationX(), homeloc.getLocationY(), homeloc.getLocationZ());
 | 
					 | 
				
			||||||
                        homeMarker.setLabel(lbl);   /* Update label */
 | 
					 | 
				
			||||||
                        homeMarker.setMarkerIcon(ico);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    if (homeMarker != null) {
 | 
					 | 
				
			||||||
                        homeMarker.setDescription(formatInfoWindow(fact)); /* Set popup */
 | 
					 | 
				
			||||||
                        newmark.put(markid, homeMarker);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        blocks_by_faction.clear();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* Now, review old map - anything left is gone */
 | 
					 | 
				
			||||||
        for (AreaMarker oldm : resareas.values()) {
 | 
					 | 
				
			||||||
            oldm.deleteMarker();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        for (Marker oldm : resmark.values()) {
 | 
					 | 
				
			||||||
            oldm.deleteMarker();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        /* And replace with new map */
 | 
					 | 
				
			||||||
        resareas = newmap;
 | 
					 | 
				
			||||||
        resmark = newmark;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void updatePlayerSets() {
 | 
					    private void updatePlayerSets() {
 | 
				
			||||||
        if (playersets) {
 | 
					        if (playerSets) {
 | 
				
			||||||
            FactionColl fc = FactionColl.get();
 | 
					            FactionColl fc = FactionColl.get();
 | 
				
			||||||
            for (Faction f : fc.getAll()) {
 | 
					            for (Faction f : fc.getAll()) {
 | 
				
			||||||
                if ((f == fc.getNone()) || (f == fc.getWarzone()) || (f == fc.getSafezone())) {
 | 
					                if ((f == fc.getNone()) || (f == fc.getWarzone()) || (f == fc.getSafezone())) {
 | 
				
			||||||
@@ -492,26 +138,16 @@ public class DynmapFactionsPlugin extends JavaPlugin {
 | 
				
			|||||||
        if (dynmap.isEnabled() && factions.isEnabled()) {
 | 
					        if (dynmap.isEnabled() && factions.isEnabled()) {
 | 
				
			||||||
            activate();
 | 
					            activate();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            MetricsLite ml = new MetricsLite(this);
 | 
					 | 
				
			||||||
            ml.start();
 | 
					 | 
				
			||||||
        } catch (IOException ignored) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private boolean reload = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void activate() {
 | 
					    void activate() {
 | 
				
			||||||
        markerapi = api.getMarkerAPI();
 | 
					        markerAPI = api.getMarkerAPI();
 | 
				
			||||||
        if (markerapi == null) {
 | 
					        if (markerAPI == null) {
 | 
				
			||||||
            severe("Error loading dynmap marker API!");
 | 
					            severe("Error loading dynmap marker API!");
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        /* Connect to factions API */
 | 
					 | 
				
			||||||
        factapi = Factions.get();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        blocksize = 16; /* Fixed at 16 */
 | 
					        blockSize = 16; /* Fixed at 16 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Load configuration */
 | 
					        /* Load configuration */
 | 
				
			||||||
        if (reload) {
 | 
					        if (reload) {
 | 
				
			||||||
@@ -528,9 +164,9 @@ public class DynmapFactionsPlugin extends JavaPlugin {
 | 
				
			|||||||
        this.saveConfig();  /* Save updates, if needed */
 | 
					        this.saveConfig();  /* Save updates, if needed */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Now, add marker set for mobs (make it transient) */
 | 
					        /* Now, add marker set for mobs (make it transient) */
 | 
				
			||||||
        set = markerapi.getMarkerSet("factions.markerset");
 | 
					        set = markerAPI.getMarkerSet("factions.markerSet");
 | 
				
			||||||
        if (set == null) {
 | 
					        if (set == null) {
 | 
				
			||||||
            set = markerapi.createMarkerSet("factions.markerset", cfg.getString("layer.name", "Factions"), null, false);
 | 
					            set = markerAPI.createMarkerSet("factions.markerSet", cfg.getString("layer.name", "Factions"), null, false);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            set.setMarkerSetLabel(cfg.getString("layer.name", "Factions"));
 | 
					            set.setMarkerSetLabel(cfg.getString("layer.name", "Factions"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -539,72 +175,72 @@ public class DynmapFactionsPlugin extends JavaPlugin {
 | 
				
			|||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        /* Make sure these are empty (on reload) */
 | 
					        /* Make sure these are empty (on reload) */
 | 
				
			||||||
        resareas.clear();
 | 
					        factionAreaMarkers.clear();
 | 
				
			||||||
        resmark.clear();
 | 
					        factionMarkers.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int minzoom = cfg.getInt("layer.minzoom", 0);
 | 
					        int minZoom = cfg.getInt("layer.minZoom", 0);
 | 
				
			||||||
        if (minzoom > 0) {
 | 
					        if (minZoom > 0) {
 | 
				
			||||||
            set.setMinZoom(minzoom);
 | 
					            set.setMinZoom(minZoom);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        set.setLayerPriority(cfg.getInt("layer.layerprio", 10));
 | 
					        set.setLayerPriority(cfg.getInt("layer.layerPriority", 10));
 | 
				
			||||||
        set.setHideByDefault(cfg.getBoolean("layer.hidebydefault", false));
 | 
					        set.setHideByDefault(cfg.getBoolean("layer.hideByDefault", false));
 | 
				
			||||||
        use3d = cfg.getBoolean("use3dregions", false);
 | 
					
 | 
				
			||||||
        infowindow = cfg.getString("infowindow", DEF_INFOWINDOW);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Get style information */
 | 
					        /* Get style information */
 | 
				
			||||||
        defstyle = new AreaStyle(this, cfg, "regionstyle");
 | 
					        defaultStyle = new AreaStyle(this, cfg, "regionStyle");
 | 
				
			||||||
        cusstyle = new HashMap<>();
 | 
					        customStyle = new HashMap<>();
 | 
				
			||||||
        ConfigurationSection sect = cfg.getConfigurationSection("custstyle");
 | 
					        ConfigurationSection sect = cfg.getConfigurationSection("customStyles");
 | 
				
			||||||
        if (sect != null) {
 | 
					        if (sect != null) {
 | 
				
			||||||
            Set<String> ids = sect.getKeys(false);
 | 
					            Set<String> ids = sect.getKeys(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (String id : ids) {
 | 
					            for (String id : ids) {
 | 
				
			||||||
                cusstyle.put(id, new AreaStyle(this, cfg, "custstyle." + id, defstyle));
 | 
					                customStyle.put(id, new AreaStyle(this, cfg, "customStyles." + id, defaultStyle));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        List<String> vis = cfg.getStringList("visibleregions");
 | 
					        List<String> vis = cfg.getStringList("visibleRegions");
 | 
				
			||||||
        if (vis != null) {
 | 
					        if (vis != null) {
 | 
				
			||||||
            visible = new HashSet<>(vis);
 | 
					            visible = new HashSet<>(vis);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        List<String> hid = cfg.getStringList("hiddenregions");
 | 
					        List<String> hid = cfg.getStringList("hiddenRegions");
 | 
				
			||||||
        if (hid != null) {
 | 
					        if (hid != null) {
 | 
				
			||||||
            hidden = new HashSet<>(hid);
 | 
					            hidden = new HashSet<>(hid);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        /* Chec if player sets enabled */
 | 
					        /* Check if player sets enabled */
 | 
				
			||||||
        playersets = cfg.getBoolean("visibility-by-faction", false);
 | 
					        playerSets = cfg.getBoolean("visibilityByFaction", false);
 | 
				
			||||||
        if (playersets) {
 | 
					        if (playerSets) {
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                if (!api.testIfPlayerInfoProtected()) {
 | 
					                if (!api.testIfPlayerInfoProtected()) {
 | 
				
			||||||
                    playersets = false;
 | 
					                    playerSets = false;
 | 
				
			||||||
                    info("Dynmap does not have player-info-protected enabled - visibility-by-faction will have no effect");
 | 
					                    info("Dynmap does not have player-info-protected enabled - visibility-by-faction will have no effect");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } catch (NoSuchMethodError x) {
 | 
					            } catch (NoSuchMethodError x) {
 | 
				
			||||||
                playersets = false;
 | 
					                playerSets = false;
 | 
				
			||||||
                info("Dynmap does not support function needed for 'visibility-by-faction' - need to upgrade to 0.60 or later");
 | 
					                info("Dynmap does not support function needed for 'visibility-by-faction' - need to upgrade to 0.60 or later");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        updatePlayerSets();
 | 
					        updatePlayerSets();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Set up update job - based on periond */
 | 
					        /* Set up update job - based on period */
 | 
				
			||||||
        int per = cfg.getInt("update.period", 300);
 | 
					        int per = cfg.getInt("update.period", 300);
 | 
				
			||||||
        if (per < 15) {
 | 
					        if (per < 15) {
 | 
				
			||||||
            per = 15;
 | 
					            per = 15;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        updperiod = (per * 20L);
 | 
					        updatePeriod = (per * 20L);
 | 
				
			||||||
        stop = false;
 | 
					        stop = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        getServer().getScheduler().scheduleSyncDelayedTask(this, new FactionsUpdate(this), 40);   /* First time is 2 seconds */
 | 
					        getServer().getScheduler().scheduleSyncDelayedTask(this, new FactionsUpdate(this, this.getConfig()), 40);   /* First time is 2 seconds */
 | 
				
			||||||
        getServer().getPluginManager().registerEvents(new OurServerListener(this), this);
 | 
					        getServer().getPluginManager().registerEvents(new DynmapFactionsListener(this), this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        info("version " + this.getDescription().getVersion() + " is activated");
 | 
					        info("version " + this.getDescription().getVersion() + " is activated");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
    public void onDisable() {
 | 
					    public void onDisable() {
 | 
				
			||||||
        if (set != null) {
 | 
					        if (set != null) {
 | 
				
			||||||
            set.deleteMarkerSet();
 | 
					            set.deleteMarkerSet();
 | 
				
			||||||
            set = null;
 | 
					            set = null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        resareas.clear();
 | 
					        factionAreaMarkers.clear();
 | 
				
			||||||
        stop = true;
 | 
					        stop = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,11 @@
 | 
				
			|||||||
package org.dynmap.factions;
 | 
					package org.dynmap.factions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.HashMap;
 | 
					import java.util.HashMap;
 | 
				
			||||||
import java.util.LinkedList;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class FactionBlocks {
 | 
					public class FactionBlocks {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final Map<String, LinkedList<FactionBlock>> blocks = new HashMap<>();
 | 
					    final Map<String, List<FactionBlock>> blocks = new HashMap<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,26 +1,397 @@
 | 
				
			|||||||
package org.dynmap.factions;
 | 
					package org.dynmap.factions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.massivecraft.factions.entity.BoardColl;
 | 
				
			||||||
 | 
					import com.massivecraft.factions.entity.Faction;
 | 
				
			||||||
 | 
					import com.massivecraft.factions.entity.FactionColl;
 | 
				
			||||||
 | 
					import com.massivecraft.factions.entity.MFlag;
 | 
				
			||||||
 | 
					import com.massivecraft.factions.entity.MFlagColl;
 | 
				
			||||||
 | 
					import com.massivecraft.factions.entity.MPlayer;
 | 
				
			||||||
 | 
					import com.massivecraft.factions.entity.Warp;
 | 
				
			||||||
 | 
					import com.massivecraft.massivecore.ps.PS;
 | 
				
			||||||
 | 
					import com.massivecraft.massivecore.store.EntityInternalMap;
 | 
				
			||||||
 | 
					import org.bukkit.ChatColor;
 | 
				
			||||||
 | 
					import org.bukkit.configuration.file.FileConfiguration;
 | 
				
			||||||
 | 
					import org.dynmap.markers.AreaMarker;
 | 
				
			||||||
 | 
					import org.dynmap.markers.Marker;
 | 
				
			||||||
 | 
					import org.dynmap.markers.MarkerIcon;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayDeque;
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.Collection;
 | 
				
			||||||
 | 
					import java.util.Deque;
 | 
				
			||||||
 | 
					import java.util.HashMap;
 | 
				
			||||||
 | 
					import java.util.LinkedList;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					import java.util.Set;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class FactionsUpdate implements Runnable {
 | 
					public class FactionsUpdate implements Runnable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static final String DEF_INFO_WINDOW = "<div class=\"infoWindow\"><span style=\"font-size:120%;\">" +
 | 
				
			||||||
 | 
					            "%regionName%</span><br />Flags<br /><span style=\"font-weight:bold;\">%flags%</span></div>";
 | 
				
			||||||
 | 
					    private final String infoWindow;
 | 
				
			||||||
    private final DynmapFactionsPlugin dynmapFactionsPlugin;
 | 
					    private final DynmapFactionsPlugin dynmapFactionsPlugin;
 | 
				
			||||||
    public boolean runonce;
 | 
					    public boolean runonce;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public FactionsUpdate(DynmapFactionsPlugin dynmapFactionsPlugin) {
 | 
					    public FactionsUpdate(DynmapFactionsPlugin dynmapFactionsPlugin, FileConfiguration configuration) {
 | 
				
			||||||
        this.dynmapFactionsPlugin = dynmapFactionsPlugin;
 | 
					        this.dynmapFactionsPlugin = dynmapFactionsPlugin;
 | 
				
			||||||
 | 
					        infoWindow = configuration.getString("infoWindow", DEF_INFO_WINDOW);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
    public void run() {
 | 
					    public void run() {
 | 
				
			||||||
        if (dynmapFactionsPlugin.stop) {
 | 
					        if (dynmapFactionsPlugin.stop) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dynmapFactionsPlugin.updateFactions();
 | 
					        updateFactions();
 | 
				
			||||||
        if (!runonce) {
 | 
					        if (!runonce) {
 | 
				
			||||||
            dynmapFactionsPlugin.getServer().getScheduler().scheduleSyncDelayedTask(dynmapFactionsPlugin,
 | 
					            dynmapFactionsPlugin.getServer().getScheduler().scheduleSyncDelayedTask(dynmapFactionsPlugin,
 | 
				
			||||||
                    this, dynmapFactionsPlugin.updperiod);
 | 
					                    this, dynmapFactionsPlugin.updatePeriod);
 | 
				
			||||||
        } else if (dynmapFactionsPlugin.pending == this) {
 | 
					        } else if (dynmapFactionsPlugin.pending == this) {
 | 
				
			||||||
            dynmapFactionsPlugin.pending = null;
 | 
					            dynmapFactionsPlugin.pending = null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Update Factions information */
 | 
				
			||||||
 | 
					    private void updateFactions() {
 | 
				
			||||||
 | 
					        Map<String, AreaMarker> newMap = new HashMap<>();
 | 
				
			||||||
 | 
					        Map<String, Marker> newMarkers = new HashMap<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Parse into faction centric mapping, split by world */
 | 
				
			||||||
 | 
					        Map<String, FactionBlocks> blocksByFaction = new HashMap<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        FactionColl fc = FactionColl.get();
 | 
				
			||||||
 | 
					        Collection<Faction> factions = fc.getAll();
 | 
				
			||||||
 | 
					        for (Faction faction : factions) {
 | 
				
			||||||
 | 
					            Set<PS> chunks = BoardColl.get().getChunks(faction);
 | 
				
			||||||
 | 
					            String fid = fc.getUniverse() + "_" + faction.getId();
 | 
				
			||||||
 | 
					            FactionBlocks factionBlocks = blocksByFaction.get(fid); /* Look up faction */
 | 
				
			||||||
 | 
					            if (factionBlocks == null) {    /* Create faction block if first time */
 | 
				
			||||||
 | 
					                factionBlocks = new FactionBlocks();
 | 
				
			||||||
 | 
					                blocksByFaction.put(fid, factionBlocks);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (PS cc : chunks) {
 | 
				
			||||||
 | 
					                String world = cc.getWorld();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                /* Get block set for given world */
 | 
				
			||||||
 | 
					                List<FactionBlock> blocks = factionBlocks.blocks.computeIfAbsent(world, k -> new LinkedList<>());
 | 
				
			||||||
 | 
					                FactionBlock fb = new FactionBlock(cc.getChunkX(), cc.getChunkZ());
 | 
				
			||||||
 | 
					                blocks.add(fb); /* Add to list */
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        /* Loop through factions */
 | 
				
			||||||
 | 
					        for (Faction faction : factions) {
 | 
				
			||||||
 | 
					            String factionName = ChatColor.stripColor(faction.getName());
 | 
				
			||||||
 | 
					            String fid = fc.getUniverse() + "_" + faction.getId();
 | 
				
			||||||
 | 
					            FactionBlocks factionBLocks = blocksByFaction.get(fid); /* Look up faction */
 | 
				
			||||||
 | 
					            if (factionBLocks == null) {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Loop through each world that faction has blocks on */
 | 
				
			||||||
 | 
					            for (Map.Entry<String, List<FactionBlock>> worldBlocks : factionBLocks.blocks.entrySet()) {
 | 
				
			||||||
 | 
					                handleFactionOnWorld(factionName, faction, worldBlocks.getKey(), worldBlocks.getValue(), newMap);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            factionBLocks.blocks.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Now, add marker for home location */
 | 
				
			||||||
 | 
					            EntityInternalMap<Warp> warps = faction.getWarps();
 | 
				
			||||||
 | 
					            Warp home = null;
 | 
				
			||||||
 | 
					            for (String warp : warps.keySet()) {
 | 
				
			||||||
 | 
					                if (warp.equalsIgnoreCase("home")) {
 | 
				
			||||||
 | 
					                    home = warps.get(warp);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (home == null) {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            PS homeLocation = home.getLocation();
 | 
				
			||||||
 | 
					            if (homeLocation != null) {
 | 
				
			||||||
 | 
					                String markId = fc.getUniverse() + "_" + factionName + "__home";
 | 
				
			||||||
 | 
					                MarkerIcon ico = getMarkerIcon(factionName);
 | 
				
			||||||
 | 
					                if (ico != null) {
 | 
				
			||||||
 | 
					                    Marker homeMarker = dynmapFactionsPlugin.factionMarkers.remove(markId);
 | 
				
			||||||
 | 
					                    String lbl = factionName + " [home]";
 | 
				
			||||||
 | 
					                    if (homeMarker == null) {
 | 
				
			||||||
 | 
					                        homeMarker = dynmapFactionsPlugin.set.createMarker(markId, lbl, homeLocation.getWorld(),
 | 
				
			||||||
 | 
					                                homeLocation.getLocationX(), homeLocation.getLocationY(), homeLocation.getLocationZ(), ico, false);
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        homeMarker.setLocation(homeLocation.getWorld(), homeLocation.getLocationX(), homeLocation.getLocationY(), homeLocation.getLocationZ());
 | 
				
			||||||
 | 
					                        homeMarker.setLabel(lbl);   /* Update label */
 | 
				
			||||||
 | 
					                        homeMarker.setMarkerIcon(ico);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (homeMarker != null) {
 | 
				
			||||||
 | 
					                        homeMarker.setDescription(formatInfoWindow(faction)); /* Set popup */
 | 
				
			||||||
 | 
					                        newMarkers.put(markId, homeMarker);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        blocksByFaction.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Now, review old map - anything left is gone */
 | 
				
			||||||
 | 
					        for (AreaMarker oldMarker : dynmapFactionsPlugin.factionAreaMarkers.values()) {
 | 
				
			||||||
 | 
					            oldMarker.deleteMarker();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        for (Marker oldMarker : dynmapFactionsPlugin.factionMarkers.values()) {
 | 
				
			||||||
 | 
					            oldMarker.deleteMarker();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        /* And replace with new map */
 | 
				
			||||||
 | 
					        dynmapFactionsPlugin.factionAreaMarkers = newMap;
 | 
				
			||||||
 | 
					        dynmapFactionsPlugin.factionMarkers = newMarkers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Handle specific faction on specific world */
 | 
				
			||||||
 | 
					    private void handleFactionOnWorld(@NotNull String factionName, @NotNull Faction faction, @NotNull String world,
 | 
				
			||||||
 | 
					                                      @NotNull List<FactionBlock> blocks, @NotNull Map<String, AreaMarker> newmap) {
 | 
				
			||||||
 | 
					        double[] x;
 | 
				
			||||||
 | 
					        double[] z;
 | 
				
			||||||
 | 
					        int poly_index = 0; /* Index of polygon for given faction */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Build popup */
 | 
				
			||||||
 | 
					        String desc = formatInfoWindow(faction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Handle areas */
 | 
				
			||||||
 | 
					        if (!isVisible(factionName, world) || blocks.isEmpty()) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        LinkedList<FactionBlock> nodeValues = new LinkedList<>();
 | 
				
			||||||
 | 
					        TileFlags currentBlocks = new TileFlags();
 | 
				
			||||||
 | 
					        /* Loop through blocks: set flags on block maps */
 | 
				
			||||||
 | 
					        for (FactionBlock b : blocks) {
 | 
				
			||||||
 | 
					            currentBlocks.setFlag(b.x(), b.z(), true); /* Set flag for block */
 | 
				
			||||||
 | 
					            nodeValues.addLast(b);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        /* Loop through until we don't find more areas */
 | 
				
			||||||
 | 
					        while (nodeValues != null) {
 | 
				
			||||||
 | 
					            LinkedList<FactionBlock> ourNodes = null;
 | 
				
			||||||
 | 
					            LinkedList<FactionBlock> newList = null;
 | 
				
			||||||
 | 
					            TileFlags ourBlocks = null;
 | 
				
			||||||
 | 
					            int minX = Integer.MAX_VALUE;
 | 
				
			||||||
 | 
					            int minZ = Integer.MAX_VALUE;
 | 
				
			||||||
 | 
					            for (FactionBlock node : nodeValues) {
 | 
				
			||||||
 | 
					                int nodeX = node.x();
 | 
				
			||||||
 | 
					                int nodeZ = node.z();
 | 
				
			||||||
 | 
					                /* If we need to start shape, and this block is not part of one yet */
 | 
				
			||||||
 | 
					                if ((ourBlocks == null) && currentBlocks.getFlag(nodeX, nodeZ)) {
 | 
				
			||||||
 | 
					                    ourBlocks = new TileFlags();  /* Create map for shape */
 | 
				
			||||||
 | 
					                    ourNodes = new LinkedList<>();
 | 
				
			||||||
 | 
					                    floodFillTarget(currentBlocks, ourBlocks, nodeX, nodeZ);   /* Copy shape */
 | 
				
			||||||
 | 
					                    ourNodes.add(node); /* Add it to our node list */
 | 
				
			||||||
 | 
					                    minX = nodeX;
 | 
				
			||||||
 | 
					                    minZ = nodeZ;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                /* If shape found, and we're in it, add to our node list */
 | 
				
			||||||
 | 
					                else if ((ourBlocks != null) && ourBlocks.getFlag(nodeX, nodeZ)) {
 | 
				
			||||||
 | 
					                    ourNodes.add(node);
 | 
				
			||||||
 | 
					                    if (nodeX < minX) {
 | 
				
			||||||
 | 
					                        minX = nodeX;
 | 
				
			||||||
 | 
					                        minZ = nodeZ;
 | 
				
			||||||
 | 
					                    } else if ((nodeX == minX) && (nodeZ < minZ)) {
 | 
				
			||||||
 | 
					                        minZ = nodeZ;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {  /* Else, keep it in the list for the next polygon */
 | 
				
			||||||
 | 
					                    if (newList == null) {
 | 
				
			||||||
 | 
					                        newList = new LinkedList<>();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    newList.add(node);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            nodeValues = newList; /* Replace list (null if no more to process) */
 | 
				
			||||||
 | 
					            if (ourBlocks != null) {
 | 
				
			||||||
 | 
					                /* Trace outline of blocks - start from minx, min z going to x+ */
 | 
				
			||||||
 | 
					                int cur_x = minX;
 | 
				
			||||||
 | 
					                int cur_z = minZ;
 | 
				
			||||||
 | 
					                Direction dir = Direction.POSITIVE_X;
 | 
				
			||||||
 | 
					                List<int[]> lineList = new ArrayList<>();
 | 
				
			||||||
 | 
					                lineList.add(new int[]{minX, minZ}); // Add start point
 | 
				
			||||||
 | 
					                while ((cur_x != minX) || (cur_z != minZ) || (dir != Direction.NEGATIVE_Z)) {
 | 
				
			||||||
 | 
					                    switch (dir) {
 | 
				
			||||||
 | 
					                        case POSITIVE_X: /* Segment in X+ direction */
 | 
				
			||||||
 | 
					                            if (!ourBlocks.getFlag(cur_x + 1, cur_z)) { /* Right turn? */
 | 
				
			||||||
 | 
					                                lineList.add(new int[]{cur_x + 1, cur_z}); /* Finish line */
 | 
				
			||||||
 | 
					                                dir = Direction.POSITIVE_Z;  /* Change direction */
 | 
				
			||||||
 | 
					                            } else if (!ourBlocks.getFlag(cur_x + 1, cur_z - 1)) {  /* Straight? */
 | 
				
			||||||
 | 
					                                cur_x++;
 | 
				
			||||||
 | 
					                            } else {  /* Left turn */
 | 
				
			||||||
 | 
					                                lineList.add(new int[]{cur_x + 1, cur_z}); /* Finish line */
 | 
				
			||||||
 | 
					                                dir = Direction.NEGATIVE_Z;
 | 
				
			||||||
 | 
					                                cur_x++;
 | 
				
			||||||
 | 
					                                cur_z--;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case POSITIVE_Z: /* Segment in Z+ direction */
 | 
				
			||||||
 | 
					                            if (!ourBlocks.getFlag(cur_x, cur_z + 1)) { /* Right turn? */
 | 
				
			||||||
 | 
					                                lineList.add(new int[]{cur_x + 1, cur_z + 1}); /* Finish line */
 | 
				
			||||||
 | 
					                                dir = Direction.NEGATIVE_X;  /* Change direction */
 | 
				
			||||||
 | 
					                            } else if (!ourBlocks.getFlag(cur_x + 1, cur_z + 1)) {  /* Straight? */
 | 
				
			||||||
 | 
					                                cur_z++;
 | 
				
			||||||
 | 
					                            } else {  /* Left turn */
 | 
				
			||||||
 | 
					                                lineList.add(new int[]{cur_x + 1, cur_z + 1}); /* Finish line */
 | 
				
			||||||
 | 
					                                dir = Direction.POSITIVE_X;
 | 
				
			||||||
 | 
					                                cur_x++;
 | 
				
			||||||
 | 
					                                cur_z++;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case NEGATIVE_X: /* Segment in X- direction */
 | 
				
			||||||
 | 
					                            if (!ourBlocks.getFlag(cur_x - 1, cur_z)) { /* Right turn? */
 | 
				
			||||||
 | 
					                                lineList.add(new int[]{cur_x, cur_z + 1}); /* Finish line */
 | 
				
			||||||
 | 
					                                dir = Direction.NEGATIVE_Z;  /* Change direction */
 | 
				
			||||||
 | 
					                            } else if (!ourBlocks.getFlag(cur_x - 1, cur_z + 1)) {  /* Straight? */
 | 
				
			||||||
 | 
					                                cur_x--;
 | 
				
			||||||
 | 
					                            } else {  /* Left turn */
 | 
				
			||||||
 | 
					                                lineList.add(new int[]{cur_x, cur_z + 1}); /* Finish line */
 | 
				
			||||||
 | 
					                                dir = Direction.POSITIVE_Z;
 | 
				
			||||||
 | 
					                                cur_x--;
 | 
				
			||||||
 | 
					                                cur_z++;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case NEGATIVE_Z: /* Segment in Z- direction */
 | 
				
			||||||
 | 
					                            if (!ourBlocks.getFlag(cur_x, cur_z - 1)) { /* Right turn? */
 | 
				
			||||||
 | 
					                                lineList.add(new int[]{cur_x, cur_z}); /* Finish line */
 | 
				
			||||||
 | 
					                                dir = Direction.POSITIVE_X;  /* Change direction */
 | 
				
			||||||
 | 
					                            } else if (!ourBlocks.getFlag(cur_x - 1, cur_z - 1)) {  /* Straight? */
 | 
				
			||||||
 | 
					                                cur_z--;
 | 
				
			||||||
 | 
					                            } else {  /* Left turn */
 | 
				
			||||||
 | 
					                                lineList.add(new int[]{cur_x, cur_z}); /* Finish line */
 | 
				
			||||||
 | 
					                                dir = Direction.NEGATIVE_X;
 | 
				
			||||||
 | 
					                                cur_x--;
 | 
				
			||||||
 | 
					                                cur_z--;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                /* Build information for specific area */
 | 
				
			||||||
 | 
					                String polyId = factionName + "__" + world + "__" + poly_index;
 | 
				
			||||||
 | 
					                int sz = lineList.size();
 | 
				
			||||||
 | 
					                x = new double[sz];
 | 
				
			||||||
 | 
					                z = new double[sz];
 | 
				
			||||||
 | 
					                for (int i = 0; i < sz; i++) {
 | 
				
			||||||
 | 
					                    int[] line = lineList.get(i);
 | 
				
			||||||
 | 
					                    x[i] = (double) line[0] * (double) dynmapFactionsPlugin.blockSize;
 | 
				
			||||||
 | 
					                    z[i] = (double) line[1] * (double) dynmapFactionsPlugin.blockSize;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                /* Find existing one */
 | 
				
			||||||
 | 
					                AreaMarker m = dynmapFactionsPlugin.factionAreaMarkers.remove(polyId); /* Existing area? */
 | 
				
			||||||
 | 
					                if (m == null) {
 | 
				
			||||||
 | 
					                    m = dynmapFactionsPlugin.set.createAreaMarker(polyId, factionName, false, world, x, z, false);
 | 
				
			||||||
 | 
					                    if (m == null) {
 | 
				
			||||||
 | 
					                        DynmapFactionsPlugin.info("error adding area marker " + polyId);
 | 
				
			||||||
 | 
					                        return;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    m.setCornerLocations(x, z); /* Replace corner locations */
 | 
				
			||||||
 | 
					                    m.setLabel(factionName);   /* Update label */
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                m.setDescription(desc); /* Set popup */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                /* Set line and fill properties */
 | 
				
			||||||
 | 
					                addStyle(factionName, m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                /* Add to map */
 | 
				
			||||||
 | 
					                newmap.put(polyId, m);
 | 
				
			||||||
 | 
					                poly_index++;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Find all contiguous blocks, set in target and clear in source
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private void floodFillTarget(TileFlags source, TileFlags destination, int x, int y) {
 | 
				
			||||||
 | 
					        Deque<int[]> stack = new ArrayDeque<>();
 | 
				
			||||||
 | 
					        stack.push(new int[]{x, y});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        while (!stack.isEmpty()) {
 | 
				
			||||||
 | 
					            int[] next = stack.pop();
 | 
				
			||||||
 | 
					            x = next[0];
 | 
				
			||||||
 | 
					            y = next[1];
 | 
				
			||||||
 | 
					            if (source.getFlag(x, y)) { /* Set in src */
 | 
				
			||||||
 | 
					                source.setFlag(x, y, false);   /* Clear source */
 | 
				
			||||||
 | 
					                destination.setFlag(x, y, true);   /* Set in destination */
 | 
				
			||||||
 | 
					                if (source.getFlag(x + 1, y)) {
 | 
				
			||||||
 | 
					                    stack.push(new int[]{x + 1, y});
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (source.getFlag(x - 1, y)) {
 | 
				
			||||||
 | 
					                    stack.push(new int[]{x - 1, y});
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (source.getFlag(x, y + 1)) {
 | 
				
			||||||
 | 
					                    stack.push(new int[]{x, y + 1});
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (source.getFlag(x, y - 1)) {
 | 
				
			||||||
 | 
					                    stack.push(new int[]{x, y - 1});
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void addStyle(String factionId, AreaMarker areaMarker) {
 | 
				
			||||||
 | 
					        AreaStyle as = dynmapFactionsPlugin.customStyle.get(factionId);
 | 
				
			||||||
 | 
					        if (as == null) {
 | 
				
			||||||
 | 
					            as = dynmapFactionsPlugin.defaultStyle;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        int sc = 0xFF0000;
 | 
				
			||||||
 | 
					        int fc = 0xFF0000;
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            sc = Integer.parseInt(as.strokeColor().substring(1), 16);
 | 
				
			||||||
 | 
					            fc = Integer.parseInt(as.fillColor().substring(1), 16);
 | 
				
			||||||
 | 
					        } catch (NumberFormatException ignored) {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        areaMarker.setLineStyle(as.strokeWeight(), as.strokeOpacity(), sc);
 | 
				
			||||||
 | 
					        areaMarker.setFillStyle(as.fillOpacity(), fc);
 | 
				
			||||||
 | 
					        areaMarker.setBoostFlag(as.boost());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private MarkerIcon getMarkerIcon(String factionName) {
 | 
				
			||||||
 | 
					        AreaStyle as = dynmapFactionsPlugin.customStyle.get(factionName);
 | 
				
			||||||
 | 
					        if (as == null) {
 | 
				
			||||||
 | 
					            as = dynmapFactionsPlugin.defaultStyle;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return as.homeIcon();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private boolean isVisible(String id, String worldName) {
 | 
				
			||||||
 | 
					        if ((dynmapFactionsPlugin.visible != null) && (!dynmapFactionsPlugin.visible.isEmpty())) {
 | 
				
			||||||
 | 
					            if ((!dynmapFactionsPlugin.visible.contains(id)) && (!dynmapFactionsPlugin.visible.contains("world:" + worldName))) {
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if ((dynmapFactionsPlugin.hidden != null) && (!dynmapFactionsPlugin.hidden.isEmpty())) {
 | 
				
			||||||
 | 
					            return !dynmapFactionsPlugin.hidden.contains(id) && !dynmapFactionsPlugin.hidden.contains("world:" + worldName);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private String formatInfoWindow(Faction fact) {
 | 
				
			||||||
 | 
					        String v = "<div class=\"regionInfo\">" + infoWindow + "</div>";
 | 
				
			||||||
 | 
					        v = v.replace("%regionName%", ChatColor.stripColor(fact.getName()));
 | 
				
			||||||
 | 
					        v = v.replace("%description%", ChatColor.stripColor(fact.getDescription()));
 | 
				
			||||||
 | 
					        MPlayer adm = fact.getLeader();
 | 
				
			||||||
 | 
					        v = v.replace("%playerOwners%", (adm != null) ? adm.getName() : "");
 | 
				
			||||||
 | 
					        StringBuilder res = new StringBuilder();
 | 
				
			||||||
 | 
					        for (MPlayer r : fact.getMPlayers()) {
 | 
				
			||||||
 | 
					            if (!res.isEmpty()) {
 | 
				
			||||||
 | 
					                res.append(", ");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            res.append(r.getName());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        v = v.replace("%playerMembers%", res.toString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        v = v.replace("%nation%", ChatColor.stripColor(fact.getName()));
 | 
				
			||||||
 | 
					        /* Build flags */
 | 
				
			||||||
 | 
					        StringBuilder flags = new StringBuilder();
 | 
				
			||||||
 | 
					        for (MFlag ff : MFlagColl.get().getAll()) {
 | 
				
			||||||
 | 
					            flags.append("<br/>").append(ff.getName()).append(": ").append(fact.getFlag(ff));
 | 
				
			||||||
 | 
					            v = v.replace("%flag." + ff.getName() + "%", fact.getFlag(ff) ? "true" : "false");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        v = v.replace("%flags%", flags.toString());
 | 
				
			||||||
 | 
					        return v;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,394 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * Copyright 2011 Tyler Blair. All rights reserved.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Redistribution and use in source and binary forms, with or without modification, are
 | 
					 | 
				
			||||||
 * permitted provided that the following conditions are met:
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *    1. Redistributions of source code must retain the above copyright notice, this list of
 | 
					 | 
				
			||||||
 *       conditions and the following disclaimer.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *    2. Redistributions in binary form must reproduce the above copyright notice, this list
 | 
					 | 
				
			||||||
 *       of conditions and the following disclaimer in the documentation and/or other materials
 | 
					 | 
				
			||||||
 *       provided with the distribution.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED
 | 
					 | 
				
			||||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
					 | 
				
			||||||
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
 | 
					 | 
				
			||||||
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
					 | 
				
			||||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
					 | 
				
			||||||
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 | 
					 | 
				
			||||||
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
					 | 
				
			||||||
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 | 
					 | 
				
			||||||
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * The views and conclusions contained in the software and documentation are those of the
 | 
					 | 
				
			||||||
 * authors and contributors and should not be interpreted as representing official policies,
 | 
					 | 
				
			||||||
 * either expressed or implied, of anybody else.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package org.dynmap.factions;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import org.bukkit.Bukkit;
 | 
					 | 
				
			||||||
import org.bukkit.configuration.InvalidConfigurationException;
 | 
					 | 
				
			||||||
import org.bukkit.configuration.file.YamlConfiguration;
 | 
					 | 
				
			||||||
import org.bukkit.plugin.Plugin;
 | 
					 | 
				
			||||||
import org.bukkit.plugin.PluginDescriptionFile;
 | 
					 | 
				
			||||||
import org.bukkit.scheduler.BukkitTask;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import java.io.BufferedReader;
 | 
					 | 
				
			||||||
import java.io.File;
 | 
					 | 
				
			||||||
import java.io.IOException;
 | 
					 | 
				
			||||||
import java.io.InputStreamReader;
 | 
					 | 
				
			||||||
import java.io.OutputStreamWriter;
 | 
					 | 
				
			||||||
import java.io.UnsupportedEncodingException;
 | 
					 | 
				
			||||||
import java.net.Proxy;
 | 
					 | 
				
			||||||
import java.net.URL;
 | 
					 | 
				
			||||||
import java.net.URLConnection;
 | 
					 | 
				
			||||||
import java.net.URLEncoder;
 | 
					 | 
				
			||||||
import java.nio.charset.StandardCharsets;
 | 
					 | 
				
			||||||
import java.util.UUID;
 | 
					 | 
				
			||||||
import java.util.logging.Level;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public class MetricsLite {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * The current revision number
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private final static int REVISION = 6;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * The base url of the metrics domain
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private static final String BASE_URL = "http://mcstats.org";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * The url used to report a server's status
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private static final String REPORT_URL = "/report/%s";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Interval of time to ping (in minutes)
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private final static int PING_INTERVAL = 10;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * The plugin this metrics submits for
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private final Plugin plugin;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * The plugin configuration file
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private final YamlConfiguration configuration;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * The plugin configuration file
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private final File configurationFile;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Unique server id
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private final String guid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Debug mode
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private final boolean debug;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Lock for synchronization
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private final Object optOutLock = new Object();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Id of the scheduled task
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private volatile BukkitTask task = null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public MetricsLite(Plugin plugin) throws IOException {
 | 
					 | 
				
			||||||
        if (plugin == null) {
 | 
					 | 
				
			||||||
            throw new IllegalArgumentException("Plugin cannot be null");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this.plugin = plugin;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // load the config
 | 
					 | 
				
			||||||
        configurationFile = getConfigFile();
 | 
					 | 
				
			||||||
        configuration = YamlConfiguration.loadConfiguration(configurationFile);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // add some defaults
 | 
					 | 
				
			||||||
        configuration.addDefault("opt-out", false);
 | 
					 | 
				
			||||||
        configuration.addDefault("guid", UUID.randomUUID().toString());
 | 
					 | 
				
			||||||
        configuration.addDefault("debug", false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Do we need to create the file?
 | 
					 | 
				
			||||||
        if (configuration.get("guid", null) == null) {
 | 
					 | 
				
			||||||
            configuration.options().header("http://mcstats.org").copyDefaults(true);
 | 
					 | 
				
			||||||
            configuration.save(configurationFile);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Load the guid then
 | 
					 | 
				
			||||||
        guid = configuration.getString("guid");
 | 
					 | 
				
			||||||
        debug = configuration.getBoolean("debug", false);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Start measuring statistics. This will immediately create an async repeating task as the plugin and send
 | 
					 | 
				
			||||||
     * the initial data to the metrics backend, and then after that it will post in increments of
 | 
					 | 
				
			||||||
     * PING_INTERVAL * 1200 ticks.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return True if statistics measuring is running, otherwise false.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public boolean start() {
 | 
					 | 
				
			||||||
        synchronized (optOutLock) {
 | 
					 | 
				
			||||||
            // Did we opt out?
 | 
					 | 
				
			||||||
            if (isOptOut()) {
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Is metrics already running?
 | 
					 | 
				
			||||||
            if (task != null) {
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Begin hitting the server with glorious data
 | 
					 | 
				
			||||||
            task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                private boolean firstPost = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                public void run() {
 | 
					 | 
				
			||||||
                    try {
 | 
					 | 
				
			||||||
                        // This has to be synchronized or it can collide with the disable method.
 | 
					 | 
				
			||||||
                        synchronized (optOutLock) {
 | 
					 | 
				
			||||||
                            // Disable Task, if it is running and the server owner decided to opt-out
 | 
					 | 
				
			||||||
                            if (isOptOut() && task != null) {
 | 
					 | 
				
			||||||
                                task.cancel();
 | 
					 | 
				
			||||||
                                task = null;
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        // We use the inverse of firstPost because if it is the first time we are posting,
 | 
					 | 
				
			||||||
                        // it is not a interval ping, so it evaluates to FALSE
 | 
					 | 
				
			||||||
                        // Each time thereafter it will evaluate to TRUE, i.e PING!
 | 
					 | 
				
			||||||
                        postPlugin(!firstPost);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        // After the first post we set firstPost to false
 | 
					 | 
				
			||||||
                        // Each post thereafter will be a ping
 | 
					 | 
				
			||||||
                        firstPost = false;
 | 
					 | 
				
			||||||
                    } catch (IOException e) {
 | 
					 | 
				
			||||||
                        if (debug) {
 | 
					 | 
				
			||||||
                            Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage());
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }, 0, PING_INTERVAL * 1200);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Has the server owner denied plugin metrics?
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return true if metrics should be opted out of it
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public boolean isOptOut() {
 | 
					 | 
				
			||||||
        synchronized (optOutLock) {
 | 
					 | 
				
			||||||
            try {
 | 
					 | 
				
			||||||
                // Reload the metrics file
 | 
					 | 
				
			||||||
                configuration.load(getConfigFile());
 | 
					 | 
				
			||||||
            } catch (IOException | InvalidConfigurationException ex) {
 | 
					 | 
				
			||||||
                if (debug) {
 | 
					 | 
				
			||||||
                    Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return configuration.getBoolean("opt-out", false);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @throws java.io.IOException
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public void enable() throws IOException {
 | 
					 | 
				
			||||||
        // This has to be synchronized or it can collide with the check in the task.
 | 
					 | 
				
			||||||
        synchronized (optOutLock) {
 | 
					 | 
				
			||||||
            // Check if the server owner has already set opt-out, if not, set it.
 | 
					 | 
				
			||||||
            if (isOptOut()) {
 | 
					 | 
				
			||||||
                configuration.set("opt-out", false);
 | 
					 | 
				
			||||||
                configuration.save(configurationFile);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Enable Task, if it is not running
 | 
					 | 
				
			||||||
            if (task == null) {
 | 
					 | 
				
			||||||
                start();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @throws java.io.IOException
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public void disable() throws IOException {
 | 
					 | 
				
			||||||
        // This has to be synchronized or it can collide with the check in the task.
 | 
					 | 
				
			||||||
        synchronized (optOutLock) {
 | 
					 | 
				
			||||||
            // Check if the server owner has already set opt-out, if not, set it.
 | 
					 | 
				
			||||||
            if (!isOptOut()) {
 | 
					 | 
				
			||||||
                configuration.set("opt-out", true);
 | 
					 | 
				
			||||||
                configuration.save(configurationFile);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Disable Task, if it is running
 | 
					 | 
				
			||||||
            if (task != null) {
 | 
					 | 
				
			||||||
                task.cancel();
 | 
					 | 
				
			||||||
                task = null;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Gets the File object of the config file that should be used to store data such as the GUID and opt-out status
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return the File object for the config file
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public File getConfigFile() {
 | 
					 | 
				
			||||||
        // I believe the easiest way to get the base folder (e.g craftbukkit set via -P) for plugins to use
 | 
					 | 
				
			||||||
        // is to abuse the plugin object we already have
 | 
					 | 
				
			||||||
        // plugin.getDataFolder() => base/plugins/PluginA/
 | 
					 | 
				
			||||||
        // pluginsFolder => base/plugins/
 | 
					 | 
				
			||||||
        // The base is not necessarily relative to the startup directory.
 | 
					 | 
				
			||||||
        File pluginsFolder = plugin.getDataFolder().getParentFile();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // return => base/plugins/PluginMetrics/config.yml
 | 
					 | 
				
			||||||
        return new File(new File(pluginsFolder, "PluginMetrics"), "config.yml");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Generic method that posts a plugin to the metrics website
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private void postPlugin(boolean isPing) throws IOException {
 | 
					 | 
				
			||||||
        // Server software specific section
 | 
					 | 
				
			||||||
        PluginDescriptionFile description = plugin.getDescription();
 | 
					 | 
				
			||||||
        String pluginName = description.getName();
 | 
					 | 
				
			||||||
        boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled
 | 
					 | 
				
			||||||
        String pluginVersion = description.getVersion();
 | 
					 | 
				
			||||||
        String serverVersion = Bukkit.getVersion();
 | 
					 | 
				
			||||||
        int playersOnline = Bukkit.getServer().getOnlinePlayers().size();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // END server software specific section -- all code below does not use any code outside of this class / Java
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Construct the post data
 | 
					 | 
				
			||||||
        final StringBuilder data = new StringBuilder();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // The plugin's description file containg all of the plugin data such as name, version, author, etc
 | 
					 | 
				
			||||||
        data.append(encode("guid")).append('=').append(encode(guid));
 | 
					 | 
				
			||||||
        encodeDataPair(data, "version", pluginVersion);
 | 
					 | 
				
			||||||
        encodeDataPair(data, "server", serverVersion);
 | 
					 | 
				
			||||||
        encodeDataPair(data, "players", Integer.toString(playersOnline));
 | 
					 | 
				
			||||||
        encodeDataPair(data, "revision", String.valueOf(REVISION));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // New data as of R6
 | 
					 | 
				
			||||||
        String osname = System.getProperty("os.name");
 | 
					 | 
				
			||||||
        String osarch = System.getProperty("os.arch");
 | 
					 | 
				
			||||||
        String osversion = System.getProperty("os.version");
 | 
					 | 
				
			||||||
        String java_version = System.getProperty("java.version");
 | 
					 | 
				
			||||||
        int coreCount = Runtime.getRuntime().availableProcessors();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // normalize os arch .. amd64 -> x86_64
 | 
					 | 
				
			||||||
        if (osarch.equals("amd64")) {
 | 
					 | 
				
			||||||
            osarch = "x86_64";
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        encodeDataPair(data, "osname", osname);
 | 
					 | 
				
			||||||
        encodeDataPair(data, "osarch", osarch);
 | 
					 | 
				
			||||||
        encodeDataPair(data, "osversion", osversion);
 | 
					 | 
				
			||||||
        encodeDataPair(data, "cores", Integer.toString(coreCount));
 | 
					 | 
				
			||||||
        encodeDataPair(data, "online-mode", Boolean.toString(onlineMode));
 | 
					 | 
				
			||||||
        encodeDataPair(data, "java_version", java_version);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // If we're pinging, append it
 | 
					 | 
				
			||||||
        if (isPing) {
 | 
					 | 
				
			||||||
            encodeDataPair(data, "ping", "true");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Create the url
 | 
					 | 
				
			||||||
        URL url = new URL(BASE_URL + String.format(REPORT_URL, encode(pluginName)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Connect to the website
 | 
					 | 
				
			||||||
        URLConnection connection;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Mineshafter creates a socks proxy, so we can safely bypass it
 | 
					 | 
				
			||||||
        // It does not reroute POST requests so we need to go around it
 | 
					 | 
				
			||||||
        if (isMineshafterPresent()) {
 | 
					 | 
				
			||||||
            connection = url.openConnection(Proxy.NO_PROXY);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            connection = url.openConnection();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        connection.setDoOutput(true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Write the data
 | 
					 | 
				
			||||||
        final OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
 | 
					 | 
				
			||||||
        writer.write(data.toString());
 | 
					 | 
				
			||||||
        writer.flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Now read the response
 | 
					 | 
				
			||||||
        final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
 | 
					 | 
				
			||||||
        final String response = reader.readLine();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // close resources
 | 
					 | 
				
			||||||
        writer.close();
 | 
					 | 
				
			||||||
        reader.close();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (response == null || response.startsWith("ERR")) {
 | 
					 | 
				
			||||||
            throw new IOException(response); //Throw the exception
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Check if mineshafter is present. If it is, we need to bypass it to send POST requests
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return true if mineshafter is installed on the server
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private boolean isMineshafterPresent() {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            Class.forName("mineshafter.MineServer");
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (Exception e) {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * <p>Encode a key/value data pair to be used in a HTTP post request. This INCLUDES a & so the first
 | 
					 | 
				
			||||||
     * key/value pair MUST be included manually, e.g:</p>
 | 
					 | 
				
			||||||
     * <code>
 | 
					 | 
				
			||||||
     * StringBuffer data = new StringBuffer();
 | 
					 | 
				
			||||||
     * data.append(encode("guid")).append('=').append(encode(guid));
 | 
					 | 
				
			||||||
     * encodeDataPair(data, "version", description.getVersion());
 | 
					 | 
				
			||||||
     * </code>
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param buffer the stringbuilder to append the data pair onto
 | 
					 | 
				
			||||||
     * @param key    the key value
 | 
					 | 
				
			||||||
     * @param value  the value
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private static void encodeDataPair(final StringBuilder buffer, final String key, final String value) {
 | 
					 | 
				
			||||||
        buffer.append('&').append(encode(key)).append('=').append(encode(value));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Encode text as UTF-8
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param text the text to encode
 | 
					 | 
				
			||||||
     * @return the encoded text, as UTF-8
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private static String encode(final String text) {
 | 
					 | 
				
			||||||
        return URLEncoder.encode(text, StandardCharsets.UTF_8);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package org.dynmap.factions;
 | 
					package org.dynmap.factions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PlayerSetUpdate implements Runnable {
 | 
					class PlayerSetUpdate implements Runnable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final DynmapFactionsPlugin dynmapFactionsPlugin;
 | 
					    private final DynmapFactionsPlugin dynmapFactionsPlugin;
 | 
				
			||||||
    public final String faction;
 | 
					    public final String faction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -14,4 +15,5 @@ class PlayerSetUpdate implements Runnable {
 | 
				
			|||||||
            dynmapFactionsPlugin.updatePlayerSet(faction);
 | 
					            dynmapFactionsPlugin.updatePlayerSet(faction);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,13 +4,12 @@ import java.util.HashMap;
 | 
				
			|||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * scalable flags primitive - used for keeping track of potentially huge number of tiles
 | 
					 * Scalable flags primitive - used for keeping track of potentially huge number of tiles
 | 
				
			||||||
 * <p>
 | 
					 * <p>Represents a flag for each tile, with 2D coordinates based on 0,0 origin. Flags are grouped 64 x 64, represented
 | 
				
			||||||
 * Represents a flag for each tile, with 2D coordinates based on 0,0 origin.  Flags are grouped
 | 
					 * by an array of 64 longs. Each set is stored in a hashmap, keyed by a long computed by ((x/64)<<32)+(y/64).</p>
 | 
				
			||||||
 * 64 x 64, represented by an array of 64 longs.  Each set is stored in a hashmap, keyed by a long
 | 
					 | 
				
			||||||
 * computed by ((x/64)<<32)+(y/64).
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class TileFlags {
 | 
					public class TileFlags {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final Map<Long, long[]> chunkMap = new HashMap<>();
 | 
					    private final Map<Long, long[]> chunkMap = new HashMap<>();
 | 
				
			||||||
    private long last_key = Long.MAX_VALUE;
 | 
					    private long last_key = Long.MAX_VALUE;
 | 
				
			||||||
    private long[] last_row;
 | 
					    private long[] last_row;
 | 
				
			||||||
@@ -59,9 +58,4 @@ public class TileFlags {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void clear() {
 | 
					 | 
				
			||||||
        chunkMap.clear();
 | 
					 | 
				
			||||||
        last_row = null;
 | 
					 | 
				
			||||||
        last_key = Long.MAX_VALUE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,37 +7,37 @@ update:
 | 
				
			|||||||
layer:
 | 
					layer:
 | 
				
			||||||
  name: "Factions"
 | 
					  name: "Factions"
 | 
				
			||||||
  # Make mobs layer hidden by default
 | 
					  # Make mobs layer hidden by default
 | 
				
			||||||
  hidebydefault: false
 | 
					  hideByDefault: false
 | 
				
			||||||
  # ordering priority in layer menu (low goes before high - default is 0)
 | 
					  # ordering priority in layer menu (low goes before high - default is 0)
 | 
				
			||||||
  layerprio: 2
 | 
					  layerPriority: 2
 | 
				
			||||||
  # (optional) set minimum zoom level before layer is visible (0 = defalt, always visible)
 | 
					  # (optional) set minimum zoom level before layer is visible (0 = default, always visible)
 | 
				
			||||||
  minzoom: 0
 | 
					  minZoom: 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Format for popup - substitute values for macros
 | 
					# Format for popup - substitute values for macros
 | 
				
			||||||
infowindow: '<div class="infowindow"><span style="font-size:120%;">%regionname%</span><br />Flags<br /><span style="font-weight:bold;">%flags%</span></div>'
 | 
					infoWindow: '<div class="infoWindow"><span style="font-size:120%;">%regionName%</span><br />Flags<br /><span style="font-weight:bold;">%flags%</span></div>'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Allow players in faction to see one another on dynmap (only relevant if dynmap has 'player-info-protected' enabled)
 | 
					# Allow players in faction to see one another on dynmap (only relevant if dynmap has 'player-info-protected' enabled)
 | 
				
			||||||
visibility-by-faction: true
 | 
					visibilityByFaction: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
regionstyle:
 | 
					regionStyle:
 | 
				
			||||||
  strokeColor: "#FF0000"
 | 
					  strokeColor: "#FF0000"
 | 
				
			||||||
  strokeOpacity: 0.8
 | 
					  strokeOpacity: 0.8
 | 
				
			||||||
  strokeWeight: 3
 | 
					  strokeWeight: 3
 | 
				
			||||||
  fillColor: "#FF0000"
 | 
					  fillColor: "#FF0000"
 | 
				
			||||||
  fillOpacity: 0.35
 | 
					  fillOpacity: 0.35
 | 
				
			||||||
  homeicon: "redflag"
 | 
					  homeIcon: "redflag"
 | 
				
			||||||
  boost: false
 | 
					  boost: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Optional setting to limit which regions to show, by name - if commented out, all regions are shown
 | 
					# Optional setting to limit which regions to show, by name - if commented out, all regions are shown
 | 
				
			||||||
# To show all regions on a given world, add 'world:<worldname>' to the list
 | 
					# To show all regions on a given world, add 'world:<worldName>' to the list
 | 
				
			||||||
visibleregions: [ ]
 | 
					visibleRegions: [ ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Optional setting to hide specific regions, by name
 | 
					# Optional setting to hide specific regions, by name
 | 
				
			||||||
# To hide all regions on a given world, add 'world:<worldname>' to the list
 | 
					# To hide all regions on a given world, add 'world:<worldName>' to the list
 | 
				
			||||||
hiddenregions: [ ]
 | 
					hiddenRegions: [ ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Optional per-region overrides for regionstyle (any defined replace those in regionstyle)
 | 
					# Optional per-region overrides for regionStyle (any defined replace those in regionStyle)
 | 
				
			||||||
custstyle:
 | 
					customStyles:
 | 
				
			||||||
  SafeZone:
 | 
					  SafeZone:
 | 
				
			||||||
    strokeColor: "#0000FF"
 | 
					    strokeColor: "#0000FF"
 | 
				
			||||||
    fillColor: "#0000FF"
 | 
					    fillColor: "#0000FF"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
name: Dynmap-Factions
 | 
					name: Dynmap-Factions
 | 
				
			||||||
main: org.dynmap.factions.DynmapFactionsPlugin
 | 
					main: org.dynmap.factions.DynmapFactionsPlugin
 | 
				
			||||||
version: "${project.version}-${BUILD_NUMBER}"
 | 
					version: "${project.version}-${BUILD_NUMBER}"
 | 
				
			||||||
author: mikeprimm
 | 
					authors: [ EpicKnarvik97, mikeprimm ]
 | 
				
			||||||
depend: [ dynmap, Factions ]
 | 
					depend: [ dynmap, Factions ]
 | 
				
			||||||
 | 
					api-version: 1.20
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user