This commit is contained in:
Bagietas 2024-03-01 14:19:50 -07:00 committed by GitHub
commit 0eb556b7ac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 354 additions and 15 deletions

View File

@ -24,6 +24,7 @@ import fr.xephi.authme.security.crypts.Sha256;
import fr.xephi.authme.service.BackupService;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.MigrationService;
import fr.xephi.authme.service.SpectateLoginService;
import fr.xephi.authme.service.bungeecord.BungeeReceiver;
import fr.xephi.authme.service.yaml.YamlParseException;
import fr.xephi.authme.settings.Settings;
@ -316,6 +317,8 @@ public class AuthMe extends JavaPlugin {
// Wait for tasks and close data source
new TaskCloser(this, database).run();
injector.getIfAvailable(SpectateLoginService.class).removeArmorstands();
// Disabled correctly
Consumer<String> infoLogMethod = logger == null ? getLogger()::info : logger::info;
infoLogMethod.accept("AuthMe " + this.getDescription().getVersion() + " disabled!");

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.data.limbo;
import fr.xephi.authme.task.MessageTask;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.scheduler.BukkitTask;
@ -22,18 +23,20 @@ public class LimboPlayer {
private final Location loc;
private final float walkSpeed;
private final float flySpeed;
private final GameMode gameMode;
private BukkitTask timeoutTask = null;
private MessageTask messageTask = null;
private LimboPlayerState state = LimboPlayerState.PASSWORD_REQUIRED;
public LimboPlayer(Location loc, boolean operator, Collection<UserGroup> groups, boolean fly, float walkSpeed,
float flySpeed) {
float flySpeed, GameMode gameMode) {
this.loc = loc;
this.operator = operator;
this.groups = new ArrayList<>(groups); // prevent bug #2413
this.canFly = fly;
this.walkSpeed = walkSpeed;
this.flySpeed = flySpeed;
this.gameMode = gameMode;
}
/**
@ -45,6 +48,15 @@ public class LimboPlayer {
return loc;
}
/**
* Return the player's original gamemode.
*
* @return The player's gamemode
*/
public GameMode getGameMode() {
return gameMode;
}
/**
* Return whether the player is an operator or not (i.e. whether he is an OP).
*

View File

@ -119,6 +119,7 @@ public class LimboService {
logger.debug("No LimboPlayer found for `{0}` - cannot restore", lowerName);
} else {
player.setOp(limbo.isOperator());
player.setGameMode(limbo.getGameMode());
settings.getProperty(RESTORE_ALLOW_FLIGHT).restoreAllowFlight(player, limbo);
settings.getProperty(RESTORE_FLY_SPEED).restoreFlySpeed(player, limbo);
settings.getProperty(RESTORE_WALK_SPEED).restoreWalkSpeed(player, limbo);

View File

@ -6,6 +6,7 @@ import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.LimboSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@ -13,6 +14,7 @@ import javax.inject.Inject;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import static fr.xephi.authme.util.Utils.isCollectionEmpty;
import static java.util.stream.Collectors.toList;
@ -44,6 +46,7 @@ class LimboServiceHelper {
boolean flyEnabled = player.getAllowFlight();
float walkSpeed = player.getWalkSpeed();
float flySpeed = player.getFlySpeed();
GameMode gameMode = player.getGameMode();
Collection<UserGroup> playerGroups = permissionsManager.hasGroupSupport()
? permissionsManager.getGroups(player) : Collections.emptyList();
@ -52,7 +55,7 @@ class LimboServiceHelper {
.collect(toList());
logger.debug("Player `{0}` has groups `{1}`", player.getName(), String.join(", ", groupNames));
return new LimboPlayer(location, isOperator, playerGroups, flyEnabled, walkSpeed, flySpeed);
return new LimboPlayer(location, isOperator, playerGroups, flyEnabled, walkSpeed, flySpeed, gameMode);
}
/**
@ -97,10 +100,11 @@ class LimboServiceHelper {
boolean canFly = newLimbo.isCanFly() || oldLimbo.isCanFly();
float flySpeed = Math.max(newLimbo.getFlySpeed(), oldLimbo.getFlySpeed());
float walkSpeed = Math.max(newLimbo.getWalkSpeed(), oldLimbo.getWalkSpeed());
GameMode gameMode = Objects.isNull(newLimbo.getGameMode()) ? oldLimbo.getGameMode() : newLimbo.getGameMode();
Collection<UserGroup> groups = getLimboGroups(oldLimbo.getGroups(), newLimbo.getGroups());
Location location = firstNotNull(oldLimbo.getLocation(), newLimbo.getLocation());
return new LimboPlayer(location, isOperator, groups, canFly, walkSpeed, flySpeed);
return new LimboPlayer(location, isOperator, groups, canFly, walkSpeed, flySpeed, gameMode);
}
private static Location firstNotNull(Location first, Location second) {

View File

@ -10,6 +10,7 @@ import com.google.gson.JsonObject;
import fr.xephi.authme.data.limbo.LimboPlayer;
import fr.xephi.authme.data.limbo.UserGroup;
import fr.xephi.authme.service.BukkitService;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.World;
@ -23,6 +24,7 @@ import java.util.function.Function;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.CAN_FLY;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.FLY_SPEED;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.GAMEMODE;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.GROUPS;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.IS_OP;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.LOCATION;
@ -64,8 +66,10 @@ class LimboPlayerDeserializer implements JsonDeserializer<LimboPlayer> {
boolean canFly = getBoolean(jsonObject, CAN_FLY);
float walkSpeed = getFloat(jsonObject, WALK_SPEED, LimboPlayer.DEFAULT_WALK_SPEED);
float flySpeed = getFloat(jsonObject, FLY_SPEED, LimboPlayer.DEFAULT_FLY_SPEED);
int gameModeId = getNumberFromElement(jsonObject.get(GAMEMODE), JsonElement::getAsInt, 0);
GameMode gameMode = GameMode.getByValue(gameModeId);
return new LimboPlayer(loc, operator, groups, canFly, walkSpeed, flySpeed);
return new LimboPlayer(loc, operator, groups, canFly, walkSpeed, flySpeed, gameMode);
}
private Location deserializeLocation(JsonObject jsonObject) {

View File

@ -31,6 +31,7 @@ class LimboPlayerSerializer implements JsonSerializer<LimboPlayer> {
static final String CAN_FLY = "can-fly";
static final String WALK_SPEED = "walk-speed";
static final String FLY_SPEED = "fly-speed";
static final String GAMEMODE = "gamemode";
private static final Gson GSON = new Gson();
@ -66,6 +67,7 @@ class LimboPlayerSerializer implements JsonSerializer<LimboPlayer> {
obj.addProperty(CAN_FLY, limboPlayer.isCanFly());
obj.addProperty(WALK_SPEED, limboPlayer.getWalkSpeed());
obj.addProperty(FLY_SPEED, limboPlayer.getFlySpeed());
obj.addProperty(GAMEMODE, limboPlayer.getGameMode().getValue());
return obj;
}
}

View File

@ -11,6 +11,7 @@ import fr.xephi.authme.process.Management;
import fr.xephi.authme.service.AntiBotService;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.JoinMessageService;
import fr.xephi.authme.service.SpectateLoginService;
import fr.xephi.authme.service.TeleportationService;
import fr.xephi.authme.service.ValidationService;
import fr.xephi.authme.settings.Settings;
@ -19,6 +20,7 @@ import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
@ -49,6 +51,8 @@ import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerShearEntityEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.bukkit.inventory.InventoryView;
import javax.inject.Inject;
@ -91,6 +95,8 @@ public class PlayerListener implements Listener {
private PermissionsManager permissionsManager;
@Inject
private QuickCommandsProtectionManager quickCommandsProtectionManager;
@Inject
private SpectateLoginService spectateLoginService;
// Lowest priority to apply fast protection checks
@EventHandler(priority = EventPriority.LOWEST)
@ -376,6 +382,32 @@ public class PlayerListener implements Listener {
if (spawn != null && spawn.getWorld() != null) {
event.setRespawnLocation(spawn);
}
if (settings.getProperty(RestrictionSettings.SPECTATE_STAND_LOGIN)
&& spectateLoginService.hasStand(event.getPlayer())) {
bukkitService.runTaskLater(() -> spectateLoginService.createStand(event.getPlayer()), 1L);
}
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onToggleSneak(PlayerToggleSneakEvent event) {
if (listenerService.shouldCancelEvent(event.getPlayer())
&& (settings.getProperty(RestrictionSettings.SPECTATE_STAND_LOGIN)
|| spectateLoginService.hasStand(event.getPlayer()))) {
event.setCancelled(true);
}
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onTeleport(PlayerTeleportEvent event) {
if (listenerService.shouldCancelEvent(event.getPlayer())
&& event.getCause() == PlayerTeleportEvent.TeleportCause.SPECTATE
&& event.getPlayer().getGameMode() == GameMode.SPECTATOR
&& (settings.getProperty(RestrictionSettings.SPECTATE_STAND_LOGIN)
|| spectateLoginService.hasStand(event.getPlayer()))) {
spectateLoginService.updateTarget(event.getPlayer());
event.setCancelled(true);
}
}
/*

View File

@ -14,6 +14,7 @@ import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.service.PluginHookService;
import fr.xephi.authme.service.SessionService;
import fr.xephi.authme.service.SpectateLoginService;
import fr.xephi.authme.service.ValidationService;
import fr.xephi.authme.service.bungeecord.BungeeSender;
import fr.xephi.authme.service.bungeecord.MessageType;
@ -83,6 +84,9 @@ public class AsynchronousJoin implements AsynchronousProcess {
@Inject
private ProxySessionManager proxySessionManager;
@Inject
private SpectateLoginService spectateLoginService;
AsynchronousJoin() {
}
@ -199,6 +203,13 @@ public class AsynchronousJoin implements AsynchronousProcess {
int blindTimeOut = (registrationTimeout <= 0) ? 99999 : registrationTimeout;
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, blindTimeOut, 2));
}
if (service.getProperty(RestrictionSettings.SPECTATE_STAND_LOGIN)) {
// The delay is necessary in order to make sure that the player is teleported to spawn
// and after authorization appears in the same place
bukkitService.runTaskLater(() -> spectateLoginService.createStand(player), 1);
}
commandManager.runCommandsOnJoin(player);
});
}

View File

@ -12,11 +12,13 @@ import fr.xephi.authme.process.SynchronousProcess;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.service.JoinMessageService;
import fr.xephi.authme.service.SpectateLoginService;
import fr.xephi.authme.service.TeleportationService;
import fr.xephi.authme.service.bungeecord.BungeeSender;
import fr.xephi.authme.settings.WelcomeMessageConfiguration;
import fr.xephi.authme.settings.commandconfig.CommandManager;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffectType;
@ -58,6 +60,9 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
@Inject
private PermissionsManager permissionsManager;
@Inject
private SpectateLoginService spectateLoginService;
ProcessSyncPlayerLogin() {
}
@ -99,6 +104,11 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
player.removePotionEffect(PotionEffectType.BLINDNESS);
}
if (commonService.getProperty(RestrictionSettings.SPECTATE_STAND_LOGIN)
|| spectateLoginService.hasStand(player)) {
spectateLoginService.removeStand(player);
}
// The Login event now fires (as intended) after everything is processed
bukkitService.callEvent(new LoginEvent(player));

View File

@ -9,6 +9,7 @@ import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.SynchronousProcess;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.service.SpectateLoginService;
import fr.xephi.authme.service.TeleportationService;
import fr.xephi.authme.settings.commandconfig.CommandManager;
import fr.xephi.authme.settings.properties.RegistrationSettings;
@ -44,6 +45,9 @@ public class ProcessSyncPlayerLogout implements SynchronousProcess {
@Inject
private CommandManager commandManager;
@Inject
private SpectateLoginService spectateLoginService;
ProcessSyncPlayerLogout() {
}
@ -65,6 +69,10 @@ public class ProcessSyncPlayerLogout implements SynchronousProcess {
service.send(player, MessageKey.LOGOUT_SUCCESS);
logger.info(player.getName() + " logged out");
if (service.getProperty(RestrictionSettings.SPECTATE_STAND_LOGIN)) {
spectateLoginService.createStand(player);
}
}
private void applyLogoutEffect(Player player) {

View File

@ -2,7 +2,10 @@ package fr.xephi.authme.process.quit;
import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.process.SynchronousProcess;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.service.SpectateLoginService;
import fr.xephi.authme.settings.commandconfig.CommandManager;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import org.bukkit.entity.Player;
import javax.inject.Inject;
@ -10,6 +13,12 @@ import javax.inject.Inject;
public class ProcessSyncPlayerQuit implements SynchronousProcess {
@Inject
private CommonService service;
@Inject
private SpectateLoginService spectateLoginService;
@Inject
private LimboService limboService;
@ -26,6 +35,11 @@ public class ProcessSyncPlayerQuit implements SynchronousProcess {
if (wasLoggedIn) {
commandManager.runCommandsOnLogout(player);
} else {
if (service.getProperty(RestrictionSettings.SPECTATE_STAND_LOGIN)
|| spectateLoginService.hasStand(player)) {
spectateLoginService.removeStand(player);
}
limboService.restoreData(player);
player.saveData(); // #1238: Speed is sometimes not restored properly
}

View File

@ -0,0 +1,109 @@
package fr.xephi.authme.service;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.util.HashMap;
import java.util.Map;
/**
* Sets the player gamemode to Spectator, puts the player in an invisible armorstand and fixes the direction of the view
*/
public class SpectateLoginService {
private Map<Player, ArmorStand> armorStands = new HashMap<>();
private Map<Player, GameMode> gameModeMap = new HashMap<>();
@Inject
private CommonService service;
/**
* Creates a stand for the player
*
* @param player the player
*/
public void createStand(Player player) {
if (player.isDead()) {
return;
}
Location location = player.getLocation();
ArmorStand stand = spawnStand(location);
armorStands.put(player, stand);
gameModeMap.put(player, player.getGameMode());
player.setGameMode(GameMode.SPECTATOR);
player.setSpectatorTarget(stand);
}
/**
* Updates spectator target for the player
*
* @param player the player
*/
public void updateTarget(Player player) {
ArmorStand stand = armorStands.get(player);
if (stand != null) {
player.setSpectatorTarget(stand);
}
}
/**
* Removes the player's stand and deletes effects
*
* @param player the player
*/
public void removeStand(Player player) {
ArmorStand stand = armorStands.get(player);
if (stand != null) {
stand.remove();
player.setSpectatorTarget(null);
player.setGameMode(gameModeMap.get(player));
gameModeMap.remove(player);
armorStands.remove(player);
}
}
/**
* Removes all armorstands and restores player gamemode
*/
public void removeArmorstands() {
for (Player player : armorStands.keySet()) {
removeStand(player);
}
gameModeMap.clear();
armorStands.clear();
}
public boolean hasStand(Player player) {
return armorStands.containsKey(player);
}
/**
* Spawns stand to given location
*
* @param loc spawn location
* @return spawned armorStand
*/
protected ArmorStand spawnStand(Location loc) {
double pitch = service.getProperty(RestrictionSettings.SPECTATE_HEAD_PITCH);
double yaw = service.getProperty(RestrictionSettings.SPECTATE_HEAD_YAW);
Location location = new Location(loc.getWorld(), loc.getX(), loc.getY(), loc.getBlockZ(),
(float) yaw, (float) pitch);
ArmorStand stand = location.getWorld().spawn(location, ArmorStand.class);
stand.setGravity(false);
stand.setAI(false);
stand.setInvisible(true);
return stand;
}
}

View File

@ -193,6 +193,22 @@ public final class RestrictionSettings implements SettingsHolder {
public static final Property<Set<String>> UNRESTRICTED_INVENTORIES =
newLowercaseStringSetProperty("settings.unrestrictions.UnrestrictedInventories");
@Comment({
"While in unregistered/logged out state, should players be set to spectator mode and",
"forced to spectate within a spawn point invisible armor stand, for 0 movement and head",
"pitch + yaw? may be more effective than 'allowMovement' at locking the player in place."
})
public static final Property<Boolean> SPECTATE_STAND_LOGIN =
newProperty("settings.restrictions.spectateStandLogin.enabled", false);
@Comment("Head Yaw position (rotation of X head) for 'spectateStandLogin'.")
public static final Property<Double> SPECTATE_HEAD_YAW =
newProperty("settings.restrictions.spectateStandLogin.headYaw", 0.0f);
@Comment("Head Pitch position (rotation of Y head) for 'spectateStandLogin'.")
public static final Property<Double> SPECTATE_HEAD_PITCH =
newProperty("settings.restrictions.spectateStandLogin.headPitch", 0.0f);
private RestrictionSettings() {
}

View File

@ -106,7 +106,7 @@ public class LimboPlayerTaskManagerTest {
String name = "rats";
Player player = mock(Player.class);
given(player.getName()).willReturn(name);
LimboPlayer limboPlayer = new LimboPlayer(null, true, Collections.singletonList(new UserGroup("grp")), false, 0.1f, 0.0f);
LimboPlayer limboPlayer = new LimboPlayer(null, true, Collections.singletonList(new UserGroup("grp")), false, 0.1f, 0.0f, player.getGameMode());
MessageTask existingMessageTask = mock(MessageTask.class);
limboPlayer.setMessageTask(existingMessageTask);
given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(8);
@ -129,7 +129,7 @@ public class LimboPlayerTaskManagerTest {
String name = "race";
Player player = mock(Player.class);
given(player.getName()).willReturn(name);
LimboPlayer limboPlayer = new LimboPlayer(null, true, Collections.singletonList(new UserGroup("grp")), false, 0.1f, 0.0f);
LimboPlayer limboPlayer = new LimboPlayer(null, true, Collections.singletonList(new UserGroup("grp")), false, 0.1f, 0.0f, player.getGameMode());
given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(12);
given(registrationCaptchaManager.isCaptchaRequired(name)).willReturn(true);
String captcha = "M032";
@ -180,7 +180,7 @@ public class LimboPlayerTaskManagerTest {
public void shouldCancelExistingTimeoutTask() {
// given
Player player = mock(Player.class);
LimboPlayer limboPlayer = new LimboPlayer(null, false, Collections.emptyList(), true, 0.3f, 0.1f);
LimboPlayer limboPlayer = new LimboPlayer(null, false, Collections.emptyList(), true, 0.3f, 0.1f, player.getGameMode());
BukkitTask existingTask = mock(BukkitTask.class);
limboPlayer.setTimeoutTask(existingTask);
given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(18);

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.data.limbo;
import fr.xephi.authme.TestHelper;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.junit.BeforeClass;
import org.junit.Test;
@ -37,9 +38,11 @@ public class LimboServiceHelperTest {
public void shouldMergeLimboPlayers() {
// given
Location newLocation = mock(Location.class);
LimboPlayer newLimbo = new LimboPlayer(newLocation, false, Collections.singletonList(new UserGroup("grp-new")), false, 0.0f, 0.0f);
GameMode newGameMode = GameMode.SPECTATOR;
LimboPlayer newLimbo = new LimboPlayer(newLocation, false, Collections.singletonList(new UserGroup("grp-new")), false, 0.0f, 0.0f, newGameMode);
Location oldLocation = mock(Location.class);
LimboPlayer oldLimbo = new LimboPlayer(oldLocation, true, Collections.singletonList(new UserGroup("grp-old")), true, 0.1f, 0.8f);
GameMode oldGameMode = GameMode.CREATIVE;
LimboPlayer oldLimbo = new LimboPlayer(oldLocation, true, Collections.singletonList(new UserGroup("grp-old")), true, 0.1f, 0.8f, oldGameMode);
// when
LimboPlayer result = limboServiceHelper.merge(newLimbo, oldLimbo);
@ -51,14 +54,15 @@ public class LimboServiceHelperTest {
assertThat(result.isCanFly(), equalTo(true));
assertThat(result.getWalkSpeed(), equalTo(0.1f));
assertThat(result.getFlySpeed(), equalTo(0.8f));
assertThat(result.getGameMode(), equalTo(newGameMode));
}
@Test
public void shouldFallBackToNewLimboForMissingData() {
// given
Location newLocation = mock(Location.class);
LimboPlayer newLimbo = new LimboPlayer(newLocation, false, Collections.singletonList(new UserGroup("grp-new")), true, 0.3f, 0.0f);
LimboPlayer oldLimbo = new LimboPlayer(null, false, Collections.emptyList(), false, 0.1f, 0.1f);
LimboPlayer newLimbo = new LimboPlayer(newLocation, false, Collections.singletonList(new UserGroup("grp-new")), true, 0.3f, 0.0f, GameMode.CREATIVE);
LimboPlayer oldLimbo = new LimboPlayer(null, false, Collections.emptyList(), false, 0.1f, 0.1f, null);
// when
LimboPlayer result = limboServiceHelper.merge(newLimbo, oldLimbo);
@ -70,6 +74,7 @@ public class LimboServiceHelperTest {
assertThat(result.isCanFly(), equalTo(true));
assertThat(result.getWalkSpeed(), equalTo(0.3f));
assertThat(result.getFlySpeed(), equalTo(0.1f));
assertThat(result.getGameMode(), equalTo(oldLimbo.getGameMode()));
}
@Test

View File

@ -243,7 +243,7 @@ public class LimboServiceTest {
private static LimboPlayer convertToLimboPlayer(Player player, Location location, Collection<UserGroup> groups) {
return new LimboPlayer(location, player.isOp(), groups, player.getAllowFlight(),
player.getWalkSpeed(), player.getFlySpeed());
player.getWalkSpeed(), player.getFlySpeed(), player.getGameMode());
}
private Map<String, LimboPlayer> getLimboMap() {

View File

@ -157,10 +157,10 @@ public class DistributedFilesPersistenceHandlerTest {
// given
Player uuidToAdd1 = mockPlayerWithUuid(UNKNOWN_UUID);
Location location1 = mockLocation("1world");
LimboPlayer limbo1 = new LimboPlayer(location1, false, Collections.singletonList(new UserGroup("group-1")), true, 0.1f, 0.2f);
LimboPlayer limbo1 = new LimboPlayer(location1, false, Collections.singletonList(new UserGroup("group-1")), true, 0.1f, 0.2f, uuidToAdd1.getGameMode());
Player uuidToAdd2 = mockPlayerWithUuid(UNKNOWN_UUID2);
Location location2 = mockLocation("2world");
LimboPlayer limbo2 = new LimboPlayer(location2, true, Collections.emptyList(), false, 0.0f, 0.25f);
LimboPlayer limbo2 = new LimboPlayer(location2, true, Collections.emptyList(), false, 0.0f, 0.25f, uuidToAdd2.getGameMode());
// when
persistenceHandler.saveLimboPlayer(uuidToAdd1, limbo1);

View File

@ -115,7 +115,7 @@ public class IndividualFilesPersistenceHandlerTest {
World world = mock(World.class);
given(world.getName()).willReturn("player-world");
Location location = new Location(world, 0.2, 102.25, -89.28, 3.02f, 90.13f);
LimboPlayer limbo = new LimboPlayer(location, true, Collections.singletonList(new UserGroup("primary-grp")), true, 1.2f, 0.8f);
LimboPlayer limbo = new LimboPlayer(location, true, Collections.singletonList(new UserGroup("primary-grp")), true, 1.2f, 0.8f, player.getGameMode());
// when
handler.saveLimboPlayer(player, limbo);

View File

@ -0,0 +1,108 @@
package fr.xephi.authme.service;
import org.bukkit.GameMode;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
/**
* Test for {@link SpectateLoginService}.
*/
@RunWith(MockitoJUnitRunner.class)
public class SpectateLoginServiceTest {
private SpectateLoginService spectateLoginService;
@Mock
private Player mockPlayer;
@Mock
private ArmorStand mockArmorStand;
@Before
public void setUp() {
spectateLoginService = new SpectateLoginService();
}
@Test
public void testCreateStand() {
when(mockPlayer.isDead()).thenReturn(false);
spectateLoginService.createStand(mockPlayer);
verify(mockPlayer).setGameMode(GameMode.SPECTATOR);
verify(mockPlayer).setSpectatorTarget(mockArmorStand);
}
@Test
public void testCreateStandPlayerDead() {
when(mockPlayer.isDead()).thenReturn(true);
spectateLoginService.createStand(mockPlayer);
verify(mockPlayer, never()).setGameMode(any());
verify(mockPlayer, never()).setSpectatorTarget(any());
}
@Test
public void testUpdateTarget() {
spectateLoginService.createStand(mockPlayer);
spectateLoginService.updateTarget(mockPlayer);
verify(mockPlayer).setSpectatorTarget(mockArmorStand);
}
@Test
public void testUpdateTargetNoStand() {
when(mockPlayer.isDead()).thenReturn(false);
spectateLoginService.updateTarget(mockPlayer);
verify(mockPlayer, never()).setSpectatorTarget(any());
}
@Test
public void testRemoveStand() {
spectateLoginService.createStand(mockPlayer);
spectateLoginService.removeStand(mockPlayer);
verify(mockArmorStand).remove();
verify(mockPlayer).setSpectatorTarget(null);
verify(mockPlayer).setGameMode(GameMode.SURVIVAL);
}
@Test
public void testRemoveStandNoStand() {
when(mockPlayer.isDead()).thenReturn(false);
spectateLoginService.removeStand(mockPlayer);
verify(mockArmorStand, never()).remove();
verify(mockPlayer, never()).setSpectatorTarget(any());
verify(mockPlayer, never()).setGameMode(any());
}
@Test
public void testHasStand() {
spectateLoginService.createStand(mockPlayer);
assertTrue(spectateLoginService.hasStand(mockPlayer));
}
@Test
public void testHasStandNoStand() {
when(mockPlayer.isDead()).thenReturn(false);
assertFalse(spectateLoginService.hasStand(mockPlayer));
}
}