Skip to content

Commit

Permalink
implement
Browse files Browse the repository at this point in the history
  • Loading branch information
Blackjack200 committed Feb 1, 2022
1 parent 0794c56 commit 823dce6
Show file tree
Hide file tree
Showing 15 changed files with 649 additions and 3 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
# WorldsX

CzechPMDevs/MultiWorld isn't good, use this

/wx help

/gamerule
7 changes: 5 additions & 2 deletions plugin.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
name: WorldsX
version: 0.0.1
version: 1.0.0
api: 4.0.0
main: blackjack200\worldsx\WorldsX
author: Blackjack200
website: https://github.com/Blackjack200/WorldsX.git
permissions:
worldsx.command:
description: "Allows the user to use the /worldsx command."
default: op
default: op
worldsx.gamerule:
description: "Allows the user to use the /gamerule command."
default: op
30 changes: 30 additions & 0 deletions resources/gamerule_name_map.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"command_blocks_enabled": "commandBlocksEnabled",
"command_block_output": "commandBlockOutput",
"do_daylight_cycle": "doDaylightCycle",
"do_entity_drops": "doEntityDrops",
"do_fire_tick": "doFireTick",
"do_insomnia": "doInsomnia",

"do_immediate_respawn": "doImmediateRespawn",
"do_mob_loot": "doMobLoot",
"do_tile_drops": "doTileDrops",
"do_weather_cycle": "doWeatherCycle",
"drowning_damage": "drowningDamage",
"fall_damage": "fallDamage",
"fire_damage": "fireDamage",
"freeze_damage": "freezeDamage",
"function_command_limit": "functionCommandLimit",
"keep_inventory": "keepInventory",
"max_command_chain_length": "maxCommandChainLength",
"mob_griefing": "mobGriefing",
"natural_regeneration": "naturalRegeneration",
"pvp": "pvp",
"random_tick_speed": "randomTickSpeed",
"send_command_feedback": "sendCommandFeedback",
"show_coordinates": "showCoordinates",
"show_death_message": "showDeathMessage",
"spawn_radius": "spawnRadius",
"tnt_explodes": "tntExplodes",
"show_tags": "showTags"
}
137 changes: 137 additions & 0 deletions resources/internal_gamerule_map.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
{
"commandBlocksEnabled": {
"internal": "commandBlocksEnabled",
"default": true,
"type": "bool"
},
"commandBlockOutput": {
"internal": "commandBlockOutput",
"default": true,
"type": "bool"
},
"doDaylightCycle": {
"internal": "doDaylightCycle",
"default": true,
"type": "bool"
},
"doEntityDrops": {
"internal": "doEntityDrops",
"default": true,
"type": "bool"
},
"doFireTick": {
"internal": "doFireTick",
"default": true,
"type": "bool"
},
"doInsomnia": {
"internal": "doInsomnia",
"default": true,
"type": "bool"
},
"doImmediateRespawn": {
"internal": "doImmediateRespawn",
"default": false,
"type": "bool"
},
"doMobLoot": {
"internal": "doMobLoot",
"default": true,
"type": "bool"
},
"doTileDrops": {
"internal": "doTileDrops",
"default": true,
"type": "bool"
},
"doWeatherCycle": {
"internal": "doWeatherCycle",
"default": true,
"type": "bool"
},
"drowningDamage": {
"internal": "drowningDamage",
"default": true,
"type": "bool"
},
"fallDamage": {
"internal": "fallDamage",
"default": true,
"type": "bool"
},
"fireDamage": {
"internal": "fireDamage",
"default": true,
"type": "bool"
},
"freezeDamage": {
"internal": "freezeDamage",
"default": true,
"type": "bool"
},
"functionCommandLimit": {
"internal": "functionCommandLimit",
"default": true,
"type": "bool"
},
"keepInventory": {
"internal": "keepInventory",
"default": false,
"type": "bool"
},
"maxCommandChainLength": {
"internal": "maxCommandChainLength",
"default": 65536,
"type": "int"
},
"mobGriefing": {
"internal": "mobGriefing",
"default": true,
"type": "bool"
},
"naturalRegeneration": {
"internal": "naturalRegeneration",
"default": true,
"type": "bool"
},
"pvp": {
"internal": "pvp",
"default": true,
"type": "bool"
},
"randomTickSpeed": {
"internal": "randomTickSpeed",
"default": 1,
"type": "int"
},
"sendCommandFeedback": {
"internal": "sendCommandFeedback",
"default": true,
"type": "bool"
},
"showCoordinates": {
"internal": "showCoordinates",
"default": true,
"type": "bool"
},
"showDeathMessage": {
"internal": "showDeathMessage",
"default": true,
"type": "bool"
},
"spawnRadius": {
"internal": "spawnRadius",
"default": 5,
"type": "int"
},
"tntExplodes": {
"internal": "tntExplodes",
"default": true,
"type": "bool"
},
"showTags": {
"internal": "showTags",
"default": true,
"type": "bool"
}
}
6 changes: 6 additions & 0 deletions resources/lang/en_US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,9 @@ command.duplicate.not-exists: "§4World [0] not exists."
command.duplicate.exists: "§4World [1] already exists."
command.duplicate.success: "§aWorld [0] duplicated to [1]."
command.duplicate.error: "§4Error duplicating world [0] to [1]: [2]."

