/[projects]/miscJava/bukkit-minecraft-plugins/HoerupUtils/src/main/java/dk/thoerup/bukkit/hoeruputils/chests/AdvancedChest.java
ViewVC logotype

Annotation of /miscJava/bukkit-minecraft-plugins/HoerupUtils/src/main/java/dk/thoerup/bukkit/hoeruputils/chests/AdvancedChest.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1853 - (hide annotations) (download)
Tue Oct 2 16:40:56 2012 UTC (11 years, 8 months ago) by torben
File size: 15269 byte(s)
fix NPE: check for null chests _before_ testing ownership
1 torben 1805 package dk.thoerup.bukkit.hoeruputils.chests;
2    
3    
4     import java.util.HashMap;
5     import java.util.List;
6 torben 1807 import java.util.Set;
7     import java.util.TreeMap;
8     import java.util.TreeSet;
9 torben 1805
10     import org.bukkit.ChatColor;
11     import org.bukkit.Location;
12     import org.bukkit.Material;
13 torben 1807 import org.bukkit.OfflinePlayer;
14 torben 1805 import org.bukkit.Server;
15     import org.bukkit.World;
16     import org.bukkit.block.Block;
17     import org.bukkit.block.Chest;
18     import org.bukkit.block.DoubleChest;
19     import org.bukkit.command.Command;
20     import org.bukkit.command.CommandExecutor;
21     import org.bukkit.command.CommandSender;
22     import org.bukkit.entity.Player;
23     import org.bukkit.event.EventHandler;
24     import org.bukkit.event.Listener;
25     import org.bukkit.event.block.Action;
26     import org.bukkit.event.block.BlockBreakEvent;
27     import org.bukkit.event.block.BlockPlaceEvent;
28 torben 1806 import org.bukkit.event.entity.EntityExplodeEvent;
29 torben 1807 import org.bukkit.event.inventory.InventoryCloseEvent;
30     import org.bukkit.event.inventory.InventoryOpenEvent;
31 torben 1805 import org.bukkit.event.player.PlayerInteractEvent;
32     import org.bukkit.inventory.InventoryHolder;
33 torben 1807 import org.bukkit.inventory.ItemStack;
34 torben 1805
35     import dk.thoerup.bukkit.hoeruputils.HoerupUtilsPlugin;
36 torben 1807 import dk.thoerup.bukkit.hoeruputils.Util;
37 torben 1805
38    
39 torben 1807
40     public class AdvancedChest implements Listener, CommandExecutor{
41    
42     class ItemCount extends TreeMap<Integer,Integer> {
43     private static final long serialVersionUID = 1L;
44     };
45 torben 1805
46 torben 1807 HashMap<String, ItemCount> contentMap = new HashMap<String, ItemCount>();
47    
48 torben 1805
49 torben 1807 HashMap<Location,ChestBean> chestMap = new HashMap<Location, ChestBean>();
50 torben 1805
51    
52     HoerupUtilsPlugin plugin;
53     Server server;
54    
55 torben 1807 public AdvancedChest(HoerupUtilsPlugin plugin, Runnable r) {
56 torben 1805 this.plugin = plugin;
57     server = plugin.getServer();
58     try {
59     loadChests();
60     } catch (Exception e) {
61     e.printStackTrace();
62     //r.run();
63     loadChests();
64     }
65     }
66    
67    
68     @Override
69     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
70     if (! (sender instanceof Player) ) {
71     sender.sendMessage("this is not a console command!");
72     return true;
73     }
74    
75     Player player = (Player) sender;
76    
77 torben 1807 if (args.length == 0) {
78     player.sendMessage("Usage:");
79     player.sendMessage("/chest (status|lock|snitch|remove|addplayer|removeplayer) [player]");
80     return true;
81     }
82 torben 1805
83 torben 1807
84     Block b = player.getTargetBlock(null, 30);
85 torben 1805
86     if (b.getTypeId() != 54) {
87 torben 1807 player.sendMessage("[Chest] Please look at the chest you want to protect");
88 torben 1805 return true;
89     }
90    
91 torben 1807 Location loc = b.getLocation();
92 torben 1805 Location loc2 = getNeighborChest(loc);
93    
94 torben 1807 ChestBean chest = chestMap.get(loc);
95     String cmd = args[0].toLowerCase();
96    
97     if (cmd.equals("status")) {
98     if (chest != null) {
99     String mode = "";
100     switch (chest.getChestType()) {
101     case ChestBean.LOCKED:
102     mode = "locked";
103     break;
104     case ChestBean.SNITCHING:
105     mode = "snitching";
106     break;
107     default:
108     mode = "unknown ??";
109     }
110    
111     player.sendMessage(ChatColor.GREEN + "Chest is a " + mode + " chest owned by " + chest.getOwner());
112     player.sendMessage(ChatColor.GREEN + "Allowed players: " + chest.getModifyPlayers() );
113     } else {
114     player.sendMessage(ChatColor.GREEN + "The chest is not protected");
115     }
116     return true;
117     }
118    
119     if (cmd.equals("lock") || cmd.equals("snitch")) {
120     if (chest == null) {
121     chest = createChest(player.getName(), "", loc);
122     if (loc2 != null) {
123     chest.setDoublechest(true);
124     }
125     String modeStr = "";
126     if (cmd.equals("lock")) {
127     chest.setChestType( ChestBean.LOCKED);
128     modeStr = "locked";
129     } else {
130     chest.setChestType( ChestBean.SNITCHING);
131     modeStr = "snitching";
132     }
133     chest.setModifyPlayers("");
134     addChest(loc, chest);
135     player.sendMessage("Chest is now " + modeStr);
136     } else {
137     player.sendMessage("This chest is already protected");
138     }
139     return true;
140     }
141    
142     if (cmd.equals("remove")) {
143 torben 1853 if (chest == null) {
144     player.sendMessage("This chest is not protected");
145     return true;
146     }
147 torben 1852 if (! chest.getOwner().equals( player.getName() ) ) {
148     player.sendMessage("You can not remove lock from a chest you don't own");
149     return true;
150     }
151 torben 1853
152     player.sendMessage("[LockedChest] Removing protection from chest");
153     removeChest(loc);
154    
155 torben 1807 return true;
156     }
157    
158     if (cmd.equals("addplayer") || cmd.equals("removeplayer")) {
159     if (chest == null) {
160     player.sendMessage("This chest is not protected");
161     return true;
162     }
163 torben 1852 if (! chest.getOwner().equals( player.getName() ) ) {
164     player.sendMessage("You can not add/remove players from a chest you don't own");
165     return true;
166     }
167 torben 1807 if (args.length != 2) {
168     player.sendMessage("You need to specify which player to add or remove");
169     return true;
170     }
171     OfflinePlayer p2 = server.getOfflinePlayer(args[1]);
172     if ( p2.hasPlayedBefore() == false && p2.isOnline() == false) {
173     player.sendMessage("Unknown user: " + args[1] );
174     return true;
175     }
176    
177     Set<String> players = Util.stringToSet( chest.getModifyPlayers() );
178     if (cmd.equals("addplayer")) {
179 torben 1808 players.add(p2.getName());
180 torben 1807 } else {
181 torben 1808 players.remove(p2.getName());
182 torben 1807 }
183    
184     chest.setModifyPlayers( Util.setToString(players) );
185     plugin.getDatabase().save( chest );
186     player.sendMessage("ok");
187     return true;
188     }
189    
190     /*
191 torben 1805 if (chest != null) {
192     if (chest.getOwner().equals(player.getName())) {
193     player.sendMessage("[LockedChest] Removing lock from chest");
194     removeChest(loc);
195     } else {
196 torben 1807 player.sendMessage("[LockedChest] Chest is already protected");
197 torben 1805 }
198    
199     return true;
200     }
201    
202     chest = createChest(player.getName(), "", loc);
203     if (loc2 != null) {
204     chest.setDoublechest(true);
205     }
206    
207     addChest(loc, chest);
208    
209    
210     player.sendMessage("[LockedChest] Chest is now locked");
211 torben 1807 */
212 torben 1805
213 torben 1807 player.sendMessage("Unknown argument, " + cmd);
214 torben 1805
215     return true;
216     }
217    
218     @EventHandler
219     public void onBlockBreak(BlockBreakEvent event) {
220     Location loc = event.getBlock().getLocation();
221 torben 1807 ChestBean chest = chestMap.get(loc);
222 torben 1805 if (chest != null) {
223     if (chest.getOwner().equals(event.getPlayer().getName())) {
224     removeChest(loc);
225 torben 1807 event.getPlayer().sendMessage("[AdvancedChest] The destroyed chest was locked or snitching");
226 torben 1805 } else {
227     event.setCancelled(true);
228     event.getPlayer().sendMessage("You can't destroy that chest");
229 torben 1810 server.getLogger().info( "[AdvancedChest] " + event.getPlayer().getName() + " tried breaking a chest owned by " + chest.getOwner() );
230 torben 1805 }
231     }
232     }
233 torben 1807 public void addChest(Location loc, ChestBean chest) {
234 torben 1805 chestMap.put(loc, chest);
235     if (chest.isDoublechest()) {
236     Location loc2 = getNeighborChest(loc);
237     chestMap.put(loc2, chest);
238     }
239     plugin.getDatabase().save(chest);
240    
241     reloadChests();
242    
243     }
244    
245     void removeChest(Location loc) {
246 torben 1807 ChestBean chest = chestMap.remove(loc);
247 torben 1805 if (chest != null) {
248     if (chest.isDoublechest()){
249     Location loc2 = getNeighborChest(loc);
250     chestMap.remove(loc2);
251     }
252     plugin.getDatabase().delete(chest);
253     }
254     }
255    
256     int loadChestsWorker() {
257 torben 1807 List<ChestBean> chestlist = plugin.getDatabase().find( ChestBean.class).findList();
258     for (ChestBean chest : chestlist) {
259 torben 1805 Location loc = getChestLocation(server, chest);
260     chestMap.put(loc, chest);
261    
262     if (chest.isDoublechest()) {
263     Location loc2 = getNeighborChest(loc);
264     chestMap.put(loc2, chest);
265     }
266     }
267    
268     return chestlist.size();
269     }
270    
271     void reloadChests() {
272     chestMap.clear();
273     loadChestsWorker();
274     }
275    
276     void loadChests() {
277     int count = loadChestsWorker();
278 torben 1813 server.getLogger().info("[AdvancedChest] loaded " + count + " chests");
279 torben 1805 }
280    
281    
282 torben 1807 public ChestBean createChest(String owner, String description, Location loc) {
283 torben 1805
284 torben 1807 ChestBean chest = new ChestBean();
285 torben 1805 chest.setOwner(owner);
286     chest.setDescription(description);
287     setChestLocation(chest, loc);
288    
289     return chest;
290     }
291    
292    
293 torben 1807 public void setChestLocation(ChestBean chest, Location loc) {
294 torben 1805 chest.setWorld( loc.getWorld().getName() );
295     chest.setX( loc.getBlockX() );
296     chest.setY( loc.getBlockY() );
297     chest.setZ( loc.getBlockZ() );
298     }
299    
300 torben 1807 public Location getChestLocation(Server server, ChestBean chest) {
301 torben 1805 World wrld = server.getWorld(chest.getWorld());
302     return new Location(wrld,chest.getX(),chest.getY(),chest.getZ());
303     }
304    
305    
306     /*
307     void saveChests() {
308    
309     }*/
310    
311     Location getNeighborChest(Location loc) {
312     World world = loc.getWorld();
313    
314     Location target = new Location(world, loc.getX()+1, loc.getY(), loc.getZ() );
315     if (world.getBlockAt(target).getType() == Material.CHEST )
316     return target;
317    
318     target = new Location(world, loc.getX()-1, loc.getY(), loc.getZ() );
319     if (world.getBlockAt(target).getType() == Material.CHEST )
320     return target;
321    
322     target = new Location(world, loc.getX(), loc.getY(), loc.getZ() +1);
323     if (world.getBlockAt(target).getType() == Material.CHEST )
324     return target;
325    
326     target = new Location(world, loc.getX(), loc.getY(), loc.getZ() -1);
327     if (world.getBlockAt(target).getType() == Material.CHEST )
328     return target;
329    
330     return null;
331     }
332    
333    
334     Location getChestLocation(InventoryHolder holder) {
335     Location loc;
336     if ( holder instanceof Chest) {
337     loc = ( (Chest)holder).getLocation();
338     } else {
339     loc = ( (DoubleChest)holder).getLocation();
340     }
341    
342     loc.setX( loc.getBlockX() ); //round to integer, since double chests apparently are placed at pos + 0.5
343     loc.setZ( loc.getBlockZ() ); // -- // --
344    
345     return loc;
346     }
347    
348     @EventHandler
349     public void onChestPlaced(BlockPlaceEvent event) {
350     Block block = event.getBlock();
351    
352     if (block.getType() != Material.CHEST) {
353     return;
354     }
355    
356     Location chestloc = getNeighborChest( block.getLocation() );
357     if (chestloc != null) {
358 torben 1807 ChestBean chest = chestMap.get(chestloc);
359 torben 1805
360     if (chest != null) { //the neighbor is a locked chest
361    
362    
363     chest.setDoublechest(true);
364     addChest(chestloc, chest);
365    
366    
367 torben 1807 event.getPlayer().sendMessage( "[AdvancedChest] Chest has been expanded" );
368 torben 1805 }
369    
370     }
371     }
372 torben 1806
373    
374     @EventHandler
375     public void onChestExplode(EntityExplodeEvent event) {
376     for (Block b : event.blockList() ) {
377 torben 1807 ChestBean chest = chestMap.get( b.getLocation() );
378 torben 1806 if (chest != null) {
379 torben 1810 server.getLogger().info( "[AdvancedChest] Prevented an explosion from destroying chest owned by " + chest.getOwner() );
380 torben 1806 event.setCancelled( true );
381     return;
382     }
383     }
384     }
385 torben 1805
386     // prevent a user from opening a chest
387     @EventHandler
388     public void onChestInteract(PlayerInteractEvent event) {
389     if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
390     Block b = event.getClickedBlock();
391    
392     if (b.getType() == Material.CHEST) {
393    
394     Location loc = b.getLocation();
395    
396 torben 1807 ChestBean chest = chestMap.get( loc );
397 torben 1805 if (chest == null) {
398     return; //chest not surveyed by this plugin
399     }
400    
401 torben 1807 if (chest.getChestType() != ChestBean.LOCKED ) {
402     return; //this is not a locked chests
403     }
404    
405 torben 1805 Player player = (Player) event.getPlayer();
406     if (player.getName().equals(chest.getOwner() )) {
407     return; //chest is opened by it's owner
408     }
409    
410 torben 1809 Set<String> players = Util.stringToSet( chest.getModifyPlayers() );
411     if ( players.contains(player.getName()) ) {
412     return; //this player is on the whitelist so he may open
413 torben 1805 }
414    
415 torben 1809
416 torben 1811 server.getLogger().info( "[AdvancedChest] " + event.getPlayer().getName() + " tried opening a chest owned by " + chest.getOwner() );
417 torben 1805 player.sendMessage( ChatColor.BLUE + "Sorry but this chest is locked !");
418     event.setCancelled(true);
419     }
420     }
421     }
422 torben 1807
423     @EventHandler
424     public void onChestOpen(InventoryOpenEvent event) {
425    
426     if (! (event.getPlayer() instanceof Player)) {
427     return;
428     }
429    
430    
431    
432     InventoryHolder holder = event.getInventory().getHolder();
433     if (holder instanceof Chest || holder instanceof DoubleChest) {
434     Location loc = getChestLocation(holder);
435    
436     ChestBean chest = chestMap.get( loc );
437     if (chest == null) {
438     return; //chest not surveyed by this plugin
439     }
440    
441     if (chest.getChestType() != ChestBean.SNITCHING) {
442     return; // not a snitching chest
443     }
444    
445    
446     Player player = (Player) event.getPlayer();
447     if (player.getName().equals(chest.getOwner() )) {
448     return; //chest is owned by it's own player
449 torben 1809 }
450 torben 1807
451 torben 1809 Set<String> players = Util.stringToSet( chest.getModifyPlayers() );
452     if ( players.contains(player.getName()) ) {
453     return; //this player is on the whitelist so he may open
454     }
455 torben 1807
456 torben 1809
457 torben 1807 ItemCount contents = countItems( event.getInventory().getContents() );
458    
459     contentMap.put(player.getName(), contents );
460     }
461     }
462 torben 1805
463 torben 1807 @EventHandler
464     public void onChestClose(InventoryCloseEvent event) {
465     if (! (event.getPlayer() instanceof Player)) {
466     return;
467     }
468    
469    
470     InventoryHolder holder = event.getInventory().getHolder();
471     if (holder instanceof Chest || holder instanceof DoubleChest) {
472     Location loc = getChestLocation(holder);
473     ChestBean chest = chestMap.get(loc);
474    
475     if (chest == null) { //chest was not a snitching chest
476     return;
477     }
478    
479     if (chest.getChestType() != ChestBean.SNITCHING) {
480     return; // not a snitching chest
481     }
482    
483    
484     OfflinePlayer owner = server.getOfflinePlayer( chest.getOwner() );
485    
486    
487     Player player = (Player) event.getPlayer();
488    
489     ItemCount savedContent = contentMap.get( player.getName() );
490    
491     if (savedContent == null) {
492     return;
493     }
494    
495     contentMap.remove( player.getName() );
496    
497     ItemCount content = countItems( event.getInventory().getContents() );
498    
499     Set<Integer> combinedKeyset = new TreeSet<Integer>();
500     combinedKeyset.addAll( savedContent.keySet() );
501     combinedKeyset.addAll( content.keySet() );
502    
503     for (Integer item : combinedKeyset ) {
504     Integer savedcount = savedContent.get(item);
505     Integer count = content.get(item);
506    
507     if (savedcount == null)
508     savedcount = 0;
509     if (count == null)
510     count = 0;
511    
512    
513     int diff = Math.abs( savedcount - count);
514    
515     if (diff > 0) {
516     String material = Material.getMaterial(item).name();
517     String msg = null;
518    
519     if (count > savedcount) {
520     msg = player.getName() + " added " + diff + " units of " + material + "(" +item + ") to " + owner.getName() + "'s chest at " + loc.getWorld().getName() + "," + loc.getBlockX() + "," +loc.getBlockY() + "," + loc.getBlockZ();
521     } else { //(count < savedcount)
522     msg = player.getName() + " removed " + diff + " units of " + material + "(" +item + ") from " + owner.getName() + "'s chest at " + loc.getWorld().getName() + "," + loc.getBlockX() + "," +loc.getBlockY() + "," + loc.getBlockZ();
523     }
524    
525    
526 torben 1813 server.getLogger().info( "[AdvancedChest]" + msg);
527 torben 1807 plugin.getMessageWrapper().sendMessage("system", owner, msg);
528     }
529    
530     }
531    
532    
533     }
534     }
535    
536     ItemCount countItems(ItemStack[] input) {
537     ItemCount output = new ItemCount();
538     for (int i=0; i<input.length; i++) {
539     ItemStack current = input[i];
540     if (current == null)
541     continue;
542    
543     int type = current.getTypeId();
544    
545     Integer amount = output.get(type);
546     if (amount == null)
547     amount = 0;
548    
549     output.put(type, amount + current.getAmount() );
550     }
551     return output;
552     }
553     /*
554     ItemStack[] cloneItemStacks(ItemStack[] input) {
555     ItemStack[] output = new ItemStack[ input.length ];
556     for (int i=0; i<input.length; i++) {
557     if (input[i] != null) {
558     output[i] = input[i].clone();
559     } else {
560     output[i] = new ItemStack(0, 0);
561     }
562     }
563     return output;
564     }*/
565    
566    
567 torben 1805 }

  ViewVC Help
Powered by ViewVC 1.1.20