1. The forums will be archived and moved to a read only mode in about 2 weeks (mid march).

Scan plugin directory for class files

Discussion in 'Development' started by jasonwynn10, Nov 21, 2016.

?

Is what I started with the correct way to start?

  1. Yes

  2. No

  3. I don't Know

Results are only viewable after voting.
  1. jasonwynn10

    jasonwynn10 Moderator Poggit Reviewer

    Messages:
    1,489
    GitHub:
    jasonwynn10
    I am currently working on a plugin that can allow players to create and add custom generators for their PM worlds. I need to do a few things to get what i want to happen:
    1. Scan the resource directory for php files with Generator in the filename
    2. Check to see if the file has a class in it that implements a Generator interface
    3. Add the class to the server for world generation

    I was wondering if something like this would work to start...
    PHP:
    $generators scandir($this->getDataFolder());
            foreach(
    $generators as $generator) {
                if(
    preg_match("*Generator.php",$generator)) {
                    
    $generatorName[0] = null;
                    
    explode($generator,$generatorName);
                    if(
    is_file($this->getDataFolder().$generatorName[0]."Generator.php")) {
                       
                    }
                }
            }
     
    Last edited: Nov 21, 2016
  2. Junkdude

    Junkdude Zombie

    Messages:
    346
    GitHub:
    JunkDaCoder
    I supposes you could make it into a plugin and then getpluginmanager
     
  3. jasonwynn10

    jasonwynn10 Moderator Poggit Reviewer

    Messages:
    1,489
    GitHub:
    jasonwynn10
    I don't want the generator as a standalone plugin, I want it to be as a .php file so the users can edit it
     
  4. Junkdude

    Junkdude Zombie

    Messages:
    346
    GitHub:
    JunkDaCoder
    Take a look at "CodeBlocks" github runs php code on like a break event etc
     
  5. Thunder33345

    Thunder33345 Moderator Staff Member

    Messages:
    2,137
    GitHub:
    Thunder33345
    so it would be like
    PHP:
    $generators scandir($this->getDataFolder());
            foreach(
    $generators as $generator) {
                if(
    preg_match("*Generator.php",$generator)) {
                    
    $genName explode("generator.php",$generator);//so it would be like [0=>"Name"]
                    
    if(is_file($this->getDataFolder().$genName[0]."Generator.php")) {//start of code that arent meant to be run
    try{ //so we dont crash PM
     
    check file cointain class $genName."Generator"
     
    check class have implemented generatorInterface 
    } catch (Exception){}
                    }
                }
            }
     
  6. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    To prevent forcing file names, consider using the method used in PocketMine Alpha_1.3 plugins.
     
    jasonwynn10 likes this.
  7. Thunder33345

    Thunder33345 Moderator Staff Member

    Messages:
    2,137
    GitHub:
    Thunder33345
    Also worth mentioning if you have time look at how pm load plugins
     
  8. jasonwynn10

    jasonwynn10 Moderator Poggit Reviewer

    Messages:
    1,489
    GitHub:
    jasonwynn10
    I did look through there, however I can only find how it used the plugin.yml file in the .phar. I am trying to look for the info I need within a single .php file
    Thank You!
     
  9. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    It is even simpler. Just use require_once.
    But I still recommend you not to try to load them according to filenames. File names directly touched by users usually should not have restricted names (although PocketMine-MP.phar does).
    https://github.com/pmmp/PocketMine-MP/blob/Alpha_1.3.12/src/API/PluginAPI.php#L201-L211
    https://github.com/pmmp/PocketMine-MP/blob/Alpha_1.3.12/src/API/PluginAPI.php#L50-L124
     
  10. jasonwynn10

    jasonwynn10 Moderator Poggit Reviewer

    Messages:
    1,489
    GitHub:
    jasonwynn10
  11. jasonwynn10

    jasonwynn10 Moderator Poggit Reviewer

    Messages:
    1,489
    GitHub:
    jasonwynn10
    Okay, so after some modifications I made this:
    PHP:
    public function loadGenerator($file) {
            if(
    is_link($file) or is_dir($file) or !file_exists($file)) {
                
    $this->getLogger()->debug(basename($file)." is not a file");
                return 
    false;
            }
                
    $content file_get_contents($file);
                
    $info strstr($content"*/"true);
                
    $content str_repeat(PHP_EOLsubstr_count($info"\n")).substr(strstr($content"*/"),2);
                if(
    preg_match_all('#([a-zA-Z0-9\-_]*)=([^\r\n]*)#u'$info$matches) == 0) {
                    
    $this->getLogger()->debug("Failed to parse ".basename($file));
                    return 
    false;
                }
                
    $info = array();
                foreach(
    $matches[1] as $k => $i) {
                    
    $v $matches[2][$k];
                    switch(
    strtolower($v)) {
                        case 
    "on":
                        case 
    "true":
                        case 
    "yes":
                            
    $v true;
                            break;
                        case 
    "off":
                        case 
    "false":
                        case 
    "no":
                            
    $v false;
                            break;
                    }
                    
    $info[$i] = $v;
                }
                
    $info["code"] = $content;
                
    $info["class"] = trim(strtolower($info["class"]));
            if(!isset(
    $info["class"]) or !isset($info["version"])) {
                
    $this->getLogger()->debug("[ERROR] Failed parsing of ".basename($file));
                return 
    false;
            }
            
    $this->getLogger()->debug("Loading generator \"".TextFormat::GREEN.$info["class"].TextFormat::RESET."\"_v".TextFormat::AQUA.$info["version"].TextFormat::RESET." by ".TextFormat::AQUA.$info["author"].TextFormat::RESET);
            if(
    $info["class"] !== "none" and $info["class"] !== null and class_exists($info["class"])) {
                
    $this->getLogger()->debug("Failed loading generator: class already exists");
                return 
    false;
            }

            
    $className $info["class"];
            
    $apiversion array_map("intval"explode(","$info["version"]));
            if(!
    in_array(self::GENERATOR_API$apiversion)) {
                
    $this->getLogger()->debug("Generator \"".$info["name"]."\" may be outdated!");
            }

            if(
    $info["class"] !== "none" or $info["class"] !== null) {
                
    $object = new $className([]);
                if(!(
    $object instanceof GeneratorTemplate)) {
                    
    $this->getLogger()->debug("Generator \"".$info["class"]."\" doesn't use the Generator Template");
                    if(
    method_exists($object"__destruct")) {
                        
    $object->__destruct();
                    }
                    
    $object null;
                    unset(
    $object);
                }else{
                    
    $this->generators[] = array($object$info);
                }
            }
            return 
    true;
        }
    Is this good for a start?
     
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.