<?php
/*
 * tngp/docs/admin.php
 *
 * Copyright (C) 2022 bzt
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * @brief Example class to integrate the TirNanoG Server into your website
 *
 */

namespace TirNanoG {

class Admin {
    /* configure where the TirNanoG Server is running */
    public static $host = "localhost";
    public static $port = 4433;
    /* configure the desired date time format */
    public static $dateformat = \DateTime::ISO8601;

    /**
     * Get Server Status
     */
    public static function Status()
    {
        $ret = self::call("status");
        if(!empty($ret) && !empty($ret->now)) {
            $d = new \DateTime();
            $d->setTimestamp($ret->now);
            $ret->now = $d->format(self::$dateformat);
            if(!empty($ret->saved)) {
                $d->setTimestamp($ret->saved);
                $ret->saved = $d->format(self::$dateformat);
            } else
                $ret->saved = "";
        }
        return $ret;
    }

    /**
     * Get World File Details
     */
    public static function TNG()
    {
        return self::call("tng");
    }

    /**
     * Synchronize to Storage (Save Game)
     */
    public static function Sync()
    {
        return self::call("sync");
    }

    /**
     * Enable / Disable Public User Registration
     */
    public static function Registration($enabled)
    {
        return self::call($enabled ? "regon" : "regoff");
    }

    /**
     * Get List of Registered Users
     */
    public static function Users()
    {
        return self::call("users");
    }

    /**
     * Add User (can register and create a character if public registration is turned off)
     */
    public static function Add($username)
    {
        if(empty($username)) return (object)[ "ret"=> false ];
        return self::call("add", $username);
    }

    /**
     * Authenticate User
     * Also returns the language code that the user last used with the TirNanoG client
     */
    public static function Authenticate($username, $password)
    {
        if(empty($username) || empty($password)) return (object)[ "ret"=> false ];
        return self::call("auth", $username, $password);
    }

    /**
     * Set Password
     */
    public static function SetPassword($username, $password)
    {
        if(empty($username) || empty($password)) return (object)[ "ret"=> false ];
        return self::call("pass", $username, $password);
    }

    /**
     * Change the User's Password
     */
    public static function ChangePassword($username, $oldpass, $newpass1, $newpass2)
    {
        if(empty($username) || empty($oldpass) || empty($newpass1) || empty($newpass2)) return (object)[ "ret"=> false ];
        if($newpass1 != $newpass2) return (object)[ "ret"=> false, "msg"=> "New password and confirmation does not match." ];
        $ret = self::call("auth", $username, $oldpass);
        if(@$ret->ret != true) return (object)[ "ret"=> false, "msg"=> "Bad old password." ];
        return self::call("pass", $username, $newpass1);
    }

    /**
     * Forcefully Logout User from the Game
     */
    public static function Kick($username)
    {
        if(empty($username)) return (object)[ "ret"=> false ];
        return self::call("kick", $username);
    }

    /**
     * Ban User
     */
    public static function Ban($username)
    {
        if(empty($username)) return (object)[ "ret"=> false ];
        return self::call("ban", $username);
    }

    /**
     * Unban User
     */
    public static function Unban($username)
    {
        if(empty($username)) return (object)[ "ret"=> false ];
        return self::call("unban", $username);
    }

    /**
     * Get List of Denied IP Addresses
     */
    public static function DeniedIPList()
    {
        return self::call("denied");
    }

    /**
     * Add to Denied List
     */
    public static function Deny($username)
    {
        if(empty($username)) return (object)[ "ret"=> false ];
        return self::call("deny", $username);
    }

    /**
     * Remove from Denied List (by user name)
     */
    public static function Allow($username)
    {
        if(empty($username)) return (object)[ "ret"=> false ];
        return self::call("allow", $username);
    }

    /**
     * Remove from Denied List (by IP address)
     */
    public static function AllowIP($ip)
    {
        if(empty($ip)) return (object)[ "ret"=> false ];
        return self::call("allowip", $ip);
    }

    /**
     * Get User's Status
     */
    public static function UserStatus($username)
    {
        if(empty($username)) return (object)[ "ret"=> false ];
        $ret = self::call("user", $username);
        if(!empty($ret) && !empty($ret->created)) {
            $d = new \DateTime();
            $d->setTimestamp($ret->created);
            $ret->created = $d->format(self::$dateformat);
            $d->setTimestamp($ret->logind);
            $ret->logind = $d->format(self::$dateformat);
            if(!empty($ret->logoutd)) {
                $d->setTimestamp($ret->logoutd);
                $ret->logoutd = $d->format(self::$dateformat);
            } else
                $ret->logoutd = "";
        }
        return $ret;
    }

    /**
     * Set User's Attribute
     */
    public static function SetAttribute($username, $attribute, $value)
    {
        if(empty($username) || empty($attribute)) return (object)[ "ret"=> false ];
        return self::call("set", $username, $attribute, $value);
    }

    /**
     * Get User's Inventory
     */
    public static function Inventory($username)
    {
        if(empty($username)) return array();
        return self::call("inv", $username);
    }

    /**
     * Get User's Skills
     */
    public static function Skills($username)
    {
        if(empty($username)) return array();
        return self::call("skills", $username);
    }

    /**
     * Get User's Quests
     */
    public static function Quests($username)
    {
        if(empty($username)) return array();
        return self::call("quests", $username);
    }

    /**
     * Add Item to User
     */
    public static function Give($username, $qty, $object)
    {
        if(empty($username) || empty($qty) || empty($object)) return (object)[ "ret"=> false ];
        return self::call("give", $username, $qty, $object);
    }

    /**
     * Take Item from User
     */
    public static function Take($username, $qty, $object)
    {
        if(empty($username) || empty($qty) || empty($object)) return (object)[ "ret"=> false ];
        return self::call("take", $username, $qty, $object);
    }

    /* internal function to make the actual call to the server */
    private static function call($func, $u = "", $q = "", $o = "")
    {
        switch($func) {
            case "add": case "kick": case "ban": case "unban": case "deny": case "allow": case "allowip": case "user": case "inv": $url = $func."?u=".urlencode($u); break;
            case "auth": case "pass": $url = $func."?u=".urlencode($u)."&p=".urlencode($q); break;
            case "set": $url = $func."?u=".urlencode($u)."&".urlencode($q)."=".urlencode($o); break;
            case "give": case "take": $url = $func."?u=".urlencode($u)."&q=".urlencode($q)."&o=".urlencode($o); break;
            default: $url = $func; break;
        }
        $ch = curl_init();
        $ipv6 = strpos(self::$host, ":") !== false;
        curl_setopt($ch, CURLOPT_URL, "https://".($ipv6 ? "[" : "").self::$host.($ipv6 ? "]" : "").":".self::$port."/".$url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $d = curl_exec($ch);
        curl_close($ch);
        return empty($d) ? (object)[ "ret"=> false, "msg"=> "connection error" ] : json_decode($d);
    }
}

/* just a quick test, remove this */
//print_r(\TirNanoG\Admin::Status());
//print_r(\TirNanoG\Admin::TNG());
//print_r(\TirNanoG\Admin::Sync());
print_r(\TirNanoG\Admin::Users());
print_r(\TirNanoG\Admin::UserStatus("valaki"));
}
