99import org .bukkit .event .EventPriority ;
1010import org .bukkit .event .Listener ;
1111import org .bukkit .event .entity .*;
12- import org .bukkit .event .hanging .HangingBreakByEntityEvent ;
1312import org .bukkit .event .hanging .HangingBreakEvent ;
14- import org .bukkit .event .hanging .HangingEvent ;
1513import org .bukkit .event .player .PlayerDropItemEvent ;
1614import org .bukkit .event .player .PlayerInteractEntityEvent ;
1715import org .bukkit .inventory .ItemStack ;
2119import xyz .n7mn .dev .yululi .itemframeprotectionplugin .data .DataAPI ;
2220import xyz .n7mn .dev .yululi .itemframeprotectionplugin .data .DropItemData ;
2321import xyz .n7mn .dev .yululi .itemframeprotectionplugin .data .FrameData ;
22+ import xyz .n7mn .dev .yululi .itemframeprotectionplugin .data .ItemFrameProtectDeleteEvent ;
2423
2524import java .util .*;
2625
@@ -29,12 +28,13 @@ class ItemFrameListener implements Listener {
2928 final private DataAPI api ;
3029 final private Plugin plugin = Bukkit .getPluginManager ().getPlugin ("ItemFrameProtectionPlugin" );
3130
31+ private Set <UUID > frameBreakList = Collections .synchronizedSet (new HashSet <>());
32+ private UUID uuid = null ;
33+
3234 public ItemFrameListener (DataAPI api ){
3335 this .api = api ;
3436 }
3537
36- private UUID uuid = null ;
37-
3838 @ EventHandler (priority = EventPriority .HIGHEST )
3939 public void PlayerInteractEntityEvent (PlayerInteractEntityEvent e ){
4040
@@ -68,6 +68,9 @@ public void run() {
6868
6969 if (foundData .getProtectUser ().equals (player .getUniqueId ())){
7070 api .deleteTableByFrame (frame .getUniqueId ());
71+ synchronized (frameBreakList ){
72+ frameBreakList .remove (frame .getUniqueId ());
73+ }
7174 player .sendMessage (ChatColor .GREEN + "保護解除しました。 もう一度保護するにはスニークしながら右クリックしてください。" );
7275
7376 e .setCancelled (true );
@@ -76,6 +79,9 @@ public void run() {
7679
7780 if (player .hasPermission ("ifp.op" )){
7881 api .deleteTableByFrame (frame .getUniqueId ());
82+ synchronized (frameBreakList ){
83+ frameBreakList .remove (frame .getUniqueId ());
84+ }
7985 player .sendMessage (ChatColor .YELLOW + "保護を代理解除しました。 もう一度保護するにはスニークしながら右クリックしてください。" );
8086 } else {
8187 player .sendMessage (ChatColor .RED + "他の人が保護しています。" );
@@ -122,8 +128,12 @@ public void run() {
122128 }
123129
124130
125- // ItemStack itemInMainHand = e.getPlayer().getInventory().getItemInMainHand();
126- // e.getPlayer().getInventory().addItem(itemInMainHand);
131+ if (e .getPlayer ().getGameMode () != GameMode .CREATIVE && e .getPlayer ().getGameMode () != GameMode .SPECTATOR ){
132+
133+ ItemStack itemInMainHand = e .getPlayer ().getInventory ().getItemInMainHand ();
134+ e .getPlayer ().getInventory ().addItem (itemInMainHand );
135+
136+ }
127137
128138
129139 } catch (Exception ex ){
@@ -139,7 +149,6 @@ public void run() {
139149 uuid = null ;
140150 }
141151
142- private Set <UUID > frameBreakList = new HashSet <>();
143152
144153 @ EventHandler (priority = EventPriority .HIGHEST )
145154 public void BlockBreakEvent (HangingBreakEvent e ){
@@ -187,20 +196,23 @@ public void EntityDamageEvent (EntityDamageEvent e){
187196 // 額縁の中身消されたとき
188197 ItemFrame frame = (ItemFrame ) e .getEntity ();
189198
190- for (UUID uuid : frameBreakList ){
191- if (uuid .equals (frame .getUniqueId ())){
199+ synchronized (frameBreakList ){
200+ for (UUID uuid : frameBreakList ){
201+ if (uuid .equals (frame .getUniqueId ())){
202+ e .setCancelled (true );
203+ return ;
204+ }
205+ }
206+
207+ FrameData itemFrame = api .getItemFrame (frame .getUniqueId ());
208+ if (itemFrame != null ){
209+
210+ frameBreakList .add (frame .getUniqueId ());
192211 e .setCancelled (true );
193212 return ;
194213 }
195214 }
196215
197- FrameData itemFrame = api .getItemFrame (frame .getUniqueId ());
198- if (itemFrame != null ){
199-
200- frameBreakList .add (frame .getUniqueId ());
201- e .setCancelled (true );
202- return ;
203- }
204216
205217 if (frame .getItem ().getType () != Material .AIR ){
206218
@@ -222,20 +234,23 @@ public void EntityDamageByEntityEvent (EntityDamageByEntityEvent e){
222234 // 額縁の中身を取り出されるとき
223235 ItemFrame frame = (ItemFrame ) e .getEntity ();
224236
225- for (UUID uuid : frameBreakList ) {
226- if (uuid .equals (frame .getUniqueId ())) {
227- frameBreakList .add (frame .getUniqueId ());
237+ synchronized (frameBreakList ){
238+ for (UUID uuid : frameBreakList ) {
239+ if (uuid .equals (frame .getUniqueId ())) {
240+
241+ e .setCancelled (true );
242+ return ;
243+ }
244+ }
245+
246+ FrameData itemFrame = api .getItemFrame (frame .getUniqueId ());
247+ if (itemFrame != null ){
228248 e .setCancelled (true );
249+ frameBreakList .add (frame .getUniqueId ());
229250 return ;
230251 }
231252 }
232253
233- FrameData itemFrame = api .getItemFrame (frame .getUniqueId ());
234- if (itemFrame != null ){
235- e .setCancelled (true );
236- return ;
237- }
238-
239254 if (e .getDamager () instanceof Player ){
240255
241256
@@ -302,23 +317,81 @@ public void EntityTeleportEvent (EntityTeleportEvent e){
302317
303318 ItemFrame frame = (ItemFrame ) e .getEntity ();
304319
305- for (UUID uuid : frameBreakList ) {
306- if (uuid .equals (frame .getUniqueId ())) {
307- frameBreakList .add (frame .getUniqueId ());
308- e .setCancelled (true );
309- return ;
320+ synchronized (frameBreakList ){
321+ for (UUID uuid : frameBreakList ) {
322+ if (uuid .equals (frame .getUniqueId ())) {
323+
324+ e .setCancelled (true );
325+ return ;
326+ }
310327 }
311328 }
312329
330+
313331 FrameData itemFrame = api .getItemFrame (frame .getUniqueId ());
314332 if (itemFrame != null ){
333+ frameBreakList .add (frame .getUniqueId ());
315334 e .setCancelled (true );
316335 return ;
317336 }
318337
319338 e .setCancelled (true );
320339 }
321340
341+ @ EventHandler (priority = EventPriority .HIGHEST )
342+ public void EntityRemoveFromWorldEvent (EntityRemoveFromWorldEvent e ){
343+
344+ // 額縁がkillされそうなとき
345+
346+ if (e .getEntity ().getType () != EntityType .ITEM_FRAME ){
347+ return ;
348+ }
349+
350+ ItemFrame frame = (ItemFrame ) e .getEntity ();
351+
352+ synchronized (frameBreakList ){
353+ for (UUID uuid : frameBreakList ) {
354+ if (uuid .equals (frame .getUniqueId ())) {
355+ ItemFramePlace (e .getEntity ().getLocation (), frame );
356+ return ;
357+ }
358+ }
359+
360+ FrameData itemFrame = api .getItemFrame (frame .getUniqueId ());
361+ if (itemFrame != null ){
362+ ItemFramePlace (e .getEntity ().getLocation (), frame );
363+ frameBreakList .add (frame .getUniqueId ());
364+ }
365+ }
366+
367+ }
368+
369+ private void ItemFramePlace (Location loc , ItemFrame frame ){
370+
371+
372+ World world = loc .getWorld ();
373+ ItemFrame spawn = world .spawn (loc , ItemFrame .class );
374+ spawn .setItem (frame .getItem ());
375+
376+ FrameData data = api .getItemFrame (frame .getUniqueId ());
377+
378+ api .deleteTableByFrame (frame .getUniqueId ());
379+ synchronized (frameBreakList ){
380+ frameBreakList .remove (frame .getUniqueId ());
381+ }
382+ api .addItemFrame (new FrameData (spawn .getUniqueId (), frame .getItem (), data .getProtectUser (), new Date (), true ));
383+
384+
385+ }
386+
387+ @ EventHandler (priority = EventPriority .HIGHEST )
388+ public void ItemFrameProtectDeleteEvent (ItemFrameProtectDeleteEvent e ){
389+ // キャッシュ削除
390+ synchronized (frameBreakList ){
391+ frameBreakList .remove (e .getItemFrameUUID ());
392+ }
393+ }
394+
322395
323396
324397 @ EventHandler (priority = EventPriority .HIGHEST )
@@ -337,7 +410,6 @@ public void PlayerDropItemEvent (PlayerDropItemEvent e){
337410 }
338411
339412
340-
341413 private boolean ItemStackEqual (ItemStack item1 , ItemStack item2 ){
342414
343415 if (item1 == null && item2 == null ){
0 commit comments