diff --git a/WitchRush/src/main/java/net/berrygames/witchrush/WitchPlayer.java b/WitchRush/src/main/java/net/berrygames/witchrush/WitchPlayer.java index 3ef280e..2f90131 100644 --- a/WitchRush/src/main/java/net/berrygames/witchrush/WitchPlayer.java +++ b/WitchRush/src/main/java/net/berrygames/witchrush/WitchPlayer.java @@ -5,6 +5,7 @@ import net.berrygames.witchrush.team.TeamInfos; import net.berrygames.witchrush.team.TeamManager; import net.berrygames.witchrush.tools.ItemFactory; import net.berrygames.witchrush.tools.Locations; +import net.berrygames.witchrush.tools.ScoreboardSign; import org.bukkit.Color; import org.bukkit.DyeColor; import org.bukkit.Material; @@ -78,7 +79,27 @@ public class WitchPlayer { } public void sendGameScoreboard(){ + ScoreboardSign scoreboard = new ScoreboardSign(player, "§5§lWitchRush"); + scoreboard.setLine(15, WitchRush.get().getState()+":"+WitchRush.get().getStateTimer()); + scoreboard.setLine(14, "§r "); + scoreboard.setLine(13, manager.isInLife(TeamInfos.BLEU) ? "§a✔": "§c✖"+ "§bBleu"+ manager.getTeamBoss(TeamInfos.BLEU).getLife()); + scoreboard.setLine(12, manager.isInLife(TeamInfos.ROUGE) ? "§a✔": "§c✖"+ "§cRouge"+ manager.getTeamBoss(TeamInfos.ROUGE).getLife()); + scoreboard.setLine(11, manager.isInLife(TeamInfos.JAUNE) ? "§a✔": "§c✖"+ "§eJaune"+ manager.getTeamBoss(TeamInfos.JAUNE).getLife()); + scoreboard.setLine(10, manager.isInLife(TeamInfos.VERT) ? "§a✔": "§c✖"+ "§aVert"+ manager.getTeamBoss(TeamInfos.VERT).getLife()); + scoreboard.setLine(9, "§r "); + scoreboard.setLine(8, "§7Kills: "+WitchPlayer.get(player).getKills()); + scoreboard.setLine(7, "§7Morts: "+WitchPlayer.get(player).getDeath()); + scoreboard.setLine(6, "§r "); + scoreboard.setLine(5, "§6play.berrygames.net"); + } + public void sendLobbyScoreboard(){ + ScoreboardSign scoreboard = new ScoreboardSign(player, "§5§lWitchRush"); + scoreboard.setLine(14, "§r "); + scoreboard.setLine(13, "§7Joueurs: "); + scoreboard.setLine(12, "§d"+WitchPlayer.getwitchMap().size()+"/16"); + scoreboard.setLine(9, "§r "); + scoreboard.setLine(8, "§6play.berrygames.net"); } public static WitchPlayer get(final Player player) { diff --git a/WitchRush/src/main/java/net/berrygames/witchrush/WitchRush.java b/WitchRush/src/main/java/net/berrygames/witchrush/WitchRush.java index 3b8d89c..cfb8991 100644 --- a/WitchRush/src/main/java/net/berrygames/witchrush/WitchRush.java +++ b/WitchRush/src/main/java/net/berrygames/witchrush/WitchRush.java @@ -2,6 +2,10 @@ package net.berrygames.witchrush; import net.berrygames.witchrush.commands.CommandsManager; import net.berrygames.witchrush.game.GameState; +import net.berrygames.witchrush.game.task.DeathMatchTask; +import net.berrygames.witchrush.game.task.NoPVPTask; +import net.berrygames.witchrush.game.task.PVPTask; +import net.berrygames.witchrush.game.task.StartTask; import net.berrygames.witchrush.listeners.ListenersManager; import net.berrygames.witchrush.team.TeamManager; import org.bukkit.Bukkit; @@ -56,6 +60,21 @@ public class WitchRush extends JavaPlugin { public GameState getState(){ return this.gameState; } + public String getStateTimer(){ + switch (getState()){ + case WAITING: + return null; + case STARTING: + return new StartTask().getTimer(); + case NOWITCH: + return new NoPVPTask().getTimer(); + case PVP: + return new PVPTask().getTimer(); + case DEATH_MATCH: + return new DeathMatchTask().getTimer(); + } + return null; + } public TeamManager getTeamManager() { return teamManager; } diff --git a/WitchRush/src/main/java/net/berrygames/witchrush/game/task/DeathMatchTask.java b/WitchRush/src/main/java/net/berrygames/witchrush/game/task/DeathMatchTask.java index 2d43be7..f86cb4a 100644 --- a/WitchRush/src/main/java/net/berrygames/witchrush/game/task/DeathMatchTask.java +++ b/WitchRush/src/main/java/net/berrygames/witchrush/game/task/DeathMatchTask.java @@ -1,17 +1,30 @@ package net.berrygames.witchrush.game.task; +import net.berrygames.witchrush.WitchPlayer; import net.berrygames.witchrush.WitchRush; import net.berrygames.witchrush.game.WinManager; import net.berrygames.witchrush.team.TeamInfos; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; public class DeathMatchTask extends BukkitRunnable { - int lifeLosed = 0; + private int sec = 0; + private int min = 3 * 60; @Override public void run() { + if(this.sec == 60){ + this.sec = 0; + this.min += min; + } + + for(Player pls : Bukkit.getOnlinePlayers()){ + WitchPlayer.get(pls).sendGameScoreboard(); + } + for(TeamInfos infos : TeamInfos.values()){ if(WitchRush.get().getTeamManager().isInLife(infos)){ if(WitchRush.get().getTeamManager().getBossEntityMap().get(infos).getLife() > 0){ @@ -23,7 +36,10 @@ public class DeathMatchTask extends BukkitRunnable { } new WinManager(); + this.sec++; + } - lifeLosed++; + public String getTimer() { + return this.min+":"+this.sec; } } diff --git a/WitchRush/src/main/java/net/berrygames/witchrush/game/task/NoPVPTask.java b/WitchRush/src/main/java/net/berrygames/witchrush/game/task/NoPVPTask.java index 373439b..2222f3b 100644 --- a/WitchRush/src/main/java/net/berrygames/witchrush/game/task/NoPVPTask.java +++ b/WitchRush/src/main/java/net/berrygames/witchrush/game/task/NoPVPTask.java @@ -1,24 +1,37 @@ package net.berrygames.witchrush.game.task; +import net.berrygames.witchrush.WitchPlayer; import net.berrygames.witchrush.WitchRush; import net.berrygames.witchrush.game.GameState; import net.berrygames.witchrush.team.TeamInfos; import net.berrygames.witchrush.tools.Locations; import net.berrygames.witchrush.tools.WitchBoss; import org.bukkit.Bukkit; +import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; public class NoPVPTask extends BukkitRunnable { - private int timer = 3 * 20; + private int sec = 0; + private int min = 3 * 60; @Override public void run() { - if(timer == 0){ + + if(this.sec == 0){ + this.sec = 60; + this.min -= min; + } + + if(this.min == 0 && this.sec == 0){ new PVPTask().runTaskTimer(WitchRush.get(), 0, 20); WitchRush.get().setState(GameState.PVP); + for(Player pls : Bukkit.getOnlinePlayers()){ + WitchPlayer.get(pls).sendGameScoreboard(); + } + Bukkit.broadcastMessage(WitchRush.prefix()+"Les §6Witchs §dsont apparues, §d§nBonne chance à vous !"); new WitchBoss(TeamInfos.ROUGE, Locations.WITCH_ROUGE.getLocation()); new WitchBoss(TeamInfos.BLEU, Locations.WITCH_BLEU.getLocation()); @@ -27,6 +40,10 @@ public class NoPVPTask extends BukkitRunnable { new HealthRunnable().runTaskTimer(WitchRush.get(), 0L, 20L); cancel(); } - timer--; + sec--; + } + + public String getTimer() { + return this.min+":"+this.sec; } } diff --git a/WitchRush/src/main/java/net/berrygames/witchrush/game/task/PVPTask.java b/WitchRush/src/main/java/net/berrygames/witchrush/game/task/PVPTask.java index 7318ff1..a7a6cad 100644 --- a/WitchRush/src/main/java/net/berrygames/witchrush/game/task/PVPTask.java +++ b/WitchRush/src/main/java/net/berrygames/witchrush/game/task/PVPTask.java @@ -1,19 +1,32 @@ package net.berrygames.witchrush.game.task; +import net.berrygames.witchrush.WitchPlayer; import net.berrygames.witchrush.WitchRush; +import net.berrygames.witchrush.game.GameState; import net.berrygames.witchrush.game.WinManager; import org.bukkit.Bukkit; +import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; public class PVPTask extends BukkitRunnable { - int timer = 20 * 60; + private int sec = 0; + private int min = 20 * 60; @Override public void run() { - if(timer == 0){ + if(this.sec == 0){ + this.sec = 60; + this.min -= min; + } + + if(this.min == 0 && this.sec == 0){ new DeathMatchTask().runTaskTimer(WitchRush.get(), 0, 20 * 5); + for(Player pls : Bukkit.getOnlinePlayers()){ + WitchPlayer.get(pls).sendGameScoreboard(); + } + WitchRush.get().setState(GameState.DEATH_MATCH); Bukkit.broadcastMessage(WitchRush.prefix()+"Le DeathMatch commence."); Bukkit.broadcastMessage(WitchRush.prefix()+"Les §5§lWitchs §dcommencent à perdre de la vie !"); cancel(); @@ -21,6 +34,11 @@ public class PVPTask extends BukkitRunnable { new WinManager(); - timer--; + this.sec--; } + + public String getTimer() { + return this.min+":"+this.sec; + } + } diff --git a/WitchRush/src/main/java/net/berrygames/witchrush/game/task/StartTask.java b/WitchRush/src/main/java/net/berrygames/witchrush/game/task/StartTask.java index 216568c..102bb7f 100644 --- a/WitchRush/src/main/java/net/berrygames/witchrush/game/task/StartTask.java +++ b/WitchRush/src/main/java/net/berrygames/witchrush/game/task/StartTask.java @@ -10,11 +10,17 @@ import org.bukkit.scheduler.BukkitRunnable; public class StartTask extends BukkitRunnable { - private int timer = WitchRush.get().isForcedStart() ? 30 : 120; + private int sec = 0; + private int min = WitchRush.get().isForcedStart() ? 0 : 2 * 60; @Override public void run() { + if(this.sec == 0){ + this.sec = 60; + this.min -= min; + } + if (Bukkit.getOnlinePlayers().size() < 4 && !WitchRush.get().isForcedStart()) { Bukkit.broadcastMessage(WitchRush.prefix()+"Il n'y a pas assez de joueurs pour lancer la partie !"); WitchRush.get().setState(GameState.WAITING); @@ -22,30 +28,47 @@ public class StartTask extends BukkitRunnable { return; } - if(timer == 0){ + if(this.min == 0 && this.sec == 0){ WitchRush.get().getTeamManager().checkNoTeamPlayers(); new GameManager(); cancel(); } - if(timer == 120 || timer == 60 || timer == 30 || timer == 15 - || timer == 10 || timer == 5 || timer == 4 || timer == 3 || timer == 2){ - Bukkit.broadcastMessage(WitchRush.prefix()+"Lancement de la partie dans §5"+timer+" §dsecondes"); - for(Player pls : Bukkit.getOnlinePlayers()){ - pls.playSound(pls.getLocation(), Sound.BLOCK_NOTE_PLING, 1, 1); + while(this.min == 2){ + if(this.sec == 0){ + Bukkit.broadcastMessage(WitchRush.prefix()+"Lancement de la partie dans §5"+this.sec+" §dsecondes"); + for(Player pls : Bukkit.getOnlinePlayers()){ + pls.playSound(pls.getLocation(), Sound.BLOCK_NOTE_PLING, 1, 1); + } } } - if(timer == 1){ - Bukkit.broadcastMessage(WitchRush.prefix()+"Lancement de la partie dans §5"+timer+" §dseconde"); - for(Player pls : Bukkit.getOnlinePlayers()){ - pls.playSound(pls.getLocation(), Sound.BLOCK_NOTE_PLING, 1, 1); + while(this.min == 1){ + if(this.sec == 30){ + Bukkit.broadcastMessage(WitchRush.prefix()+"Lancement de la partie dans §5"+this.sec+" §dsecondes"); + for(Player pls : Bukkit.getOnlinePlayers()){ + pls.playSound(pls.getLocation(), Sound.BLOCK_NOTE_PLING, 1, 1); + } } } - - for(Player pls : Bukkit.getOnlinePlayers()){ - pls.setLevel(timer); + while(this.min == 0){ + if(this.sec == 30 || this.sec == 15 || this.sec == 10 || this.sec == 5 || this.sec == 4 + || this.sec == 3 || this.sec == 2){ + Bukkit.broadcastMessage(WitchRush.prefix()+"Lancement de la partie dans §5"+this.sec+" §dsecondes"); + for(Player pls : Bukkit.getOnlinePlayers()){ + pls.playSound(pls.getLocation(), Sound.BLOCK_NOTE_PLING, 1, 1); + } + } + if(this.sec == 1){ + Bukkit.broadcastMessage(WitchRush.prefix()+"Lancement de la partie dans §5"+this.sec+" §dseconde"); + for(Player pls : Bukkit.getOnlinePlayers()){ + pls.playSound(pls.getLocation(), Sound.BLOCK_NOTE_PLING, 1, 1); + } + } } + this.sec--; + } - timer--; + public String getTimer() { + return min+":"+sec; } } diff --git a/WitchRush/src/main/java/net/berrygames/witchrush/listeners/players/PlayerJoin.java b/WitchRush/src/main/java/net/berrygames/witchrush/listeners/players/PlayerJoin.java index d6ae6e1..c988eae 100644 --- a/WitchRush/src/main/java/net/berrygames/witchrush/listeners/players/PlayerJoin.java +++ b/WitchRush/src/main/java/net/berrygames/witchrush/listeners/players/PlayerJoin.java @@ -35,7 +35,7 @@ public class PlayerJoin implements Listener { player.setFoodLevel(20); player.teleport(Locations.PLAYER_SPAWN_WAITING_ROOM.getLocation()); witchPlayer.sendWaitingStuff(); - witchPlayer.sendGameScoreboard(); + witchPlayer.sendLobbyScoreboard(); TeamsTagsManager.setNameTag(player, player.getName(), "§7"); diff --git a/WitchRush/src/main/java/net/berrygames/witchrush/listeners/servers/PingServer.java b/WitchRush/src/main/java/net/berrygames/witchrush/listeners/servers/PingServer.java index 584d4ff..12c4af7 100644 --- a/WitchRush/src/main/java/net/berrygames/witchrush/listeners/servers/PingServer.java +++ b/WitchRush/src/main/java/net/berrygames/witchrush/listeners/servers/PingServer.java @@ -10,6 +10,7 @@ public class PingServer implements Listener { @EventHandler public void ping(ServerListPingEvent e){ e.setMotd(WitchRush.prefix()+WitchRush.get().getState()); + e.setMaxPlayers(16); } } diff --git a/WitchRush/src/main/java/net/berrygames/witchrush/tools/ScoreboardSign.java b/WitchRush/src/main/java/net/berrygames/witchrush/tools/ScoreboardSign.java new file mode 100644 index 0000000..6b4dfcc --- /dev/null +++ b/WitchRush/src/main/java/net/berrygames/witchrush/tools/ScoreboardSign.java @@ -0,0 +1,371 @@ +package net.berrygames.witchrush.tools; + +import net.minecraft.server.v1_12_R1.*; +import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +public class ScoreboardSign { + + private boolean created = false; + private final VirtualTeam[] lines = new VirtualTeam[15]; + private final Player player; + private String objectiveName; + + /** + * Create a scoreboard sign for a given player and using a specifig objective name + * @param player the player viewing the scoreboard sign + * @param objectiveName the name of the scoreboard sign (displayed at the top of the scoreboard) + */ + public ScoreboardSign(Player player, String objectiveName) { + this.player = player; + this.objectiveName = objectiveName; + } + + /** + * Send the initial creation packets for this scoreboard sign. Must be called at least once. + */ + public void create() { + if (created) + return; + + PlayerConnection player = getPlayer(); + player.sendPacket(createObjectivePacket(0, objectiveName)); + player.sendPacket(setObjectiveSlot()); + int i = 0; + while (i < lines.length) + sendLine(i++); + + created = true; + } + + /** + * Send the packets to remove this scoreboard sign. A destroyed scoreboard sign must be recreated using {@link ScoreboardSign#create()} in order + * to be used again + */ + public void destroy() { + if (!created) + return; + + getPlayer().sendPacket(createObjectivePacket(1, null)); + for (VirtualTeam team : lines) + if (team != null) + getPlayer().sendPacket(team.removeTeam()); + + created = false; + } + + /** + * Change the name of the objective. The name is displayed at the top of the scoreboard. + * @param name the name of the objective, max 32 char + */ + public void setObjectiveName(String name) { + this.objectiveName = name; + if (created) + getPlayer().sendPacket(createObjectivePacket(2, name)); + } + + /** + * Change a scoreboard line and send the packets to the player. Can be called async. + * @param line the number of the line (0 <= line < 15) + * @param value the new value for the scoreboard line + */ + public void setLine(int line, String value) { + VirtualTeam team = getOrCreateTeam(line); + String old = team.getCurrentPlayer(); + + if (old != null && created) + getPlayer().sendPacket(removeLine(old)); + + team.setValue(value); + sendLine(line); + } + + /** + * Remove a given scoreboard line + * @param line the line to remove + */ + public void removeLine(int line) { + VirtualTeam team = getOrCreateTeam(line); + String old = team.getCurrentPlayer(); + + if (old != null && created) { + getPlayer().sendPacket(removeLine(old)); + getPlayer().sendPacket(team.removeTeam()); + } + + lines[line] = null; + } + + /** + * Get the current value for a line + * @param line the line + * @return the content of the line + */ + public String getLine(int line) { + if (line > 14) + return null; + if (line < 0) + return null; + return getOrCreateTeam(line).getValue(); + } + + /** + * Get the team assigned to a line + * @return the {@link VirtualTeam} used to display this line + */ + public VirtualTeam getTeam(int line) { + if (line > 14) + return null; + if (line < 0) + return null; + return getOrCreateTeam(line); + } + + private PlayerConnection getPlayer() { + return ((CraftPlayer) player).getHandle().playerConnection; + } + + @SuppressWarnings("rawtypes") + private void sendLine(int line) { + if (line > 14) + return; + if (line < 0) + return; + if (!created) + return; + + int score = (15 - line); + VirtualTeam val = getOrCreateTeam(line); + for (Packet packet : val.sendLine()) + getPlayer().sendPacket(packet); + getPlayer().sendPacket(sendScore(val.getCurrentPlayer(), score)); + val.reset(); + } + + private VirtualTeam getOrCreateTeam(int line) { + if (lines[line] == null) + lines[line] = new VirtualTeam("__fakeScore" + line); + + return lines[line]; + } + + /* + Factories + */ + private PacketPlayOutScoreboardObjective createObjectivePacket(int mode, String displayName) { + PacketPlayOutScoreboardObjective packet = new PacketPlayOutScoreboardObjective(); + // Nom de l'objectif + setField(packet, "a", player.getName()); + + // Mode + // 0 : créer + // 1 : Supprimer + // 2 : Mettre à jour + setField(packet, "d", mode); + + if (mode == 0 || mode == 2) { + setField(packet, "b", displayName); + setField(packet, "c", IScoreboardCriteria.EnumScoreboardHealthDisplay.INTEGER); + } + + return packet; + } + + private PacketPlayOutScoreboardDisplayObjective setObjectiveSlot() { + PacketPlayOutScoreboardDisplayObjective packet = new PacketPlayOutScoreboardDisplayObjective(); + // Slot + setField(packet, "a", 1); + setField(packet, "b", player.getName()); + + return packet; + } + + private PacketPlayOutScoreboardScore sendScore(String line, int score) { + PacketPlayOutScoreboardScore packet = new PacketPlayOutScoreboardScore(line); + setField(packet, "b", player.getName()); + setField(packet, "c", score); + setField(packet, "d", PacketPlayOutScoreboardScore.EnumScoreboardAction.CHANGE); + + return packet; + } + + private PacketPlayOutScoreboardScore removeLine(String line) { + return new PacketPlayOutScoreboardScore(line); + } + + /** + * This class is used to manage the content of a line. Advanced users can use it as they want, but they are encouraged to read and understand the + * code before doing so. Use these methods at your own risk. + */ + public class VirtualTeam { + private final String name; + private String prefix; + private String suffix; + private String currentPlayer; + private String oldPlayer; + + private boolean prefixChanged, suffixChanged, playerChanged = false; + private boolean first = true; + + private VirtualTeam(String name, String prefix, String suffix) { + this.name = name; + this.prefix = prefix; + this.suffix = suffix; + } + + private VirtualTeam(String name) { + this(name, "", ""); + } + + public String getName() { + return name; + } + + public String getPrefix() { + return prefix; + } + + public void setPrefix(String prefix) { + if (this.prefix == null || !this.prefix.equals(prefix)) + this.prefixChanged = true; + this.prefix = prefix; + } + + public String getSuffix() { + return suffix; + } + + public void setSuffix(String suffix) { + if (this.suffix == null || !this.suffix.equals(prefix)) + this.suffixChanged = true; + this.suffix = suffix; + } + + private PacketPlayOutScoreboardTeam createPacket(int mode) { + PacketPlayOutScoreboardTeam packet = new PacketPlayOutScoreboardTeam(); + setField(packet, "a", name); + setField(packet, "b", ""); + setField(packet, "c", prefix); + setField(packet, "d", suffix); + setField(packet, "i", 0); + setField(packet, "e", "always"); + setField(packet, "g", 0); + setField(packet, "i", mode); + + return packet; + } + + public PacketPlayOutScoreboardTeam createTeam() { + return createPacket(0); + } + + public PacketPlayOutScoreboardTeam updateTeam() { + return createPacket(2); + } + + public PacketPlayOutScoreboardTeam removeTeam() { + PacketPlayOutScoreboardTeam packet = new PacketPlayOutScoreboardTeam(); + setField(packet, "a", name); + setField(packet, "i", 1); + first = true; + return packet; + } + + public void setPlayer(String name) { + if (this.currentPlayer == null || !this.currentPlayer.equals(name)) + this.playerChanged = true; + this.oldPlayer = this.currentPlayer; + this.currentPlayer = name; + } + + public Iterable sendLine() { + List packets = new ArrayList<>(); + + if (first) { + packets.add(createTeam()); + } else if (prefixChanged || suffixChanged) { + packets.add(updateTeam()); + } + + if (first || playerChanged) { + if (oldPlayer != null) // remove these two lines ? + packets.add(addOrRemovePlayer(4, oldPlayer)); // + packets.add(changePlayer()); + } + + if (first) + first = false; + + return packets; + } + + public void reset() { + prefixChanged = false; + suffixChanged = false; + playerChanged = false; + oldPlayer = null; + } + + public PacketPlayOutScoreboardTeam changePlayer() { + return addOrRemovePlayer(3, currentPlayer); + } + + @SuppressWarnings("unchecked") + public PacketPlayOutScoreboardTeam addOrRemovePlayer(int mode, String playerName) { + PacketPlayOutScoreboardTeam packet = new PacketPlayOutScoreboardTeam(); + setField(packet, "a", name); + setField(packet, "i", mode); + + try { + Field f = packet.getClass().getDeclaredField("h"); + f.setAccessible(true); + ((List) f.get(packet)).add(playerName); + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + + return packet; + } + + public String getCurrentPlayer() { + return currentPlayer; + } + + public String getValue() { + return getPrefix() + getCurrentPlayer() + getSuffix(); + } + + public void setValue(String value) { + if (value.length() <= 16) { + setPrefix(""); + setSuffix(""); + setPlayer(value); + } else if (value.length() <= 32) { + setPrefix(value.substring(0, 16)); + setPlayer(value.substring(16)); + setSuffix(""); + } else if (value.length() <= 48) { + setPrefix(value.substring(0, 16)); + setPlayer(value.substring(16, 32)); + setSuffix(value.substring(32)); + } else { + throw new IllegalArgumentException("Too long value ! Max 48 characters, value was " + value.length() + " !"); + } + } + } + + private static void setField(Object edit, String fieldName, Object value) { + try { + Field field = edit.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + field.set(edit, value); + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + } + +}