Merge branch 'dev' into redesign

This commit is contained in:
Norbi Peti 2018-11-20 20:38:46 +01:00 committed by GitHub
commit f63443bf44
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 268 additions and 211 deletions

View file

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: com.github.TBMCPlugins.ButtonCore:Towny:master-v1.0-g8d3b6b6-296">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/github/TBMCPlugins/ButtonCore/Towny/master-v1.0-g8d3b6b6-296/Towny-master-v1.0-g8d3b6b6-296.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/github/TBMCPlugins/ButtonCore/Towny/master-v1.0-g8d3b6b6-296/Towny-master-v1.0-g8d3b6b6-296-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/github/TBMCPlugins/ButtonCore/Towny/master-v1.0-g8d3b6b6-296/Towny-master-v1.0-g8d3b6b6-296-sources.jar!/" />
</SOURCES>
</library>
</component>

View file

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: com.github.milkbowl:VaultAPI:master-c8cb88f27a-1">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/github/milkbowl/VaultAPI/master-c8cb88f27a-1/VaultAPI-master-c8cb88f27a-1.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/github/milkbowl/VaultAPI/master-c8cb88f27a-1/VaultAPI-master-c8cb88f27a-1-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/github/milkbowl/VaultAPI/master-c8cb88f27a-1/VaultAPI-master-c8cb88f27a-1-sources.jar!/" />
</SOURCES>
</library>
</component>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MarkdownExportedFiles">
<htmlFiles />
<imageFiles />
<otherFiles />
</component>
</project>

View file

@ -66,7 +66,7 @@
<bodyTop />
<bodyBottom />
</HtmlSettings>
<CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false" isCssUriSerial="true" isCssTextEnabled="false" isDynamicPageWidth="true">
<CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false" isCssUriSerial="false" isCssTextEnabled="false" isDynamicPageWidth="true">
<StylesheetProvider>
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.css" providerName="Default Swing Stylesheet" />
</StylesheetProvider>

View file

@ -132,7 +132,7 @@ publish/
*.publishproj
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
## TO!DO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output

View file