command.gamerule.usage: "§4Usage: /gamerule <rule> <value> <world>"
command.gamerule.rule-not-exists: "§4Gamerule [0] not exists."
command.gamerule.world-not-exists: "§4World [0] not exists."
command.gamerule.success: "§aGamerule [0] set to [1] in world [2]."
command.gamerule.error: "§4Error setting gamerule [0] to [1] in world [2]."
7 changes: 7 additions & 0 deletions resources/lang/zh_CN.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,10 @@ command.duplicate.not-exists: "§4世界 [0] 不存在."
command.duplicate.exists: "§4世界 [1] 已经存在."
command.duplicate.success: "§a世界 [0] 复制到 [1]."
command.duplicate.error: "§4复制世界 [0] 到 [1] 错误: [2]."


command.gamerule.usage: "§4用法: /gamerule <规则> <值> <世界>"
command.gamerule.rule-not-exists: "§4游戏规则 [0] 不存在."
command.gamerule.world-not-exists: "§4世界 [0] 不存在."
command.gamerule.success: "§a世界 [2] 的游戏规则 [0] 设置为 [1]."
command.gamerule.error: "§4设置世界 [2] 的游戏模式 [0] 为 [1] 出错."
12 changes: 11 additions & 1 deletion src/blackjack200/worldsx/WorldsX.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

namespace blackjack200\worldsx;

