├── .idea ├── copyright │ └── profiles_settings.xml ├── vcs.xml ├── php.xml ├── dictionaries │ └── primus.xml ├── modules.xml ├── misc.xml ├── UltraFactions_v1.0.0.iml └── workspace.xml ├── README.md ├── resources └── config.yml ├── src └── ultrafactions │ ├── handler │ ├── FactionEventListener.php │ └── PlayerEventListener.php │ ├── data │ ├── MySQLDataProvider.php │ ├── SQLite3DataProvider.php │ ├── PocketCoreDataProvider.php │ ├── DataProvider.php │ └── DefaultDataProvider.php │ ├── manager │ ├── Manager.php │ ├── MemberManager.php │ ├── FactionManager.php │ └── PlotManager.php │ ├── economy │ └── Economy.php │ ├── Member.php │ ├── faction │ ├── FactionBuilder.php │ └── Faction.php │ ├── UltraFactions.php │ └── command │ └── FactionCommand.php ├── manual.txt ├── plugin.yml └── LICENSE /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # It's not dead 2 | This project has rewritten at [FactionsPE](https://github.com/Chris-Prime/FactionsPE) Star it :D 3 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/php.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/dictionaries/primus.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | motd 5 | primus 6 | strtolower 7 | ultrafactions 8 | unclaim 9 | yaml 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /resources/config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | data: 3 | provider: 'default' 4 | settings: 5 | mysql: 6 | user: root 7 | host: localhost 8 | db: UltraFactions 9 | password: mysqlpassword 10 | yaml: [] 11 | sqlite: [] 12 | pc: [] 13 | economy: 14 | prefer: 'EconomyAPI' 15 | 16 | # faction.create === 'prices' => ['faction' => ['create' => 1000]] 17 | prices: 18 | faction: 19 | create: 1000 20 | claim: 500 21 | sethome: 100 22 | 23 | chat-format: "[{RANK}][{FACTION}] {PLAYER}: {MESSAGE}" 24 | ... 25 | -------------------------------------------------------------------------------- /src/ultrafactions/handler/FactionEventListener.php: -------------------------------------------------------------------------------- 1 | plugin = $plugin; 16 | } 17 | 18 | public function getPlugin() : UltraFactions 19 | { 20 | return $this->plugin; 21 | } 22 | } -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/UltraFactions_v1.0.0.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/ultrafactions/data/MySQLDataProvider.php: -------------------------------------------------------------------------------- 1 | getPlugin() instanceof UltraFactions === false) return false; 34 | return true; 35 | } 36 | 37 | public function getPlugin() : UltraFactions 38 | { 39 | return self::$plugin; 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /src/ultrafactions/data/PocketCoreDataProvider.php: -------------------------------------------------------------------------------- 1 | Creating and adding members to faction 4 | - Faction and Member are chained together 5 | 6 | To create new faction and add player to it, you must follow these instructions: 7 | 1) UltraFactions::createFaction($name, $data) 8 | * $data must, contain 'displayName' key 9 | * $data must, contain 'members' with leader member 10 | 2) Member::setRank(Member::RANK_LEADER); 11 | 3) Member::join(Faction) 12 | 13 | Delete faction: 14 | 1) Faction::destroy(); 15 | 16 | To give leader to different player do: 17 | 1) Faction::newLeader(Member $member) 18 | * Player must be attached to Faction before calling this 19 | 20 | Demote player: 21 | 1) Member::demote() 22 | 23 | Promote player: 24 | 1) Member::promote() 25 | 26 | Kick player from faction: 27 | 1) Faction::kick(Member $member, $reason = '') 28 | 29 | 30 | > Invitations 31 | - When invitation is sent, delayed task 32 | - Is scheduled to cancel it if it expires 33 | - After time is passed task will 34 | - notify Faction and Member about it 35 | 36 | Invite player to faction: 37 | 1) Member::sendInvitation(Faction $f) 38 | * Invitation expires in 15 seconds 39 | 40 | Accept invitation: 41 | 1) Member::acceptInvitation(); 42 | * Latest invitation will be accepted 43 | 44 | Decline: 45 | 2) Member::declineInvitation(); 46 | * Latest invitation will be declined 47 | 48 | 49 | > Claiming and un-claiming plots 50 | - When claiming plots functions will check 51 | - if plot isn't claimed already or/and 52 | - isn't in protected world 53 | 54 | Claim: 55 | 1) Faction::claimPlot(FullChunk $chunk) 56 | 57 | Unclaim: 58 | 1) Faction::unclaimPlot(FullChunk $chunk) 59 | -------------------------------------------------------------------------------- /plugin.yml: -------------------------------------------------------------------------------- 1 | name: UltraFactions 2 | author: Primus 3 | api: 2.0.0 4 | description: "Fully featured faction plugin for PocketMine-MP" 5 | version: 0.0.1 6 | main: ultrafactions\UltraFactions 7 | 8 | commands: 9 | faction: 10 | description: "Main UltraFactions command type \'/f help\' for more info" 11 | default: true 12 | permission: uf.* 13 | alias: [f, fac] 14 | 15 | permissions: 16 | uf.*: 17 | default: true 18 | description: "Top Permission, allows all plugin features" 19 | children: 20 | uf.command.*: 21 | default: true 22 | description: "Top command permission, allows all commands" 23 | children: 24 | uf.command.info: 25 | default: true 26 | description: "Allows command \'info\'" 27 | uf.command.create: 28 | default: true 29 | description: "Allows command \'create\'" 30 | uf.damage.*: 31 | default: false 32 | description: "Allows to damage all faction memebers" 33 | children: 34 | uf.damage.team: 35 | default: false 36 | description: "Allow to hit team mates" 37 | uf.damage.friends: 38 | default: false 39 | description: "Allow to hit friend faction members" 40 | uf.damage.enemies: 41 | default: true 42 | description: "Allow to hit enemy faction members" 43 | uf.damage.neutral: 44 | default: true 45 | description: "Allow to hit neutral faction members" 46 | uf.break.*: 47 | default: false 48 | description: "Allow to use all faction's claimed plots" 49 | # uf.break.friends 50 | # uf.break.enemies 51 | # uf.break.neutral 52 | # uf.interact.friends 53 | # uf.interact.enemies 54 | # uf.interact.neutral 55 | # uf.place.friends 56 | # uf.place.enemies 57 | # uf.place.neutral 58 | -------------------------------------------------------------------------------- /src/ultrafactions/data/DataProvider.php: -------------------------------------------------------------------------------- 1 | plugin = $plugin; 17 | 18 | $this->valid = $this->init(); 19 | } 20 | 21 | /** 22 | * Called when provider is loading, we should load files or connect to databases in this function 23 | * If something in here goes wrong the provider will be useless and plugin should stop 24 | * 25 | * You can throw exceptions here and it will be catch 26 | */ 27 | protected abstract function init() : bool; 28 | 29 | public static function playerName(Player $player) 30 | { 31 | return strtolower(trim($player->getName())); 32 | } 33 | 34 | public function isValid() : bool 35 | { 36 | return $this->valid === true; 37 | } 38 | 39 | /* 40 | 41 | Data related setters and getters 42 | 43 | */ 44 | 45 | public abstract function getFactionData($name) : array; 46 | 47 | public abstract function getMemberData($name) : array; 48 | 49 | public abstract function setFactionData($name, array $data, $append = true); 50 | 51 | public abstract function setMemberData($name, array $data, $append = true); 52 | 53 | public abstract function get($key); 54 | 55 | public abstract function save($key, array $data); 56 | 57 | public function close() 58 | { 59 | # Call parent function to display this message :P 60 | $this->getPlugin()->getLogger()->info("Closed {$this->getType()} data provider."); 61 | } 62 | 63 | public function getPlugin() : UltraFactions 64 | { 65 | return $this->plugin; 66 | } 67 | 68 | public function getType() : string 69 | { 70 | return $this->type; 71 | } 72 | 73 | } -------------------------------------------------------------------------------- /src/ultrafactions/handler/PlayerEventListener.php: -------------------------------------------------------------------------------- 1 | plugin = $plugin; 21 | 22 | if ($cf = $plugin->getConfig()->get('chat-format')) { 23 | $this->chatFormat = $cf; 24 | } 25 | } 26 | 27 | /** 28 | * @param PlayerPreLoginEvent $e 29 | * @ignoreCancelled false 30 | * @priority HIGHEST 31 | */ 32 | public function onPlayerPreLogin(PlayerPreLoginEvent $e) 33 | { 34 | $p = $e->getPlayer(); 35 | 36 | 37 | # Create Member class if player is in any faction 38 | if ($this->getPlugin()->getMemberManager()->isMember($p)) { 39 | echo "Player is member"; 40 | $this->getPlugin()->getMemberManager()->registerPlayer($p); 41 | } else { 42 | echo "Player is not a member"; 43 | } 44 | } 45 | 46 | public function getPlugin() : UltraFactions 47 | { 48 | return $this->plugin; 49 | } 50 | 51 | /** 52 | * @param PlayerChatEvent $e 53 | * @ignoreCancelled false 54 | * @priority HIGHEST 55 | */ 56 | public function onPlayerChat(PlayerChatEvent $e) 57 | { 58 | $p = $e->getPlayer(); 59 | if ($this->getPlugin()->isInFaction($p)) { 60 | $m = $this->plugin->getMember($p); 61 | $f = $m->getFaction(); // Well this should return Faction 62 | $cf = $this->chatFormat; 63 | /** @var Member $m */ 64 | $cf = str_replace(["{PLAYER}", "{FACTION}", "{RANK}", "{MESSAGE}"], [$p->getDisplayName(), $f->getName(), $m->getRank(), $e->getMessage()], $cf); 65 | $e->setFormat($cf); 66 | } 67 | } 68 | 69 | /** 70 | * Handle damage events and cancel them in certain conditions, like players are on same faction or their factions are allies 71 | * 72 | * @param EntityDamageEvent $e 73 | * @ignoreCancelled true 74 | * @priority MONITOR 75 | */ 76 | public function onDamage(EntityDamageEvent $e) 77 | { 78 | # TODO 79 | } 80 | } -------------------------------------------------------------------------------- /src/ultrafactions/data/DefaultDataProvider.php: -------------------------------------------------------------------------------- 1 | getDataFolder() . "/factions"; # Check if the slash is necessary 17 | self::$memberFolder = $plugin->getDataFolder() . "/members"; 18 | parent::__construct($plugin); 19 | $this->type = "YAML (Default)"; 20 | } 21 | 22 | public function getFactionData($name) : array 23 | { 24 | return (new Config(self::factionFile($name), Config::YAML))->getAll(); 25 | } 26 | 27 | public static function factionFile($name) 28 | { 29 | return self::$factionFolder . "/" . strtolower(trim($name)) . ".yml"; 30 | } 31 | 32 | public function getMemberData($name) : array 33 | { 34 | return (new Config(self::memberFile($name), Config::YAML))->getAll(); 35 | } 36 | 37 | public static function memberFile($name) 38 | { 39 | return self::$memberFolder . "/" . strtolower(trim($name)) . ".yml"; 40 | } 41 | 42 | public function setFactionData($name, array $data, $append = true) 43 | { 44 | if (!$append) @unlink(self::factionFile($name)); 45 | new Config(self::factionFile($name), Config::YAML, $data); 46 | } 47 | 48 | public function setMemberData($name, array $data, $append = true) 49 | { 50 | if (!$append) @unlink(self::memberFile($name)); 51 | return new Config(self::memberFile($name), Config::YAML, $data); 52 | } 53 | 54 | public function deleteFactionFile($name){ 55 | @unlink(self::factionFile($name)); 56 | } 57 | 58 | public function deleteMemberFile($name){ 59 | @unlink(self::memberFile($name)); 60 | } 61 | 62 | public function get($key) 63 | { 64 | switch ($key) { 65 | case 'plots': 66 | return $this->plots; 67 | break; 68 | default: 69 | break; 70 | } 71 | return null; 72 | } 73 | 74 | public function save($key, array $data) 75 | { 76 | switch ($key) { 77 | case 'plots': 78 | new Config($this->getPlugin()->getDataFolder() . "plots.yml", Config::YAML, $data); 79 | break; 80 | default: 81 | break; 82 | } 83 | } 84 | 85 | public function close() 86 | { 87 | # There is nothing to do here 88 | parent::close(); 89 | } 90 | 91 | protected function init() : bool 92 | { 93 | # Init function for YAML data provider 94 | # This class will use two more files: factions.yml and members.yml 95 | @mkdir(self::$factionFolder); 96 | @mkdir(self::$memberFolder); 97 | 98 | $this->plots = (new Config($this->getPlugin()->getDataFolder() . "plots.yml", Config::YAML))->getAll(); 99 | 100 | return true; 101 | } 102 | 103 | } -------------------------------------------------------------------------------- /src/ultrafactions/manager/MemberManager.php: -------------------------------------------------------------------------------- 1 | init(); 25 | } 26 | 27 | public function init() : bool 28 | { 29 | return parent::init(); 30 | } 31 | 32 | public function getMember(Player $player, $register = false) 33 | { 34 | if(isset($this->members[strtolower($player->getName())])){ 35 | return $this->members[strtolower($player->getName())]; 36 | } else { 37 | if ($register) { 38 | return $this->registerPlayer($player); 39 | } 40 | } 41 | return null; 42 | } 43 | 44 | /** 45 | * Before players can use UltraFaction features they have to be registered 46 | * 47 | * @param Player $player 48 | * @return Member 49 | */ 50 | public function registerPlayer(Player $player) : Member 51 | { 52 | $memberD = $this->getPlugin()->getDataProvider()->getMemberData(DataProvider::playerName($player)); 53 | $power = isset($memberD['power']) ? $memberD['power'] : 0; 54 | $faction = null; 55 | if(isset($memberD['faction'])) { 56 | try { 57 | $faction = $this->getPlugin()->getFactionManager()->getFactionByName($memberD['faction']); 58 | if (!$faction INSTANCEOF Faction) { 59 | $faction = null; 60 | throw new \Exception("Member is in invalid faction"); 61 | } 62 | } catch (\Exception $e) { 63 | $this->getPlugin()->getLogger()->warning("Following error occurred while registering player: " . $e->getMessage()); 64 | } 65 | } 66 | $m = new Member($player, $faction, $power); 67 | $this->members[strtolower($player->getName())] = $m; 68 | return $m; 69 | } 70 | 71 | public function isMember($player) : bool 72 | { 73 | $name = $player instanceof Player ? $player->getName() : $player; 74 | foreach ($this->getPlugin()->getFactionManager()->getAll() as $faction) { 75 | if ($faction->isMember($name)) return true; 76 | } 77 | return false; 78 | } 79 | 80 | public function getMembers() : array { 81 | return $this->members; 82 | } 83 | 84 | public function close() 85 | { 86 | $this->save(); 87 | $this->getPlugin()->getLogger()->debug("Closed MemberManager."); 88 | } 89 | 90 | public function save(){ 91 | foreach($this->members as $member){ 92 | $member->save(); 93 | $this->getPlugin()->getLogger()->debug("Saved member's '{$member->getName()}' data"); 94 | } 95 | $this->getPlugin()->getLogger()->info("Saved members data."); 96 | } 97 | 98 | /** 99 | * @return Member[] 100 | */ 101 | public function getAll() : array 102 | { 103 | return $this->members; 104 | } 105 | } -------------------------------------------------------------------------------- /src/ultrafactions/economy/Economy.php: -------------------------------------------------------------------------------- 1 | owner = $plugin; 16 | $economy = ["EconomyAPI", "PocketMoney", "MassiveEconomy", "GoldStd"]; 17 | $ec = []; 18 | foreach($economy as $e){ 19 | $ins = $plugin->getServer()->getPluginManager()->getPlugin($e); 20 | if($ins instanceof Plugin && $ins->isEnabled()){ 21 | $ec[$ins->getName()] = $ins; 22 | } 23 | } 24 | if (isset($ec[$preferred])) { 25 | $this->economy = $ec[$preferred]; 26 | } else { 27 | if(!empty($ec)){ 28 | $this->economy = $ec[array_rand($e)]; 29 | } 30 | } 31 | if($this->isLoaded()){ 32 | $this->owner->getLogger()->info("Economy plugin: ".TextFormat::GOLD."".$this->getName()); 33 | } 34 | } 35 | 36 | public function isLoaded() : bool 37 | { 38 | return $this->economy instanceof Plugin; 39 | } 40 | 41 | public function getName() : String 42 | { 43 | return $this->economy->getDescription()->getName(); 44 | } 45 | 46 | public function takeMoney(Player $player, $amount, $force = false) 47 | { 48 | if($this->getName() === 'EconomyAPI'){ 49 | return $this->economy->reduceMoney($player, $amount, $force); 50 | } 51 | if($this->getName() === 'PocketMoney'){ 52 | return $this->economy->grantMoney($player, $amount, $force); 53 | } 54 | if($this->getName() === 'GoldStd'){ 55 | return $this->economy->grantMoney($player, $amount, $force); // CHECK 56 | } 57 | if($this->getName() === 'MassiveEconomy'){ 58 | return $this->economy->takeMoney($player, $amount, $force); 59 | } 60 | return false; 61 | } 62 | 63 | public function getMoney(Player $player) : int 64 | { 65 | if($this->getName() === 'EconomyAPI'){ 66 | return $this->economy->myMoney($player); 67 | } 68 | if($this->getName() === 'PocketMoney'){ 69 | return $this->economy->getMoney($player->getName()); 70 | } 71 | if($this->getName() === 'GoldStd'){ 72 | return $this->economy->getMoney($player); // Check 73 | } 74 | if($this->getName() === 'MassiveEconomy'){ 75 | if ($this->economy->isPlayerRegistered($player->getName())) { 76 | return $this->economy->getMoney($player->getName()); 77 | } 78 | } 79 | return 0; 80 | } 81 | 82 | public function formatMoney($amount) : string 83 | { 84 | if($this->getName() === 'EconomyAPI'){ 85 | return $this->getMonetaryUnit() . $amount; 86 | } 87 | if($this->getName() === 'PocketMoney'){ 88 | return $amount . ' ' . $this->getMonetaryUnit(); 89 | } 90 | if($this->getName() === 'GoldStd'){ 91 | return $amount . $this->getMonetaryUnit(); 92 | } 93 | if($this->getName() === 'MassiveEconomy'){ 94 | return $this->getMonetaryUnit() . $amount; 95 | } 96 | return $amount; 97 | } 98 | 99 | public function getMonetaryUnit() : string 100 | { 101 | if($this->getName() === 'EconomyAPI'){ 102 | return $this->economy->getMonetaryUnit(); 103 | } 104 | if($this->getName() === 'PocketMoney'){ 105 | return 'PM'; 106 | } 107 | if($this->getName() === 'GoldStd'){ 108 | return 'G'; 109 | } 110 | if($this->getName() === 'MassiveEconomy'){ 111 | return $this->economy->getMoneySymbol() != null ? $this->economy->getMoneySymbol() : '$'; 112 | } 113 | return ""; 114 | } 115 | 116 | public function getApi() : Plugin 117 | { 118 | return $this->economy; 119 | } 120 | } -------------------------------------------------------------------------------- /src/ultrafactions/Member.php: -------------------------------------------------------------------------------- 1 | 0, 27 | "faction" => null, 28 | "rank" => Member::RANK_MEMBER 29 | ]; 30 | 31 | protected $stats = []; 32 | protected $rank = Member::RANK_MEMBER; 33 | 34 | protected $faction; 35 | protected $player; 36 | 37 | public function __construct(Player $player, $faction, $power = 0) 38 | { 39 | $this->player = $player; 40 | 41 | if ($faction != null) { 42 | if ($faction instanceof Faction) { 43 | $this->faction = $faction; 44 | } elseif (($f = $this->getPlugin()->getFactionManager()->getFactionByName($faction)) instanceof Faction) { 45 | $this->faction = $f; 46 | } else { 47 | $this->faction = null; 48 | } 49 | } else { 50 | $this->faction = null; 51 | } 52 | $this->power = $power; 53 | 54 | } 55 | 56 | private function getPlugin() : UltraFactions 57 | { 58 | return self::$plugin; 59 | } 60 | 61 | public static function setPlugin(UltraFactions $p) 62 | { 63 | if (!self::$plugin) self::$plugin = $p; 64 | } 65 | 66 | /** 67 | * @return UltraFactions|null 68 | */ 69 | public function getFaction() 70 | { 71 | return $this->faction; 72 | } 73 | 74 | /** 75 | * @return bool|void 76 | */ 77 | public function leave() 78 | { 79 | if ($this->faction instanceof Faction) { 80 | $f = $this->faction; 81 | $this->faction = null; 82 | return $f->detachMember($this); 83 | } 84 | return false; 85 | } 86 | 87 | public function join(Faction $faction) 88 | { 89 | // TODO: Call event 90 | if ($this->faction === $faction or $this->isInFaction()) return false; 91 | $rank = $faction->attachMember($this); 92 | if ($rank === false) return false; 93 | $this->faction = $faction; 94 | $this->rank = $rank; 95 | return true; 96 | } 97 | 98 | public function isInFaction() 99 | { 100 | if ($this->faction instanceof Faction) { 101 | return true; 102 | } 103 | return false; 104 | } 105 | 106 | public function getName() 107 | { 108 | return $this->getPlayer()->getName(); 109 | } 110 | 111 | public function getPlayer() : Player 112 | { 113 | return $this->player; 114 | } 115 | 116 | public function save() 117 | { 118 | var_dump($this->getMemberData()); 119 | $this->getPlugin()->getDataProvider()->setMemberData($this->getPlayer()->getName(), $this->getMemberData(), true); 120 | } 121 | 122 | public function getMemberData() : array 123 | { 124 | $nData = []; 125 | foreach (self::$defaultData as $key => $value) { 126 | if ($key == 'faction') { 127 | $nData['faction'] = $this->faction instanceof Faction ? $this->faction->getName() : null; 128 | } 129 | if (isset($this->{$key})) $nData[$key] = $this->{$key}; 130 | } 131 | return $nData; 132 | } 133 | 134 | // Integration with plugin 135 | 136 | public function getRank() : int 137 | { 138 | return $this->rank; 139 | } 140 | 141 | public function setRank($rank) 142 | { 143 | $this->rank = $rank; 144 | } 145 | 146 | } -------------------------------------------------------------------------------- /src/ultrafactions/manager/FactionManager.php: -------------------------------------------------------------------------------- 1 | getPlugin()->getDataFolder() . "factions.yml", Config::YAML))->get('factions'); 23 | if (!empty($factions)){ 24 | $this->loadFactions($factions); 25 | $this->getPlugin()->getLogger()->info("Loaded factions."); 26 | } else { 27 | $this->getPlugin()->getLogger()->info("No factions to load."); 28 | } 29 | 30 | return parent::init(); 31 | } 32 | 33 | /** 34 | * @param array $factions 35 | * @return null|Faction 36 | */ 37 | private function loadFactions(array $factions) 38 | { 39 | foreach ($factions as $i => $name) { 40 | $faction = $this->getPlugin()->getDataProvider()->getFactionData($name); 41 | if(empty($faction)){ 42 | return; 43 | } 44 | if($this->loadFaction($name, $faction) instanceof Faction){ 45 | $this->getPlugin()->getLogger()->debug("#$i: Loaded faction '$name'"); 46 | } 47 | } 48 | } 49 | 50 | /** 51 | * @param $name 52 | * @param array $faction 53 | * @return null|Faction 54 | */ 55 | private function loadFaction($name, array $faction) 56 | { 57 | try { 58 | $b = new FactionBuilder(); 59 | $b->setName($name) 60 | ->fromArray($faction); 61 | $f = $b->build(); 62 | if ($f instanceof Faction) echo "Faction " . $f->getDisplayName() . " loaded"; 63 | } catch (\Exception $e) { 64 | $this->getPlugin()->getLogger()->warning("Following error occurred while loading faction: ".$e->getMessage()); 65 | return null; 66 | } 67 | $this->factions[strtolower($f->getName())] = $f; 68 | return $f; 69 | } 70 | 71 | /** 72 | * @param $faction 73 | * @return null|Faction 74 | */ 75 | public function getFactionByName($faction) 76 | { 77 | foreach ($this->factions as $f) { 78 | if ($f->getName() == strtolower($faction)) return $f; 79 | } 80 | return null; 81 | } 82 | 83 | /** 84 | * @param Faction $faction 85 | */ 86 | public function addFaction(Faction $faction) 87 | { 88 | $this->factions[strtolower($faction->getName())] = $faction; 89 | } 90 | 91 | /** 92 | * @param string $name 93 | * @param array $data 94 | * @return null|Faction 95 | */ 96 | public function createFaction($name, array $data) 97 | { 98 | return $this->loadFaction($name, $data); 99 | } 100 | 101 | /** 102 | * @param Faction $faction 103 | */ 104 | public function deleteFaction(Faction $faction) 105 | { 106 | } 107 | 108 | /** 109 | * @param Faction $faction 110 | */ 111 | public function saveFaction(Faction $faction) 112 | { 113 | $faction->save(); // What an useless function, isn't it? xD 114 | } 115 | 116 | public function getAll() 117 | { 118 | return $this->factions; 119 | } 120 | 121 | public function close() 122 | { 123 | $this->save(); 124 | $this->getPlugin()->getLogger()->debug("Closed FactionManager."); 125 | } 126 | 127 | /** 128 | * Saves all loaded factions into faction.yml 129 | * And each faction class 130 | */ 131 | public function save() 132 | { 133 | $factions = []; 134 | foreach ($this->factions as $name => $f) { 135 | $f->save(); 136 | $this->getPlugin()->getLogger()->debug("Saved faction's '{$f->getName()}' data."); 137 | $factions[] = $name; 138 | } 139 | @unlink($this->getPlugin()->getDataFolder() . "factions.yml"); 140 | new Config($this->getPlugin()->getDataFolder() . "factions.yml", Config::YAML, ['factions' => $factions]); 141 | $this->getPlugin()->getLogger()->info("Saved factions data."); 142 | } 143 | 144 | } -------------------------------------------------------------------------------- /src/ultrafactions/manager/PlotManager.php: -------------------------------------------------------------------------------- 1 | World -> plot (x:y) 13 | * 14 | * @var array 15 | */ 16 | protected $plots = []; 17 | protected $protectedWorlds = []; 18 | 19 | public function __construct() 20 | { 21 | } 22 | 23 | public function init() : bool 24 | { 25 | $plots = $this->getPlugin()->getDataProvider()->get('plots'); 26 | if (!empty($plots)) { 27 | # Load 28 | $this->plots = $plots; 29 | } 30 | // DEBUG 31 | $out = ['factionCount' => 0, 'worldCount' => 0, 'loadedPlotCount' => 0]; 32 | $out['factionCount'] = count($plots); 33 | foreach ($plots as $faction => $world) { 34 | $out['worldCount'] += count($faction); 35 | $out['loadedPlotCount'] += count($world); 36 | } 37 | 38 | $this->getPlugin()->getLogger()->debug("Loaded: " . $out['loadedPlotCount'] . " plots in " . $out['worldCount'] . " worlds, for " . $out['factionCount'] . " factions"); 39 | 40 | return parent::init(); 41 | } 42 | 43 | public function close() 44 | { 45 | $this->save(); 46 | $this->getPlugin()->getLogger()->debug("Closed PlotManager."); 47 | } 48 | 49 | private function save() 50 | { 51 | $this->getPlugin()->getDataProvider()->save('plots', $this->plots); 52 | $this->getPlugin()->getLogger()->debug('Saved plots'); 53 | } 54 | 55 | // Plots 56 | 57 | /** 58 | * $x and $z are real coordinates not chunk's 59 | * @param Faction $faction 60 | * @param Position $pos 61 | * @param bool $force 62 | * @return bool 63 | */ 64 | public function claimPlot(Faction $faction, Position $pos, $force = false) : bool 65 | { 66 | if ($this->getPlotOwner($pos) != null and !$force) return false; 67 | if ($this->isAreaProtected($pos) and !$force) return false; 68 | $this->plots[$faction->getName()][$pos->getLevel()->getName()][] = self::hashPlot($pos); 69 | return $this->getPlotOwner($pos) === $faction; 70 | //return true; # TODO 71 | } 72 | 73 | /** 74 | * @param Position $pos 75 | * @return null|\ultrafactions\Faction 76 | */ 77 | public function getPlotOwner(Position $pos) 78 | { 79 | $name = $pos->getLevel()->getName(); 80 | $hash = self::hashPlot($pos); 81 | foreach ($this->plots as $faction => $world) { 82 | foreach ($world as $worldName => $plots) { 83 | foreach ($plots as $plot) { 84 | if ($worldName == $name and $hash == $plot) { 85 | if ($f = $this->getPlugin()->getFactionManager()->getFactionByName($faction)) { 86 | return $f; 87 | } else { 88 | # Remove faction plots if faction is invalid? 89 | break; 90 | } 91 | } 92 | } 93 | } 94 | } 95 | return null; 96 | } 97 | 98 | public static function hashPlot(Position $pos) : string 99 | { 100 | return ($pos->x >> 4) . ":" . ($pos->z >> 4); 101 | } 102 | 103 | /** 104 | * @param Position $pos 105 | * @return bool 106 | */ 107 | public function isAreaProtected(Position $pos) : bool 108 | { 109 | if (array_key_exists($pos->getLevel()->getName(), $this->protectedWorlds)) return true; 110 | # TODO 111 | return false; 112 | } 113 | 114 | /** 115 | * @param Position $pos 116 | * @return array 117 | */ 118 | public function unclaimPlot(Position $pos) : array 119 | { 120 | if (($f = $this->getPlotOwner($pos)) == null) return false; 121 | unset($this->plots[$f->getName()][$pos->getLevel()->getName()][self::hashPlot($pos)]); 122 | return true; 123 | } 124 | 125 | /** 126 | * @param Faction $faction 127 | * @return array 128 | */ 129 | public function getPlotsByFaction(Faction $faction) : array 130 | { 131 | if (isset($this->plots[$faction->getName()])) { 132 | return $this->plots[$faction->getName()]; 133 | } 134 | return []; 135 | } 136 | 137 | 138 | } -------------------------------------------------------------------------------- /src/ultrafactions/faction/FactionBuilder.php: -------------------------------------------------------------------------------- 1 | "", 23 | "home" => null, 24 | "members" => [], 25 | "power" => 0, 26 | "created" => 0, # time() 27 | "displayName" => "" 28 | ]; 29 | 30 | /** @var string $name */ 31 | public $name = ""; 32 | /** @var string $displayName */ 33 | public $displayName = ""; 34 | /** @var int $power */ 35 | public $power; 36 | /** @var Position $home */ 37 | public $home = null; 38 | /** @var String[] $members */ 39 | public $members = []; 40 | /** @var int $created */ 41 | public $created; 42 | /** 43 | * Do not use this variable to set the leader it's for internal purposes only 44 | * 45 | * @var null|string $leader 46 | */ 47 | private $leader; 48 | 49 | /** 50 | * FactionBuilder constructor. 51 | */ 52 | public function __construct($name = null, $displayName = null, $leader = null) 53 | { 54 | $this->name = $name; 55 | $this->displayName = $displayName; 56 | $this->leader = $leader; 57 | } 58 | 59 | /** 60 | * @param UltraFactions $plugin 61 | */ 62 | public static function setPlugin(UltraFactions $plugin) 63 | { 64 | if (self::$plugin === null) self::$plugin = $plugin; 65 | } 66 | 67 | /** 68 | * @param string $name 69 | * @return FactionBuilder 70 | */ 71 | public function setName($name) 72 | { 73 | $this->name = $name; 74 | return $this; 75 | } 76 | 77 | /** 78 | * @param string $displayName 79 | * @return FactionBuilder 80 | */ 81 | public function setDisplayName($displayName) 82 | { 83 | $this->displayName = $displayName; 84 | return $this; 85 | } 86 | 87 | /** 88 | * @param int $power 89 | * @return FactionBuilder 90 | */ 91 | public function setPower($power) 92 | { 93 | $this->power = $power; 94 | return $this; 95 | } 96 | 97 | /** 98 | * @param Position $home 99 | * @return FactionBuilder 100 | */ 101 | public function setHome($home) 102 | { 103 | $this->home = $home; 104 | return $this; 105 | } 106 | 107 | /** 108 | * @param String[] $members 109 | * @return FactionBuilder 110 | */ 111 | public function setMembers($members) 112 | { 113 | $this->members = $members; 114 | return $this; 115 | } 116 | 117 | /** 118 | * @param string $player 119 | * @param int $rank 120 | * @return FactionBuilder 121 | */ 122 | public function addMember($player, $rank = Member::RANK_MEMBER) 123 | { 124 | $this->members[$player] = $rank; 125 | return $this; 126 | } 127 | 128 | public function setLeader($player) 129 | { 130 | $name = $player instanceof Player ? $player->getName() : $player; 131 | $this->leader = $name; // Yes, this should be here 132 | $this->members[strtolower($name)] = Member::RANK_LEADER; 133 | } 134 | 135 | public function fromArray(array $data) 136 | { 137 | foreach ($data as $key => $item) { 138 | $this->{$key} = $item; 139 | 140 | if ($key == 'members') { 141 | echo $key; 142 | foreach ($item as $member => $rank) { 143 | if ($rank === Member::RANK_LEADER) $this->leader = $member; 144 | } 145 | } 146 | } 147 | } 148 | 149 | /** 150 | * Returns created faction on success or null on failure 151 | * 152 | * @return Faction|null 153 | * @throws \Exception 154 | */ 155 | public function build() 156 | { 157 | if (($r = $this->isValidData()) === true) { 158 | $faction = new Faction($this->name, $this->toArray()); 159 | $this->getPlugin()->getFactionManager()->addFaction($faction); 160 | return $this->getPlugin()->getFactionManager()->getFactionByName($this->name); 161 | } else { 162 | $err = ""; 163 | if ($r === self::RET_DUPLICATE) $err = "Faction with that name already exists"; 164 | if ($r === self::RET_INVALID_LEADER) $err = "Given player can not be this faction leader"; 165 | if ($r === self::RET_NO_LEADER) $err = "Faction can not exist without a leader"; 166 | if ($r === self::RET_INVALID_NAME) $err = "Invalid name"; 167 | if ($r === self::RET_INVALID_DISPLAY_NAME) $err = "Invalid display name ({$this->displayName})"; 168 | throw new \Exception($err); 169 | } 170 | } 171 | 172 | /** 173 | * @return int 174 | */ 175 | public function isValidData() 176 | { 177 | # Check if faction with that name doesn't exist 178 | # Check if name is valid 179 | # Make sure leader is valid 180 | # ... 181 | if ($this->getPlugin()->getFactionManager()->getFactionByName($this->name) instanceof Faction) return self::RET_DUPLICATE; 182 | if (/** Check if name is valid */ 183 | !true 184 | ) return self::RET_INVALID_NAME; 185 | if ($this->displayName == "") return self::RET_INVALID_DISPLAY_NAME; 186 | 187 | // Check if leader is valid 188 | if (($leader = $this->leader) != null) { 189 | /*if(($player = $this->getPlugin()->getServer()->getPlayerExact($leader)) instanceof \pocketmine\Player){ 190 | # Player is online 191 | $member = $this->getPlugin()->getMemberManager()->getMember($player); 192 | } else { 193 | # Player is offline :/ 194 | $member = $this->getPlugin()->getMemberManager()->getOfflineMember($leader); 195 | } 196 | if($member->getFaction() instanceof Faction) return self::RET_LEADER_IN_FACTION; */ 197 | if ($this->getPlugin()->getMemberManager()->isMember($leader)) { 198 | return self::RET_INVALID_LEADER; 199 | } 200 | } else { 201 | return self::RET_INVALID_LEADER; 202 | } 203 | return true; 204 | } 205 | 206 | 207 | 208 | // Get & Set main class 209 | 210 | /** 211 | * @return UltraFactions 212 | */ 213 | public function getPlugin() 214 | { 215 | return self::$plugin; 216 | } 217 | 218 | public function toArray() : array 219 | { 220 | $d = []; 221 | foreach (self::$defaultData as $key => $item) { 222 | $d[$key] = $this->{$key}; 223 | } 224 | return $d; 225 | } 226 | } -------------------------------------------------------------------------------- /src/ultrafactions/UltraFactions.php: -------------------------------------------------------------------------------- 1 | getDataFolder()); 45 | $this->saveDefaultConfig(); 46 | 47 | Manager::setPlugin($this); 48 | Member::setPlugin($this); 49 | Faction::setPlugin($this); 50 | FactionBuilder::setPlugin($this); 51 | } 52 | 53 | /** 54 | * Normal plugin init :P 55 | */ 56 | public function onEnable() 57 | { 58 | $pm = $this->getServer()->getPluginManager(); 59 | 60 | try { 61 | $this->loadDataProvider(); 62 | if ($this->data->isValid() === false) { 63 | throw new \Exception("Failed to init data provider"); 64 | } 65 | } catch (\Exception $e) { 66 | $this->getServer()->getPluginManager()->disablePlugin($this); 67 | $this->getLogger()->critical("Following error occurred while initializing data provider: " . $e->getMessage()); 68 | return; // Don't execute any furthermore code or it may cause other errors 69 | } 70 | $this->economy = new Economy($this, $this->getConfig()->get('economy')['prefer']); 71 | if(!$this->economy->isLoaded()){ 72 | $this->getLogger()->warning("No Economy plugin loaded!"); 73 | $this->getServer()->getPluginManager()->disablePlugin($this); 74 | return; 75 | } 76 | 77 | // Load prices 78 | $prices = $this->getConfig()->get('prices'); 79 | $this->prices = $prices; 80 | $this->getLogger()->info("Prices loaded."); 81 | 82 | // Load managers 83 | $this->getLogger()->debug("Loading managers..."); 84 | $this->memberManager = new MemberManager($this); 85 | $this->memberManager->init(); 86 | $this->factionManager = new FactionManager($this); 87 | $this->factionManager->init(); 88 | $this->plotManager = new PlotManager($this); 89 | $this->plotManager->init(); 90 | $this->getLogger()->debug("Managers loaded."); 91 | 92 | // Lets register some event listeners below 93 | $pm->registerEvents(new PlayerEventListener($this), $this); 94 | $pm->registerEvents(new FactionEventListener($this), $this); 95 | 96 | // Function name sucks, It will be register only one command xP 97 | $this->registerCommands(); 98 | 99 | $this->getLogger()->info(Text::GREEN."Plugin loaded."); 100 | 101 | } 102 | 103 | private function loadDataProvider() 104 | { 105 | $providerType = $this->getConfig()->get('data'); 106 | if (!$providerType) { 107 | throw new \Exception('Can not receive \'data\' from config', 0); 108 | } 109 | if(!isset($providerType['provider'])){ 110 | throw new \Exception('Unset \'provider\' under \'data\' key'); 111 | } 112 | switch (strtolower($providerType['provider'])) { 113 | case 'yaml': # YAML is default data provider 114 | default: 115 | $this->data = new DefaultDataProvider($this); 116 | break; 117 | case 'mysql': 118 | $this->data = new MySQLDataProvider($this); 119 | break; 120 | case 'sql3': 121 | case 'sqlite3': 122 | $this->data = new SQLite3DataProvider($this); 123 | break; 124 | case 'pocketcore': 125 | case 'pc': 126 | $this->data = new PocketCoreDataProvider($this); 127 | break; 128 | } 129 | $this->getLogger()->info("Data provider: " . $this->data->getType()); 130 | return true; 131 | } 132 | 133 | private function registerCommands() 134 | { 135 | $map = $this->getServer()->getCommandMap(); 136 | $map->register("UltraFactions", new FactionCommand($this)); 137 | } 138 | 139 | public function onDisable() 140 | { 141 | # Save all factions 142 | if ($this->factionManager != null) $this->factionManager->close(); 143 | # Save members 144 | if ($this->factionManager != null) $this->memberManager->close(); 145 | # Save plots 146 | if ($this->plotManager != null) $this->plotManager->close(); 147 | # And close connections or so on data provider class 148 | if ($this->data != null) $this->data->close(); 149 | 150 | $this->getLogger()->info(Text::LIGHT_PURPLE . "Plugin disabled."); 151 | } 152 | 153 | // API Functions 154 | 155 | public function getDataProvider() : DataProvider 156 | { 157 | return $this->data; 158 | } 159 | 160 | /** 161 | * @return FactionManager 162 | */ 163 | public function getFactionManager() : FactionManager 164 | { 165 | return $this->factionManager; 166 | } 167 | 168 | /** 169 | * @return MemberManager 170 | */ 171 | public function getMemberManager() 172 | { 173 | return $this->memberManager; 174 | } 175 | 176 | /** 177 | * @return PlotManager 178 | */ 179 | public function getPlotManager() 180 | { 181 | return $this->plotManager; 182 | } 183 | 184 | /** 185 | * @return Economy 186 | */ 187 | public function getEconomy() : Economy { 188 | return $this->economy; 189 | } 190 | 191 | /** 192 | * @param string $node 193 | * @return int 194 | */ 195 | public function getPrice($node) : int { 196 | $keys = explode('.', $node); 197 | $i = 0; 198 | if(isset($this->prices[$keys[$i]])){ 199 | $prices = $this->prices[$keys[$i]]; 200 | while(is_array($prices)){ 201 | $i++; 202 | $prices = isset($prices[$keys[$i]]) ? $prices[$keys[$i]] : 0; 203 | } 204 | return $prices; 205 | } else { 206 | return 0; 207 | } 208 | } 209 | 210 | 211 | } -------------------------------------------------------------------------------- /src/ultrafactions/faction/Faction.php: -------------------------------------------------------------------------------- 1 | is got from factions.yml 14 | * displayName => is from $data 15 | */ 16 | 17 | private static $plugin; 18 | 19 | private static $defaultData = [ 20 | "name" => "", 21 | "bank" => 0, 22 | "home" => null, 23 | "allies" => [], 24 | "enemies" => [], 25 | "members" => [], 26 | "power" => 0, 27 | "plots" => [], 28 | "created" => 0, # time() 29 | "displayName" => "" 30 | ]; 31 | 32 | /** 33 | * Members are assigned to factions not factions to members 34 | */ 35 | 36 | /** @var string $name */ 37 | protected $name = ""; 38 | /** @var string $displayName */ 39 | protected $displayName = ""; 40 | /** @var int $power */ 41 | protected $power; 42 | /** @var Position $home */ 43 | protected $home = null; 44 | /** @var String[] $members */ 45 | protected $members = []; 46 | /** @var String[] $plots */ 47 | /** @var int $created */ 48 | protected $created; 49 | 50 | /** 51 | * Faction constructor. 52 | * Faction will adapt to invalid data given and use Faction::$defaultData 53 | * 54 | * @throws \Exception 55 | * @param $name 56 | * @param array $data 57 | */ 58 | public function __construct($name, array $data) 59 | { 60 | $this->name = $name; 61 | 62 | // Fill the gaps in the array 63 | $bank = isset($data['bank']) ? $data['bank'] : self::$defaultData['bank']; 64 | $home = isset($data['home']) ? $data['home'] : self::$defaultData['home']; 65 | $allies = isset($data['allies']) ? $data['allies'] : self::$defaultData['allies']; 66 | $enemies = isset($data['enemies']) ? $data['enemies'] : self::$defaultData['enemies']; 67 | $members = isset($data['members']) ? $data['members'] : self::$defaultData['members']; 68 | $power = isset($data['power']) ? $data['power'] : self::$defaultData['power']; 69 | $plots = isset($data['plots']) ? $data['plots'] : self::$defaultData['plots']; 70 | $created = isset($data['created']) ? $data['created'] : time(); 71 | $displayName = isset($data['displayName']) ? $data['displayName'] : self::$defaultData['displayName']; 72 | 73 | // Convert some data to right instances 74 | # TODO: Lazy + this isn't urgent :P 75 | 76 | $this->bank = $bank; 77 | $this->power = $power; 78 | $this->home = $home; 79 | $this->allies = $allies; 80 | $this->enemies = $enemies; 81 | $this->members = $members; 82 | $this->plots = $plots; 83 | $this->created = $created; 84 | $this->displayName = $displayName; 85 | 86 | if( $this->getDisplayName() === "" ){ # Of course I could do it above but what would be the difference? 87 | throw new \Exception("Invalid display name"); 88 | } 89 | if( $this->getLeader() === "" ){ 90 | throw new \Exception("Faction can not exist without leader"); 91 | } 92 | } 93 | 94 | public function getDisplayName() : string 95 | { 96 | return $this->displayName; 97 | } 98 | 99 | public function getLeader() : string 100 | { 101 | foreach ($this->members as $member => $rank) { 102 | if ($rank === Member::RANK_LEADER) return $member; 103 | } 104 | return ""; 105 | } 106 | 107 | public static function getDefaultData() : array 108 | { 109 | return self::$defaultData; 110 | } 111 | 112 | public static function setPlugin(UltraFactions $p) 113 | { 114 | if (!self::$plugin) self::$plugin = $p; 115 | } 116 | 117 | /** 118 | * @return int 119 | */ 120 | public function getBank() : int 121 | { 122 | return $this->bank; 123 | } 124 | 125 | public function getPower() : int 126 | { 127 | return $this->power; 128 | } 129 | 130 | /** 131 | * @return Position|null 132 | */ 133 | public function getHome() 134 | { 135 | return $this->home; 136 | } 137 | 138 | /** 139 | * @param Position $home 140 | */ 141 | public function setHome(Position $home) 142 | { 143 | $this->home = $home; 144 | } 145 | 146 | /** 147 | * @return array 148 | */ 149 | public function getAllies() : array 150 | { 151 | return $this->allies; 152 | } 153 | 154 | /** 155 | * @return array 156 | */ 157 | public function getEnemies() : array 158 | { 159 | return $this->enemies; 160 | } 161 | 162 | /** 163 | * @return array 164 | */ 165 | public function getPlots() : array 166 | { 167 | return $this->plots; 168 | } 169 | 170 | public function getCreationTime() : int 171 | { 172 | return $this->created; 173 | } 174 | 175 | /** 176 | * @return Player[] 177 | */ 178 | public function getOnlineMembers() : array 179 | { 180 | $m = []; 181 | foreach ($this->getPlugin()->getMemberManager()->getAll() as $p) { 182 | if ($p->getFaction() === $this) $m[] = $p; 183 | } 184 | return $m; 185 | } 186 | 187 | private function getPlugin() : UltraFactions 188 | { 189 | return self::$plugin; 190 | } 191 | 192 | public function sendMessage($message) 193 | { 194 | foreach ($this->getMembers() as $player) { 195 | $player->sendMessage($message); 196 | } 197 | } 198 | 199 | // Some functions :D 200 | 201 | /** 202 | * This returns all member's names 203 | * 204 | * @return String[] 205 | */ 206 | public function getMembers() : array 207 | { 208 | return $this->members; 209 | } 210 | 211 | public function sendPopup($popup) 212 | { 213 | foreach ($this->getMembers() as $player) { 214 | $player->sendPopup($popup); 215 | } 216 | } 217 | 218 | public function sendTip($tip) 219 | { 220 | foreach ($this->getMembers() as $player) { 221 | $player->sendTip($tip); 222 | } 223 | } 224 | 225 | public function update() 226 | { 227 | # TODO 228 | } 229 | 230 | public function save() 231 | { 232 | $this->getPlugin()->getDataProvider()->setFactionData($this->getName(), $this->getFactionData(), true); 233 | } 234 | 235 | /** 236 | * @return string 237 | */ 238 | public function getName() : string 239 | { 240 | return $this->name; 241 | } 242 | 243 | public function getFactionData() : array 244 | { 245 | $d = []; 246 | foreach (self::$defaultData as $key => $value) { 247 | $d[$key] = $this->{$key}; 248 | } 249 | return $d; 250 | } 251 | 252 | public function attachMember(Member $player, $rank = Member::RANK_MEMBER) 253 | { 254 | $this->members[strtolower($player->getName())] = $rank; 255 | return $rank; 256 | } 257 | 258 | public function detachMember(Member $player) : bool 259 | { 260 | unset($this->members[strtolower($player->getName())]); 261 | return true; 262 | } 263 | 264 | public function setMemberRank(Member $member, $rank) : bool 265 | { 266 | if ($this->isMember($member->getPlayer()->getName())) { 267 | $this->members[strtolower($member->getPlayer()->getName())] = $rank; 268 | return true; 269 | } 270 | return false; 271 | } 272 | 273 | // Integration with plugin 274 | 275 | /** 276 | * @param $name 277 | * @return bool 278 | */ 279 | public function isMember($name) : bool 280 | { 281 | var_dump($this->members); 282 | if (array_key_exists(strtolower($name), $this->members)) { 283 | echo "Player is member of " . $this->getDisplayName() . " faction"; 284 | return true; 285 | } else { 286 | echo "Player isn't member of " . $this->getDisplayName() . " faction"; 287 | return false; 288 | } 289 | } 290 | 291 | public function newLeader(Member $member) 292 | { 293 | # TODO 294 | } 295 | 296 | } -------------------------------------------------------------------------------- /src/ultrafactions/command/FactionCommand.php: -------------------------------------------------------------------------------- 1 | plugin = $plugin; 30 | 31 | parent::__construct("faction"); 32 | $this->setAliases(['fac', 'f']); 33 | $this->setDescription("UltraFactions main command"); 34 | $this->setPermission("uf.command.*"); 35 | } 36 | 37 | /** 38 | * @param CommandSender $sender 39 | * @param string $commandLabel 40 | * @param string[] $args 41 | * 42 | * @return mixed 43 | */ 44 | public function execute(CommandSender $sender, $commandLabel, array $args) 45 | { 46 | if (!$this->testPermission($sender)) { 47 | return true; 48 | } 49 | 50 | if (isset($args[0])) { 51 | switch (strtolower($args[0])) { 52 | 53 | case 'create': 54 | if(!$sender instanceof Player){ 55 | $sender->sendMessage("Please run this command in-game"); 56 | return true; 57 | } 58 | $member = $this->getPlugin()->getMemberManager()->getMember($sender, true); 59 | if ($member->getFaction() != null) { 60 | $member->getPlayer()->sendMessage("You are already in faction!"); # BadBoy 61 | return true; 62 | } 63 | if(isset($args[1])){ 64 | if ($this->getPlugin()->getFactionManager()->getFactionByName($args[1]) instanceof Faction) { 65 | $sender->sendMessage("Faction already exists"); 66 | return true; 67 | } 68 | # Check if player has enough money 69 | $price = $this->getPlugin()->getPrice('faction.create'); 70 | $money = $this->getPlugin()->getEconomy()->getMoney($sender); 71 | if($price != 0){ 72 | if($price > $money){ 73 | $sender->sendMessage("You don't have enough money"); 74 | return true; 75 | } 76 | } 77 | # Filter name 78 | if(!ctype_alnum($args[1])){ 79 | $sender->sendMessage("Only numbers and letters allowed"); 80 | return true; 81 | } 82 | if(strlen($args[1]) > 8){ 83 | $sender->sendMessage("Name is too long"); 84 | return true; 85 | } elseif (strlen($args[1]) < 3){ 86 | $sender->sendMessage("Name is too short"); 87 | return true; 88 | } 89 | /* 90 | if($this->getPlugin()->isNameBanned($args[1])){ 91 | # TODO 92 | } 93 | */ 94 | 95 | # Create faction 96 | $data = [ 97 | 'displayName' => $args[1], 98 | 'members' => [$sender->getName() => Member::RANK_LEADER], 99 | ]; 100 | if (($f = $this->getPlugin()->getFactionManager()->createFaction($args[1], $data)) instanceof Faction) { 101 | $member->join($f); 102 | $sender->sendMessage("Faction created"); 103 | } else { 104 | $sender->sendMessage("Failed to create faction"); 105 | } 106 | 107 | } else { 108 | $this->sendUsage($sender, 'create'); 109 | } 110 | break; 111 | 112 | case 'info': 113 | # TODO 114 | if ( isset($args[1]) ){ 115 | $faction = $this->getPlugin()->getFactionManager()->getFactionByName($args[1]); 116 | if($faction instanceof Faction){ 117 | $sender->sendMessage("--- Showing Faction's {$faction->getName()} info ---"); 118 | $sender->sendMessage("Name: ".$faction->getName()); 119 | $sender->sendMessage("Created: ".date("d.m.Y H:i:s", $faction->getCreationTime())); 120 | $sender->sendMessage("Members: ".count($faction->getMembers())); 121 | $sender->sendMessage("Leader: ".$faction->getLeader()); 122 | $sender->sendMessage("Bank: ".($sender->hasPermission("uf.command.info.bank") ? $faction->getBank() : "SECRET")); 123 | $sender->sendMessage("Home: ".($sender->hasPermission("uf.command.info.home") ? $faction->getHome() : "SECRET")); 124 | $sender->sendMessage("Plots: " . count($this->getPlugin()->getPlotManager()->getPlotsByFaction($faction))); 125 | } else { 126 | $sender->sendMessage("Faction not found"); 127 | } 128 | } else { 129 | $sender->sendMessage("Usage: /faction info "); 130 | } 131 | break; 132 | 133 | case 'claim': 134 | # TODO 135 | break; 136 | 137 | case 'invite': 138 | # TODO 139 | break; 140 | 141 | case 'accept': 142 | # Accept invitation 143 | # TODO 144 | break; 145 | case 'decline': 146 | # Decline invitation 147 | # TODO 148 | break; 149 | 150 | case 'kick': 151 | # TODO 152 | break; 153 | 154 | case 'leave': 155 | case 'quit': 156 | case 'exit': 157 | # TODO 158 | break; 159 | 160 | case 'motd': 161 | # TODO: To be honest Idk what this does but I saw this on FactionsPro xD 162 | break; 163 | 164 | case 'promote': 165 | # TODO 166 | break; 167 | 168 | case 'demote': 169 | # TODO 170 | break; 171 | 172 | case 'bank': 173 | # TODO 174 | if($sender instanceof Player === false){ 175 | $sender->sendMessage("Please run this command in-game"); 176 | return true; 177 | } 178 | # TODO: Check if player is leader or co-leader 179 | if (isset($args[1])) { 180 | switch (strtolower($args[1])) { 181 | 182 | case 'withdraw': 183 | # TODO 184 | break; 185 | 186 | case 'balance': 187 | 188 | # TODO 189 | break; 190 | 191 | default: 192 | # Unknown operation 193 | # Send usage message 194 | break; 195 | } 196 | } else { 197 | # Send usage of sub-command 'bank' 198 | } 199 | break; 200 | 201 | case 'help': 202 | $pages = [ 203 | 1 => [ 204 | # Page 1 205 | "create" => "Create new faction", 206 | "info" => "See Faction's information", 207 | "claim" => "Add this land to your faction", 208 | "invite" => "Invite new member to your faction", 209 | "accept" => "Accept invitation", 210 | "decline" => "Decline invitation", 211 | "kick" => "Kick member from your faction" 212 | ], 213 | 2 => [ 214 | "leave" => "Leave the clan you're in", 215 | "motd" => "Set faction's motd", 216 | "promote" => "Promote factions member", 217 | "demote" => "Demote factions member", 218 | "bank" => "Use your faction's money", 219 | "help" => "Displays this help page" 220 | # Page 2 221 | ] 222 | ]; 223 | $page = isset($args[1]) ? $args[1] : 1; 224 | if(isset($pages[$page])){ 225 | $sender->sendMessage("--- Showing help page $page of ".count($pages)." (/f help ) ---"); 226 | foreach($pages[$page] as $cmd => $desc){ 227 | $sender->sendMessage(" ".($sender->hasPermission("uf.command.".$cmd) ? Text::GREEN : Text::RED )."/".$cmd.": ".Text::RESET.$desc); 228 | } 229 | } 230 | # TODO 231 | break; 232 | 233 | default: 234 | $sender->sendMessage("Unknown sub-command. Use '/factions help' for help."); 235 | } 236 | } else { 237 | $sender->sendMessage("Undefined sub-command. Use '/factions help' for help"); 238 | } 239 | return false; # Invalid usage 240 | 241 | } 242 | 243 | /** 244 | * @return UltraFactions 245 | */ 246 | public function getPlugin() : UltraFactions 247 | { 248 | return $this->plugin; 249 | } 250 | 251 | private function sendUsage($sender, $string) 252 | { 253 | # TODO 254 | } 255 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 158 | 160 | 161 | 186 | 187 | 188 | 189 | 190 | true 191 | DEFINITION_ORDER 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | Blade files 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 256 | 257 | 258 | 259 | 262 | 263 | 266 | 267 | 268 | 269 | 272 | 273 | 276 | 277 | 280 | 281 | 284 | 285 | 286 | 287 | 290 | 291 | 294 | 295 | 298 | 299 | 302 | 303 | 306 | 307 | 308 | 309 | 312 | 313 | 316 | 317 | 320 | 321 | 324 | 325 | 328 | 329 | 330 | 331 | 334 | 335 | 338 | 339 | 342 | 343 | 346 | 347 | 350 | 351 | 352 | 353 | 356 | 357 | 360 | 361 | 364 | 365 | 368 | 369 | 372 | 373 | 374 | 375 | 378 | 379 | 382 | 383 | 386 | 387 | 390 | 391 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | project 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 1461321736119 454 | 471 | 472 | 1461331065264 473 | 478 | 479 | 1461507844776 480 | 485 | 486 | 1461509600363 487 | 492 | 493 | 1461512151445 494 | 499 | 500 | 1461512203755 501 | 506 | 507 | 1461681298136 508 | 513 | 514 | 1463338962853 515 | 520 | 521 | 1463405283261 522 | 527 | 528 | 1463405428439 529 | 534 | 535 | 1463409484805 536 | 541 | 544 | 545 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 603 | 604 | 607 | 610 | 611 | 612 | 614 | 615 | 629 | 630 | 631 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 996 | 997 | 998 | 999 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | 1053 | 1054 | 1055 | 1056 | 1057 | 1058 | 1059 | 1064 | 1065 | 1066 | 1067 | 1068 | 1069 | --------------------------------------------------------------------------------