Begin improving documentation: update README, add some JavaDoc.
parent
f7f37a18f8
commit
ea101d5c07
75
README.md
75
README.md
|
@ -1,14 +1,71 @@
|
|||
# Wasteland
|
||||
My friend Obamallama is making an apocalyse-themed Minecraft server,
|
||||
which is in many ways the spiritual successor to the Minecraft servers Skuli_Steinulf and I used to run.
|
||||
# Wasteland Plugin Suite
|
||||
This is the plugin suite I am developing for my work-in-progress Minecraft server, Wasteland.
|
||||
|
||||
This plugin will implement the custom functionality for that server that he cannot accomplish through existing plugins.
|
||||
The system we (Skuli and I) originally used to implement our custom functionality is long dead,
|
||||
so Obama cannot simply copy over the original code.
|
||||
I will also be implementing new features that did not exist in the original server.
|
||||
Wasteland is a post-nuclear zombie apocalypse server with a gameplay experience dramatically different from any other.
|
||||
It includes custom world generation, a custom (sophisticated!) spawn algorithm, a radiation system,
|
||||
world and weather events, a player rank system based on the Marines, handles chat,
|
||||
and includes many, many other supplementary features.
|
||||
|
||||
Obama has not been working on the server for a few months now, but still intends to continue.
|
||||
I will continue work on this plugin when that time comes.
|
||||
The server is spiritual successor to the servers Skuli_Steinulf and I used to run.
|
||||
Huge credit goes to Skuli_Steinulf for founding it all, and he and my friends Lyokan and Obamallama for many ideas and much help.
|
||||
|
||||
## The Wasteland Plugin
|
||||
I don't feel like documenting all of this plugin's features right now; I'll do it later.
|
||||
|
||||
## The Wasteland Permissions Plugin
|
||||
This plugin was motivated because existing permissions were either
|
||||
* buggy,
|
||||
* incompatible with the `/reload` command,
|
||||
* not fully compatible with Java 9+ (LuckPerms in particular), or
|
||||
* encompassed a broader scope than I wanted, interfering with other features.
|
||||
|
||||
So I implemented my own, an extremely simple plugin which loads groups and player permissions from a YAML config file.
|
||||
It only took two or three hours to write, but is exactly what I need and does the job perfectly.
|
||||
|
||||
For documentation on how to use this plugin, please see the default `config.yml`.
|
||||
|
||||
## The Wasteland ModTools plugin
|
||||
**This plugin is currently only partially implemented.**
|
||||
|
||||
This plugin provides tools which both help moderators track what rule infractions a player has committed,
|
||||
and help server administrators hold moderators accountable through an audit log.
|
||||
|
||||
This plugin provides these basic commands:
|
||||
* `/ban` and `/unban`
|
||||
* `/kick`
|
||||
* `/mute` and `/unmute`
|
||||
* `/warn`
|
||||
|
||||
All bans, kicks, mutes, and warnings are logged,
|
||||
both to help moderators track what rule infractions a player has committed,
|
||||
and to help server administrators hold moderators accountable through an audit log.
|
||||
|
||||
It is also possible to set the maximum length of bans or mutes that a moderator can issue
|
||||
in the configuration file.
|
||||
|
||||
You may view the currently active bans and mutes using `/bans` and `/mutes` respectively,
|
||||
or see the history of infractions a player has committed using `/infractions`.
|
||||
|
||||
You can remove an infraction from a player's account using commands like `/unwarn`.
|
||||
Removing an infraction from a player's account will not remove the infraction from the audit log,
|
||||
and in fact will just add that the infraction was removed to the audit log.
|
||||
|
||||
You may view the audit log using `/auditlog`.
|
||||
|
||||
For more information on how to use these commands please see the in game `/help` or the `plugin.yml`
|
||||
For more information on how to configure this plugin, please see the default `config.yml`.
|
||||
|
||||
### Infraction histories & audit logs
|
||||
A set of moderator tools which logs all moderator actions,
|
||||
|
||||
### Manuals
|
||||
There are two built-in manuals: `/rules` and `/faq`.
|
||||
These manuals provide both brief overviews and more detail which players may view if they wish.
|
||||
|
||||
It is also possible for moderators to (forcibly) show players portions of the rules or faq,
|
||||
as a brief reminder of the rules or to quickly answer a question they were asking.
|
||||
|
||||
Please see the in-game `/help` menu or `plugin.yml` for more information on how to use these commands.
|
||||
|
||||
## Current Features
|
||||
* Tracks how many zombies or husks a player kills.
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
#
|
||||
# Groups are collections of permissions which make it easier to assign a set of permissions to a lot of players at once.
|
||||
# It also makes it easier to define permission hierarchies (e.g. trial mod, mod, head mod, admin),
|
||||
# through the inheritence mechanism.
|
||||
#
|
||||
# However, you are not required to use them and can assign permissions directly to players if you choose.
|
||||
#
|
||||
# groups:
|
||||
# # The default group will only be assigned to players with no other group assigned.
|
||||
# # If you assign a player a group, they will not receive the default permissions,
|
||||
# # unless you explicitly unclude them as a member of this group.
|
||||
# default:
|
||||
# permission.for.newbies: true # track a player's permission
|
||||
# <groupName>:
|
||||
|
@ -16,7 +25,7 @@
|
|||
# c.d: true
|
||||
#
|
||||
# players:
|
||||
# # You *must* use player UUIDs, not player names.
|
||||
# # You *must* use player UUIDs, not player names, because player names are not guaranteed to be unique across sessions.
|
||||
# # You can see a player's UUID in the server log when they join, or look it up online.
|
||||
# # I would recommend including the player's name as a comment to help you remember whose UUID this is.
|
||||
# <player-uuid>:
|
||||
|
|
|
@ -8,32 +8,34 @@ version '0.1.0'
|
|||
sourceCompatibility = 14
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenCentral()
|
||||
|
||||
maven {
|
||||
url = 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/'
|
||||
maven {
|
||||
url = 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/'
|
||||
|
||||
content {
|
||||
includeGroup 'org.bukkit'
|
||||
includeGroup 'org.spigotmc'
|
||||
content {
|
||||
includeGroup 'org.bukkit'
|
||||
includeGroup 'org.spigotmc'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
maven { url = 'https://oss.sonatype.org/content/repositories/snapshots' }
|
||||
maven { url = 'https://oss.sonatype.org/content/repositories/snapshots' }
|
||||
|
||||
maven {
|
||||
name = "Towny"
|
||||
url = "https://maven.pkg.github.com/TownyAdvanced/Towny"
|
||||
credentials {
|
||||
username = project.findProperty("gpr.user") ?: System.getenv("GITHUB_ACTOR")
|
||||
password = project.findProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN")
|
||||
maven {
|
||||
name = "Towny"
|
||||
url = "https://maven.pkg.github.com/TownyAdvanced/Towny"
|
||||
credentials {
|
||||
username = project.findProperty("gpr.user") ?: System.getenv("GITHUB_ACTOR")
|
||||
password = project.findProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly 'org.spigotmc:spigot-api:1.16.4-R0.1-SNAPSHOT'
|
||||
compileOnly 'com.palmergames.bukkit.towny:Towny:0.96.2.17'
|
||||
compileOnly 'com.google.guava:guava:21.0'
|
||||
// compileOnly 'com.google.guava:guava:27.1
|
||||
// APIs and libraries provided with the server distribution
|
||||
compileOnly 'org.spigotmc:spigot-api:1.16.4-R0.1-SNAPSHOT'
|
||||
compileOnly 'com.google.guava:guava:21.0'
|
||||
|
||||
// Plugin APIs
|
||||
compileOnly 'com.palmergames.bukkit.towny:Towny:0.96.2.17'
|
||||
}
|
|
@ -4,6 +4,9 @@ import org.bukkit.command.Command;
|
|||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
* The command used to manage the state of the {@link Wasteland plugin} as a whole.
|
||||
*/
|
||||
class CommandWasteland implements CommandExecutor {
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
|
|
|
@ -2,13 +2,68 @@ package me.jamestmartin.wasteland;
|
|||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This plugin implements a lot of functionality,
|
||||
* and although it is all needed together to create the desired player experience,
|
||||
* most parts of the plugin do not depend on most other parts.
|
||||
* For example, the spawning subsystem does not depend on the chat subsystem.
|
||||
* However, splitting the plugin into many tiny independent plugins would be excessive.
|
||||
*
|
||||
* <p>
|
||||
* Thus, instead, the plugin is split into many submodules which each manages its own
|
||||
* state, configuration, et cetera independently.
|
||||
* This interface is a common interface to those submodules.
|
||||
*
|
||||
* @see WastelandState The plugin's main state class which contains all of the other substates.
|
||||
*/
|
||||
public interface Substate {
|
||||
/**
|
||||
* Register all:
|
||||
* <ul>
|
||||
* <li>commands
|
||||
* <li>listeners
|
||||
* <li>permission attachments
|
||||
* </ul>
|
||||
* and connect to any databases.
|
||||
*
|
||||
* @param plugin
|
||||
* Bukkit requires a {@link JavaPlugin} instances
|
||||
* to register commands and listeners *for*.
|
||||
*/
|
||||
void register(JavaPlugin plugin);
|
||||
|
||||
/**
|
||||
* Disable and unregister all:
|
||||
* <ul>
|
||||
* <li>commands
|
||||
* <li>listeners
|
||||
* <li>permission attachments
|
||||
* </ul>
|
||||
* and disconnect from any databases.
|
||||
*
|
||||
* @param plugin
|
||||
* Bukkit requires a {@link JavaPlugin} instances
|
||||
* to unregister commands and listeners *from*.
|
||||
*
|
||||
* @see #disable(JavaPlugin)
|
||||
*/
|
||||
void unregister(JavaPlugin plugin);
|
||||
|
||||
/**
|
||||
* Close everything that needs to be closed without unregistering anything.
|
||||
* This is called when the plugin is being disabled.
|
||||
* <p>
|
||||
* Close everything that needs to be closed without
|
||||
* {@link #unregister(JavaPlugin) unregistering} anything.
|
||||
*
|
||||
* <p>
|
||||
* When a plugin is disabled, Bukkit automatically unregisters most things, like commands, listeners, and attachments,
|
||||
* and in fact if we tried to unregister themselves, exceptions would be thrown.
|
||||
* However, it may still be necessary to do things like clean up database connections,
|
||||
* which is the purpose of this method.
|
||||
*
|
||||
* @param plugin The plugin being disabled.
|
||||
*
|
||||
* @see #unregister(JavaPlugin)
|
||||
*/
|
||||
default void disable(JavaPlugin plugin) { }
|
||||
}
|
||||
|
|
|
@ -18,10 +18,27 @@ public class Wasteland extends JavaPlugin {
|
|||
private WastelandConfig config;
|
||||
private WastelandState state;
|
||||
|
||||
/**
|
||||
* The active, enabled instance of this plugin.
|
||||
*
|
||||
* @return
|
||||
* May be null if the plugin:
|
||||
* <ul>
|
||||
* <li>has been loaded but not yet enabled,
|
||||
* <li>has been disabled,
|
||||
* <li>is in the process of reloading.
|
||||
* </ul>
|
||||
*/
|
||||
public static Wasteland getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* Either the proxy for accessing Towny if the plugin is loaded,
|
||||
* or a dummy implementation.
|
||||
* @see TownyDependency
|
||||
*/
|
||||
public static TownyDependency getTowny() {
|
||||
return towny;
|
||||
}
|
||||
|
@ -43,12 +60,18 @@ public class Wasteland extends JavaPlugin {
|
|||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
// We do not need to disable
|
||||
state.disable(this);
|
||||
state = null;
|
||||
towny = null;
|
||||
instance = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Completely disable and re-enable the plugin,
|
||||
* which has the effect of reloading the plugin's configuration
|
||||
* and database.
|
||||
*/
|
||||
public void reload() {
|
||||
getLogger().info("Reloading wasteland...");
|
||||
saveDefaultConfig();
|
||||
|
@ -64,6 +87,7 @@ public class Wasteland extends JavaPlugin {
|
|||
config = ConfigParser.parseConfig(getConfig());
|
||||
}
|
||||
|
||||
/** Register all commands, listeners, permission attachments, etc. */
|
||||
private void register() {
|
||||
try {
|
||||
state = new WastelandState(config);
|
||||
|
@ -80,6 +104,7 @@ public class Wasteland extends JavaPlugin {
|
|||
state.register(this);
|
||||
}
|
||||
|
||||
/** Disable all commands, unregister all listeners and permission attachments, etc. */
|
||||
private void unregister() {
|
||||
state.unregister(this);
|
||||
state = null;
|
||||
|
|
|
@ -15,7 +15,15 @@ import me.jamestmartin.wasteland.spawns.SpawnsState;
|
|||
import me.jamestmartin.wasteland.store.StoreState;
|
||||
import me.jamestmartin.wasteland.store.sqlite.SqliteState;
|
||||
|
||||
public class WastelandState implements Substate {
|
||||
/**
|
||||
* This class contains virtually all of the plugin's internal state.
|
||||
* Keeping this out of {@link Wasteland the plugin's main class}
|
||||
* makes it easier to keep track of and reload,
|
||||
* because we can reset the plugin's state just by setting this to null
|
||||
* and creating a new instance,
|
||||
* rather than having to handle each sub-state individually.
|
||||
*/
|
||||
class WastelandState implements Substate {
|
||||
private final CommandWasteland commandWasteland;
|
||||
|
||||
private final StoreState storeState;
|
||||
|
|
|
@ -69,7 +69,7 @@ public class ChatConfig implements ChatFormatter {
|
|||
}
|
||||
|
||||
private String formatPlayerTownPrefix(Player player) {
|
||||
Optional<String> townTag = Wasteland.getTowny().getTownAbbreviation(player);
|
||||
Optional<String> townTag = Wasteland.getTowny().getTownTag(player);
|
||||
if (townTag.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -5,13 +5,20 @@ import java.util.HashSet;
|
|||
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
/**
|
||||
* Collections of {@link EntityType}s.
|
||||
*
|
||||
* The primary purpose of this class is to provide {@link #lookupEntityType(String)}.
|
||||
*/
|
||||
class EntityTypes {
|
||||
private static final EntityType[] BOSSES = {
|
||||
/** The ender dragon and wither. */
|
||||
public static final EntityType[] BOSSES = {
|
||||
EntityType.ENDER_DRAGON,
|
||||
EntityType.WITHER,
|
||||
};
|
||||
|
||||
private static final EntityType[] HOSTILES = {
|
||||
/** Monsters which will attack the player on sight. */
|
||||
public static final EntityType[] HOSTILES = {
|
||||
EntityType.BLAZE,
|
||||
EntityType.CREEPER,
|
||||
EntityType.DROWNED,
|
||||
|
@ -44,7 +51,8 @@ class EntityTypes {
|
|||
EntityType.ZOMBIE_VILLAGER,
|
||||
};
|
||||
|
||||
private static final EntityType[] NEUTRALS = {
|
||||
/** Mobs which will attack the player only if provoked. */
|
||||
public static final EntityType[] NEUTRALS = {
|
||||
EntityType.BEE,
|
||||
EntityType.CAVE_SPIDER,
|
||||
EntityType.DOLPHIN,
|
||||
|
@ -62,21 +70,23 @@ class EntityTypes {
|
|||
|
||||
/**
|
||||
* Monsters which are eligible for the monster hunter achievement but are not hostile.
|
||||
* All hostile monsters are eligable.
|
||||
* All hostile monsters are eligible.
|
||||
*/
|
||||
private static final EntityType[] NON_HOSTILE_MONSTERS = {
|
||||
public static final EntityType[] NON_HOSTILE_MONSTERS = {
|
||||
EntityType.CAVE_SPIDER,
|
||||
EntityType.ENDERMAN,
|
||||
EntityType.SPIDER,
|
||||
EntityType.ZOMBIFIED_PIGLIN,
|
||||
};
|
||||
|
||||
private static final EntityType[] SPIDERS = {
|
||||
/** Spiders and cave spiders. */
|
||||
public static final EntityType[] SPIDERS = {
|
||||
EntityType.CAVE_SPIDER,
|
||||
EntityType.SPIDER,
|
||||
};
|
||||
|
||||
private static final EntityType[] ZOMBIES = {
|
||||
/** All zombie variants, including zombie villagers, zoglins, etc. */
|
||||
public static final EntityType[] ZOMBIES = {
|
||||
EntityType.GIANT,
|
||||
EntityType.ZOGLIN,
|
||||
EntityType.ZOMBIE,
|
||||
|
@ -85,6 +95,22 @@ class EntityTypes {
|
|||
EntityType.ZOMBIFIED_PIGLIN,
|
||||
};
|
||||
|
||||
/**
|
||||
* @param typeName
|
||||
* Either a string representing an EntityType value,
|
||||
* or a lower-case string representing one of the entity collections provided by this class.
|
||||
* @return
|
||||
* Either the single entity type represented by the string provided,
|
||||
* or the collection of entity types specified by the string provided.
|
||||
*
|
||||
* @see EntityType#valueOf(String)
|
||||
* @see BOSSES bosses
|
||||
* @see HOSTILES hostiles
|
||||
* @see NEUTRALS neutrals
|
||||
* @see NON_HOSTILE_MONSTERS monsters
|
||||
* @see SPIDERS spiders
|
||||
* @see ZOMBIES zombies
|
||||
*/
|
||||
public static EntityType[] lookupEntityType(String typeName) {
|
||||
switch(typeName) {
|
||||
case "bosses":
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
package me.jamestmartin.wasteland.towny;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface TownAbbreviationProvider {
|
||||
public Optional<String> getTownAbbreviation(Player player);
|
||||
}
|
|
@ -1,5 +1,21 @@
|
|||
package me.jamestmartin.wasteland.towny;
|
||||
|
||||
public interface TownyDependency extends TownAbbreviationProvider {
|
||||
/**
|
||||
* <p>
|
||||
* This plugin would like to be able to use features of Towny if it is available,
|
||||
* without being unable to function if Towny is not available.
|
||||
* <p>
|
||||
* Any class which imports Towny packages will not be possible to load if Towny is not available,
|
||||
* so instead, we restrict all Towny imports to one class, and decide whether or not to load it at runtime.
|
||||
* If Towny is not available, we will instead use a dummy class which does nothing and returns nothing.
|
||||
* <p>
|
||||
* We split the functionality of towny that one might want to access into various provider interfaces.
|
||||
* This interface collects them all into a single interface so that they might all be implemented
|
||||
* at once and loaded at once through the enabled/disabled implementation.
|
||||
*
|
||||
* @see TownyDisabled The dummy implementation used if Towny is not available.
|
||||
* @see TownyEnabled The actual implementation used if Towny *is* available.
|
||||
*/
|
||||
public interface TownyDependency extends TownyTagProvider {
|
||||
|
||||
}
|
||||
|
|
|
@ -4,9 +4,24 @@ import java.util.Optional;
|
|||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A set of dummy implementations of Towny-related functionality
|
||||
* which we will substitute for the actual functionality if Towny is not installed.
|
||||
* <p>
|
||||
* These methods do nothing and return nothing.
|
||||
*
|
||||
* @see TownyDependency
|
||||
* @see TownyEnabled
|
||||
*/
|
||||
public class TownyDisabled implements TownyDependency {
|
||||
@Override
|
||||
public Optional<String> getTownAbbreviation(Player player) {
|
||||
public Optional<String> getTownTag(Player player) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getNationTag(Player player) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,22 +3,57 @@ package me.jamestmartin.wasteland.towny;
|
|||
import java.util.Optional;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.palmergames.bukkit.towny.TownyAPI;
|
||||
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
|
||||
import com.palmergames.bukkit.towny.object.Government;
|
||||
import com.palmergames.bukkit.towny.object.Nation;
|
||||
import com.palmergames.bukkit.towny.object.Resident;
|
||||
import com.palmergames.bukkit.towny.object.Town;
|
||||
|
||||
/**
|
||||
* The one class in the entire plugin that directly depends on Towny.
|
||||
* If Towny is installed, it will be dynamically loaded;
|
||||
* if not, a dummy implementation will be loaded instead.
|
||||
*
|
||||
* @see TownyDependency
|
||||
* @see TownyDisabled
|
||||
*/
|
||||
public class TownyEnabled implements TownyDependency {
|
||||
private static Resident getResident(Player player) throws NotRegisteredException {
|
||||
return TownyAPI.getInstance().getDataSource().getResident(player.getName());
|
||||
}
|
||||
|
||||
private static Optional<Town> getTown(Player player) {
|
||||
try {
|
||||
return Optional.of(getResident(player).getTown());
|
||||
} catch (NotRegisteredException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private static Optional<Nation> getNation(Player player) {
|
||||
try {
|
||||
return Optional.of(getResident(player).getTown().getNation());
|
||||
} catch (NotRegisteredException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private static Optional<String> getTag(Government gov) {
|
||||
String tag = gov.getTag();
|
||||
if (tag == null || tag.isBlank()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getTownAbbreviation(Player player) {
|
||||
try {
|
||||
Resident resident = TownyAPI.getInstance().getDataSource().getResident(player.getName());
|
||||
String tag = resident.getTown().getTag();
|
||||
if (tag != null && !tag.equals("")) {
|
||||
return Optional.of(tag);
|
||||
}
|
||||
} catch (NotRegisteredException e) {
|
||||
}
|
||||
return Optional.empty();
|
||||
public Optional<String> getTownTag(Player player) {
|
||||
return getTown(player).flatMap(TownyEnabled::getTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getNationTag(Player player) {
|
||||
return getNation(player).flatMap(TownyEnabled::getTag);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
package me.jamestmartin.wasteland.towny;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* Provides the tags for the town and nation that a player is a member of,
|
||||
* if Towny is installed and the player is a member of a town or nation.
|
||||
*/
|
||||
public interface TownyTagProvider {
|
||||
/**
|
||||
* <p>
|
||||
* A town tag is a short identifier for a town which the town may opt to set.
|
||||
* It may be used in places where the town's full name would be too long,
|
||||
* for example to include what town a player is member of in chat.
|
||||
* <p>
|
||||
* If Towny is installed, the player is a member of a town,
|
||||
* and that town has opted to set a town tag,
|
||||
* then this method will get that town tag.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
* If the player is in a town which has a town tag, that town tag;
|
||||
* otherwise, the return value will be empty.
|
||||
* @see #getNationTag(Player)
|
||||
*/
|
||||
public Optional<String> getTownTag(Player player);
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A nation tag is a short identifier for a nation which the nation may opt to set.
|
||||
* It may be used in places where the nation's full name would be too long,
|
||||
* for example to include what nation a player is member of in chat.
|
||||
* <p>
|
||||
* If Towny is installed, the player is a member of a nation,
|
||||
* and that nation has opted to set a nation tag,
|
||||
* then this method will get that nation tag.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
* If the player is in a nation which has a nation tag, that town nation;
|
||||
* otherwise, the return value will be empty.
|
||||
* @see #getTownTag(Player)
|
||||
*/
|
||||
public Optional<String> getNationTag(Player player);
|
||||
}
|
Loading…
Reference in New Issue