use blackjack200\worldsx\command\GameRuleCommand;
use blackjack200\worldsx\command\WorldsXCommand;
use blackjack200\worldsx\generator\VoidGenerator;
use blackjack200\worldsx\lang\Language;
use blackjack200\worldsx\session\WorldsXListener;
use blackjack200\worldsx\world\types\GameRuleParser;
use pocketmine\plugin\PluginBase;
use pocketmine\Server;
use pocketmine\world\generator\GeneratorManager;
Expand All @@ -16,12 +19,19 @@ protected function onEnable() : void {
$this->saveDefaultConfig();
$language = $this->setupLanguage();
GeneratorManager::getInstance()->addGenerator(VoidGenerator::class, "void", fn() => null);
if (Server::getInstance()->getPluginManager()->getPlugin('MultiWorld') === null) {
if (Server::getInstance()->getPluginManager()->getPlugin('MultiWorld') !== null) {
$this->getLogger()->warning($language->translateString('multiworld.warning') ?? throw new RuntimeException());
$this->getServer()->getPluginManager()->disablePlugin($this);
return;
}
GameRuleParser::setup(
json_decode(stream_get_contents($this->getResource('gamerule_name_map.json')), true),
json_decode(stream_get_contents($this->getResource('internal_gamerule_map.json')), true),
);
$listener = new WorldsXListener();
$this->getServer()->getPluginManager()->registerEvents($listener, $this);
$this->getServer()->getCommandMap()->register('wx', new WorldsXCommand($language));
$this->getServer()->getCommandMap()->register('gamerule', new GameRuleCommand($language, $listener));
}

protected function onDisable() : void {
Expand Down
66 changes: 66 additions & 0 deletions src/blackjack200/worldsx/command/GameRuleCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace blackjack200\worldsx\command;

use blackjack200\worldsx\lang\Language;
use blackjack200\worldsx\session\WorldGameRules;
use blackjack200\worldsx\session\WorldsXListener;
use blackjack200\worldsx\world\GameRuleUtil;
use blackjack200\worldsx\world\types\GameRuleParser;
use blackjack200\worldsx\world\WorldUtil;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\player\Player;
use pocketmine\Server;
use pocketmine\world\format\io\data\BaseNbtWorldData;

class GameRuleCommand extends Command {
private Language $lang;
private WorldsXListener $listener;

public function __construct(Language $lang, WorldsXListener $listener) {
$this->lang = $lang;
$this->listener = $listener;
parent::__construct('gamerule', 'GameRules', '/gamerule <name> <value> <world>', ['gr']);
$this->setPermission('worldsx.gamerule');
}

public function execute(CommandSender $sender, string $commandLabel, array $args) {
if ($this->testPermission($sender)) {
if (count($args) < 2) {
$sender->sendMessage($this->lang->translateString('command.gamerule.usage'));
return;
}
$world = $args[2] ?? null;
if ($world === null) {
if ($sender instanceof Player) {
$world = $sender->getWorld()->getFolderName();
} else {
$world = Server::getInstance()->getWorldManager()->getDefaultWorld()->getFolderName();
}
}

[$name, $value] = $args;
$world = WorldUtil::findWorldByFolderName($world);
if ($world === null) {
$sender->sendMessage($this->lang->translateString('command.gamerule.world-not-exists', [$world]));
return;
}
$internal = GameRuleParser::toInternal($name);
if ($internal === null) {
$sender->sendMessage($this->lang->translateString('command.gamerule.rule-not-exists', [$name]));
return;
}
$g = WorldGameRules::getGameRule($world);
$g->set($internal, $value);
$data = $world->getProvider()->getWorldData();
if ($data instanceof BaseNbtWorldData) {
GameRuleUtil::save($data, $g);
$this->listener->syncGameRules($world);
$sender->sendMessage($this->lang->translateString('command.gamerule.success', $args));
} else {
$sender->sendMessage($this->lang->translateString('command.gamerule.error', $args));
}
}
}
}
27 changes: 27 additions & 0 deletions src/blackjack200/worldsx/session/PlayerSession.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace blackjack200\worldsx\session;

use blackjack200\worldsx\world\GameRuleCollection;
use pocketmine\network\mcpe\protocol\GameRulesChangedPacket;
use pocketmine\player\Player;

class PlayerSession {
public Player $player;
public GameRuleCollection $collection;

public function __construct(Player $player, GameRuleCollection $collection) {
$this->collection = $collection;
$this->player = $player;
}

public function syncGameRules(GameRuleCollection $collection) : void {
$this->collection = $collection;
$this->sendGameRules();
}

public function sendGameRules() : void {
$pk = GameRulesChangedPacket::create($this->collection->toGameRules());
$this->player->getNetworkSession()->sendDataPacket($pk);
}
}
45 changes: 45 additions & 0 deletions src/blackjack200/worldsx/session/WorldGameRules.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace blackjack200\worldsx\session;

use blackjack200\worldsx\world\GameRuleCollection;
use blackjack200\worldsx\world\GameRuleUtil;
use blackjack200\worldsx\world\types\GameRules;
use pocketmine\utils\AssumptionFailedError;
use pocketmine\world\format\io\data\BaseNbtWorldData;
use pocketmine\world\World;
use RuntimeException;

class WorldGameRules {
/** @var GameRuleCollection[] */
private static array $gameRules = [];

public static function setupGameRules(World $w) : void {
$data = $w->getProvider()->getWorldData();
if ($data instanceof BaseNbtWorldData) {
$c = GameRuleUtil::parse($data);
if ($c !== null) {
self::$gameRules[$w->getFolderName()] = $c;
self::initialGameRules($c, $w);
} else {
throw new RuntimeException('Failed to parse game rules for world ' . $w->getFolderName());
}
} else {
throw new RuntimeException('World ' . $w->getFolderName() . ' is not a NBT-data-based world');
}
}

protected static function initialGameRules(GameRuleCollection $c, World $w) : void {
if (!$c->get(GameRules::DO_DAYLIGHT_CYCLE)) {
$w->stopTime();
}
}

public static function getGameRule(World $world) : GameRuleCollection {
return self::$gameRules[$world->getFolderName()] ?? throw new AssumptionFailedError('Game rules not loaded');
}

public static function remove(World $world) : void {
unset(self::$gameRules[$world->getFolderName()]);
}
}
Loading

0 comments on commit 823dce6

Please sign in to comment.