├── .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 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
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 |