@ -9,10 +9,15 @@ import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.chat.ChatRoom;
import buttondevteam.lib.chat.Color;
import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.TBMCPlayer;
import buttondevteam.lib.player.TBMCPlayerBase;
import com.earth2me.essentials.Essentials;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
@ -23,6 +28,8 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
import java.util.Optional;
import java.util.UUID;
import java.util.logging.Logger;
public class MainPlugin extends JavaPlugin {
@ -46,7 +53,12 @@ public class MainPlugin extends JavaPlugin {
Component.registerComponent(this, new PluginUpdaterComponent());
Component.registerComponent(this, new RestartComponent());
ComponentManager.enableComponents();
TBMCChatAPI.AddCommand(this, MemberCommand.class);
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this);
ChromaGamerBase.addConverter(commandSender -> Optional.ofNullable(commandSender instanceof ConsoleCommandSender || commandSender instanceof BlockCommandSender
? TBMCPlayer.getPlayer(new UUID(0, 0), TBMCPlayer.class) : null)); //Console & cmdblocks
ChromaGamerBase.addConverter(sender -> Optional.ofNullable(sender instanceof Player
? TBMCPlayer.getPlayer(((Player) sender).getUniqueId(), TBMCPlayer.class) : null)); //Players, has higher priority
TBMCCoreAPI.RegisterUserClass(TBMCPlayerBase.class);
TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fOOC§f", Color.White, "ooc", null));
Channel.GlobalChat.IDs = new String[]{"g"}; //Support /g as well

View file

@ -0,0 +1,55 @@
package buttondevteam.core;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.TBMCCommandBase;
import lombok.val;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
@CommandClass(modOnly = true, path = "member")
public class MemberCommand extends TBMCCommandBase {
@Override
public boolean OnCommand(CommandSender sender, String alias, String[] args) {
if (args.length < 2)
return false;
final boolean add;
if (args[0].equalsIgnoreCase("add"))
add = true;
else if (args[0].equalsIgnoreCase("remove"))
add = false;
else
return false;
Bukkit.getScheduler().runTaskAsynchronously(MainPlugin.Instance, () -> {
if (MainPlugin.permission == null) {
sender.sendMessage("§cError: No permission plugin found!");
return;
}
val op = Bukkit.getOfflinePlayer(args[1]);
if (!op.hasPlayedBefore()) {
sender.sendMessage("§cCannot find player or haven't played before.");
return;
}
if (add) {
if (MainPlugin.permission.playerAddGroup(null, op, "member"))
sender.sendMessage("§b" + op.getName() + " added as a member!");
else
sender.sendMessage("§cFailed to add " + op.getName() + " as a member!");
} else {
if (MainPlugin.permission.playerRemoveGroup(null, op, "member"))
sender.sendMessage("§b" + op.getName() + " removed as a member!");
else
sender.sendMessage("§bFailed to remove " + op.getName() + " as a member!");
}
});
return true;
}
@Override
public String[] GetHelpText(String alias) {
return new String[]{ //
"06---- Member ----", //
"Add or remove server members.", //
"Usage: /member <add|remove> <player>" //
};
}
}

View file

@ -32,7 +32,7 @@ public class ScheduledRestartCommand extends TBMCCommandBase {
return false;
}
final int restarttime = restartcounter = ticks;
restartbar = Bukkit.createBossBar("Server restart in " + ticks / 20f, BarColor.RED, BarStyle.SOLID,
restartbar = Bukkit.createBossBar("Server restart in " + ticks / 20f + "s", BarColor.RED, BarStyle.SOLID,
BarFlag.DARKEN_SKY);
restartbar.setProgress(1);
Bukkit.getOnlinePlayers().forEach(p -> restartbar.addPlayer(p));

View file

@ -1,53 +0,0 @@
package buttondevteam.lib;
import buttondevteam.lib.chat.Channel;
import lombok.Getter;
import org.bukkit.command.CommandSender;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import javax.annotation.Nullable;
/**
* The purpose of this event is to determine which group the given channel belongs to
* or to validate that they have access to the given group chat.<br>
* It's not meant to be called from any plugin - it should be only created to use the helper methods
*/
@Getter
public class TBMCChannelConnectFakeEvent extends TBMCChatEventBase implements Cancellable {
private static final HandlerList handlers = new HandlerList();
@Nullable
private final CommandSender sender;
/**
* Using this the group will be determined based on the sender.
*
* @param sender The sender to get the group from
* @param channel The channel to use
*/
public TBMCChannelConnectFakeEvent(CommandSender sender, Channel channel) {
super(channel, "Channel connecting message. One of the things users should never see in action.", -1, null);
this.sender = sender;
}
/**
* Using this the given group will be validated and used.
*
* @param groupid The group to use, for example the name of a town or nation
* @param channel The channel to use
*/
public TBMCChannelConnectFakeEvent(String groupid, Channel channel) {
super(channel, "Channel connecting message. One of the things users should never see in action.", -1, groupid);
this.sender = null;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View file

@ -1,7 +1,6 @@
package buttondevteam.lib;
import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.chat.Channel.RecipientTestResult;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
@ -31,20 +30,14 @@ public abstract class TBMCChatEventBase extends Event implements Cancellable {
* Note: Errors are sent to the sender automatically
*/
public boolean shouldSendTo(CommandSender sender) {
if (channel.filteranderrormsg == null)
return true;
RecipientTestResult result = channel.filteranderrormsg.apply(sender);
return result.errormessage == null && score == result.score;
return channel.shouldSendTo(sender, score);
}
/**
* Note: Errors are sent to the sender automatically
*/
public int getMCScore(CommandSender sender) {
if (channel.filteranderrormsg == null)
return 0;
RecipientTestResult result = channel.filteranderrormsg.apply(sender);
return result.errormessage == null ? result.score : -1;
return channel.getMCScore(sender);
}
/**
@ -54,9 +47,6 @@ public abstract class TBMCChatEventBase extends Event implements Cancellable {
*/
@Nullable
public String getGroupID(CommandSender sender) {
if (channel.filteranderrormsg == null)
return "everyone";
RecipientTestResult result = channel.filteranderrormsg.apply(sender);
return result.errormessage == null ? result.groupID : null;
return channel.getGroupID(sender); //TODO: Performance-wise it'd be much better to use serialization for player data - it's only converted once
}
}

View file

@ -14,6 +14,18 @@ import java.util.function.Function;
import java.util.function.Predicate;
public class Channel {
/**
* Specifies a score that means it's OK to send - but it does not define any groups, only send or not send. See {@link #GROUP_EVERYONE}
*/
public static final int SCORE_SEND_OK = 0;
/**
* Specifies a score that means the user doesn't have permission to see or send the message. Any negative value has the same effect.
*/
public static final int SCORE_SEND_NOPE = -1;
/**
* Send the message to everyone <i>who has access to the channel</i> - this does not necessarily mean all players
*/
public static final String GROUP_EVERYONE = "everyone";
public final String DisplayName;
public final Color color;
public final String ID;
@ -57,6 +69,43 @@ public class Channel {
this.filteranderrormsg = s -> filteranderrormsg.apply((T) this, s);
}
public boolean isGlobal() {
return filteranderrormsg == null;
}
/**
* Note: Errors are sent to the sender automatically
*
* @param sender The user we're sending to
* @param score The (source) score to compare with the user's
*/
public boolean shouldSendTo(CommandSender sender, int score) {
return score == getMCScore(sender); //If there's any error, the score won't be equal
}
/**
* Note: Errors are sent to the sender automatically
*/
public int getMCScore(CommandSender sender) {
if (filteranderrormsg == null)
return SCORE_SEND_OK;
RecipientTestResult result = filteranderrormsg.apply(sender);
return result.errormessage == null ? result.score : SCORE_SEND_NOPE;
}
/**
* Note: Errors are sent to the sender automatically<br>
* <p>
* Null means don't send
*/
@Nullable
public String getGroupID(CommandSender sender) {
if (filteranderrormsg == null)
return GROUP_EVERYONE;
RecipientTestResult result = filteranderrormsg.apply(sender);
return result.errormessage == null ? result.groupID : null;
}
public static List<Channel> getChannels() {
return channels;
}
@ -76,12 +125,12 @@ public class Channel {
public static Function<CommandSender, RecipientTestResult> noScoreResult(Predicate<CommandSender> filter,
String errormsg) {
return s -> filter.test(s) ? new RecipientTestResult(0, "everyone") : new RecipientTestResult(errormsg);
return s -> filter.test(s) ? new RecipientTestResult(SCORE_SEND_OK, GROUP_EVERYONE) : new RecipientTestResult(errormsg);
}
public static <T extends Channel> BiFunction<T, CommandSender, RecipientTestResult> noScoreResult(
BiPredicate<T, CommandSender> filter, String errormsg) {
return (this_, s) -> filter.test(this_, s) ? new RecipientTestResult(0, "everyone") : new RecipientTestResult(errormsg);
return (this_, s) -> filter.test(this_, s) ? new RecipientTestResult(SCORE_SEND_OK, GROUP_EVERYONE) : new RecipientTestResult(errormsg);
}
public static Channel GlobalChat;
@ -95,7 +144,7 @@ public class Channel {
public static class RecipientTestResult {
public String errormessage = null;
public int score = -1; // Anything below 0 is "never send"
public int score = SCORE_SEND_NOPE; // Anything below 0 is "never send"
public String groupID = null;
/**
@ -110,7 +159,7 @@ public class Channel {
/**
* Creates a result that indicates a <b>success</b>
*
* @param score The score that identifies the target group. For example, the index of the town or nation to send to.
* @param score The score that identifies the target group. <b>Must be non-negative.</b> For example, the index of the town or nation to send to.
* @param groupID The ID of the target group.
*/
public RecipientTestResult(int score, String groupID) {

View file

@ -9,10 +9,6 @@ import org.bukkit.command.CommandSender;
@Builder
@Getter
public class ChatMessage {
/**
* The MC channel to send the message to.
*/
private final Channel channel;
/**
* The sender which sends the message.
*/
@ -44,6 +40,6 @@ public class ChatMessage {
@NonNull
public static ChatMessageBuilder builder(Channel channel, CommandSender sender, ChromaGamerBase user, String message) {
return builder().channel(channel).sender(sender).user(user).message(message);
return builder().sender(sender).user(user).message(message);
}
}

View file

@ -214,19 +214,31 @@ public class TBMCChatAPI {
* @return The event cancelled state
*/
public static boolean SendChatMessage(ChatMessage cm) {
if (!Channel.getChannels().contains(cm.getChannel()))
throw new RuntimeException("Channel " + cm.getChannel().DisplayName + " not registered!");
return SendChatMessage(cm, cm.getUser().channel().get());
}
/**
* Sends a chat message to Minecraft. Make sure that the channel is registered with {@link #RegisterChatChannel(Channel)}.<br>
* This will also send the error message to the sender, if they can't send the message.
*
* @param cm The message to send
* @param channel The MC channel to send in
* @return The event cancelled state
*/
public static boolean SendChatMessage(ChatMessage cm, Channel channel) {
if (!Channel.getChannels().contains(channel))
throw new RuntimeException("Channel " + channel.DisplayName + " not registered!");
val permcheck = cm.getPermCheck() == null ? cm.getSender() : cm.getPermCheck();
RecipientTestResult rtr = getScoreOrSendError(cm.getChannel(), permcheck);
RecipientTestResult rtr = getScoreOrSendError(channel, permcheck);
int score = rtr.score;
if (score == -1 || rtr.groupID == null)
return true;
TBMCChatPreprocessEvent eventPre = new TBMCChatPreprocessEvent(cm.getSender(), cm.getChannel(), cm.getMessage());
TBMCChatPreprocessEvent eventPre = new TBMCChatPreprocessEvent(cm.getSender(), channel, cm.getMessage());
Bukkit.getPluginManager().callEvent(eventPre);
if (eventPre.isCancelled())
return true;
TBMCChatEvent event;
event = new TBMCChatEvent(cm.getSender(), cm.getUser(), cm.getChannel(), eventPre.getMessage(), score, cm.isFromCommand(), rtr.groupID, permcheck != cm.getSender());
event = new TBMCChatEvent(cm.getSender(), cm.getUser(), channel, eventPre.getMessage(), score, cm.isFromCommand(), rtr.groupID, permcheck != cm.getSender());
Bukkit.getPluginManager().callEvent(event);
return event.isCancelled();
}

View file

@ -0,0 +1,25 @@
package buttondevteam.lib.player;
import buttondevteam.lib.chat.Channel;
import org.bukkit.configuration.file.YamlConfiguration;
public class ChannelPlayerData { //I just want this to work
private final PlayerData<String> data;
private final Channel def;
public ChannelPlayerData(String name, YamlConfiguration yaml, Channel def) {
data = new PlayerData<>(name, yaml, "");
this.def = def;
}
public Channel get() {
String str = data.get();
if (str.isEmpty())
return def;
return Channel.getChannels().stream().filter(c -> str.equals(c.ID)).findAny().orElse(def);
}
public void set(Channel value) {
data.set(value.ID);
}
}

View file

@ -1,14 +1,19 @@
package buttondevteam.lib.player;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Channel;
import com.google.common.collect.HashBiMap;
import lombok.val;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
@ChromaGamerEnforcer
public abstract class ChromaGamerBase implements AutoCloseable {
@ -92,6 +97,32 @@ public abstract class ChromaGamerBase implements AutoCloseable {
return null;
}
private static ArrayList<Function<CommandSender, ? extends Optional<? extends ChromaGamerBase>>> senderConverters = new ArrayList<>();
/**
* Adds a converter to the start of the list.
*
* @param converter The converter that returns an object corresponding to the sender or null, if it's not the right type.
*/
public static <T extends ChromaGamerBase> void addConverter(Function<CommandSender, Optional<T>> converter) {
senderConverters.add(0, converter);
}
/**
* Get from the given sender. the object's type will depend on the sender's type. May be null, but shouldn't be.
*
* @param sender The sender to use
* @return A user as returned by a converter or null if none can supply it
*/
public static ChromaGamerBase getFromSender(CommandSender sender) {
for (val converter : senderConverters) {
val ocg = converter.apply(sender);
if (ocg.isPresent())
return ocg.get();
}
return null;
}
/**
* Saves the player. It'll pass all exceptions to the caller. To automatically handle the exception, use {@link #save()} instead.
*/
@ -123,8 +154,10 @@ public abstract class ChromaGamerBase implements AutoCloseable {
if (!playerTypes.containsKey(getClass()))
throw new RuntimeException("Class not registered as a user class! Use TBMCCoreAPI.RegisterUserClass");
final String ownFolder = getFolder();
user.plugindata.set(ownFolder + "_id", plugindata.getString(ownFolder + "_id"));
final String userFolder = user.getFolder();
if (ownFolder.equalsIgnoreCase(userFolder))
throw new RuntimeException("Do not connect two accounts of the same type! Type: "+ownFolder);
user.plugindata.set(ownFolder + "_id", plugindata.getString(ownFolder + "_id"));
plugindata.set(userFolder + "_id", user.plugindata.getString(userFolder + "_id"));
Consumer<YamlConfiguration> sync = sourcedata -> {
final String sourcefolder = sourcedata == plugindata ? ownFolder : userFolder;
@ -225,7 +258,8 @@ public abstract class ChromaGamerBase implements AutoCloseable {
}
@SuppressWarnings("rawtypes")
private final HashMap<String, EnumPlayerData> dataenummap = new HashMap<>();
private final HashMap<String, EnumPlayerData> dataenummap = new HashMap<>();
private ChannelPlayerData datachannel;
/**
* Use from a data() method, which is in a method with the name of the key. For example, use flair() for the enclosing method of the outer data() to save to and load from "flair"
@ -243,7 +277,7 @@ public abstract class ChromaGamerBase implements AutoCloseable {
/**
* Use from a method with the name of the key. For example, use flair() for the enclosing method to save to and load from "flair"
*
*
* @return A data object with methods to get and set
*/
@SuppressWarnings("unchecked")
@ -255,6 +289,19 @@ public abstract class ChromaGamerBase implements AutoCloseable {
return dataenummap.get(mname);
}
/**
* Channel
*
* @return A data object with methods to get and set
*/
@SuppressWarnings("unchecked")
protected ChannelPlayerData dataChannel(Channel def) { //TODO: Make interface with fromString() method and require use of that for player data types
ThrowIfNoUser();
if (datachannel == null)
datachannel = new ChannelPlayerData("channel", plugindata, def);
return datachannel;
}
/**
* Get player information. This method calls the {@link TBMCPlayerGetInfoEvent} to get all the player information across the TBMC plugins.
*
@ -271,4 +318,10 @@ public abstract class ChromaGamerBase implements AutoCloseable {
public enum InfoTarget {
MCHover, MCCommand, Discord
}
//-----------------------------------------------------------------
public ChannelPlayerData channel() {
return dataChannel(Channel.GlobalChat);
}
}

View file

@ -206,119 +206,4 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase {
if (keys.size() > 1) // PlayerName is always saved, but we don't need a file for just that
super.close();
}
/*private static void renameInTowny(TBMCPlayerBase player, Resident resident, String newName, TownyDatabaseHandler tdh) throws Exception {
val field=TownyDataSource.class.getDeclaredField("lock"); //TODO: Remove
field.setAccessible(true);
Lock lock=(Lock)field.get(tdh);
lock.lock(); //From Towny, removed the economy part, as that works by UUIDs
String oldName = resident.getName();
try {
String filteredName;
try {
filteredName = NameValidation.checkAndFilterName(newName);
} catch (InvalidNameException var39) {
throw new NotRegisteredException(var39.getMessage());
}
double balance = 0.0D;
Town town = null;
long registered = 0L;
long lastOnline = 0L;
boolean isMayor = false;
boolean isJailed = false;
int JailSpawn = 0;
//Don't do anything with economy balance as that works based on UUIDs
List<Resident> friends = resident.getFriends();
List<String> nationRanks = resident.getNationRanks();
TownyPermission permissions = resident.getPermissions();
String surname = resident.getSurname();
String title = resident.getTitle();
if (resident.hasTown()) {
town = resident.getTown();
}
List<TownBlock> townBlocks = resident.getTownBlocks();
List<String> townRanks = resident.getTownRanks();
registered = resident.getRegistered();
lastOnline = resident.getLastOnline();
isMayor = resident.isMayor();
isJailed = resident.isJailed();
int JailSpawn = resident.getJailSpawn();
this.deleteResident(resident);
this.universe.getResidentMap().remove(oldName.toLowerCase());
resident.setName(filteredName);
this.universe.getResidentMap().put(filteredName.toLowerCase(), resident);
if (transferBalance && TownySettings.isUsingEconomy()) {
try {
resident.setBalance(balance, "Rename Player - Transfer to new account");
} catch (EconomyException var37) {
var37.printStackTrace();
}
}
resident.setFriends(friends);
resident.setNationRanks(nationRanks);
resident.setPermissions(permissions.toString());
resident.setSurname(surname);
resident.setTitle(title);
resident.setTown(town);
resident.setTownblocks(townBlocks);
resident.setTownRanks(townRanks);
resident.setRegistered(registered);
resident.setLastOnline(lastOnline);
if (isMayor) {
try {
town.setMayor(resident);
} catch (TownyException var36) {
;
}
}
resident.setJailed(isJailed);
resident.setJailSpawn(JailSpawn);
this.saveResidentList();
this.saveResident(resident);
if (town != null) {
this.saveTown(town);
}
Iterator i$ = townBlocks.iterator();
while(i$.hasNext()) {
TownBlock tb = (TownBlock)i$.next();
this.saveTownBlock(tb);
}
Resident oldResident = new Resident(oldName);
List<Resident> toSaveResident = new ArrayList(this.getResidents());
Iterator i$ = toSaveResident.iterator();
Resident toCheck;
while(i$.hasNext()) {
toCheck = (Resident)i$.next();
if (toCheck.hasFriend(oldResident)) {
try {
toCheck.removeFriend(oldResident);
toCheck.addFriend(resident);
} catch (NotRegisteredException var35) {
var35.printStackTrace();
}
}
}
i$ = toSaveResident.iterator();
while(i$.hasNext()) {
toCheck = (Resident)i$.next();
this.saveResident(toCheck);
}
} finally {
this.lock.unlock();
}
BukkitTools.getPluginManager().callEvent(new RenameResidentEvent(oldName, resident));
this.universe.setChangedNotify(TownyObservableType.RENAME_RESIDENT);
}*/
}

View file

@ -10,4 +10,6 @@ commands:
primerestart:
description: Restarts the server as soon as nobody is online.
randomtp:
description: teleport player to random location within world border. Every five players teleport to the same general area, and then a new general area is randomly selected for the next five players.
description: teleport player to random location within world border. Every five players teleport to the same general area, and then a new general area is randomly selected for the next five players.
member:
description: Add or remove a member

View file

@ -37,13 +37,4 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View file

@ -28,6 +28,12 @@
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader> <!-- https://stackoverflow.com/a/53012553/2703239 -->
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>