├── .classpath
├── Example.java
├── Readme.md
├── bin
└── de
│ └── sebpas
│ └── replay
│ ├── RePlayer$1.class
│ ├── RePlayer.class
│ ├── Recorder$1.class
│ ├── Recorder.class
│ ├── ReplaySystem.class
│ ├── command
│ └── CommandReplay.class
│ ├── event
│ ├── RecordingStartEvent.class
│ ├── RecordingStoppedEvent.class
│ ├── ReplayStartEvent.class
│ └── ReplayStoppedEvent.class
│ ├── filesystem
│ └── FileManager.class
│ ├── npc
│ └── NPC.class
│ ├── recorder
│ └── listener
│ │ ├── InteractListener.class
│ │ ├── MoveListener.class
│ │ └── SpawnDespawnListener.class
│ └── util
│ ├── InventoryUtilities.class
│ ├── ItemUtilities.class
│ ├── PlayingPlayer$1.class
│ ├── PlayingPlayer.class
│ ├── Reflections.class
│ └── ReplayStoppedEvent.class
├── plugin.yml
├── spigot.jar
└── src
└── de
└── sebpas
└── replay
├── RePlayer.java
├── Recorder.java
├── ReplaySystem.java
├── command
└── CommandReplay.java
├── event
├── RecordingStartEvent.java
├── RecordingStoppedEvent.java
├── ReplayStartEvent.java
└── ReplayStoppedEvent.java
├── filesystem
└── FileManager.java
├── npc
└── NPC.java
├── recorder
└── listener
│ ├── InteractListener.java
│ ├── MoveListener.java
│ └── SpawnDespawnListener.java
└── util
├── InventoryUtilities.java
├── ItemUtilities.java
├── PlayingPlayer.java
├── Reflections.java
└── ReplayStoppedEvent.java
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example.java:
--------------------------------------------------------------------------------
1 | package examples;
2 |
3 | import org.bukkit.entity.Player;
4 |
5 | import de.sebpas.replay.RePlayer;
6 | import de.sebpas.replay.ReplaySystem;
7 |
8 | public class Example {
9 | /** start recording */
10 | public void startRecording(){
11 | ReplaySystem.getInstance().start();
12 | }
13 | /**
14 | * stop recording:
15 | */
16 | public void stopRecording(){
17 | ReplaySystem.getInstance().stop();
18 | }
19 | /**
20 | * replay file file to player p and stop it
21 | * @param file
22 | * @param p
23 | */
24 | public void replayFile(String file, Player p){
25 | RePlayer replayer = new RePlayer(file, p);
26 | replayer.start();
27 |
28 | //velocity
29 |
30 | replayer.setVelocity(0.25D);
31 |
32 | // pause and continue it
33 |
34 | replayer.pause();
35 |
36 | replayer.continueReplay();
37 |
38 | // jump to 60 seconds (20 * 60 ticks)
39 |
40 | replayer.setCurrentTick(20 * 60);
41 |
42 | // stop
43 |
44 | replayer.stop();
45 | }
46 | /**
47 | * Events: de.sebpas.event (package)
48 | *
49 | * - RecordingStartEvent
50 | * - RecordingStoppedEvent
51 | * - ReplayStartEvent
52 | * - ReplayStoppedEvent
53 | * http://www.youtube.com/c/thepnlpchannel may be helpful too! (Video called 'ReplayAPI - Tutorial' (in german)
54 | */
55 | }
56 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # ReplayAPI - Development paused :( I am sorry
2 | ReplayAPI a plugin for Bukkit / Spigot to record and replay ingame action
3 |
4 | IMPORTANT: Here is a newer version of this project - still not continued but way better than this one:
5 | https://bitbucket.org/thepn/replayapi/src/master/src/de/sebpas/replay/filesystem/serializable/
6 |
7 | Languages: english and german
8 |
9 | Why use this plugin:
10 | - No network, sql or bungeecord needed
11 | - create own plugins or features using the api
12 | - open source :D
13 |
14 | # Ingame Commands
15 |
16 | - /replay play - plays a captured gameplay
17 | - /replay stop - stops the replay
18 | - /rplstart - starts capturing
19 | - /rplstop - stops capturing
20 | - /replay time - jumps to the wished time (eg. /replay time 1:30 to go to 1 minute and 30 seconds
21 |
22 | # API documentation:
23 | API examples can be found here
24 |
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/RePlayer$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/RePlayer$1.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/RePlayer.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/RePlayer.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/Recorder$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/Recorder$1.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/Recorder.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/Recorder.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/ReplaySystem.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/ReplaySystem.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/command/CommandReplay.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/command/CommandReplay.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/event/RecordingStartEvent.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/event/RecordingStartEvent.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/event/RecordingStoppedEvent.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/event/RecordingStoppedEvent.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/event/ReplayStartEvent.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/event/ReplayStartEvent.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/event/ReplayStoppedEvent.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/event/ReplayStoppedEvent.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/filesystem/FileManager.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/filesystem/FileManager.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/npc/NPC.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/npc/NPC.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/recorder/listener/InteractListener.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/recorder/listener/InteractListener.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/recorder/listener/MoveListener.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/recorder/listener/MoveListener.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/recorder/listener/SpawnDespawnListener.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/recorder/listener/SpawnDespawnListener.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/util/InventoryUtilities.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/util/InventoryUtilities.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/util/ItemUtilities.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/util/ItemUtilities.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/util/PlayingPlayer$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/util/PlayingPlayer$1.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/util/PlayingPlayer.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/util/PlayingPlayer.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/util/Reflections.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/util/Reflections.class
--------------------------------------------------------------------------------
/bin/de/sebpas/replay/util/ReplayStoppedEvent.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/bin/de/sebpas/replay/util/ReplayStoppedEvent.class
--------------------------------------------------------------------------------
/plugin.yml:
--------------------------------------------------------------------------------
1 | name: ReplayAPI
2 | main: de.sebpas.replay.ReplaySystem
3 | version: 1.0
4 | authors: [SPMinecraftWorld, thepn,]
5 | commands:
6 | rplstart:
7 | usage: /start
8 | description: starts the replay recorder
9 | rplstop:
10 | usage: /stop
11 | description: stops the replay recorder
12 | replay:
13 | permissions:
14 | replay.*:
15 | description: Erlaubt Zugriff auf alle Befehle des Replay - Plugins.
16 | children:
17 | replay.command: true
18 | replay.command:
19 | default: op
--------------------------------------------------------------------------------
/spigot.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/spigot.jar
--------------------------------------------------------------------------------
/src/de/sebpas/replay/RePlayer.java:
--------------------------------------------------------------------------------
1 | package de.sebpas.replay;
2 |
3 | import java.util.ArrayList;
4 | import java.util.HashMap;
5 | import java.util.List;
6 | import java.util.Map;
7 |
8 | import net.md_5.bungee.api.ChatColor;
9 |
10 | import org.bukkit.Bukkit;
11 | import org.bukkit.GameMode;
12 | import org.bukkit.Location;
13 | import org.bukkit.Material;
14 | import org.bukkit.Sound;
15 | import org.bukkit.entity.Player;
16 | import org.bukkit.inventory.ItemStack;
17 |
18 | import de.sebpas.replay.event.ReplayStartEvent;
19 | import de.sebpas.replay.npc.NPC;
20 | import de.sebpas.replay.util.PlayingPlayer;
21 |
22 | public class RePlayer {
23 | private double lastTick;
24 | private Map players;
25 | private List tickList;
26 | private double currentTick;
27 | private double velocity = 1;
28 | private boolean isRunning = false;
29 |
30 | /** NPC stuff */
31 | private List npcs = new ArrayList();
32 |
33 | /** thread stuff */
34 | private int taskID;
35 | private Runnable task = new Runnable() {
36 |
37 | @Override
38 | public void run() {
39 | if(isRunning){
40 | // if(currentTick - lastTick > 1 && lastTick % 1 == 0){
41 | double ticks = Math.floor(currentTick - lastTick);
42 | System.out.println("Last tick: " + lastTick + ", current: " + currentTick + ", ticks to run: " + ticks);
43 | for(int j = 0; j < ticks; j++){
44 | System.out.println("running: " + j + " / " + ticks + " ticks!");
45 | for(String s : getCurrentStringList((int) lastTick + j)){
46 | if(s.split(";").length == 1)
47 | break;
48 | String name = s.split(";")[2];
49 | String uuid = s.split(";")[1];
50 | if(!isExisting(s.split(";")[2])){
51 | double x = 0, y = 0, z = 0;
52 | float yaw = 0, pitch = 0;
53 | String[] temp = s.split(";")[3].replace("moved:", "").split(",");
54 | try{
55 | x = Double.parseDouble(temp[0]);
56 | y = Double.parseDouble(temp[1]);
57 | z = Double.parseDouble(temp[2]);
58 |
59 | yaw = Float.parseFloat(temp[3]);
60 | pitch = Float.parseFloat(temp[4]);
61 | }catch(Exception e){
62 | x = 0;
63 | y = 255;
64 | z = 0;
65 | yaw = 45;
66 | pitch = 0;
67 | }
68 | NPC npc = new NPC(uuid, name, new Location(((Player) players.keySet().toArray()[0]).getWorld(), x, y, z, yaw, pitch), (Player) players.keySet().toArray()[0]);
69 | npcs.add(npc);
70 | npc.spawn();
71 | }else if(s.split(";")[3].startsWith("moved:")){ /** movement */
72 | double x = 0, y = 0, z = 0;
73 | float yaw = 0, pitch = 0;
74 | String[] temp = s.split(";")[3].replace("moved:", "").split(",");
75 | x = Double.parseDouble(temp[0]);
76 | y = Double.parseDouble(temp[1]);
77 | z = Double.parseDouble(temp[2]);
78 |
79 | yaw = Float.parseFloat(temp[3]);
80 | pitch = Float.parseFloat(temp[4]);
81 |
82 | if(currentTick % 2 != 0){
83 | float yawR = (float) Math.toRadians(yaw);
84 | x = -Math.sin(yawR);
85 | z = Math.cos(yawR);
86 | }
87 |
88 | double speed = 4.3D;
89 |
90 | if(s.split(";").length == 4 && getNPCByName(name).isBlocking() || getNPCByName(name).isSneaking() || getNPCByName(name).isSprinting())
91 | getNPCByName(name).resetMovement();
92 |
93 | if(s.split(";").length == 5){
94 | if(s.split(";")[4].equalsIgnoreCase("sprint"))
95 | getNPCByName(name).sprint();
96 | if(s.split(";")[4].equalsIgnoreCase("sneak")){
97 | getNPCByName(name).sneak();
98 | speed /= 3D;
99 | }
100 | if(s.split(";")[4].equalsIgnoreCase("block")){
101 | getNPCByName(name).block();
102 | speed /= 4D;
103 | }
104 | }
105 |
106 | if(s.split(";").length == 6){
107 | if(s.split(";")[4].equalsIgnoreCase("block"))
108 | getNPCByName(name).block();
109 | }
110 |
111 | getNPCByName(name).look(yaw, pitch);
112 | getNPCByName(name).move(x * (speed / 20), y - getNPCByName(name).getLocation().getY(), z * (speed / 20), yaw, pitch);
113 |
114 | if(currentTick % 2 == 0)
115 | getNPCByName(name).teleport(new Location(((Player) players.keySet().toArray()[0]).getWorld(), x, y, z, yaw, pitch));
116 | }else if(s.split(";").length == 1)
117 | break;
118 |
119 | if(s.split(";")[3].startsWith("swing")) /** swinging the item in hand */ {
120 | getNPCByName(name).swingArm();
121 | }else if(s.split(";")[3].startsWith("dmg")) /** damage animation */ {
122 | getNPCByName(name).damageAnimation();
123 | }else if(s.split(";")[3].startsWith("armr")) /** armor content updating */ {
124 | String[] temp = s.split(";")[3].replace("armr:", "").split(",");
125 | ItemStack[] armor = new ItemStack[4];
126 | for(int i = 0; i < temp.length; i++){
127 | armor[i] = new ItemStack(Material.getMaterial(temp[i]));
128 | }
129 | getNPCByName(name).updateItems(getNPCByName(name).getItemInHand(), armor[3], armor[2], armor[1], armor[0]);
130 | }else if(s.split(";")[3].startsWith("itmhnd")) /** item in hand */ {
131 | getNPCByName(name).updateItems(new ItemStack(Material.getMaterial(s.split(";")[3].replace("itmhnd:", ""))), getNPCByName(name).getArmorContents()[0], getNPCByName(name).getArmorContents()[1], getNPCByName(name).getArmorContents()[2], getNPCByName(name).getArmorContents()[3]);
132 | }else if(s.split(";")[3].startsWith("lggdin")) /** joined the game */ {
133 | double x = 0, y = 0, z = 0;
134 | String[] temp = s.split(";")[3].replace("lggdin:", "").split(",");
135 | try{
136 | x = Double.parseDouble(temp[0]);
137 | y = Double.parseDouble(temp[1]);
138 | z = Double.parseDouble(temp[2]);
139 | }catch(Exception e){
140 | x = 0;
141 | y = 255;
142 | z = 0;
143 | }
144 |
145 | sendChatMessageToAll(s.split(";")[4]);
146 | getNPCByName(name).spawn(new Location(((Player) players.keySet().toArray()[0]).getWorld(), x, y, z));
147 | }else if(s.split(";")[3].startsWith("lggdout")) /** left the game */ {
148 | sendChatMessageToAll(s.split(";")[4]);
149 | getNPCByName(name).deSpawn();
150 | }else if(s.split(";")[3].startsWith("died")) /** died */ {
151 | sendChatMessageToAll(s.split(";")[4]);
152 | getNPCByName(name).deSpawn();
153 | }else if(s.split(";")[3].startsWith("rspn")) /** respawned */ {
154 | double x = 0, y = 0, z = 0;
155 | String[] temp = s.split(";")[3].replace("rspn:", "").split(",");
156 | try{
157 | x = Double.parseDouble(temp[0]);
158 | y = Double.parseDouble(temp[1]);
159 | z = Double.parseDouble(temp[2]);
160 | }catch(Exception e){
161 | x = 0;
162 | y = 255;
163 | z = 0;
164 | }
165 |
166 | sendChatMessageToAll(s.split(";")[4]);
167 | getNPCByName(name).spawn(new Location(((Player) players.keySet().toArray()[0]).getWorld(), x, y, z));
168 | }else if(s.split(";")[3].startsWith("cht")) /** chat message sent */ {
169 | for(Player p : players.keySet())
170 | p.sendMessage(ChatColor.translateAlternateColorCodes('&', s.split(";")[4]));
171 | }
172 | }
173 | lastTick = Math.floor(currentTick);
174 | }
175 |
176 | /** tick decrease */
177 | currentTick += velocity;
178 | }
179 | for(Player p : players.keySet()){
180 | p.setExp((float) currentTick / (float) getLastTick());
181 | if(currentTick % 20 == 0)
182 | p.setLevel((int) currentTick / 20);
183 | p.setHealth(20D);
184 | p.setFoodLevel(20);
185 | }
186 | if(currentTick > getLastTick() || players.isEmpty())
187 | stop();
188 |
189 | }
190 | };
191 |
192 | public void pause(){
193 | this.isRunning = false;
194 | }
195 |
196 | public void continueReplay(){
197 | this.isRunning = true;
198 | }
199 |
200 | public RePlayer(String file, Player player){
201 | this.currentTick = 0;
202 | this.players = new HashMap();
203 | this.players.put(player, new PlayingPlayer(player));
204 | tickList = ReplaySystem.getInstance().getFileManager().readFile(file + ".rpl");
205 | if(!tickList.isEmpty())
206 | ReplaySystem.getInstance().addPlayer(this);
207 | }
208 |
209 | public RePlayer(String file, Map players){
210 | this.currentTick = 0;
211 | this.players = players;
212 | tickList = ReplaySystem.getInstance().getFileManager().readFile(file + ".rpl");
213 | if(!tickList.isEmpty())
214 | ReplaySystem.getInstance().addPlayer(this);
215 | }
216 |
217 | @SuppressWarnings("deprecation")
218 | public void start(){
219 | this.isRunning = true;
220 | Bukkit.getPluginManager().callEvent(new ReplayStartEvent(this));
221 | if(tickList == null){
222 | for(Player p : this.players.keySet()){
223 | p.sendMessage(ChatColor.translateAlternateColorCodes('&', ReplaySystem.getInstance().getErrorPrefix() + " &3Fehler beim lesen der Datei!"));
224 | }
225 | return;
226 | }
227 | for(Player p : this.players.keySet()){
228 | p.setGameMode(GameMode.ADVENTURE);
229 | p.setAllowFlight(true);
230 | p.setFlying(true);
231 | p.setHealth(20D);
232 | p.setFoodLevel(20);
233 | p.sendMessage(ChatColor.translateAlternateColorCodes('&', ReplaySystem.getInstance().getPrefix() + "&3Replay gestartet!"));
234 | }
235 | taskID = Bukkit.getScheduler().scheduleAsyncRepeatingTask(ReplaySystem.getInstance(), task, 1L, 1L);
236 | }
237 |
238 | public void stop(){
239 | this.isRunning = false;
240 | Bukkit.getScheduler().cancelTask(taskID);
241 | for(NPC n : npcs)
242 | n.deSpawn();
243 | for(Player p : this.players.keySet()){
244 | p.playSound(p.getLocation(), Sound.LEVEL_UP, 1, 1);
245 | this.getPlayers().get(p).throwIntoGame(p, true);
246 | p.sendMessage(ChatColor.translateAlternateColorCodes('&', ReplaySystem.getInstance().getPrefix() + " &3Das Replay ist beendet. Du hast das Replay verlassen."));
247 | }
248 | ReplaySystem.getInstance().onPlayerStopped(this);
249 | }
250 |
251 | /**
252 | * ONLY use while stopping plugin
253 | */
254 | public void stopWithoutTask(){
255 | this.isRunning = false;
256 | Bukkit.getScheduler().cancelTask(taskID);
257 | for(NPC n : npcs)
258 | n.deSpawn();
259 | for(Player p : this.players.keySet()){
260 | p.playSound(p.getLocation(), Sound.LEVEL_UP, 1, 1);
261 | this.getPlayers().get(p).throwIntoGame(p, false);
262 | p.sendMessage(ChatColor.translateAlternateColorCodes('&', ReplaySystem.getInstance().getPrefix() + " &3Das Replay ist beendet. Du hast das Replay verlassen."));
263 | }
264 | ReplaySystem.getInstance().onPlayerStopped(this);
265 | }
266 |
267 | @Deprecated
268 | /**
269 | * use RePlayer.stop() instead
270 | * @param p
271 | */
272 | public void removePlayer(Player p){
273 | this.players.remove(p);
274 | p.sendMessage(ChatColor.translateAlternateColorCodes('&', ReplaySystem.getInstance().getPrefix() + " &3Du hast das Replay verlassen."));
275 | this.stop();
276 | }
277 |
278 | public double getVelocity() {
279 | return velocity;
280 | }
281 | public void setVelocity(double velocity) {
282 | this.velocity = velocity;
283 | }
284 | public double getCurrentTick() {
285 | return currentTick;
286 | }
287 | public boolean setCurrentTick(double currentTick) {
288 | if(currentTick >= this.getLastTick() || currentTick < 0)
289 | return false;
290 | this.currentTick = currentTick;
291 | this.lastTick = currentTick -= velocity;
292 | return true;
293 | }
294 | public Map getPlayers() {
295 | return players;
296 | }
297 | public boolean isRunning() {
298 | return isRunning;
299 | }
300 | private int getLastTick(){
301 | int max = 0;
302 | for(String s : tickList){
303 | if(Integer.parseInt(s.split(";")[0]) > max)
304 | max = Integer.parseInt(s.split(";")[0]);
305 | }
306 | return max;
307 | }
308 |
309 | private List getCurrentStringList(int tick){
310 | List rtn = new ArrayList();
311 | for(String s : tickList){
312 | if(Integer.parseInt(s.split(";")[0]) == tick)
313 | rtn.add(s);
314 | }
315 | return rtn;
316 | }
317 | private boolean isExisting(String name){
318 | for(NPC n : this.npcs){
319 | if(n.getName().equalsIgnoreCase(name))
320 | return true;
321 | }
322 | return false;
323 | }
324 | public NPC getNPCByName(String name){
325 | for(NPC n : npcs){
326 | if(n.getName().equalsIgnoreCase(name))
327 | return n;
328 | }
329 | return null;
330 | }
331 |
332 | public List getNpcs() {
333 | return npcs;
334 | }
335 | private void sendChatMessageToAll(String msg){
336 | for(Player p : this.players.keySet())
337 | p.sendMessage(ChatColor.translateAlternateColorCodes('&', msg));
338 | }
339 | }
340 |
--------------------------------------------------------------------------------
/src/de/sebpas/replay/Recorder.java:
--------------------------------------------------------------------------------
1 | package de.sebpas.replay;
2 |
3 | import org.bukkit.Bukkit;
4 | import org.bukkit.entity.Player;
5 |
6 | import de.sebpas.replay.event.RecordingStartEvent;
7 | import de.sebpas.replay.event.RecordingStoppedEvent;
8 | import de.sebpas.replay.recorder.listener.InteractListener;
9 | import de.sebpas.replay.recorder.listener.MoveListener;
10 | import de.sebpas.replay.recorder.listener.SpawnDespawnListener;
11 | import de.sebpas.replay.util.InventoryUtilities;
12 |
13 | public class Recorder{
14 | private ReplaySystem plugin;
15 | private boolean isRecording = false;
16 |
17 | private Runnable runnable = new Runnable() {
18 |
19 | @Override
20 | public void run() {
21 | if(Bukkit.getOnlinePlayers().size() != 0)
22 | plugin.addTick();
23 | }
24 | };
25 |
26 | public Recorder(ReplaySystem plugin){
27 | this.plugin = plugin;
28 | Bukkit.getPluginManager().registerEvents(new MoveListener(plugin), plugin);
29 | Bukkit.getPluginManager().registerEvents(new InteractListener(plugin), plugin);
30 | Bukkit.getPluginManager().registerEvents(new SpawnDespawnListener(plugin), plugin);
31 | Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, 1L, 1L);
32 | }
33 | /** starts capturing */
34 | public void recorde(){
35 | Bukkit.getPluginManager().callEvent(new RecordingStartEvent());
36 | this.isRecording = true;
37 | for(Player p : Bukkit.getOnlinePlayers()){
38 | addString(plugin.getHandledTicks() + ";" + p.getUniqueId() + ";" + p.getName() + ";moved:" + p.getLocation().getX() + "," + p.getLocation().getY() + "," + p.getLocation().getZ()+ "," + p.getLocation().getYaw() + "," + p.getLocation().getPitch() + ";" + ";");
39 | InventoryUtilities.saveArmor(p, plugin);
40 | this.addString(plugin.getHandledTicks() + ";" + p.getUniqueId() + ";" + p.getName() + ";itmhnd:" + p.getItemInHand().getType());
41 | }
42 | }
43 | /** stops capturing */
44 | public void stop(){
45 | this.addString(plugin.getHandledTicks() + "");
46 | Bukkit.getPluginManager().callEvent(new RecordingStoppedEvent());
47 | this.isRecording = false;
48 | }
49 |
50 | public boolean isRecording(){
51 | return this.isRecording;
52 | }
53 | /** adds a string to the file the replay will be saved in */
54 | public void addString(String s){
55 | if(isRecording())
56 | this.plugin.getFileManager().appendString(s);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/de/sebpas/replay/ReplaySystem.java:
--------------------------------------------------------------------------------
1 | package de.sebpas.replay;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import org.bukkit.Bukkit;
7 | import org.bukkit.ChatColor;
8 | import org.bukkit.entity.HumanEntity;
9 | import org.bukkit.entity.Player;
10 | import org.bukkit.plugin.java.JavaPlugin;
11 |
12 | import de.sebpas.replay.command.CommandReplay;
13 | import de.sebpas.replay.event.ReplayStoppedEvent;
14 | import de.sebpas.replay.filesystem.FileManager;
15 | import de.sebpas.replay.util.PlayingPlayer;
16 |
17 | public class ReplaySystem extends JavaPlugin{
18 | private int ranTicks = 0;
19 | private FileManager fileSystem;
20 | private Recorder recorder;
21 |
22 | private static ReplaySystem instance = null;
23 |
24 | /** list of all replayers */
25 | private List replayers = new ArrayList();
26 |
27 | /** plugin prefixes */
28 | private static String prefix = "&8[&3Replay&8]: &r";
29 | private static String error = "&8[&cReplay&8]: &c";
30 |
31 |
32 | /**
33 | * Bukkit methods
34 | */
35 |
36 | @Override
37 | public void onEnable() {
38 | System.out.println("[Replay]: Enabled!");
39 | this.fileSystem = new FileManager();
40 | this.recorder = new Recorder(this);
41 |
42 | this.getCommand("rplstart").setExecutor(new CommandReplay(this));
43 | this.getCommand("rplstop").setExecutor(new CommandReplay(this));
44 | this.getCommand("replay").setExecutor(new CommandReplay(this));
45 |
46 | this.getServer().getPluginManager().registerEvents(new PlayingPlayer(), this);
47 |
48 | instance = this;
49 | }
50 | @Override
51 | public void onDisable() {
52 | if(recorder.isRecording()){
53 | this.stop();
54 | }
55 | for(RePlayer r : replayers)
56 | r.stopWithoutTask();
57 | }
58 |
59 | /** returns a new instance of this main class */
60 | public static ReplaySystem getInstance(){
61 | return instance;
62 | }
63 |
64 | public void start(){
65 | this.ranTicks = 0;
66 | this.fileSystem.reset();
67 | this.recorder.recorde();
68 | }
69 |
70 | public void stop(){
71 | this.recorder.stop();
72 | this.ranTicks = 0;
73 | this.fileSystem.save();
74 | }
75 |
76 | /** returns the amount of recorded ticks */
77 | public int getHandledTicks(){
78 | return this.ranTicks;
79 | }
80 |
81 | /** sends a message to all players and the console */
82 | public static void sendBroadcast(String msg){
83 | Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&', prefix + msg));
84 | }
85 |
86 | /** sends an error message to all players and the console */
87 | public static void sendBroadcastError(String msg){
88 | Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&', error + msg));
89 | }
90 | public String getPrefix(){
91 | return prefix;
92 | }
93 | public String getErrorPrefix(){
94 | return error;
95 | }
96 |
97 | /** the tick counter */
98 | public void addTick(){
99 | ++ ranTicks;
100 | }
101 |
102 | /** returns the filemanager */
103 | public FileManager getFileManager(){
104 | return fileSystem;
105 | }
106 |
107 | /** returns the recording thread */
108 | public Recorder getRecorder(){
109 | return this.recorder;
110 | }
111 | /** returns true if the player is already watching a replay */
112 | public boolean isAlreadyInReplay(Player p){
113 | for(RePlayer r : replayers)
114 | if(r.getPlayers().containsKey(p))
115 | return true;
116 | return false;
117 | }
118 |
119 | public void addPlayer(RePlayer p){
120 | this.replayers.add(p);
121 | }
122 |
123 | public void onPlayerStopped(RePlayer p){
124 | this.replayers.remove(p);
125 | synchronized (p) {
126 | this.getServer().getPluginManager().callEvent(new ReplayStoppedEvent(p));
127 | }
128 | }
129 | public RePlayer getPlayersRePlayer(Player p){
130 | for(RePlayer r : replayers){
131 | if(r.getPlayers().containsKey(p))
132 | return r;
133 | }
134 | return null;
135 | }
136 | public RePlayer getPlayersRePlayer(HumanEntity p){
137 | for(RePlayer r : replayers){
138 | for(Player t : r.getPlayers().keySet())
139 | if(t.getName().equals(p.getName()))
140 | return r;
141 | }
142 | return null;
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/src/de/sebpas/replay/command/CommandReplay.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/src/de/sebpas/replay/command/CommandReplay.java
--------------------------------------------------------------------------------
/src/de/sebpas/replay/event/RecordingStartEvent.java:
--------------------------------------------------------------------------------
1 | package de.sebpas.replay.event;
2 |
3 | import org.bukkit.event.Event;
4 | import org.bukkit.event.HandlerList;
5 |
6 | public class RecordingStartEvent extends Event{
7 | private static final HandlerList handlers = new HandlerList();
8 | public RecordingStartEvent(){}
9 |
10 | @Override
11 | public HandlerList getHandlers() {
12 | return handlers;
13 | }
14 | public static HandlerList getHandlerList(){
15 | return handlers;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/de/sebpas/replay/event/RecordingStoppedEvent.java:
--------------------------------------------------------------------------------
1 | package de.sebpas.replay.event;
2 |
3 | import org.bukkit.event.Event;
4 | import org.bukkit.event.HandlerList;
5 |
6 | public class RecordingStoppedEvent extends Event{
7 | private static final HandlerList handlers = new HandlerList();
8 | public RecordingStoppedEvent(){}
9 |
10 | @Override
11 | public HandlerList getHandlers() {
12 | return handlers;
13 | }
14 | public static HandlerList getHandlerList(){
15 | return handlers;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/de/sebpas/replay/event/ReplayStartEvent.java:
--------------------------------------------------------------------------------
1 | package de.sebpas.replay.event;
2 |
3 | import org.bukkit.event.Event;
4 | import org.bukkit.event.HandlerList;
5 |
6 | import de.sebpas.replay.RePlayer;
7 |
8 | public class ReplayStartEvent extends Event{
9 | private static final HandlerList handlers = new HandlerList();
10 |
11 | private RePlayer replayer;
12 |
13 | public ReplayStartEvent(RePlayer replayer){
14 | this.replayer = replayer;
15 | }
16 |
17 | @Override
18 | public HandlerList getHandlers() {
19 | return handlers;
20 | }
21 | public static HandlerList getHandlerList(){
22 | return handlers;
23 | }
24 | public RePlayer getRePlayer(){
25 | return replayer;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/de/sebpas/replay/event/ReplayStoppedEvent.java:
--------------------------------------------------------------------------------
1 | package de.sebpas.replay.event;
2 |
3 | import org.bukkit.event.Event;
4 | import org.bukkit.event.HandlerList;
5 |
6 | import de.sebpas.replay.RePlayer;
7 |
8 | public class ReplayStoppedEvent extends Event{
9 | private static final HandlerList handlers = new HandlerList();
10 |
11 | private RePlayer replayer;
12 |
13 | public ReplayStoppedEvent(RePlayer replayer){
14 | this.replayer = replayer;
15 | }
16 |
17 | @Override
18 | public HandlerList getHandlers() {
19 | return handlers;
20 | }
21 | public static HandlerList getHandlerList(){
22 | return handlers;
23 | }
24 | public RePlayer getRePlayer(){
25 | return replayer;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/de/sebpas/replay/filesystem/FileManager.java:
--------------------------------------------------------------------------------
1 | package de.sebpas.replay.filesystem;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.File;
5 | import java.io.FileNotFoundException;
6 | import java.io.FileReader;
7 | import java.io.IOException;
8 | import java.io.PrintWriter;
9 | import java.text.SimpleDateFormat;
10 | import java.util.ArrayList;
11 | import java.util.Date;
12 | import java.util.List;
13 |
14 | import de.sebpas.replay.ReplaySystem;
15 |
16 | public class FileManager {
17 | private String fileContent = "";
18 | private File file;
19 | private PrintWriter writer;
20 | public FileManager(){
21 |
22 | }
23 |
24 | public synchronized boolean save(){
25 | Date date = new Date();
26 | SimpleDateFormat format = new SimpleDateFormat("YY-MM-D-H-m-s");
27 | file = new File("plugins/Replays/", format.format(date) + ".rpl");
28 | if(!file.exists())
29 | try {
30 | file.createNewFile();
31 | } catch (IOException e1) {
32 | ReplaySystem.sendBroadcastError(e1.getMessage());
33 | e1.printStackTrace();
34 | }
35 | try {
36 | writer = new PrintWriter(file);
37 | } catch (FileNotFoundException e) {
38 | ReplaySystem.sendBroadcastError(e.getMessage());
39 | e.printStackTrace();
40 | return false;
41 | }
42 | writer.print(fileContent);
43 | System.out.println("[Replay] Saving..." + fileContent);
44 | writer.flush();
45 | writer.close();
46 | return true;
47 | }
48 | public synchronized List readFile(String name){
49 | List rtn = new ArrayList();
50 | try {
51 | BufferedReader reader = new BufferedReader(new FileReader(new File("plugins/Replays/", name)));
52 | String t;
53 | while((t = reader.readLine()) != null)
54 | rtn.add(t);
55 | reader.close();
56 | return rtn;
57 | } catch (FileNotFoundException e) {
58 | ReplaySystem.sendBroadcastError(e.getMessage());
59 | } catch (IOException e) {
60 | ReplaySystem.sendBroadcastError(e.getMessage());
61 | e.printStackTrace();
62 | }
63 | return null;
64 | }
65 | public void reset(){
66 | this.fileContent = "";
67 | }
68 | public void appendString(String s){
69 | fileContent += s + "\n";
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/de/sebpas/replay/npc/NPC.java:
--------------------------------------------------------------------------------
1 | package de.sebpas.replay.npc;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 | import java.util.UUID;
6 |
7 | import net.minecraft.server.v1_8_R2.DataWatcher;
8 | import net.minecraft.server.v1_8_R2.MathHelper;
9 | import net.minecraft.server.v1_8_R2.PacketPlayOutAnimation;
10 | import net.minecraft.server.v1_8_R2.PacketPlayOutEntity.PacketPlayOutEntityLook;
11 | import net.minecraft.server.v1_8_R2.PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook;
12 | import net.minecraft.server.v1_8_R2.PacketPlayOutEntityDestroy;
13 | import net.minecraft.server.v1_8_R2.PacketPlayOutEntityEquipment;
14 | import net.minecraft.server.v1_8_R2.PacketPlayOutEntityHeadRotation;
15 | import net.minecraft.server.v1_8_R2.PacketPlayOutEntityMetadata;
16 | import net.minecraft.server.v1_8_R2.PacketPlayOutEntityTeleport;
17 | import net.minecraft.server.v1_8_R2.PacketPlayOutNamedEntitySpawn;
18 | import net.minecraft.server.v1_8_R2.PacketPlayOutPlayerInfo;
19 | import net.minecraft.server.v1_8_R2.PacketPlayOutPlayerInfo.EnumPlayerInfoAction;
20 | import net.minecraft.server.v1_8_R2.WorldSettings.EnumGamemode;
21 |
22 | import org.bukkit.Bukkit;
23 | import org.bukkit.Location;
24 | import org.bukkit.Sound;
25 | import org.bukkit.craftbukkit.v1_8_R2.inventory.CraftItemStack;
26 | import org.bukkit.craftbukkit.v1_8_R2.util.CraftChatMessage;
27 | import org.bukkit.entity.Player;
28 | import org.bukkit.inventory.ItemStack;
29 |
30 | import com.mojang.authlib.GameProfile;
31 |
32 | import de.sebpas.replay.util.Reflections;
33 |
34 | public class NPC extends Reflections{
35 | private int ID;
36 | private Location location;
37 | private GameProfile profile;
38 | private String name;
39 | private Player player;
40 |
41 | /** movement */
42 | private boolean isSneaking = false;
43 | private boolean isSprinting = false;
44 | private boolean isBlocking = false;
45 |
46 | /** items (armor, item in hand etc) */
47 | private ItemStack helmet;
48 | private ItemStack chestplate;
49 | private ItemStack leggins;
50 | private ItemStack boots;
51 | private ItemStack handHeld;
52 |
53 | /**
54 | * @param name
55 | * @param loc
56 | */
57 | public NPC(String uuid, String name, Location loc){
58 | this.ID = (int) Math.ceil(Math.random() * 1000) + 2000;
59 | profile = new GameProfile(UUID.fromString(uuid), name);
60 | this.location = loc;
61 | this.name = name;
62 | }
63 | public NPC(String uuid, String name, Location loc, Player player){
64 | this.ID = (int) Math.ceil(Math.random() * 1000) + 2000;
65 | profile = new GameProfile(UUID.fromString(uuid), name);
66 | this.location = loc;
67 | this.player = player;
68 | this.name = name;
69 | }
70 | /** spawns this npc */
71 | public void spawn(){
72 | this.spawn(location);
73 | }
74 | /** spawns this npc at location location */
75 | public void spawn(Location location){
76 | PacketPlayOutNamedEntitySpawn packet = new PacketPlayOutNamedEntitySpawn();
77 | setValue(packet, "a", ID);
78 | setValue(packet, "b", profile.getId());
79 | setValue(packet, "c", (int) MathHelper.floor(location.getX() * 32.0D));
80 | setValue(packet, "d", (int) MathHelper.floor(location.getY() * 32.0D));
81 | setValue(packet, "e", (int) MathHelper.floor(location.getZ() * 32.0D));
82 |
83 | setValue(packet, "f", (byte) ((int) (location.getYaw() * 256.0F / 360.0F)));
84 | setValue(packet, "g", (byte) ((int) (location.getYaw() * 256.0F / 360.0F)));
85 |
86 | setValue(packet, "h", 0);
87 |
88 | DataWatcher w = new DataWatcher(null);
89 | w.a(10, (byte) 127);
90 | w.a(6, (float) 20);
91 | setValue(packet, "i", w);
92 | this.sendTablistPacket();
93 | if(player != null)
94 | sendPacket(packet, player);
95 | else
96 | sendPacket(packet);
97 | }
98 |
99 | /** tp to location loc */
100 | public void teleport(Location loc) {
101 | PacketPlayOutEntityTeleport tp = new PacketPlayOutEntityTeleport();
102 | setValue(tp, "a", Integer.valueOf(this.ID));
103 | setValue(tp, "b", Integer.valueOf((int)(loc.getX() * 32.0D)));
104 | setValue(tp, "c", Integer.valueOf((int)(loc.getY() * 32.0D)));
105 | setValue(tp, "d", Integer.valueOf((int)(loc.getZ() * 32.0D)));
106 | setValue(tp, "e", Byte.valueOf(toAngle(loc.getYaw())));
107 | setValue(tp, "f", Byte.valueOf(toAngle(loc.getPitch())));
108 | this.location = loc;
109 | if(player != null)
110 | sendPacket(tp, player);
111 | else
112 | sendPacket(tp);
113 | }
114 |
115 | /** let this npc sneak */
116 | public void sneak(){
117 | this.isSneaking = true;
118 | this.isBlocking = false;
119 | this.isSprinting = false;
120 | DataWatcher w = new DataWatcher(null);
121 | w.a(0, (byte) 2);
122 | w.a(1, (short) 0);
123 | w.a(8, (byte) 0);
124 | PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(this.ID, w, true);
125 | if(player != null)
126 | sendPacket(packet, player);
127 | else
128 | sendPacket(packet);
129 | }
130 |
131 | /** resets the sprinting, sneaking [...] values */
132 | public void resetMovement(){
133 | this.isBlocking = false;
134 | this.isSneaking = false;
135 | this.isSprinting = false;
136 | DataWatcher w = new DataWatcher(null);
137 | w.a(0, (byte) 0);
138 | w.a(1, (short) 0);
139 | w.a(8, (byte) 0);
140 | PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(this.ID, w, true);
141 | if(player != null)
142 | sendPacket(packet, player);
143 | else
144 | sendPacket(packet);
145 | }
146 |
147 | /** let this npc sprint */
148 | public void sprint(){
149 | this.isSprinting = true;
150 | this.isBlocking = false;
151 | this.isSneaking = false;
152 | DataWatcher w = new DataWatcher(null);
153 | w.a(0, (byte) 8);
154 | w.a(1, (short) 0);
155 | w.a(8, (byte) 0);
156 | PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(this.ID, w, true);
157 | if(player != null)
158 | sendPacket(packet, player);
159 | else
160 | sendPacket(packet);
161 | }
162 |
163 | /** blocks with sword, bow or consumables */
164 | public void block() {
165 | this.isBlocking = true;
166 | this.isSneaking = false;
167 | this.isSprinting = false;
168 | DataWatcher w = new DataWatcher(null);
169 | w.a(0, (byte) 16);
170 | w.a(1, (short) 0);
171 | w.a(6, (byte) 0);
172 | PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(this.ID, w, true);
173 | if(player != null)
174 | sendPacket(packet, player);
175 | else
176 | sendPacket(packet);
177 | }
178 |
179 | /** updates the inventory (esp. armor and item in hand) */
180 | public void updateItems(ItemStack inHand, ItemStack boots, ItemStack leggins, ItemStack chestplate, ItemStack helmet){
181 | if(inHand != null)
182 | this.handHeld = inHand;
183 | if(boots != null)
184 | this.boots = boots;
185 | if(leggins != null)
186 | this.leggins = leggins;
187 | if(chestplate != null)
188 | this.chestplate = chestplate;
189 | if(helmet != null)
190 | this.helmet = helmet;
191 |
192 | PacketPlayOutEntityEquipment[] packets = { new PacketPlayOutEntityEquipment(this.ID, 1, CraftItemStack.asNMSCopy(this.helmet)), new PacketPlayOutEntityEquipment(this.ID, 2, CraftItemStack.asNMSCopy(this.chestplate)), new PacketPlayOutEntityEquipment(this.ID, 3, CraftItemStack.asNMSCopy(this.leggins)), new PacketPlayOutEntityEquipment(this.ID, 4, CraftItemStack.asNMSCopy(this.boots)), new PacketPlayOutEntityEquipment(this.ID, 0, CraftItemStack.asNMSCopy(this.handHeld)) };
193 |
194 | for(int i = 0; i < packets.length; i++)
195 | if(player != null)
196 | sendPacket(packets[i], player);
197 | else
198 | sendPacket(packets[i]);
199 | }
200 |
201 | /** sends a damage animation to all players */
202 | public void damageAnimation(){
203 | PacketPlayOutAnimation packet = new PacketPlayOutAnimation();
204 | setValue(packet, "a", (int) this.ID);
205 | setValue(packet, "b", (int) 1);
206 | if(player != null){
207 | sendPacket(packet, player);
208 | player.playSound(this.location, Sound.HURT_FLESH, 1, 2);
209 | }
210 | else{
211 | sendPacket(packet);
212 | for(Player p : Bukkit.getOnlinePlayers())
213 | p.playSound(this.location, Sound.HURT_FLESH, 1, 2);
214 | }
215 | }
216 |
217 | /** moves the npc with walking animation */
218 | public void move(double x, double y, double z, float yaw, float pitch){
219 | if(player != null)
220 | sendPacket(new PacketPlayOutRelEntityMoveLook(this.ID, (byte) toFxdPnt(x), (byte) toFxdPnt(y), (byte) toFxdPnt(z), toAngle(yaw), toAngle(pitch), true), player);
221 | else
222 | sendPacket(new PacketPlayOutRelEntityMoveLook(this.ID, (byte) toFxdPnt(x), (byte) toFxdPnt(y), (byte) toFxdPnt(z), toAngle(yaw), toAngle(pitch), true));
223 | this.location.add(toFxdPnt(x) / 32D, toFxdPnt(y) / 32D, toFxdPnt(z) / 32D);
224 | this.location.setYaw(yaw);
225 | this.location.setPitch(pitch);
226 | }
227 |
228 | private int toFxdPnt(double value){
229 | return (int) Math.floor(value * 32.0D);
230 | }
231 |
232 | public Location getLocation(){
233 | return this.location;
234 | }
235 |
236 | /** changes players head rotation */
237 | public void look(float yaw, float pitch){
238 | PacketPlayOutEntityHeadRotation headRot = new PacketPlayOutEntityHeadRotation();
239 | setValue(headRot, "a", this.ID);
240 | setValue(headRot, "b", toAngle(yaw));
241 |
242 | if(player != null){
243 | sendPacket(headRot);
244 | sendPacket(new PacketPlayOutEntityLook(this.ID, toAngle(yaw), toAngle(pitch), true), player);
245 | }
246 | else{
247 | sendPacket(headRot);
248 | sendPacket(new PacketPlayOutEntityLook(this.ID, toAngle(yaw), toAngle(pitch), true), player);
249 | }
250 | this.location.setYaw(yaw);
251 | this.location.setPitch(pitch);
252 | }
253 |
254 | private byte toAngle(float value){
255 | return (byte) ((int) (value * 256.0F / 360.0F));
256 | }
257 |
258 | /** adds the npc to the target's tablist */
259 | private void sendTablistPacket(){
260 | PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo();
261 | PacketPlayOutPlayerInfo.PlayerInfoData data = packet.new PlayerInfoData(profile, 1, EnumGamemode.NOT_SET, CraftChatMessage.fromString(profile.getName())[0]);
262 | @SuppressWarnings("unchecked")
263 | List players = (List) getValue(packet, "b");
264 | players.add(data);
265 | setValue(packet, "a", PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER);
266 | setValue(packet, "b", players);
267 | if(player != null)
268 | sendPacket(packet, player);
269 | else
270 | sendPacket(packet);
271 | }
272 | /** removes the npc from the target's tablist */
273 | private void removeFromTablist(){
274 | boolean isOnline = false;
275 | for(Player p : Bukkit.getOnlinePlayers()){
276 | if(this.getName().equals(p.getName()))
277 | isOnline = true;
278 | }
279 | if(isOnline)
280 | return;
281 | PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER);
282 | setValue(packet, "b", Arrays.asList(packet.new PlayerInfoData(this.profile, 0, null, null)));
283 | if(player != null)
284 | sendPacket(packet, player);
285 | else
286 | sendPacket(packet);
287 | }
288 | /** kills this npc */
289 | public void deSpawn(){
290 | PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(this.ID);
291 | if(player != null)
292 | sendPacket(packet, player);
293 | else
294 | sendPacket(packet);
295 | this.removeFromTablist();
296 | }
297 |
298 | /** plays the item use animation (hit or place blocks...) */
299 | public void swingArm(){
300 | PacketPlayOutAnimation packet18 = new PacketPlayOutAnimation();
301 | setValue(packet18, "a", Integer.valueOf(this.ID));
302 | setValue(packet18, "b", Integer.valueOf(0));
303 | if(player != null)
304 | sendPacket(packet18, player);
305 | else
306 | sendPacket(packet18);
307 | }
308 |
309 | public String getName(){
310 | return this.name;
311 | }
312 | public boolean isSneaking() {
313 | return isSneaking;
314 | }
315 | public boolean isSprinting() {
316 | return isSprinting;
317 | }
318 | public boolean isBlocking() {
319 | return isBlocking;
320 | }
321 | public ItemStack getItemInHand(){
322 | return this.handHeld;
323 | }
324 | public ItemStack[] getArmorContents(){
325 | return new ItemStack[]{ helmet, chestplate, leggins, boots };
326 | }
327 | }
328 |
--------------------------------------------------------------------------------
/src/de/sebpas/replay/recorder/listener/InteractListener.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/src/de/sebpas/replay/recorder/listener/InteractListener.java
--------------------------------------------------------------------------------
/src/de/sebpas/replay/recorder/listener/MoveListener.java:
--------------------------------------------------------------------------------
1 | package de.sebpas.replay.recorder.listener;
2 |
3 | import org.bukkit.event.EventHandler;
4 | import org.bukkit.event.Listener;
5 | import org.bukkit.event.player.PlayerMoveEvent;
6 |
7 | import de.sebpas.replay.ReplaySystem;
8 |
9 | public class MoveListener implements Listener{
10 | private ReplaySystem plugin;
11 | public MoveListener(ReplaySystem plugin){
12 | this.plugin = plugin;
13 | }
14 | @EventHandler
15 | public void onMove(PlayerMoveEvent e){
16 | plugin.getRecorder().addString(plugin.getHandledTicks() + ";" + e.getPlayer().getUniqueId() + ";" + e.getPlayer().getName() + ";moved:" + e.getTo().getX() + "," + e.getTo().getY() + "," + e.getTo().getZ()
17 | + "," + e.getTo().getYaw() + "," + e.getTo().getPitch() + ";" + (e.getPlayer().isSneaking() ? "sneak" : (e.getPlayer().isSprinting() ? "sprint" : ""))
18 | + ";" + (e.getPlayer().isBlocking() ? "block" : ""));
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/de/sebpas/replay/recorder/listener/SpawnDespawnListener.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/src/de/sebpas/replay/recorder/listener/SpawnDespawnListener.java
--------------------------------------------------------------------------------
/src/de/sebpas/replay/util/InventoryUtilities.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/src/de/sebpas/replay/util/InventoryUtilities.java
--------------------------------------------------------------------------------
/src/de/sebpas/replay/util/ItemUtilities.java:
--------------------------------------------------------------------------------
1 | package de.sebpas.replay.util;
2 |
3 | import org.bukkit.Material;
4 | import org.bukkit.inventory.ItemStack;
5 | import org.bukkit.inventory.meta.ItemMeta;
6 | import org.bukkit.inventory.meta.SkullMeta;
7 |
8 | public class ItemUtilities {
9 | private ItemUtilities() {}
10 |
11 | public static ItemStack createItem(Material mat, int amount, int shortid, String displayname){
12 | short s = (short) shortid;
13 | ItemStack i = new ItemStack(mat, amount, s);
14 | ItemMeta meta = i.getItemMeta();
15 | meta.setDisplayName(displayname);
16 | i.setItemMeta(meta);
17 | return i;
18 | }
19 | /**
20 | * You need a player head?
21 | * @param mat
22 | * @param amount
23 | * @param shortid
24 | * @param name
25 | * @param displayname
26 | * @return skull of a specified player
27 | */
28 | public static ItemStack createItem(int amount, String name, String displayname){
29 | ItemStack item = new ItemStack(Material.SKULL_ITEM, amount, (short) 3);
30 | SkullMeta meta = (SkullMeta) item.getItemMeta();
31 | meta.setDisplayName(displayname);
32 | meta.setOwner(name);
33 | item.setItemMeta(meta);
34 | return item;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/de/sebpas/replay/util/PlayingPlayer.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pscln/ReplayAPI/4ad4152dc4c4fdfb65084f0beaeb4452f63fcf61/src/de/sebpas/replay/util/PlayingPlayer.java
--------------------------------------------------------------------------------
/src/de/sebpas/replay/util/Reflections.java:
--------------------------------------------------------------------------------
1 | package de.sebpas.replay.util;
2 |
3 | import java.lang.reflect.Field;
4 |
5 | import net.minecraft.server.v1_8_R2.Packet;
6 |
7 | import org.bukkit.Bukkit;
8 | import org.bukkit.craftbukkit.v1_8_R2.entity.CraftPlayer;
9 | import org.bukkit.entity.Player;
10 |
11 | import de.sebpas.replay.ReplaySystem;
12 |
13 | public class Reflections {
14 |
15 | public void setValue(Object obj, String name, Object value){
16 | try{
17 | Field field = obj.getClass().getDeclaredField(name);
18 | field.setAccessible(true);
19 | field.set(obj, value);
20 | }catch(Exception e){
21 | ReplaySystem.sendBroadcastError(e.getMessage());
22 | e.printStackTrace();
23 | }
24 | }
25 | public Object getValue(Object obj, String name){
26 | try{
27 | Field field = obj.getClass().getDeclaredField(name);
28 | field.setAccessible(true);
29 | return field.get(obj);
30 | }catch(Exception e){
31 | ReplaySystem.sendBroadcastError(e.getMessage());
32 | e.printStackTrace();
33 | }
34 | return null;
35 | }
36 | public void sendPacket(Packet> packet, Player player){
37 | ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
38 | }
39 | public void sendPacket(Packet> packet){
40 | for(Player p : Bukkit.getOnlinePlayers()){
41 | this.sendPacket(packet, p);
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/de/sebpas/replay/util/ReplayStoppedEvent.java:
--------------------------------------------------------------------------------
1 | package de.sebpas.replay.util;
2 |
3 | import org.bukkit.event.Event;
4 | import org.bukkit.event.HandlerList;
5 |
6 | import de.sebpas.replay.RePlayer;
7 |
8 | public class ReplayStoppedEvent extends Event{
9 | private static final HandlerList handlers = new HandlerList();
10 |
11 | private RePlayer replayer;
12 |
13 | public ReplayStoppedEvent(RePlayer replayer){
14 | this.replayer = replayer;
15 | }
16 |
17 | @Override
18 | public HandlerList getHandlers() {
19 | return handlers;
20 | }
21 | public static HandlerList getHandlerList(){
22 | return handlers;
23 | }
24 | public RePlayer getRePlayer(){
25 | return replayer;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------