Skip to content

Instantly share code, notes, and snippets.

@PEMapModder
Last active February 8, 2016 13:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PEMapModder/c2f5aec0c9a8a4d5dc24 to your computer and use it in GitHub Desktop.
Save PEMapModder/c2f5aec0c9a8a4d5dc24 to your computer and use it in GitHub Desktop.

The LegionPE Hub Plugin

Copyright (C) 2014 PEMapModder (a.k.a. mcpesrccode and MCPE_modder_for_maps)

You may not distribute or use this software or its modifications without prior permission from PEMapModder or MCPE_modder_for_maps from http://formus.pocketmine.net or http://minecraftforum.net or https://github.com.

===

The main plugin (Hub.php) contains the following features:

  • Auth
  • Teams choosing
  • Worlds Manager
  • Some hardcoded coordinates in LegionPE server

The file Disguise_and_Vanish.php contains the following features:

  • A public API for making players vanished
  • A public API for disguised players

The file PvP_Minigame.php contains the following features:

  • Hardcoded coordinates for joining the PvP world from Hub
  • Player kills counting
  • Auto-equipment
  • Teleportations through portals and sign portals

===

If you want to contribute code here, please contact MCPE_modder_for_maps at http://minecraftforum.net.

<?php
/*
__PocketMine Plugin__
class=none
name=Disguise&Vanish
author=PEMapModder
version=alpha 0
apiversion=12
*/
require_once(FILE_PATH."plugins/Hub.php");
class DgVnApi{
// API functions //
public function checkStatus(Player $player){
$status=@$this->status[$this->getPlyrKey($player)];
if($status===false)
$status="!isset";
return $status;
}
public function setStatus(Player $player, $newStatus){
$current=$this->checkStatus($player);
if($current[0]===$newStatus[0] or ($current[0]!==self::STS_SELF and $newStatus[0]!==self::STS_SELF))
return false;
$key=$this->getPlyrKey($player);
if($current==="!isset"){
$this->status[$key]=$newStatus;
return true;
}
if($newStatus[0]!==self::STS_SELF){
$pkr=new RemoveEntityPacket; // remove self
$pkr->eid=$player->eid;
foreach($this->api->player->getAll($player->entity->level) as $other){
if($other->username!==$player->username)
$other->dataPacket($pkr);
}
}
$ent=$player->ent;
switch($current[0]){ // clear entity
case self::STS_SELF:
case STS_ELSE_PLYR:
case self::STS_MOB:
case self::STS_ITEM:
case self::STS_BLOCK:
case self::STS_ENT:
$pkr=new RemoveEntityPacket;
$pkr->eid=$player->eid;
foreach($this->api->player->getAll($player->entity->level) as $other){
if($other->username!==$player->username)
$other->dataPacket($pkr); // remove old entity
}
break;
case self::STS_VANISH:
break;
}
switch($newStatus[0]){ // regenerate entity
case self::STS_SELF: // spawn self
$pka=new AddPlayerPacket; // regenerate entity
$pka->clientID=0;
$pka->username=$player->username;
$pka->eid=$player->eid; // *
$pka->x=$ent->x;
$pka->y=$ent->y;
$pka->z=$ent->z;
$pka->yaw=$ent->yaw;
$pka->pitch=$ent->pitch;
$pka->unknown1=0;
$pka->unknown2=0;
$pka->metadata=$ent->getMetadata();
foreach($this->api->player->getAll($player->entity->level) as $other){
if($other->username!==$player->username)
$other->dataPacket($pka); // regenerate new entity
}
break;
case STS_ELSE_PLYR: // send new player
$name=$newStatus[1]["new-name"];
$pka=new AddPlayerPacket;
$pka->clientID=0;
$pka->username=$name;
$pka->eid=$player->eid;
$pka->x=$ent->x;
$pka->y=$ent->y;
$pka->z=$ent->z;
$pka->yaw=$ent->yaw;
$pka->pitch=$ent->pitch;
$pka->unknown1=0;
$pka->unknown2=0;
$pka->metadata=$ent->getMetadata();
foreach($this->api->player->getAll($player->entity->level) as $other){
if($other->username!==$player->username)
$other->dataPacket($pka);
}
break;
case STS_MOB: // send spawn mob
$type=$newStatus[1]["ent-type"];
$pka=new AddMobPacket;
$pka->eid=$player->eid;
$pka->type=$type;
$pka->x=$ent->x;
$pka->y=$ent->y;
$pka->z=$ent->z;
$pka->pitch=$ent->pitch;
$pka->yaw=$ent->yaw;
$pka->metadata=$ent->getMetadata();
foreach($this->api->player->getAll($player->entity->level) as $other){
if($other->username!==$player->username)
$other->dataPacket($pka);
}
$pkm=new SetEntityMotionPacket;
$pkm->eid=$player->eid;
$pkm->speedX=$ent->speedX;
$pkm->speedY=$ent->speedY;
$pkm->speedZ=$ent->speedZ;
foreach($this->api->player->getAll($player->entity->level) as $other){
if($other->username!==$player->username)
$other->dataPacket($pkm);
}
break;
case STS_ITEM: // send spawn dropped item (unpickable)
$pka=new AddItemEntityPacket;
$pka->eid=$player->eid;
$pka->item=$newStatus[1]["item"];
$pka->x=$ent->x;
$pka->y=$ent->y;
$pka->z=$ent->z;
$pka->yaw=$ent->yaw;
$pka->pitch=$ent->pitch;
$pka->roll=0;
$pka->metadata=$ent->getMetadata();
$pkm=new SetEntityMotionPacket;
$pkm->eid=$player->eid;
$pkm->speedX=$ent->speedX;
$pkm->speedY=$ent->speedY;
$pkm->speedZ=$ent->speedZ;
foreach($this->api->player->getAll($ent->level) as $other){
if($other->username!==$player->username){
$other->dataPacket($pka);
$other->dataPacket($pkm);
}
}
break;
case STS_BLOCK: // send spawn (namely falling) block
break;
case STS_ENT: // send spawn misc entity
$pka=new AddEntityPacket;
$pka->eid=$player->eid;
$pka->x=$ent->x;
$pka->y=$ent->y;
$pka->z=$ent->z;
$pka->did=0;
$pkm=new SetEntityMotionPacket;
$pkm->eid=$player->eid;
$pkm->speedX=$ent->speedX;
$pkm->speedY=$ent->speedY;
$pkm->speedZ=$ent->speedZ;
switch($newStatus[1]["ent-type"]){
case OBJECT_PAINTING:
return false; // don't add this. This crashes all clients in the world. (Mojang Bug MCPE-6790, PocketMine-MP GitHub repo issue #1335, #1156, #1098 and #375
case OBJECT_PRIMEDTNT:
$pka->type=OBJECT_PRIMEDTNT;
break;
case OBJECT_ARROW:
$pka->type=OBJECT_ARROW;
break;
}
foreach($this->api->player->getAll($ent->level) as $other){
if($other->username!==$player->username){
$other->dataPacket($pka);
$other->dataPacket($pkm);
}
}
break;
case STS_VANISH: // nothing sent
break;
}
$this->status[$key]=$newStatus;
return true;
}
// Event handlers //
public function sentPacket($evt){
$pk=$evt->getPacket();
// TODO ?
}
public function evt($data, $evt){ // event redirector
// Utils functions //
switch($evt){
case "player.spawn":
$this->setStatus($data, array(self::STS_SELF));
}
}
public function getPlyrKey(Player $player){
return $player->iusername;
}
public function addHandlers(){
$this->addHdlr("player.spawn", "player.quit");
DataPacketSendEvent::register(array($this, "sentPacket"), EventPriority::HIGHEST);
}
protected function addHdlr($evt, $priority=5){
if(is_array($evt)){
foreach($evt as $subevt)
$this->addHdlr($evt, $priority);
return;
}
$this->api->addHandler($evt, array($this, "evt"), $priority);
}
// Vars and Constants //
private $status=array();
const STS_SELF=0,STS_ELSE_PLYR=ENTITY_PLAYER,STS_MOB=ENTITY_MOB,STS_ITEM=ENTITY_ITEM,STS_BLOCK=ENTITY_FALLING,STS_ENT=ENTITY_OBJECT, STS_VANISH=-1; // $status[$key]=>array($const, array())
// magic functions //
public function __construct($server, Hub $hub){
$this->server=$server;
$this->api=$server->api;
$this->hub=$hub;
$this->addHandlers();
}
# reserved empty line
}
class DAVP implements Plugin{
public $apiRequest=false;
public function __construct(ServerAPI $api, $server=false){
self::$apiRequest=new DgVnApi(ServerAPI::request(), Hub::request());
}
public function init(){
self::request()->init();
}
public function __destruct(){
$cd=array(self::request(), "__destruct");
if(is_callable($cd))
call_user_func($cd);
}
public static function request(){
return self::$apiRequest;
}
}
<?php
/*
__PocketMine Plugin__
class=Hub
name=Hub
description=Hub plugin (gamma edition) for LegionPE
version=Gamma 1.1
apiversion=12,13
author=PEMapModder
*/
class Hub implements Plugin{
private static $instance = false;
public static function request(){
return self::$instance;
}
public $players=array();
public $ranks, $teams, $signs;
public function __construct(ServerAPI $a, $s=false){
$path=FILE_PATH."hub players/";
@mkdir($path);
$path=FILE_PATH."security/";
@mkdir($path);
$path.="logs/";
@mkdir($path);
self::$instance=$this;
$this->a=$a;
$this->p=$a->player;
$this->l=$a->level;
$this->t=$a->tile;
$this->c=$a->console;
$this->s=ServerAPI::request();
$this->ranks=new RankMgr($this);
$this->teams=new TeamMgr();
// $this->signs=new SignMgr();
}
public function __destruct(){
}
public function init(){
$this->s->addHandler("player.spawn", array($this, "onSpawn"), 51);
$this->s->addHandler("player.quit", array($this, "onQuit"));
}
public function onSpawn(Player $player){
if($player->username == "Steve"){
$player->sendChat("The default username, \"Steve\", is rejected in this server.\n----------------\nPlease change your username to another name.\n----------------\nYou are going to be kicked in ten seconds.");
$this->s->schedule(200, array($player, "close"), "Default username usage");
}
$this->players[strtolower(trim($player->username))]=new HubPlayer($player);
}
public function onQuit(Player $player){
$path="\$this->players[strtolower(trim(\$player->username))]";
eval("if(isset($path)){"."$path=false; unset($path);}");
}
public function getPlayer($player){
$path="\$this->players[strtolower(trim(\"\$player\"))]";
eval("return (isset($path)?$path:false);");
}
}
class HubPlayer{
const REGISTER_ONE=31;
const REGISTER_TWO=32;
const TO_LOGIN=21;
const OFFLINE=21;
const UNBLOCKED=11; // playing
public $blockTouchStatus="auth";
public $entityAttackStatus="auth";
public $chatStatus="auth";
public $p;
public $cfg;
public $session;
private $loginTrials=0;
public function __construct(Player $player){
$this->p=$player;
$this->addHandlers();
$r=HubConfig::fromPlayer($player);
$this->cfg=$r[0];
$line_seperator="-----------------------";
if($r[1] and $r[0]->get("passwordhash")!=="THIS PASSWORD IS NOT SET"){ // login
$player->sendChat("Welcome back to LegionPE - Ultimate PvP!");
$player->sendChat($line_seperator);
$player->sendChat("[Login wizard] Please login by typing your password directly into chat. You have 5 chances to type your password. You will be kicked if you fail in all five attempts to login.");
$this->loginTrials=5;
$this->session=self::TO_LOGIN;
}
else{ // register
$player->sendChat($line_seperator);
$player->sendChat("Welcome to LegionPE - Ultimate PvP!");
$player->sendChat($line_seperator);
$player->sendChat("Please follow the registering wizard to register your account, in order to protect your account.");
$player->sendChat($line_seperator);
$player->sendChat("[Register wizard] Please type in your password. It has to have a minimal length of 4 characters.");
$player->sendChat($line_seperator);
$this->session=self::REGISTER_ONE;
}
}
public function addHandlers(){
$s=ServerAPI::request();
$s->addHandler("player.chat", array($this, "onChat"), PHP_INT_MAX);
$s->addHandler("player.quit", array($this, "onQuit"), PHP_INT_MAX);
$s->addHandler("player.chat", array($this, "onChatLP"), 3);
$s->addHandler("console.command", array($this, "onCmd"), PHP_INT_MAX);
$s->addHandler("player.interact", array($this, "onHit"), 0x1000);
$s->addHandler("entity.health.change", array($this, "onHurt"), 0x1000);
$s->addHandler("player.teleport", array($this, "onTeleported"), 0x1000);
$s->addHandler("player.block.touch", array($this, "blockTouch"), 0x1000);
$s->addHandler("player.move", array($this, "onMove"), 0x1000);
}
//event handlers
public function onMove($data){
if($data->player->username!=$this->p->username){
return;
}
if($this->session!==self::UNBLOCKED){
$data->fallY=false;
$data->fallStart=false;
$pk=new MovePlayerPacket;
$pk->eid=0;
$pk->x=$data->x;
$pk->y=$data->y;
$pk->z=$data->z;
$pk->yaw=0;
$pk->pitch=0;
$pk->bodyYaw=0;
$this->p->dataPacket($pk);
return false;
}
}
public function onChat($msg){
if($msg["player"]->username!=$this->p->username)
return;
$msg=$msg["message"];
if($this->session===self::REGISTER_ONE){ // first time enter password
$this->tempPass=$msg;
$this->p->sendChat("[Register wizard] You have typed the password. Please type again to confirm.");
$this->session=self::REGISTER_TWO;
return false;
}
if($this->session===self::REGISTER_TWO){ // confirm password # unblock
if($msg===$this->tempPass){ // registry success!
$this->cfg->set("passwordhash", self::hashStr($msg));
$this->cfg->save();
$this->tempPass=0;
$this->session=self::UNBLOCKED;
$this->p->sendChat("[Register wizard] You have successfully registered your LegionPE account. Now you can move.");
ServerAPI::request()->handle("player.auth", $this->p);
$this->onRegister();
}
else{ // two times of typing password do not match
$this->session=self::REGISTER_ONE;
$this->p->sendChat("[Register wizard] The two passwords you typed in do not match. The register wizard has been reset.");
}
return false;
}
if($this->session===self::TO_LOGIN){ // typing password
if($this->cfg->get("passwordhash")!=$this->hashStr($msg)){ // if password incorrect
console("[WARNING] $this is using incorrect password. Hash mismatch: ".substr($this->hashStr($msg), 7)." is different from the registered password ".substr($this->cfg->get("passwordhash"), 7));
$this->loginTrials--;
echo $this->loginTrials;
if($this->loginTrials <= 0){ // auth failure kick
$this->p->sendChat("You failed to login into the account. Are you trying to hack the account? This failure is being logged. You will be kicked in 10 seconds.");
file_put_contents(FILE_PATH."security/logs/login failiures (>5).log", date(DATE_ATOM)." $this's account has been tried to be logged in from IP ".$this->p->ip." and failed for 5 times.", FILE_APPEND);
ServerAPI::request()->schedule(20*5, array($this->p, "close"), "kick $this Failing to login with the correct password for 5 times.");
}
$this->p->sendChat("[Login wizard] The password you entered is incorrect. Please try again. You have ".$this->loginTrials." more chance(s).");
}
else{ // login success!
$this->tell("[Login wizard] You have logged in. You can now move.");
$this->session=self::UNBLOCKED;
ServerAPI::request()->handle("player.auth", $this->p);
$this->onLogin();
}
return false;
}
if($this->p->entity->level->getName() == "world"){ // only talk to players at Hub
foreach(ServerAPI::request()->api->player->getAll(ServerAPI::request()->api->level->get("world")) as $p){
$p->sendChat("$this> ".strtolower($msg));
}
return false;
}
}
public function onChatLP($data){ // after most of the handlers are screened
if($data["player"]->username != $this->p->username)
return;
$msg=$data["message"];
foreach(ServerAPI::request()->api->player->getAll($this->p->entity->level) as $p)
$p->sendChat("$this: ".strtolower($msg));
}
public function onQuit($player){
if($player->username !== $this->p->username)
return;
$this->session=self::OFFLINE;
}
public function onCmd($data){
if(is_string($data["issuer"]))
return;
if($data["issuer"]->username !== $this->p->username)
return;
if($this->session!==self::UNBLOCKED){
$this->tell("Please login/register first.");
return true;
}
$params=$data["parameters"];
if($data["cmd"]==="tp" and (count($params)===4 or (isset($params[1]) and is_string($params[1]) and substr($params[1], 0, 2)=="w:"))){
if(Hub::request()->getPlayer($params[0])->getSession !== self::UNBLOCKED){
$this->tell("You cannot teleport a registering/logging-in player!");
return true;
}
}
}
public function onHit($data){
if($data["entity"]->player->username !== $this->p->username){
return;
}
if($this->session!==self::UNBLOCKED){
$this->tell("Please login/register first.");
return false;
}
$target=ServerAPI::request()->api->entity->get($data["target"]);
if($target->distance($this->p->entity) > 10){ // this is much enough
$this->tell("Don't use mods! You are being suspected using the mod \"Pick me\". This is going to be reported to the staffs. You are going to be kicked in 5 seconds.");
ServerAPI::request()->schedule(100, array($this->p, "close"), "being kicked for using mods");
foreach(ServerAPI::request()->api->player->getAll() as $p){
$p->sendChat("$this has been kicked for using the mod \"Pick me\"!");
}
}
}
public function onHurt($data){
if($data["eid"] !== $this->p->entity->eid)
return;
if($this->session !== self::UNBLOCKED){
if(($p=ServerAPI::request()->api->player->getByEID($data["cause"])) instanceof Player){
$p->sendChat("You cannot attack a logging-in or registering player!");
}
return false;
}
if($this->p->entity->level->getName() === "world" and $data["health"]!==20){
$this->p->entity->setHealth(20);
$this->tp(LegionPE::getHubSpawn());
return false;
}
}
public function onTeleported($data){
if($this->session!==self::UNBLOCKED){
return false;
}
}
public function blockTouch($data){
if($data["player"]->username !== $this->p->username)
return;
if($this->session !== self::UNBLOCKED){
$this->tell("Please login/register first.");
return false;
}
if($data["target"]->distance($this->p->entity) >= 12){ // Pick Me
$this->tell("Don't use mods! You are being suspected using the mod \"Pick me\". This is going to be reported to the staffs. You are going to be kicked in 5 seconds.");
console("[WARNING] $this is using the mod \"Picke Me\". Distance is ".$data["target"]->distance($this->p->entity));
ServerAPI::request()->schedule(100, array($this->p, "close"), "being kicked for using mods");
foreach(ServerAPI::request()->api->player->getAll() as $p)
$p->sendChat("$this has been kicked for using the mod \"Pick me\"!");
}
if($data["target"] instanceof SignPostBlock){ // TODO
$tile=Hub::request()->t->get($data["target"]);
$data=$tile->data;
if(Hub::request()->ranks->getRank($data["creator"]) !== "trust")
return;
$t=$data["target"];
// choose teams
for($i=0; $i<4; $i++){
if($t->equals(LegionPE::getChooseTeamSign($i))){
Hub::request()->team->joinTeam($i, $this->p);
break;
}
}
return false;
}
}
//functions//
public function onRegister(){
$this->tp(LegionPE::getTeamChoosingStandPoint());
$this->tell("[Teams] Please choose a team among these four. Tap the sign to confirm.");
$this->tell("-------------------------");
$this->tell("[Teams] Some teams may be locked from being joined because they are too popular. Choose other team(s).");
$this->tell("-------------------------");
$this->tell("[Teams] [Hint] If you badly want to join a particular team (like if your brother is also in that team), wait a while or come back later.");
}
public function onLogin(){
$this->tp(LegionPE::getHubSpawn());
$this->tell("[Hub] Welcome back to the LegionPE Hub! Choose a minigame or read the score chart or just chat here.");
}
public function getRank(){
return Hub::request()->ranks->getRank($this);
}
public function getSession(){
return $this->session;
}
public function getTeam(){
return Hub::request()->team->get($this);
}
public function getPts(){
return $this->cfg->getPts();
}
public function addPts($pts){
return $this->cfg->addPts($pts);
}
//redirectors//
public function tell($msg){
return $this->p->sendChat($msg);
}
public function tp(Vector3 $pos){
return $this->p->teleport($pos);
}
public function __toString(){
return $this->p->username;
}
//static utils//
public static function hashStr($str){
return bin2hex(hash(hash_algos()[12], $str, TRUE));
}
}
class HubConfig extends Config{
public static function fromPlayer(Player $player){
$ign=self::pign($player);
$path=FILE_PATH."hub players/".substr($ign, 0, 1)."/";
@mkdir($path);
$path.="$ign.yml";
$e=file_exists($path);
$c=new HubConfig($path, $player);
return array($c, $e);
}
public static function pign($p){
return strtolower(trim("$p"));
}
public function __construct($path, Player $player){
if(defined("CONFIG_YAML"))
eval("\$type=CONFIG_YAML;");
else eval("\$type=Config::YAML;");
$preConfig=self::$preConfig;
// ...
parent::__construct($path, $type, $preConfig);
ServerAPI::request()->schedule(1200, array($this, "save"));
}
public static $preConfig = array(
"team" => -1,
"personalpoints" => 0,
"passwordhash" => "THIS PASSWORD IS NOT SET",
"preferences" => array(
"authbyip" => false,
"lang" => "en_US",
),
);
}
class RankMgr{
public $hub;
public $ranks=array();
public function __construct(Hub $hub){
$this->hub=$hub;
$this->reloadAll();
ServerAPI::request()->schedule(1200, array($this, "reloadAll"), array(), true);
console(FORMAT_LIGHT_PURPLE."[DEBUG] Evaluated ranks: ".self::arrToStr($this->ranks));
}
public static function arrToStr(array $arr){
$output="array(";
foreach($arr as $key=>$item){
if(is_string($key))
$output.="\"$key\"=>";
else $output.="$key=>";
if(is_string($item))
$output.="\"$item\", ";
elseif(is_numeric($item))
$output.="$item, ";
elseif(is_object($item)){
if(is_callable(array($item, "__toString")))
$output.=get_class($item)." instance $item, ";
else $output.=get_class($item)." instance, ";
}
elseif(is_null($item))
$output.="null, ";
elseif(is_bool($item))
$output.=(($item?"true":"false").", ");
elseif(is_array($item))
$output.=(self::arrToStr($item).", ");
}
$output.=")";
return $output;
}
public function reloadAll(){
@mkdir(FILE_PATH."ranks/");
foreach(array_keys(self::$rankValues) as $rank){
$this->ranks[$rank]=array();
if($rank==="guest")continue;
if(!file_exists(FILE_PATH."ranks/$rank.txt"))
file_put_contents(FILE_PATH."ranks/$rank.txt", <<<default
#list of player names of $rank
REM lines starting with "rem " or "#" are remarks/comments and would not be read.
#This list is case-insensitive. They are automatically read into and checked case-insensitive at the server runtime.
rEm This file is reloaded every minute.
#names containing spaces (" ") will be automatically trimmed.
rem e.g. " pe map modder " => "pemapmodder"
#names, after trimmed, shorter than or equal to 3 characters, will not be read.
ReM duplications are not to be counted
default
);
$list=explode(PHP_EOL, file_get_contents(FILE_PATH."ranks/$rank.txt"));
foreach($list as $name){
$real=str_replace(array(" ", "\n", "\r"), array("", "", ""), strtolower($name));
if(substr($name, 0, 1)!=="#" and strtoupper(substr($name, 0, 4))!=="REM " and strlen($real)> 3 and !in_array($real, $this->ranks[$rank]))
$this->ranks[$rank][]=$real;;
}
}
}
public function getRank($name){
$name=strtolower("$name");
foreach($this->ranks as $rank=>$names){
if(in_array($name, $names))
return $rank;
}
return "guest";
}
public function getRankIndex($name){
return self::$rankValues[$name];
}
public function getRankByIndex($idx){
return array_search(self::$rankValues);
}
public static $rankValues=array("dangerous"=>-5, "guest"=>0, "vip-lite"=>10, "vip"=>15, "vip-plus"=>20, "vip-star"=>25, "vip-hyper"=>30, "trust"=>100);
}
class TeamMgr{
public $teams;
public function __construct(){
@mkdir(FILE_PATH."teams/");
for($i=0; $i<4; $i++){
$path=FILE_PATH."teams/team-$i.yml";
$exist=file_exists($path);
if(defined("CONFIG_YAML"))
eval("\$yaml=CONFIG_YAML;");
else eval("\$yaml=Config::YAML"); // API update
$this->teams[$i]=new Team($path, $yaml, array(
"name" => $this->getNames($i)[0],
"points" => 1000, // prevent division by zero error
"total players count" => 1, // fix division by zero error
));
}
// ServerAPI::request()->schedule(20, array($this, "updateSigns"), array(), true);
}
public function getTeam($team){
return $this->teams[$team&0x03];
}
public function getNames($id){
if($id===-1)
return array("new player");
switch($id&0b11){
case 0b00:
return array("magma", "red", );
case 0b01:
return array("lapiz", "blue", );
case 0b10:
return array("lilac", "violet", "purple", );
case 0b11:
return array("lime", "green", );
}
}
public function updateBars(){
$scores=array();
foreach($this->teams as $team)
$scores[]=$team->get("points");
$max=max($scores);
$maxBlocks=LegionPE::getMaxScoreBarLength();
$direction=LegionPE::getScoreBarDirection();//return "x" or "z"
$ratio=$maxBlocks/$max;
for($team=0; $team<4; $team++){
$start=LegionPE::getScoreBarStartPos($team);
for($i=0; $i<$maxBlocks; $i++){ // reset
$temp=$start;
$temp->addDir($direction, $i);
$temp->setBlock(BlockAPI::get(0), false);
}
}
foreach($scores as $team=>$score){
$length=(int)($score*$ratio);
$start=LegionPE::getScoreBarStartPos($team); // return new MyPosition($x, $y, $z, $this->api->level->get("world"));
for($i=0; $i<=$length; $i++){
$temp=$start;
$temp->addDir($direction, $i);
$temp->setBlock(BlockAPI::get(WOOL, $this->getTeamColor($team)), false);
}
}
}
public function getTeamColor($team){
switch($team){
case 0:
return 1;
case 1:
return 3;
case 2:
return 2;
case 3:
return 5;
}
}
public function updateSigns(){
$ppl=array();
foreach($this->teams as $data){
$ppl[]=$data->get("total players count");
}
$min=min($ppl);
$max=max($ppl);
foreach($this->teams as $team=>$data){
$loc=LegionPE::getChooseTeamSign($team);
$sign=Hub::request()->t->get($loc);
$name=strtoupper($this->getNames($team)[0]);
$cnt=$ppl[$team];
$can=true;
if(100*($cnt-$min)/$min > 5 and $ppl[$team] == $max)
$can=false;
if($can)
$sign->setText("Tap me to", "enter the team", "[TEAM $name]");
else
$sign->setText("[TEAM $name]", "is full. Come", "back later to", "join this team.");
}
}
public function joinTeam($team, Player $player){
if(ServerAPI::request()->api->tile->get(LegionPE::getChooseTeamSign(team))->data["Text1"] !== "Tap me to"){
$player->sendChat("This team is full! Come back later if you insist to join it.");
return false;
}
$this->teams[$team&0b11]->addPlayer();
Hub::request()->getPlayer($player)->cfg->set("team", $team&0b11);
$player->sendChat("Welcome to team ".$this->getNames($team)."!");
$player->teleport(LegionPE::getHubSpawn());
return true;
}
}
class MyPosition extends Position{
public function __construct($x, $y, $z, Level $level){
parent::__construct($x, $y, $z, $level);
}
public function addX($delta){
$this->x+=$delta;
}
public function addY($delta){
$this->y+=$delta;
}
public function addZ($delta){
$this->z+=$delta;
}
public function addDir($direction, $delta){
switch($direction){
case "x":
return $this->addX($delta);
case "y":
return $this->addY($delta);
case "z":
return $this->addZ($delta);
}
}
public function setBlock(Block $block, $update=true){
return $this->level->setBlock($this, $block, $update, false, true);
}
public function getBlock(){
return $this->level->getBlock($this);
}
public function equals(Vector3 $other){
$ret=true;
$ret=$ret and ($other->x===$this->x);
$ret=$ret and ($other->y===$this->y);
$ret=$ret and ($other->z===$this->z);
if($other instanceof Position)
$ret=$ret and ($other->level->getName()===$this->level->getName());
return $ret;
}
}
class Team extends Config{
public function __construct($path, $yml, $data){
parent::__construct($path, $yml, $data);
}
public function addPoints($delta){
$this->config["points"]+=$delta;
}
public function &getPoints(){
return $this->config["points"];
}
public function addPlayer(){
Hub::request()->teams->updateSigns();
return ++$this->config["total players count"];
}
}
class LegionPE{
public static function getTeamChoosingStandPoint(){
return new MyPosition(180, 128, 180, ServerAPI::request()->api->level->get("world"));
}
public static function getHubSpawn(){
return new MyPosition(128, 70, 128, ServerAPI::request()->api->level->get("world"));
}
public static function getMaxScoreBarLength(){
return 10;
}
public static function getScoreBarDirection(){
return "x"; // or "z"
}
public static function getScoreBarStartPos($team){
$team=$team&0b11;
return new MyPosition(128+5*$team, 18, 100);
}
public static function getChooseTeamSign($team){
return new MyPosition(128+($team&0b11), 99, 100);
}
}
class HubWorldMgr{
public function __construct($prefix0, $prefix1, $interval, $cnt, $evac, $notice=false){
$this->basePrefix=$prefix0;
$this->copyPrefix=$prefix1;
$this->interval=$interval;
$this->cnt=$cnt;
$this->evac=$evac; // evacuate site
if(is_array($notice)){
ServerAPI::request()->schedule($this->interval, array($this, "broadcast"), $notice[1], true);
$this->delay=$notice[0];
}
}
public function init(){
$this->regen(false);
ServerAPI::request()->schedule($this->delay, array($this, "schedule"));
}
public function schedule(){
ServerAPI::request()->schedule($this->interval, array($this, "regen"), true, true);
}
public function broadcast($msg){
for($i=0; $i<$this->cnt; $i++){
$api=ServerAPI::request()->api;
if(($l=$api->level->get($this->copyPrefix.$i)) instanceof Player){
foreach($api->player->getAll($l) as $p)
$p->sendChat($msg);
}
}
}
public function regen(boolean $del){
$api=ServerAPI::request()->api;
if($del){
for($i=0; $i<$this->cnt; $i++){
$name=$this->copyPrefix.$i;
if(($l=$api->level->get($name)) instanceof Level){
foreach($api->player->getAll($l) as $p){
if($this->evac instanceof Position)
$p->teleport($this->evac);
elseif($this->evac instanceof Level)
$p->teleport($this->evac->getSafeSpawn());
elseif(is_callable($this->evac))
call_user_func($this->evac, $p, $name);
elseif(is_string($this->evac) and (($l=$api->level->get($this->evac)) instanceof Level))
$p->teleport($l->getSafeSpawn());
}
$api->level->unloadLevel($l, true);
}
$this->delDir(FILE_PATH."worlds/$name/");
}
}
for($i=0; $i<$this->cnt; $i++){
$name=$this->copyPrefix.$i;
$this->copyDir(FILE_PATH."worlds/".$this->basePrefix.$i, FILE_PATH."worlds/$name/");
$api->level->loadLevel($name);
}
}
public function delDir($dir){
if(substr($dir, -1)!="/" and substr($dir, -1)!="\\")
$dir.="/";
$directory=dir($dir);
while(($file=$directory->read())!==false){
if(is_file($dir.$file))
unlink($dir.$file);
elseif(is_dir($dir.$file) and str_replace(array(".", "/"), array("", ""), $file)===""){
$this->delDir($dir.$file);
}
}
rmdir($dir);
}
public function copyDir($dir, $to){
if(substr($dir, -1)!="/" and substr($dir, -1)!="\\")
$dir.="/";
$directory=dir($dir);
while(($file=$directory->read())!==false){
if(is_file($dir.$file))
copy($dir.$file, $to.$file);
elseif(is_dir($dir.$file) and str_replace(array(".", "/"), array("", ""), $file)===""){
$this->copyDir($dir.$file, $to.$file);
}
}
}
}
class MySpace{
public $start, $end;
public function __construct(Vector3 $start, Vector3 $end, Level $level){
$this->start=new Position(
min($start->x, $end->x),
min($start->y, $end->y),
min($start->z, $end->z),
$level
);
$this->start=new Position(
max($start->x, $end->x),
max($start->y, $end->y),
max($start->z, $end->z),
$level
);
}
public function isInSpace(Position $p){
return $this->isInside($p);
}
public function isInside(Position $pos){
return ($pos->x>$this->start->x and $pos->x<$this->end->x
and $pos->y>$this->start->y and $pos->y<$this->end->y
and $pos->z>$this->start->z and $pos->z>$thsi->end->z
and $pos->level->getName()===$this->end->level->getName());
}
}
@echo off
echo Adding files...
echo ------------------------
git add -A
echo ------------------------
echo Adding completed.
echo Comparing and committing changes with message "Untitled commit"...
echo ------------------------
git commit -m "Untitled commit"
echo ------------------------
echo Comparing and committing completed.
echo Merging new commits from remote GitHub (if exist). This will take a while...
echo ------------------------
git pull origin master
echo ------------------------
echo Pull completed.
echo Pushing commits to remote GitHub. Please enter your username and password. This will take a while...
git push -u origin master
echo ------------------------
echo Done! Press any key to close the window.
pause
<?php
/*
__PocketMine Plugin__
class=ParkourMinigamePlugin
name=Parkour Minigame
author=PEMapModder
apiversion=12
version=1
*/
require_once(FILE_PATH."plugins/Hub.php");
class ParkourMinigamePlugin implements Plugin{
public function __construct(ServerAPI $api, $server=false){
}
public function __destruct(){
}
public function init(){
$this->server=ServerAPI::request();
$this->server->addHandler("player.move", array($this, "onMove"));
}
public function onMove(Entity $ent){
if($ent->class!==ENTITY_PLAYER)
return;
if(ParkourWorldMgr::getJoinPortal()->isInSpace($ent)){
$plyr=$ent->player;
$plyr->teleport(array_rand(ParkourWorldMgr::getArenas()));
$plyr->sendChat("You have been teleported to the parkour arena.");
}
}
}
class ParkourWorldMgr{// extends HubWorldMgr{
public static function getJoinPortal(){
return new MySpace(new Vector3(124, 31, 157), new Vector3(133, 41, 159), ServerAPI::request()->api->level->get("world"));
}
public static function getArenas(){
$level=ServerAPI::request()->api->level->get("world_parkour");
return array(
new Position(41, 75, 41, $level),
new Position(41, 72, 116, $level),
new Position(104, 75, 103, $level),
new Position(104, 75, 27, $level),
new Position(105, 74, 174, $level),
);
}
}
<?php
/*
__PocketMine Plugin__
class=PvpMinigamePlugin
name=Hub PvP Minigame
author=PEMapModder
version=1
apiversion=12
*/
require_once(FILE_PATH."plugins/Hub.php");
class PvpMinigamePlugin implements Plugin{
public $worldList=array("pvp_base_0", "pvp_base_1");
// interface functions
public function __construct(ServerAPI $api, $s=0){
$this->api=$api;
$this->server=ServerAPI::request();
$this->hub=Hub::request();
$this->hubItf=new PvpHubInterface($this);
// $this->worldmgr=new PvpWorldMgr();
}
public function __destruct(){
}
// PocketMine interface
public function init(){
$this->api->addHandler("player.death", array($this, "pmevt"));
$this->api->addHandler("player.respawn", array($this, "pmevt"));
@mkdir(FILE_PATH."minigames/");
$this->worldmgr->init();
}
public function pmevt($data, $event){
switch($event){
case "entity.health.change":
$e=$data["entity"];
if($e->class!==ENTITY_PLAYER or strtolower(substr($e->level->getName(), 0, 9))!="pvp_copy_")
return;
if($e->health > $data["health"])
return $this->onHeal($e->player, $e->health-$data["health"]);
return $this->onHurt($e->player, $data["health"]-$e->health, $data["cause"]);
case "player.death":
if(strtolower(substr($data["player"]->entity->level->getName(), 0, 9))!="pvp_copy_")
return;
$p=$data["player"];
$c=$data["cause"];
if(($kl=$this->api->player->getByEID($c)) instanceof Player)
$this->onKill($p, $kl);
return $this->onDie($p, $c);
case "player.respawn":
if(strtolower(substr($data->entity->level->getName(), 0, 9))!="pvp_copy_")
return;
return $this->onRespawn($data);
}
}
private function onHeal($healed, $amount){
}
private function onHurt($victim, $damage, $reason){
}
private function onKill($victim, $killer){
}
private function onDie($victim, $cause){
}
}
class PvpHubInterface{
public function __construct(PvpMinigamePlugin $p){
ServerAPI::request()->schedule(20, array($this, "init"));
$this->plugin=$p;
}
public function init(){
$this->server=ServerAPI::request();
$this->api=$this->server->api;
$this->hub=Hub::request();
$this->api->addHandler("player.block.touch", array($this, "evt"));
}
public function evt($data, $event){
switch($event){
case "player.block.touch":
}
}
}
class PvpWorldMgr extends HubWorldMgr{
public static function getJoinPortal(){
return new MySpace(new Vector3(157, 31, 134), new Vector3(159, 41, 125), ServerAPI::request()->api->level->get("world"));
}
public static function getUltimateParkourer(){
return new MyPosition(84, 126, 60, ServerAPI::request()->api->level->get("world_pvp"));
}
public static function getLifeboatSpace(){
return new MySpace(new Vector3(90, 124, 68), new Vector3(81, 119, 64), ServerAPI::request()->api->level->get("world"));
}
public function __construct(){
parent::__construct("pvp_base_", "pvp_copy_", 20*60*60*2, 4, "world", array(20*30, "You are going to be evacuated to hub for level reloading in thirty seconds. Prepare yourself for that.")); // dont ever load the base world!!!!!
}
}

List of TODO

  • Hub
  • Disguise&Vanish
  • PvP minigame plugin
  • CNR minigame plugin
  • Parkour minigame plugin
  • Chunk Claimers minigame plugin
@PEMapModder
Copy link
Author

I will not load the Disguise one, don't worry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment