Skip to content
This repository was archived by the owner on Jul 11, 2018. It is now read-only.

Commit e1e013f

Browse files
committed
1.1.1
1 parent 9007dd9 commit e1e013f

File tree

11 files changed

+585
-1
lines changed

11 files changed

+585
-1
lines changed

README.md

+100-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,101 @@
1+
<img src="https://raw.githubusercontent.com/Muirfield/NetherChests/master/media/EnderChest.png" style="width:64px;height:64px" width="64" height="64"/>
2+
13
# NetherChests
2-
An Ender Chest implementation
4+
5+
* Summary: An Ender Chest type plugin
6+
* Dependency Plugins: N/A
7+
* PocketMine-MP version: 1.5 (API:1.12.0)
8+
* OptionalPlugins: -
9+
* Categories: mechanics
10+
* Plugin Access: Databases, Tile Entities
11+
12+
## Overview
13+
14+
<!-- php: $v_forum_thread = "http://forums.pocketmine.net/threads/netherchests.9269/"; -->
15+
<!-- template: prologue.md -->
16+
17+
**DO NOT POST QUESTION/BUG-REPORTS/REQUESTS IN THE REVIEWS**
18+
19+
It is difficult to carry a conversation in the reviews. If you
20+
have a question/bug-report/request please use the
21+
[Thread](http://forums.pocketmine.net/threads/netherchests.9269/) for
22+
that. You are more likely to get a response and help that way.
23+
24+
_NOTE:_
25+
26+
This documentation was last updated for version **1.1.1**.
27+
28+
Please go to
29+
[github](https://github.com/alejandroliu/pocketmine-plugins/tree/master/NetherChests)
30+
for the most up-to-date documentation.
31+
32+
You can also download this plugin from this [page](https://github.com/alejandroliu/pocketmine-plugins/releases/tag/NetherChests-1.1.1).
33+
34+
<!-- template-end -->
35+
36+
An Ender Chest implementation.
37+
38+
Place a Chest on top of a NettherRack, will turn that chest into an NetherChest.
39+
40+
### Configuration
41+
42+
Configuration is through the `config.yml` file.
43+
The following sections are defined:
44+
45+
#### config.yml
46+
47+
* settings: Configuration settings
48+
* global: If true all worlds share the same NetherChest
49+
* particles: Decorate NetherChests...
50+
* p-ticks: Particle ticks
51+
* base-block: Block to use for the base
52+
* backend: Use YamlMgr or MySqlMgr
53+
* MySql: MySQL settings. Only used if backend is MySqlMgr to configure MySql settings
54+
55+
56+
## Permission nodes
57+
58+
# FAQ
59+
60+
* Q: What happens when more than one player use the NetherChest?
61+
* A: when a player opens a NetherChest they see their own inventory,
62+
not somebody elses. However, only one player can use a NetherChest
63+
at a time.
64+
* Q: It doesn't work with iProtector!
65+
* A: I don't use iProtector. This plugin only listens to
66+
_InventoryOpen_ and _InventoryClose_ (it also listens to
67+
_BlockPlace_ and _PlayerQuit_, but that has nothing to do with
68+
opening chests). iProtector listens and **Cancels** PlayerInteract
69+
events. These are fired **before** Inventory events. So, if you
70+
are not able to get it to work with _iProtector_, your configuration
71+
is **wrong**.
72+
73+
# Changes
74+
75+
* 1.1.1: Bug fix
76+
- Fixed item duplication cheat/bug (Reported by @predawnia)
77+
* 1.1.0 : flexibility
78+
- more configuration, NetherChests can be global now
79+
- MySQL support
80+
- Translation: English, Spanish, Dutch
81+
* 1.0.0 : First submission
82+
83+
# Copyright
84+
85+
NetherChests
86+
Copyright (C) 2015 Alejandro Liu
87+
All Rights Reserved.
88+
89+
This program is free software: you can redistribute it and/or modify
90+
it under the terms of the GNU General Public License as published by
91+
the Free Software Foundation, either version 2 of the License, or
92+
(at your option) any later version.
93+
94+
This program is distributed in the hope that it will be useful,
95+
but WITHOUT ANY WARRANTY; without even the implied warranty of
96+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
97+
GNU General Public License for more details.
98+
99+
You should have received a copy of the GNU General Public License
100+
along with this program. If not, see <http://www.gnu.org/licenses/>.
101+

media/EnderChest.png

2.41 KB
Loading

plugin.yml

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
main: aliuly\nechest\Main
2+
api: 1.12.0
3+
load: POSTWORLD
4+
5+
name: NetherChests
6+
description: An Ender Chest type plugin
7+
version: 1.1.1
8+
author: aliuly
9+
website: https://github.com/alejandroliu/pocketmine-plugins/tree/master/NetherChests
10+
11+
permissions:

resources/messages/messages.ini

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
; messages.ini
2+
"Closing NetherChest!"=""
3+
"Invalid base-block %1%"=""
4+
"Opening NetherChest!"=""
5+
"Placed a NetherChest"=""
6+
"That NetherChest is in use!"=""
7+
"Using %1% as backend"=""
8+
"#Placed a Nether Chest"=""
9+
"#That Nether Chest is in use!"=""

resources/messages/nld.ini

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
; nld.ini
2+
"Closing NetherChest!"="Sluiten NetherChest"
3+
"Invalid base-block %1%"="Ongeldig base-block %1%"
4+
"Opening NetherChest!"="Openen NetherChest"
5+
"Placed a NetherChest"="Plaatsing NetherChest"
6+
"That NetherChest is in use!"="NetherChest is bezet"
7+
"Using %1% as backend"="Met %1% als backend"

resources/messages/spa.ini

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
; spa.ini
2+
"Closing NetherChest!"="Cerrando NetherChest!"
3+
"Invalid base-block %1%"="base-block erroneo %1%"
4+
"Opening NetherChest!"="Abriendo NetherChest!"
5+
"Placed a NetherChest"="Colocando un NetherChest"
6+
"That NetherChest is in use!"="Ese NetherChest ya esta en uso!"
7+
"Using %1% as backend"="Usando %1% como proveedor de datos"
8+
"#%1%-mode"="modo-%1%"
9+
"#* EconomyAPI or"="* EconomyAPI ó"
10+
"#* GoldStd"="* GoldStd"
11+
"#* MassiveEconomy"="* MassiveEconomy"
12+
"#* PocketMoney"="* PocketMoney"
13+
"#. Please install one of the following:"=". Por favor instale uno de los siguientes:"
14+
"#Adventure"="Aventura"
15+
"#Available sub-commands for %1%"="Subcomandos disponibles para %1%"
16+
"#Creative"="Creativo"
17+
"#Description: "="Descripción: "
18+
"#Enable %1% features"="Activando %1% módulos"
19+
"#Enabled %1% features"="Activando %1% módulos"
20+
"#Enabled one feature"="Activando un módulo"
21+
"#Help: "="Ayuda: "
22+
"# MISSING MONEY API PLUGIN"="# NO SE ENCONTRÓ UN PLUGIN DE ECONOMÍA"
23+
"#NO features enabled"="NO módulos activados"
24+
"#No help for %1%"="No hay ayuda para %1%"
25+
"#No sub-command specified"="No sub-comando proporcionado"
26+
"#Spectator"="Espectador"
27+
"#Survival"="Supervivencia"
28+
"#Unknown feature \"%1%\" ignored."="Módulo \"%1%\" desconocido, ignorando..."
29+
"#Unknown sub-command %2% (try /%1% help)"="Sub-comando %2% desconocido. (Pruebe /%1% help)"
30+
"#Usage: "="Uso: "
31+
"#Using money API from %1%"="Usando el API de economía de %1%"
32+
"#You are not allowed to do this"="No esta autorizado a hacer esto"
33+
"#You can only do this in-game"="Esto sólo se puede hacer dentro del juego"
34+
"#You do not have permission to do that."="No tiene permiso para hacer eso."
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
namespace aliuly\nechest;
3+
use pocketmine\plugin\PluginBase;
4+
use pocketmine\Player;
5+
use pocketmine\inventory\Inventory;
6+
7+
8+
interface DatabaseManager {
9+
public function __construct(PluginBase $owner,$isGlobal);
10+
public function saveInventory(Player $player,Inventory $inv);
11+
public function loadInventory(Player $player,Inventory $inv);
12+
public function close();
13+
}

src/aliuly/nechest/Main.php

+215
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
<?php
2+
/**
3+
** CONFIG:config.yml
4+
**/
5+
namespace aliuly\nechest;
6+
7+
use pocketmine\plugin\PluginBase;
8+
use pocketmine\event\Listener;
9+
10+
use pocketmine\utils\Config;
11+
use pocketmine\item\Item;
12+
use pocketmine\block\Block;
13+
use pocketmine\Player;
14+
use pocketmine\inventory\Inventory;
15+
use pocketmine\inventory\DoubleChestInventory;
16+
use pocketmine\inventory\ChestInventory;
17+
use pocketmine\tile\Tile;
18+
use pocketmine\tile\Chest;
19+
use pocketmine\math\Vector3;
20+
21+
22+
use pocketmine\event\player\PlayerQuitEvent;
23+
use pocketmine\event\inventory\InventoryCloseEvent;
24+
use pocketmine\event\inventory\InventoryOpenEvent;
25+
use pocketmine\event\block\BlockBreakEvent;
26+
use pocketmine\event\block\BlockPlaceEvent;
27+
28+
use aliuly\nechest\common\mc;
29+
30+
// OPEN
31+
//- PlayerInteractEvent;
32+
//- InventoryOpenEvent;
33+
34+
//PUT IN CHEST|GET FROM CHEST
35+
//- InventoryTransactionEvent;
36+
//- EntityInventoryChangeEvent;
37+
38+
// CLOSE
39+
//- InventoryCloseEvent;
40+
41+
42+
//
43+
//use pocketmine\level\Level;
44+
//use pocketmine\event\entity\EntityLevelChangeEvent;
45+
//use pocketmine\block\Block;
46+
//use pocketmine\Server;
47+
//use pocketmine\utils\TextFormat;
48+
//use pocketmine\scheduler\CallbackTask;
49+
50+
51+
class Main extends PluginBase implements Listener {
52+
protected $chests; // Array with active chests
53+
protected $base_block;
54+
protected $dbm;
55+
56+
protected static function iName($player) {
57+
return strtolower($player->getName());
58+
}
59+
protected static function chestId($obj) {
60+
if ($obj instanceof ChestInventory) $obj = $obj->getHolder();
61+
if ($obj instanceof Chest) $obj = $obj->getBlock();
62+
return implode(":",[$obj->getLevel()->getName(),(int)$obj->getX(),(int)$obj->getY(),(int)$obj->getZ()]);
63+
}
64+
65+
public function onDisable() {
66+
if ($this->dbm !== null) $this->dbm->close();
67+
$this->dbm = null;
68+
}
69+
public function onEnable(){
70+
if (!is_dir($this->getDataFolder())) mkdir($this->getDataFolder());
71+
$this->getServer()->getPluginManager()->registerEvents($this, $this);
72+
$this->dbm = null;
73+
if (!is_dir($this->getDataFolder())) mkdir($this->getDataFolder());
74+
mc::plugin_init($this,$this->getFile());
75+
$defaults = [
76+
"version" => $this->getDescription()->getVersion(),
77+
"# settings" => "Configuration settings",
78+
"settings" => [
79+
"# global" => "If true all worlds share the same NetherChest",
80+
"global" => false,
81+
"# particles" => "Decorate NetherChests...",
82+
"particles" => true,
83+
"# p-ticks" => "Particle ticks",
84+
"p-ticks" => 20,
85+
"# base-block" => "Block to use for the base",
86+
"base-block" => "NETHERRACK",
87+
],
88+
"# backend" => "Use YamlMgr or MySqlMgr",
89+
"backend" => "YamlMgr",
90+
"# MySql" => "MySQL settings.", // Only used if backend is MySqlMgr to configure MySql settings
91+
"MySql" => [
92+
"host" => "localhost",
93+
"user" => "nobody",
94+
"password" => "secret",
95+
"database" => "netherchestdb",
96+
"port" => 3306,
97+
],
98+
];
99+
$cf = (new Config($this->getDataFolder()."config.yml",
100+
Config::YAML,$defaults))->getAll();
101+
$backend = __NAMESPACE__."\\".$cf["backend"];
102+
$this->dbm = new $backend($this,$cf);
103+
$this->getLogger()->info(mc::_("Using %1% as backend",$cf["backend"]));
104+
105+
$bl = Item::fromString($cf["settings"]["base-block"]);
106+
if ($bl->getBlock()->getId() == Item::AIR) {
107+
$this->getLogger()->warning(mc::_("Invalid base-block %1%",$cf["settings"]["base-block"]));
108+
$this->base_block = Block::NETHERRACK;
109+
} else {
110+
$this->base_block = $bl->getBlock()->getId();
111+
}
112+
113+
$this->chests = [];
114+
if ($cf["settings"]["particles"]) {
115+
$this->getServer()->getScheduler()->scheduleRepeatingTask(
116+
new ParticleTask($this),
117+
$cf["settings"]["p-ticks"]);
118+
}
119+
}
120+
private function saveInventory(Player $player,Inventory $inv) {
121+
return $this->dbm->saveInventory($player,$inv);
122+
}
123+
private function loadInventory(Player $player,Inventory $inv) {
124+
return $this->dbm->loadInventory($player,$inv);
125+
}
126+
private function lockChest(Player $player,$obj){
127+
$cid = self::chestId($obj);
128+
if (isset($this->chests[$cid])) return false;
129+
$this->chests[$cid] = self::iName($player);
130+
return true;
131+
}
132+
private function unlockChest(Player $player,$obj){
133+
$cid = self::chestId($obj);
134+
if (!isset($this->chests[$cid])) return false;
135+
if ($this->chests[$cid] != self::iName($player)) return false;
136+
unset($this->chests[$cid]);
137+
return true;
138+
}
139+
140+
public function isNeChest(Inventory $inv) {
141+
if ($inv instanceof DoubleChestInventory) return false;
142+
if (!($inv instanceof ChestInventory)) return false;
143+
$tile = $inv->getHolder();
144+
if (!($tile instanceof Chest)) return false;
145+
$bl = $tile->getBlock();
146+
if ($bl->getId() != Block::CHEST) return false;
147+
if ($bl->getSide(Vector3::SIDE_DOWN)->getId() != $this->base_block) return false;
148+
return true;
149+
}
150+
public function onBlockPlaceEvent(BlockPlaceEvent $ev) {
151+
if ($ev->isCancelled()) return;
152+
$bl = $ev->getBlock();
153+
if ($bl->getId() != Block::CHEST || $bl->getSide(Vector3::SIDE_DOWN)->getId() != $this->base_block) return;
154+
$ev->getPlayer()->sendMessage(mc::_("Placed a NetherChest"));
155+
}
156+
public function onBlockBreakEvent(BlockBreakEvent $ev) {
157+
if ($ev->isCancelled()) return;
158+
$bl = $ev->getBlock();
159+
if ($bl->getId() == $this->base_block) $bl = $bl->getSide(Vector3::SIDE_UP);
160+
if ($bl->getId() == Block::CHEST) {
161+
$tile = $bl->getLevel()->getTile($bl);
162+
if ($tile == null) return;
163+
if (!($tile instanceof Chest)) return;
164+
$inv = $tile->getInventory();
165+
if (!$this->isNeChest($inv)) return;
166+
$cid = self::chestId($inv);
167+
if (!isset($this->chests[$cid])) return;
168+
$ev->getPlayer()->sendTip(mc::_("That NetherChest is in use!"));
169+
$ev->setCancelled();
170+
return;
171+
}
172+
}
173+
174+
public function onPlayerQuitEvent(PlayerQuitEvent $ev) {
175+
$pn = self::iName($ev->getPlayer());
176+
foreach (array_keys($this->chests) as $cid) {
177+
if ($this->chests[$cid] == $pn) {
178+
unset($this->chests[$cid]);
179+
list($level,$x,$y,$z) = explode(":",$cid);
180+
$level = $this->getServer()->getLevelByName($level);
181+
if ($level == null) continue;
182+
$tile = $level->getTile(new Vector3($x,$y,$z));
183+
if ($tile == null) continue;
184+
if (!($tile instanceof Chest)) continue;
185+
$inv = $tile->getInventory();
186+
if (!$this->isNeChest($inv)) continue;
187+
// QUITING WHILE NETHER CHEST IS OPEN!
188+
$this->saveInventory($ev->getPlayer(),$inv);
189+
}
190+
}
191+
}
192+
public function onInventoryCloseEvent(InventoryCloseEvent $ev) {
193+
$player = $ev->getPlayer();
194+
$inv = $ev->getInventory();
195+
if (!$this->isNeChest($inv)) return;
196+
if ($this->unlockChest($player,$inv)) {
197+
$player->sendMessage(mc::_("Closing NetherChest!"));
198+
$this->saveInventory($player,$inv);
199+
}
200+
}
201+
public function onInventoryOpenEvent(InventoryOpenEvent $ev) {
202+
if ($ev->isCancelled()) return;
203+
$player = $ev->getPlayer();
204+
$inv = $ev->getInventory();
205+
if (!$this->isNeChest($inv)) return;
206+
if (!$this->lockChest($player,$inv)) {
207+
$player->sendTip(mc::_("That NetherChest is in use!"));
208+
$ev->setCancelled();
209+
return;
210+
}
211+
$player->sendMessage(mc::_("Opening NetherChest!"));
212+
$this->loadInventory($player,$inv);
213+
}
214+
215+
}

0 commit comments

Comments
 (0)