-
Notifications
You must be signed in to change notification settings - Fork 518
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SpectateLogin implementation #2552
base: master
Are you sure you want to change the base?
Changes from all commits
8692637
e51fbdf
b9bb7bd
208790e
6de4a9c
37dd1b0
7cd7bdb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
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 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good name! Allows us to remember that this will set players to SPECTATOR game mode :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added a description of the class behavior |
||
|
||
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()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if the server shuts down while players are not logged in? I guess they'll be saved with the spectator game mode, and next time when they'll join, they'll already have spectator game mode and won't be able to leave it. I think this is quite relevant because it's not only an inconvenience to a player, it's giving them access to a game mode that many servers don't want to give to players... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apparently, when the plugin disabled, I can call a function that will remove all armorstands and return the players to their previous state. Is it possible to implement it this way? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please tell me if I can call SpectateLoginService in onDisable directly to remove armorstands, or is this not a good practice? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for the late reply. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Untraceable armorstand is not as critical as players in Spectator gamemode. It would be really cool if it could be done with LimboPlayer There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about adding a "limboArmorStandUUID" field to LimboPlayer? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean adding a way to keep track of whether a player is assigned an armorstand? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mrchefran yes, exactly |
||
|
||
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); | ||
} | ||
|
||
private ArmorStand spawnStand(Location loc) { | ||
double pitch = service.getProperty(RestrictionSettings.HEAD_PITCH); | ||
double yaw = service.getProperty(RestrictionSettings.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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this cause issues if two players have the same location? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This does not affect the position of the stand in any way. The only thing is that players can see the stands of others if their view is directed low enough. The players don't see each other There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So the first armor stand doesn't get replaced by the second one when the same location is used? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, it won't be replaced |
||
|
||
stand.setGravity(false); | ||
stand.setAI(false); | ||
stand.setInvisible(true); | ||
|
||
return stand; | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about listening at the player spawn/respawn event?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+ doesn't the armor stand have to be deleted if the player disconnects as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this will also require a delay, because at this stage it's impossible to change the player gamemode
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Armorstands are removed if an unauthorized player leaves the server