Advertisement
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

[New API] Help with saving player scores

Comments in 'Plugin Development' started by The_Marcster, Aug 31, 2014.

  1. The_Marcster
    Offline

    The_Marcster New Member

    Joined:
    Aug 31, 2014
    Posts:
    3
    Minecraft User:
    The_Marcster_PE
    I just started programming with PocketMine and want to develop a plugin. The plugin should be able to save values for every player, like scoreboards in MCPC, where you have different objectives and every player has a score in every objective. It would be nice, if anybody could write me some example code of how to save multiple scores for every player. I've seen, that you can use config files, but because I haven't found any good tutorial for the new API, so maybe someone can explain that.
    Thanks in advance :)
  2. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    If you want to save simple key-value sets (player name converted to lowercase as key, score as value), there are three methods.
    1. Using the config class. Create a Config object with
    PHP:
    $this->scores = new Config($this->getDataFolder()."scores.yml");
    . Every time you want to read from the file,
    PHP:
    $this->scores->get(strtolower($playerName))
    should return the data you save in the config about the player. If the player doesn't have data in the config, this function call should return false. If you want to insert/replace a player's score into the config, you use
    PHP:
    $this->scores->set(strtolower($playerName), $score);
    . However, the score is only saved in temporary memory. If you want to save the data after the server restarts, you should do $this->scores->save();. Nevertheless, this type of database is laggy for servers with many registered usernames, so for big servers, every call of $this->scores->save() should be slow, so you should not call it every time player data are modified. Best is you schedule it to be called periodically.
    $score can be a number or a string, or an array if you want to save multiple values. But keep in mind that whatever you have for $score, you normally get the same value back from the get() method.

    2. Create one file per player to read data efficiently. Since files are indexed by the OS, you can create one config file for each player. I'm not going to give examples here.

    3. Use an SQLite3 database. This is the best method if you know how to, since the first method lags with I/O and the second method creates a lot of files, which could make users dislike it. To use it, initialize an SQLite3 database when your plugin is enabled (for the first line) and initialize the table in the database if it doesn't exist (second line):
    PHP:
    $this->db = new \SQLite3($this->getDataFolder());
    $this->db->exec("CREATE TABLE IF NOT EXISTS players (player TEXT COLLATE NOCASE PRIMARY KEY, score1 INTEGER DEFAULT 0, score2 INTEGER DEFAULT 0, some_text_you_want_to_save TEXT DEFAULT '', score3_which_can_be_decimal REAL DEFAULT 0);");
    COLLATE NOCASE makes the player names case-insensitive.
    Remember to close it when your plugin is disabled:
    PHP:
    $this->db->close();
    To read score1 from the database, given the player name $name:
    PHP:
    $query $this->db->prepare("SELECT score1 FROM players WHERE player = :name;");
    $query->bindValue(":name"$name);
    $result $query->execute();
    $array $result->fetchArray(SQLITE3_ASSOC);
    if(
    is_array($array)){
        
    $score1 $array["score1"];
        
    // the player is found in the database, and $score1 stores his score 1. Do something with it now.
    }
    else{
        
    // do something. The player is not found in the database.
    }
    To insert data into the table, do this:
    PHP:
    $query $this->db->prepare("INSERT INTO players (player, score1) VALUES (:name, :score);");
    $query->bindValue(":name"$name);
    $query->bindValue(":score"$score);
    $query->execute();
    There is in fact a fourth method: MySQL database too, but the 9 alerts I haven't read are rushing me, and I'm not going to explain it here. You can find examples at SimpleAuth, although it is not easy for new developers to learn with.

    Hope this post helps everyone! If I have anything wrong with the SQLite3 database, you're welcome to point it out. I'm, in fact, not very sure about those primary key things.
    Lambo, iJoshuaHD, Falk and 1 other person like this.
  3. The_Marcster
    Offline

    The_Marcster New Member

    Joined:
    Aug 31, 2014
    Posts:
    3
    Minecraft User:
    The_Marcster_PE
    Thanks for the answer! I think I will go with the first method because I hardly have any experience with database in PHP. I have just one more question:
    How do I load the config file, if I restart the server? Does

    $this->scores = new Config($this->getDataFolder()."scores.yml");

    create a new file or is it just loading it if it's already existent?
  4. Lambo
    Offline

    Lambo Notable Member Plugin Developer

    Joined:
    Sep 14, 2013
    Posts:
    431
    Plugins:
    4
    Minecraft User:
    Lambo
    That should create a config and return the Config object
  5. iJoshuaHD
    Offline

    iJoshuaHD Notable Member Plugin Developer

    Joined:
    Nov 7, 2013
    Posts:
    1,167
    Plugins:
    4
    Minecraft User:
    iJoshuaHD
    it loads the existed scores.yml.
  6. The_Marcster
    Offline

    The_Marcster New Member

    Joined:
    Aug 31, 2014
    Posts:
    3
    Minecraft User:
    The_Marcster_PE
    Thanks to both of you!
  7. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    If the file exists, it reads the file. If it doesn't exist, it creates a file that contains no data and pretends to read the file.

    I'm going to create a thread, when I have time, in the Resources forum to compare different database types.
    The_Marcster and Falk like this.

Share This Page

Advertisement