minecraftpockete...吧 关注:1,312贴子:11,125
  • 8回复贴,共1

[ PM学习辅助 ] SimpleAuth 完全注释

只看楼主收藏回复

有些长...分段来...
001 <?php
002
003 /*
004 __PocketMine Plugin__
005 name=SimpleAuth
006 description=Prevents people to impersonate an account, requering registration and login when connecting.
007 version=0.1
008 author=shoghicp
009 class=SimpleAuth
010 apiversion=9
011 */
012
013 class SimpleAuth implements Plugin{
014 private $api, $server, $config, $sessions, $lastBroadcast = 0;
015 public function __construct(ServerAPI $api, $server = false){
016 $this->api = $api;
017 $this->server = ServerAPI::request();
018 $this->sessions = array();
019 SimpleAuthAPI::set($this);
020 }
021
022 public function init(){
023 $this->config = new Config($this->api->plugin->configPath($this)."config.yml", CONFIG_YAML, array(
024 "allowChat" => false,
025 "messageInterval" => 5,
026 "timeout" => 60,
027 "allowRegister" => true,
028 "forceSingleSession" => true,
029 ));//建立配置文件
030 $this->playerFile = new Config($this->api->plugin->configPath($this)."players.yml", CONFIG_YAML, array());
031
032 $this->api->addHandler("player.quit", array($this,"eventHandler"), 50);//增加对player.quit(玩家退出)的事件监视
033 $this->api->addHandler("player.connect", array($this,"eventHandler"), 50);///增加对player.connect(玩家连接)的事件监视
034 $this->api->addHandler("player.spawn", array($this,"eventHandler"), 50);//增加对player.spawn(玩家出生)的事件监视
035 $this->api->addHandler("player.respawn", array($this,"eventHandler"), 50);//增加对player.respawn(玩家重生)的事件监视
036 $this->api->addHandler("player.chat", array($this,"eventHandler"), 50);//增加对player.chat(聊天)的事件监视
037 $this->api->addHandler("console.command", array($this,"eventHandler"), 50);//增加console.command(控制台命令)的事件监视
038 $this->api->addHandler("op.check", array($this,"eventHandler"), 50);//增加对op.check(OP权限检查)的调用
039 $this->api->schedule(20, array($this, "checkTimer"), array(), true);//增加计时器调用
040 $this->api->console->register("unregister", "<password>",array($this, "commandHandler"));//注册unregister命令
041 $this->api->ban->cmdWhitelist("unregister");//将unregister命令加入可使用命令的列表
042 console("[INFO] SimpleAuth enabled!");//输出正常启动提示
043 }
044
045 public function commandHandler($cmd, $params, $issuer, $alias){//检测命令
046 $output = "";//意义不明
047 switch($cmd){//以cmd变量为开关
048 case "unregister"://当使用unregister时
049 if(!($issuer instanceof Player)){//若不是从玩家中执行
050 $output .= "Please run this command inside the game.\n";//输出请在游戏中运行此命令
051 break;//中断,学过编程应该知道,Switch语句会继续执行其他的case
052 }
053 if($this->sessions[$issuer->CID] !== true){//若会话不为真,即未登陆
054 $output .= "Please login first.\n";//输出请先登陆
055 break;//中断,学过编程应该知道,Switch语句会继续执行其他的case
056 }
057 $d = $this->playerFile->get($issuer->iusername);//检测是否有执行命令者的玩家数据,返回布尔值,即True或其他
058 if($d !== false and $d["hash"] === $this->hash($issuer->iusername, implode(" ", $params))){//如果存在用户数据,且hash值相同(即密码正确)
059 $this->playerFile->remove($issuer->iusername);//移出该玩家玩家数据
060 $this->logout($issuer);//注销用户
061 $output .= "[SimpleAuth] Unregistered correctly.\n";//输出成功信息
062 }else{//若不符合"如果存在用户数据,且hash值相同"
063 $output .= "[SimpleAuth] Error during authentication.\n";//输出失败信息
064 }
065 break;//中断,学过编程应该知道,Switch语句会继续执行其他的case
066 }
067 return $output;//返回输出值给执行者
068 }
069
070 public function checkTimer(){
071 if($this->config->get("allowRegister") !== false and ($this->lastBroadcast + $this->config->get("messageInterval")) <= time()){//配置文件中允许注册不为假且未登陆超时
072 $broadcast = true;//设置发送广播为真(即发送)
073 $this->lastBroadcast = time();//把当前时间置于最后一次广播(lastBroadcast)这个变量之中
074 }else{
075 $broadcast = false;//若不符合"配置文件中允许注册不为假且未登陆超时",设置发送广播为假(即不发送)
076 }
077
078 if(($timeout = $this->config->get("timeout")) <= 0){//若配置文件中超时的设置小于等于0
079 $timeout = false;//设置永不登陆超时
080 }
081
082 foreach($this->sessions as $CID => $timer){//将会话定义为用户CID
083 if($timer !== true and $timer !== false){//Timer既不真也不假时
084 if($broadcast === true){//广播为真时
085 $d = $this->playerFile->get($this->server->clients[$CID]->iusername);//判断是否有用户文件,一布尔值方式放于d
086 if($d === false){//没有用户文件
087 $this->server->clients[$CID]->sendChat("[SimpleAuth] You must register using /register <password>");//输出请注册
088 }else{//有用户文件
089 $this->server->clients[$CID]->sendChat("[SimpleAuth] You must authenticate using /login <password>");//输出请登陆
090 }
091 }
092 if($timeout !== false and ($timer + $timeout) <= time()){//判断超时
093 $this->server->clients[$CID]->close("authentication timeout");//关闭连接(踢出),原因为验证超时
094 }
095 }
096 }
097
098 }
099
100 private function hash($salt, $password){//加密函数


1楼2013-07-24 23:29回复
    101 return Utils::strToHex(hash("sha512", $password . $salt, true) ^ hash("whirlpool", $salt . $password, true));//返回加密后的值
    102 }
    103
    104 public function checkLogin(Player $player, $password){//登陆验证函数
    105 $d = $this->playerFile->get($player->iusername);//判断是否有用户文件,一布尔值方式放于d
    106 if($d !== false and $d["hash"] === $this->hash($player->iusername, $password)){//当d为真且hash值匹配时
    107 return true;//返回真(既验证成功),注:编程党应该知道retuen将会退出当前函数
    108 }
    109 return false;//返回假(既验证失败)
    110 }
    111
    112 public function login(Player $player){//登陆函数
    113 $d = $this->playerFile->get($player->iusername);//判断是否有用户文件,以布尔值方式放于d
    114 if($d !== false){//若d不为假
    115 $d["logindate"] = time();//更新数组d的用户登陆时间
    116 $this->playerFile->set($player->iusername, $d);//设置玩家数据为数组d
    117 $this->playerFile->save();//保存玩家文件
    118 }
    119 $this->sessions[$player->CID] = true;//会话设置为真.此时玩家在游戏中的操作将变得有效.
    120 $player->blocked = false;//不再固定玩家
    121 $player->sendChat("[SimpleAuth] You've been authenticated.");//输出成功信息
    122 return true;//返回真,退出函数
    123 }
    124
    125 public function logout(Player $player){//注销函数
    126 $this->sessions[$player->CID] = time();//会话设置为假.此时玩家在游戏中的操作将变得无效.
    127 $player->blocked = true;//固定玩家
    128 }
    129
    130 public function register(Player $player, $password){//注册函数
    131 $d = $this->playerFile->get($player->iusername);//判断是否有用户文件,一布尔值方式放于d
    132 if($d === false){//若未注册
    133 $data = array(
    134 "registerdate" => time(),//设置data数组注册时间(registerdate)值为当前时间
    135 "logindate" => time(),,//设置data数组登陆时间(logindate)值为当前时间
    136 "hash" => $this->hash($player->iusername,$password),//调用加密函数,加密密码
    137 );
    138 $this->playerFile->set($player->iusername, $data);//设置玩家数据文件
    139 $this->playerFile->save();//保存玩家数据文件
    140 return true;//返回真,退出函数
    141 }
    142 return false;//若未退出函数(即没有通过"若未注册"条件),返回假,退出函数
    143 }
    144
    145 public function eventHandler($data, $event){//事件监视
    146 switch($event){
    147 case "player.quit"://玩家退出
    148 unset($this->sessions[$data->CID]);//终止该会话,即注销
    149 break;//中断,学过编程应该知道,Switch语句会继续执行其他的case
    150 case "player.connect"://玩家加入


    2楼2013-07-24 23:31
    回复
      201 case "player.respawn"://玩家重生
      202 if($this->sessions[$data->CID] !== true){//若未登陆
      203 $data->blocked = true;//固定玩家
      204 }
      205 break;//中断,学过编程应该知道,Switch语句会继续执行其他的case
      206 }
      207 }
      208
      209 public function __destruct(){//停止运行时执行
      210 $this->config->save();//保存配置
      211 $this->playerFile->save();//保存玩具数据
      212 }
      213
      214 }
      215
      216 class SimpleAuthAPI{//SimepleAuth的接口,别的插件可以调用
      217 private static $object;
      218 public static function set(SimpleAuth $plugin){
      219 if(SimpleAuthAPI::$object instanceof SimpleAuth){
      220 return false;
      221 }
      222 SimpleAuthAPI::$object = $plugin;
      223 }
      224
      225 public static function get(){
      226 return SimpleAuthAPI::$object;
      227 }
      228
      229 public static function login(Player $player){
      230 return SimpleAuthAPI::$object->login($player);
      231 }
      232
      233 public static function logout(Player $player){
      234 return SimpleAuthAPI::$object->logout($player);
      235 }
      236 }


      4楼2013-07-24 23:32
      回复
        嗯...居然毫无阻拦的发完了w


        5楼2013-07-24 23:32
        回复
          PE吧就不行∑(っ °Д °;)っ


          6楼2013-07-24 23:36
          回复
            来自http://nat.dynet.com:1000/
            经常挂 勿在意


            7楼2013-07-24 23:37
            回复
              好厉害→_→


              IP属地:云南来自Android客户端8楼2013-07-24 23:54
              回复
                @Mineswo 我是智商捉鸡了,你懂这个……


                IP属地:江苏来自Android客户端9楼2013-07-24 23:54
                回复
                  吓得我先给你个精了……←_←


                  IP属地:江苏来自Android客户端10楼2013-07-24 23:55
                  回复