i am working on an addon, but i got a problem
[22:03:08] [CRITICAL]: "Could not pass event 'pocketmine\event\player\PlayerInteractEvent' to 'MTeamPvP v1.0.0 Beta': Argument 1 passed to MCrafters\TeamPvP\GameManager::__construct() must be an instance of MCrafters\TeamPvP\TeamPvP, none given, called in C:\Users\USER\Desktop\Taha\FlashCraft PE\lobby 1\plugins\DevTools\src\MCrafters\TeamPvP\TeamPvP.php on line 120 and defined on MCrafters\TeamPvP\TeamPvP
[22:03:08] [NOTICE]: InvalidArgumentException: "Argument 1 passed to MCrafters\TeamPvP\GameManager::__construct() must be an instance of MCrafters\TeamPvP\TeamPvP, none given, called in C:\Users\USER\Desktop\Taha\FlashCraft PE\lobby 1\plugins\DevTools\src\MCrafters\TeamPvP\TeamPvP.php on line 120 and defined" (E_RECOVERABLE_ERROR) in "/DevTools/src/MCrafters/TeamPvP/GameManager" at line 13
also sorry for the different error broadcasting
code : (please don't care about the other classes except GameManager and TeamPvP)
TeamPvP.php:
<?php
namespace MCrafters\TeamPvP;
use pocketmine\plugin\PluginBase;
use pocketmine\utils\TextFormat as Color;
use pocketmine\utils\Config;
use pocketmine\event\Listener;
use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\EntityDamageByEntityEvent;
use pocketmine\event\player\PlayerInteractEvent;
use pocketmine\event\player\PlayerDeathEvent;
use pocketmine\math\Vector3;
use pocketmine\level\Position;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\Player;
use pocketmine\block\Block;
use pocketmine\item\Item;
use pocketmine\block\WallSign;
use pocketmine\block\PostSign;
use pocketmine\scheduler\ServerScheduler;
class TeamPvP extends PluginBase implements Listener
{
// Teams
public $reds = [];
public $blues = [];
public $gameStarted = false;
public $yml;
public function onEnable()
{
// Initializing config files
$this->saveResource("config.yml");
$yml = new Config($this->getDataFolder() . "config.yml", Config::YAML);
$this->yml = $yml->getAll();
$this->getLogger()->debug("Config files have been saved!");
$this->getServer()->getScheduler()->scheduleRepeatingTask(new Tasks\SignUpdaterTask($this), 15);
$this->getServer()->getPluginManager()->registerEvents($this, $this);
$this->getServer()->getLogger()->info(Color::BOLD . Color::GOLD . "M" . Color::AQUA . "TeamPvP " . Color::GREEN . "Enabled" . Color::RED . "!");
}
public function isFriend($p1, $p2)
{
if ($this->getTeam($p1) === $this->getTeam($p2) && $this->getTeam($p1) !== false) {
return true;
} else {
return false;
}
}
// isFriend
public function getTeam($p)
{
if (in_array($p, $this->reds)) {
return "red";
} elseif (in_array($p, $this->blues)) {
return "blue";
} else {
return false;
}
}
public function setTeam($p, $team)
{
if (strtolower($team) === "red") {
if (count($this->reds) < 5) {
if ($this->getTeam($p) === "blue") {
unset($this->blues[array_search($p, $this->blues)]);
}
array_push($this->reds, $p);
$this->getServer()->getPlayer($p)->setNameTag("§c§l" . $p);
$this->getServer()->getPlayer($p)->teleport(new Vector3($this->yml["waiting_x"], $this->yml["waiting_y"], $this->yml["waiting_z"]));
return true;
} elseif (count($this->blues) < 5) {
$this->setTeam($p, "blue");
} else {
return false;
}
} elseif (strtolower($team) === "blue") {
if (count($this->blues) < 5) {
if ($this->getTeam($p) === "red") {
unset($this->reds[array_search($p, $this->reds)]);
}
array_push($this->blues, $p);
$this->getServer()->getPlayer($p)->setNameTag("§b§l" . $p);
$this->getServer()->getPlayer($p)->teleport(new Vector3($this->yml["waiting_x"], $this->yml["waiting_y"], $this->yml["waiting_z"]));
return true;
} elseif (count($this->reds) < 5) {
$this->setTeam($p, "red");
} else {
return false;
}
}
}
public function removeFromTeam($p, $team)
{
if (strtolower($team) == "red") {
unset($this->reds[array_search($p, $this->reds)]);
return true;
} elseif (strtolower($team) == "blue") {
unset($this->blues[array_search($p, $this->blues)]);
return true;
}
}
public function onInteract(PlayerInteractEvent $event)
{
$p = $event->getPlayer();
$teams = array("red", "blue");
if ($event->getBlock()->getX() === $this->yml["sign_join_x"] && $event->getBlock()->getY() === $this->yml["sign_join_y"] && $event->getBlock()->getZ() === $this->yml["sign_join_z"]) {
if (count($this->blues) < 5 && count($this->reds) < 5) {
$this->setTeam($p->getName(), $teams[array_rand($teams, 1)]);
$s = new GameManager();
$s->run();
} else {
$p->sendMessage($this->yml["teams_are_full_message"]);
}
}
}
public function onEntityDamage(EntityDamageEvent $event)
{
if ($event instanceof EntityDamageByEntityEvent) {
if ($event->getEntity() instanceof Player) {
if ($this->isFriend($event->getDamager()->getName(), $event->getEntity()->getName()) && $this->gameStarted == true) {
$event->setCancelled(true);
$event->getDamager()->sendMessage(str_replace("{player}", $event->getPlayer()->getName(), $this->yml["hit_same_team_message"]));
}
if ($this->isFriend($event->getDamager()->getName(), $event->getEntity()->getName())) {
$event->setCancelled(true);
}
}
}
}
public function onDeath(PlayerDeathEvent $event)
{
if ($this->getTeam($event->getEntity()->getName()) == "red" && $this->gameStarted == true) {
$this->removeFromTeam($event->getEntity()->getName(), "red");
$event->getEntity()->teleport($this->getServer()->getLevelByName($this->yml["spawn_level"])->getSafeSpawn());
} elseif ($this->getTeam($event->getEntity()->getName()) == "blue" && $this->gameStarted == true) {
$this->removeFromTeam($event->getEntity()->getName(), "blue");
$event->getEntity()->teleport($this->getServer()->getLevelByName($this->yml["spawn_level"])->getSafeSpawn());
}
foreach ($this->blues as $b) {
foreach ($this->reds as $r) {
if (count($this->reds) == 0 && $this->gameStarted == true) {
$this->getServer()->getPlayer($b)->getInventory()->clearAll();
$this->removeFromTeam($b, "blue");
$this->getServer()->getPlayer($b)->teleport($this->getServer()->getLevelByName($this->yml["spawn_level"])->getSafeSpawn());
$this->getServer()->broadcastMessage("Blue Team won TeamPvP!");
} elseif (count($this->blues) == 0 && $this->gameStarted == true) {
$this->getServer()->getPlayer($r)->getInventory()->clearAll();
$this->removeFromTeam($r, "red");
$this->getServer()->getPlayer($r)->teleport($this->getServer()->getLevelByName($this->yml["spawn_level"])->getSafeSpawn());
}
}
}
}
}//class
GameManager.php :
<?php
namespace MCrafters\TeamPvP;
use pocketmine\scheduler\ServerScheduler as Tasks;
class GameManager
{
public $reds;
public $blues;
public $gst;
public $gwt;
public function __construct(\MCrafters\TeamPvP\TeamPvP $plugin)
{
parent::__construct($plugin);
$this->plugin = $plugin;
}
public function run()
{
$this->reds = $this->plugin->reds;
$this->blues = $this->plugin->blues;
if (count($this->reds) < 5 && count($this->blues) < 5) {
$this->gst = Tasks::scheduleRepeatingTask(new Tasks\GameStartTask($this), 20)->getTaskId();
Tasks::cancelTask($this->gwt);
} else {
$this->gwt = Tasks::scheduleRepeatingTask(new Tasks\GameWaitingTask($this), 15)->getTaskId();
}
}
}
namespace correct, class and file name correct, and all other functions from other classes have nothing to do with this :) check the line where there is GameManager::run() in TeamPvP class.
i already know there is one about this, but i didn't understand it.
Thank You for your help.
You have a type hint
public function __construct(\MCrafters\TeamPvP\TeamPvP $plugin)
{
parent::__construct($plugin);
$this->plugin = $plugin;
}
So when you go to instantiate MCrafters\TeamPvP\GameManager you have to pass it an instance of \MCrafters\TeamPvP\TeamPvP
$team = new \MCrafters\TeamPvP\TeamPvP();
$manager = new \MCrafters\TeamPvP\GameManager($team)
Related
I just started using wordpress.
I created this function inside function.php, and include file below, works!:
function is_live_2020() {
if(is_page_template('landing.php') || is_page_template('collection.php')) {
return true;
}
return false;
}
include get_template_directory().'/model-filter.php';
but when I created new function again, include file doesn't work:
function is_staging() {
if(is_page_template('landing-staging.php') || is_page_template('collection-staging.php')) {
return true;
}
return false;
}
function load_model_filter() {
if (is_live_2020()) {
include get_template_directory().'/model-filter.php';
} else {
include get_template_directory().'/model-filter-new.php';
}
}
add_action('wp', 'load_model_filter');
how is the correct way to include those function files?
btw.. here model-filter.php:
<?php
function collectionFilter() {
global $wpdb;
$where = array();
if (location_slug()=='my') {
if (1 == $_POST['fman'] && 0 == $_POST['fwoman']) {
$where[] = "filter_Gender like '".(_x_filter_strings($_POST['en'],"men"))."%'";
} else if (0 == $_POST['fman'] && 1 == $_POST['fwoman']) {
$where[] = "filter_Gender like '%".(_x_filter_strings($_POST['en'],"women"))."'";
}
$size = array();
if (1 == $_POST['f28']) {
$size[] = (_x_filter_strings($_POST['en'],"small_size"));
}
if (1 == $_POST['f36']) {
$size[] = (_x_filter_strings($_POST['en'],"mid_size"));
}
if (1 == $_POST['f40']) {
$size[] = (_x_filter_strings($_POST['en'],"large_size"));
}
if (0 < count($size)) {
$where[] = "filter_Size IN ('" . implode("', '", $size) . "')";
etc.....
Is there a cleaner way to achieve a similar result, but without using all of these elseif statements? I need there to always be a true statement, depending on dynamic variables. Thanks!
$a = true;
$b = false;
$c = false;
if ($a == true && $b == false && $c == false) {
echo 'only $a is running';
} elseif ($a == true && $b == false && $c == true) {
echo '$a and $c are running, but not $b';
} elseif ($a == true && $b == true && $c == false) {
echo '$a and $b are running, but not $c';
} elseif ($a == false && $b == true && $c == true) {
echo '$b and $c are running, but not $a';
} elseif ($a == false && $b == false && $c == true) {
echo 'only $c is running';
} elseif ($a == false && $b == true && $c == false) {
echo 'only $b is running';
} else {
echo 'nope';
};
Consider to use an array, that way you can make more alphabet letters than you have in your example right now, and it will just work:
<?php
$arr = [
'a' => true,
'b' => true,
'c' => true
];
$running = [];
$not_running = [];
foreach($arr as $key=>$val)
if ($val)
$running[] = $key;
else
$not_running[] = $key;
if (count($running) == 0)
echo "Nope";
else if (count($running) == 1)
echo "Only ".$running[0]." is running";
else if (count($not_running) == 0)
echo "All are running";
else
echo "Only " . implode($running, ' and ') . " are running, but not ". implode($not_running, ' and ');
So now you can make your array bigger, for example like this:
for($i=0; $i<=25; $i++)
{
$arr[chr($i+97)] = (bool)rand(0,1);
}
which will output something like:
Only c and d and e and f and g and h and l and m and n and q and u and w and y and z are running, but not a and b and i and j and k and o and p and r and s and t and v and x
Here is one potential way you could do it by utilising __toString(), it's pretty rushed so you'll probably want to clean it up a bit. You can find a working example here
You may want to play with the __toString() return to get it to what you want, but essentially you just have to echo the collection.
Side note: I didn't implement Countable, ArrayAccess, Iterator or any other useful inbuilt interfaces due to time constraints. If you were to use this solution i'd suggest implementing them
<?php
class Instance
{
/** #var string */
private $name;
/** #var bool */
private $active;
public function __construct($name, $active = false)
{
$this->name = $name;
$this->active = $active;
}
public function turnOn()
{
$this->active = true;
}
public function turnOff()
{
$this->active = false;
}
public function getName()
{
return $this->name;
}
public function getActive()
{
return $this->active;
}
public function __toString()
{
$state = $this->getActive() === true ? 'on' : 'off';
return sprintf("%s is switched %s", $this->getName(), $state);
}
}
class InstanceCollection
{
private $collection = [];
public function add(Instance $item)
{
$this->collection[] = $item;
}
public function __toString()
{
$on = $this->getInstancesByState(true);
$off = $this->getInstancesByState(false);
return rtrim(implode(', ', $on), ', ') . rtrim(implode(', ', $off), ', ');
}
public function getInstancesByState($state)
{
return array_map(function($instance) use ($state) {
if ($instance->getActive() === $state) {
return $instance;
}
}, $this->collection);
}
}
Usage:
$instance = new Instance('eu');
$instance->turnOn();
$instance2 = new Instance('us');
$instance2->turnOff();
$collection = new InstanceCollection();
$collection->add($instance);
$collection->add($instance2);
echo $collection;
And output:
eu is switched on, us is switched off
function d20() {
$rollAll = false;
$roll = rand(1,20);
if ($rollAll == false) {
echo $roll;
}
}
function rollAll() {
$rollAll = true;
d20();
}
rollAll();
I want to make it so that whenever I call the rollAll function, $rollAll will be true and it won't echo the roll. Sorry if this problem seems really stupid, but I'm new to PHP.
Thanks.
#Rizier123 Answered just i pass the variable from rollAll to d20
function d20($rollAll) {
$roll = rand(1,20);
if ($rollAll == false) {
echo $roll;
}
}
function rollAll() {
$rollAll = true;
d20($rollAll );
}
rollAll();
set the variable $rollAll in global scope or pass as function params
function d20($rollAll) {
$rollAll = false;
$roll = rand(1,20);
if ($rollAll == false) {
echo $roll;
}
}
function rollAll() {
$rollAll = true;
d20( $rollAll );
}
rollAll();
or
$rollAll = true;// or false
function d20() {
$rollAll = false;
$roll = rand(1,20);
if ($rollAll == false) {
echo $roll;
}
}
function rollAll() {
$rollAll = true;
d20( );
}
rollAll();
I am implementing my own StringTokenizer class in php, because the strtok function can only handle one opened tokenizer at the same time.
With
Hello;this;is;a;text
it works perfectly.
The output is:
**Hello**
**this**
**is**
**a**
**text**
But with
Hello;this;is;a;text;
it outputs:
**Hello**
**this**
**is**
**a**
**text**
****
****
<endless loop>
But I except the following output:
**Hello**
**this**
**is**
**a**
**text**
****
See my code below and please correct me:
class StringTokenizer
{
private $_str;
private $_chToken;
private $_iPosToken = 0;
private $_bInit;
public function __construct($str, $chToken)
{
if (empty($str) && empty($chToken))
{
throw new Exception('String and the token char variables cannot be empty.');
}
elseif(empty($chToken) && !empty($str))
{
throw new Exception('Missing parameter: Token char cannot be empty.');
}
elseif(!empty($chToken) && empty($str))
{
throw new Exception('Missing parameter: String cannot be empty.');
}
elseif(!empty($chToken) && !empty($str) && is_string($str) && strlen($chToken) >= 0)
{
$this->_str = $str;
$this->_chToken = $chToken;
$this->_bInit = true;
}
else
{
throw new Exception('TypeError: Illegal call to __construct from class StringTokenizer.');
}
}
public function next()
{
if ($this->_iPosToken === false)
{
return false;
}
if ($this->_bInit === true && (strlen($this->_str) - 1) > $this->_iPosToken)
{
$iCh1stPos = strpos($this->_str, $this->_chToken, $this->_iPosToken) + 1;
$this->_iPosToken = $iCh1stPos;
$this->_bInit = false;
return substr($this->_str, 0, $this->_iPosToken - 1);
}
elseif ($this->_bInit === false && (strlen($this->_str) - 1) > $this->_iPosToken)
{
$iCh1stPos = $this->_iPosToken;
$iCh2ndPos = strpos($this->_str, $this->_chToken, $this->_iPosToken);
if ($iCh2ndPos === false)
{
$this->_iPosToken = false;
return substr($this->_str, $iCh1stPos);
}
else
{
$this->_iPosToken = $iCh2ndPos + 1;
return substr($this->_str, $iCh1stPos, $iCh2ndPos - $iCh1stPos);
}
}
}
public function hasNext()
{
return strpos($this->_str, $this->chToken, $this->_iPosToken) === false ? false : true;
}
}
$strText = 'Hello;this;is;a;text';
$tokenizer = new StringTokenizer($strText, ';');
$tok = $tokenizer->Next();
while ($tok !== false)
{
echo '**' . $tok . '**' . PHP_EOL;
$tok = $tokenizer->next();
}
exit(0);
The problem with the third condition in the next() is this. String length is 26 and the last character match is 26 which you represent with the _iPosToken. so the condition in the 3rd if is false and the block never executes for the last semicolon.
A function in php returns NULL not FALSE by default.source
and the while never terminates at the bottom of the code.
So you have two options here. change the condition in the 3rd if to (strlen($this->_str)) >= $this->_iPosToken
OR
add a 4th condtion which returns false, as shown below.
public function next()
{
if ($this->_iPosToken === false)
{
return false;
}
if ($this->_bInit === true && (strlen($this->_str) - 1) > $this->_iPosToken)
{
$iCh1stPos = strpos($this->_str, $this->_chToken, $this->_iPosToken) + 1;
$this->_iPosToken = $iCh1stPos;
$this->_bInit = false;
return substr($this->_str, 0, $this->_iPosToken - 1);
}
elseif ($this->_bInit === false && (strlen($this->_str)-1 ) > $this->_iPosToken)
{
$iCh1stPos = $this->_iPosToken;
echo $this->_iPosToken;
$iCh2ndPos = strpos($this->_str, $this->_chToken, $this->_iPosToken);
if ($iCh2ndPos === FALSE) // You can chuck this if block. I put a echo here and //it never executed.
{
$this->_iPosToken = false;
return substr($this->_str, $iCh1stPos);
}
else
{
$this->_iPosToken = $iCh2ndPos + 1;
return substr($this->_str, $iCh1stPos, $iCh2ndPos - $iCh1stPos);
}
}
else return false;
}
Why do you like reinvent the wheel ?
You can use explode function, and then implements Iterator pattern in this tokenizer, i think it's an good approach.
http://php.net/explode
http://br1.php.net/Iterator
Example
<?php
class StringTokenizer implements Iterator
{
private $tokens = [];
private $position = 0;
public function __construct($string, $separator)
{
$this->tokens = explode($separator, $string);
}
public function rewind()
{
$this->position = 0;
}
public function current()
{
return $this->tokens[$this->position];
}
public function next()
{
++ $this->position;
}
public function key()
{
return $this->position;
}
public function valid()
{
return isset($this->tokens[$this->position]);
}
}
And using it:
$tokenizer = new StringTokenizer('h;e;l;l;o;', ';');
while($tokenizer->valid()) {
printf('**%s**', $tokenizer->current());
$tokenizer->next();
}
So I started using MVC. I don't use a framework. It's just self-practice.
So this is my register part:
protected function _instance()
{
if ($_POST != null)
{
/**
* Validating if forms are not empty
**/
if (self::validateForms())
{
echo 1;
}
else
{
new Error("One of the forums was empty..");
}
}
}
private static function validateForms()
{
$inputs = array (
'username', 'password', 'repassword',
'email', 'password_f', 'repassword_f',
'display'
);
$i = 0;
foreach ($inputs as $key)
{
if (isset($_POST[$key]) && !empty($_POST[$key]))
{
$i++;
if ((int) $i == count($inputs))
{
return true;
}
else
{
return false;
}
}
}
}
Now it only must check if inputs were set, if not, throw error.
But it seems like it doesn't work as it always runs that error.
$i must grow everytime a input was full, but I don't think it does.
When I do echo $i, it only echoing "1".
Why is it only looping through it once?
The problem is you are returning within your loop after the first test.
foreach ($inputs as $key)
{
if (isset($_POST[$key]) && !empty($_POST[$key]))
{
$i++;
if ((int) $i == count($inputs))
{
return true;
}
else
{
return false;
}
}
}
should be
foreach ($inputs as $key)
{
if (isset($_POST[$key]) && !empty($_POST[$key]))
{
$i++;
}
}
if ((int) $i == count($inputs))
{
return true;
}
else
{
return false;
}
or more concisely
foreach ($inputs as $key)
{
if (!isset($_POST[$key]) || empty($_POST[$key]))
{
return false;
}
}
return true;
You need to take the checking of $i out of the loop so that it checks how many were actually set once all the inputs have been cycled through. Otherwise, it is checking on the first time, seeing that it is not equal and returning false.
foreach ($inputs as $key)
{
if (isset($_POST[$key]) && !empty($_POST[$key]))
{
$i++;
}
}
if ((int) $i == count($inputs))
{
return true;
}
else
{
return false;
}