<?php

class player {
	private $mod;
	private $rcon;
	private $players;
	private $logging;
	private $guid;
	private $pid;
	private $name;
	private $customvars = array();
	private $lastkiller = false;
	private $lastvictim = false;
	private $team = "none";
	public $joined = 0;
	public $lastweaponkill = false;
	public $lastweapondeath = false;
	public $kills = 0;
	public $deaths = 0;
	public $teamkills = 0;
	public $teamdeaths = 0;
	public $selfkills = 0;
	public $headshots = 0;
	public $lastdeathwastk = false;
	public $lastkillwastk = false;
	public $lastCommand = 0;
	public $damagegiven = 0;
	public $teamdamagegiven = 0;
	public $damagetaken = 0;
	public $vehicledamagegiven = 0;
	public $teamvehicledamagegiven = 0;
	public $actorsdamagegiven = 0;
	public $teamactorsdamagegiven = 0;

	public function __construct($guid, $pid, $name) {
		$this->mod = & $GLOBALS['mod'];
		$this->rcon = & $GLOBALS['rcon'];
		$this->logging = & $GLOBALS['logging'];
		$this->players = & $GLOBALS['players'];
		$this->guid = $guid;
		$this->pid = $pid;
		$this->name = $name;
		$this->joined = time();
	}

	public function __destruct() {}

	public function __set($name, $value) {

	    //Abw�rtskompatiblit�t
	    if ($name == "team") {
	        $this->setTeam($value);
	    }

		$this->customvars[$name] = $value;
	}

	public function __get($name) {

	    //Abw�rtskompatiblit�t
	    if ($name == "team") {
	        return $this->getTeam();
	    }

		return $this->customvars[$name];
	}

	public function __isset($name) {
		return array_key_exists($name, $this->customvars);
	}

	public function __unset($name) {
		unset($this->customvars[$name]);
	}

	public function dumpUser() {
		$return = $this->rcon->rcon("dumpuser \"$this->name\"");
		if (preg_match('|^Player .+ is not on the server\s?$|', $return)) return false;
		$return = explode("\n", $return);
		$info = array();
		foreach ($return as $value) {
			if (preg_match('|^([a-z0-9_]+)\s+(.*)$|i', $value, $subpatterns)) {
				$info[$subpatterns[1]] = $subpatterns[2];
			}
		}
		return $info;
	}

	public function say($msg) {
	    $msg = str_replace("{{br}}", "\n", $msg);
	    $msg = wordwrap($msg, 140 - strlen($this->mod->getCV("main", "pmprefix")), "\n", true);
	    $split = explode("\n", $msg);
	    foreach ($split as $value) {
	       $value = $this->mod->getCV("main", "pmprefix") . $value;
		   $this->rcon->rcon("tell $this->pid $value");
	    }
	}

	public function update($pid, $name = false) {
		if ($name != false && $name != $this->name) {
			$this->logging->write(MOD_NOTICE, "Player '$this->name' changed name to '$name', PID: $this->pid, GUID: $this->guid");
			$oldname = $this->name;
			$this->name = $name;
			$this->mod->triggerEvent("playerNameChange", array($this->guid, $oldname, $name));
		}
		if ($pid != $this->pid) {
			$this->logging->write(MOD_NOTICE, "Player '$this->name's PID was changed from $this->pid to $pid, GUID: $this->guid");
			$oldpid = $this->pid;
			$this->pid = $pid;
			$this->mod->triggerEvent("playerPIDChange", array($this->guid, $oldpid, $pid));
		}
	}

	public function getGroup() {
		$admin = $this->mod->getAdminByGuid($this->guid);
		if (!$admin) return "default";
		return $admin["group"];
	}

	public function getName() {
		return $this->name;
	}

	public function getPID() {
		return $this->pid;
	}

	public function getGuid() {
		return $this->guid;
	}

	public function setTeam($team) {
        if ($team != $this->team) {
            $oldteam = $this->team;
            $this->team = $team;
            $this->mod->triggerEvent("playerTeamChange", array($this->guid, $oldteam));
        }
	}

	public function getTeam() {
	    return $this->team;
	}

	public function isAllowedToExec($command) {
		return in_array($command, $this->mod->getGroupCommands($this->getGroup()));
	}

	public function resetTeam() {
		$this->team = "none";
	}

	public function kick($reason = false, $kicker = false) {
		if (!$reason) {
			$reason = $this->mod->getCV("kickban", "defaultkickreason");
		}

		if ($this->mod->getCV("kickban", "usepb")) {
			/*$dump = $this->dumpUser();
			if (!$dump) {
				$this->logging->write(MOD_WARNING, "Couldn't dump user '".$this->name."', can't kick him with pb_sv_kick, using clientkick, PID: ".$this->pid.", GUID:".$this->guid);
				$this->rcon->rcon("clientkick " . $this->pid);
			}*/
			$result = $this->rcon->rcon("pb_sv_kick ".$this->getPbid()." 0 $reason^7");
			// ^3PunkBuster Server: Matched: ^1FN^0! ^2manu (slot #1)
            // 0:^1FN^0! ^2manu PunkBuster kicked player '^1FN^0! ^2manu' (for 0 minutes) ... Kicked by Admin [Admin Decision]
            // ^3PunkBuster Server: Kick Command Issued (Kicked by Admin [Admin Decision]) for (slot#1) 192.168.2.21:28960 c90dc162f630049cec0cb632e5e0aa50 ^1FN^0! ^2manu
            if (stripos($result, "Kick Command Issued") === false) {
                $this->logging->write(MOD_WARNING, "Error kicking player '".$this->name."' with pb_sv_kick, using clientkick, PID: ".$this->pid.", GUID:".$this->guid);
                $this->rcon->rcon("clientkick " . $this->pid);
            }


		}
		else {
	        $this->say($this->mod->getLngString("playerKickReasonNoPb", array("<REASON>"), array($reason)));
	        $this->say($this->mod->getLngString("playerKickReasonNoPb", array("<REASON>"), array($reason)));

		    sleep(1);

			$this->rcon->rcon("clientkick " . $this->pid);
		}

		$kickerlog = ($kicker !== false) ? $this->players[$kicker]->getName() : "MOD";
		$this->logging->write(MOD_NOTICE, "Player '$this->name' got kicked (by: $kickerlog), reason: $reason, PID: $this->pid, GUID: $this->guid");


	    if ($this->mod->getCV("kickban", "announce")) {
	        if ($kicker !== false) {
    	        $search = array("<PLAYER>", "<KICKER>", "<REASON>");
    	        $replace = array($this->getName(), $this->players[$kicker]->getName(), $reason ? $reason : $this->mod->getCV("kickban", "defaultkickreason"));
    	        $this->mod->rconSay($this->mod->getLngString("playerKickedPublicMsg", $search, $replace));
	        }
	        else {
    	        $search = array("<PLAYER>", "<REASON>");
    	        $replace = array($this->getName(), $reason ? $reason : $this->mod->getCV("kickban", "defaultkickreason"));
    	        $this->mod->rconSay($this->mod->getLngString("playerKickedPublicMsgAuto", $search, $replace));
	        }
	    }

		$this->mod->triggerEvent("playerKicked", array($this->guid, $reason, $kicker));

		return true;
	}

	public function ban($reason = false, $kicker = false) {
		if (!$reason) {
			$reason = $this->mod->getCV("kickban", "defaultbanreason");
		}
		if ($this->mod->getCV("kickban", "usepb")) {
			/*$dump = $this->dumpUser();
			if (!$dump) {
				$this->logging->write(MOD_WARNING, "Couldn't dump user '".$this->name."', can't ban him with pb_sv_ban, using banclient, PID: ".$this->pid.", GUID:".$this->guid);
				$this->rcon->rcon("banClient " . $this->pid);
			}*/
			$result = $this->rcon->rcon("pb_sv_ban ".$this->getPbid()." $reason^7");
			if (stripos($result, "Kick/Ban Command Issued") === false) {
                $this->logging->write(MOD_WARNING, "Error kicking player '".$this->name."' with pb_sv_kick, using clientkick, PID: ".$this->pid.", GUID:".$this->guid);
                $this->rcon->rcon("banClient " . $this->pid);
            }
		}
	   else {
	        $this->say($this->mod->getLngString("playerBanReasonNoPb", array("<REASON>"), array($reason)));
	        $this->say($this->mod->getLngString("playerBanReasonNoPb", array("<REASON>"), array($reason)));

		    sleep(1);

			$this->rcon->rcon("banClient " . $this->pid);
		}

        $kickerlog = ($kicker !== false) ? $this->players[$kicker]->getName() : "MOD";
		$this->logging->write(MOD_NOTICE, "Player '$this->name' got banned (by: $kickerlog), reason: $reason, PID: $this->pid, GUID: $this->guid");

	    if ($this->mod->getCV("kickban", "announce")) {
	        if ($kicker !== false) {
    	        $search = array("<PLAYER>", "<KICKER>", "<REASON>");
    	        $replace = array($this->getName(), $this->players[$kicker]->getName(), $reason ? $reason : $this->mod->getCV("kickban", "defaultbanreason"));
    	        $this->mod->rconSay($this->mod->getLngString("playerBannedPublicMsg", $search, $replace));
	        }
	        else {
    	        $search = array("<PLAYER>", "<REASON>");
    	        $replace = array($this->getName(), $reason ? $reason : $this->mod->getCV("kickban", "defaultbanreason"));
    	        $this->mod->rconSay($this->mod->getLngString("playerBannedPublicMsgAuto", $search, $replace));
	        }
	    }

		$this->mod->triggerEvent("playerBanned", array($this->guid, $reason, $kicker));

		return true;
	}

	public function tempBan($reason = false, $time = false, $kicker = false) {
		if (!$reason) {
			$reason = $this->mod->getCV("kickban", "defaultbanreason");
		}
		if ($this->mod->getCV("kickban", "usepb")) {
			if (!$time || !is_numeric($time) || $time < 0) {
			    $time = $this->mod->getCV("kickban", "pbtempbanduration");
			}
			else {
			    $time = (int)$time;
			}
			$result = $this->rcon->rcon("pb_sv_kick ".$this->getPbid()." $time $reason^7");
			if (stripos($result, "Kick Command Issued") === false) {
                $this->logging->write(MOD_WARNING, "Error kicking player '".$this->name."' with pb_sv_kick, using clientkick, PID: ".$this->pid.", GUID:".$this->guid);
                $this->rcon->rcon("tempBanClient " . $this->pid);
            }
		}
		else {
	        $this->say($this->mod->getLngString("playerBanReasonNoPb", array("<REASON>"), array($reason)));
	        $this->say($this->mod->getLngString("playerBanReasonNoPb", array("<REASON>"), array($reason)));

		    sleep(1);

			$this->rcon->rcon("tempBanClient " . $this->pid);
		}

        $kickerlog = ($kicker !== false) ? $this->players[$kicker]->getName() : "MOD";
		$this->logging->write(MOD_NOTICE, "Player '$this->name' got temporarily banned for $time minutes (by: $kickerlog), reason: $reason, PID: $this->pid, GUID: $this->guid");

		if ($this->mod->getCV("kickban", "announce")) {
	        if ($kicker !== false) {
			        $search = array("<PLAYER>", "<KICKER>", "<REASON>", "<TIME>");
			        $replace = array($this->getName(), $this->players[$kicker]->getName(), $reason ? $reason : $this->mod->getCV("kickban", "defaultbanreason"), ($time) ? $time : $this->mod->getCV("kickban", "pbtempbanduration"));
			        $this->mod->rconSay($this->mod->getLngString("playerTempBannedPublicMsg", $search, $replace));
	        }
	        else {
    	        $search = array("<PLAYER>", "<REASON>", "<TIME>");
    	        $replace = array($this->getName(), $reason ? $reason : $this->mod->getCV("kickban", "defaultbanreason"), ($time) ? $time : $this->mod->getCV("kickban", "pbtempbanduration"));
    	        $this->mod->rconSay($this->mod->getLngString("playerTempBannedPublicMsgAuto", $search, $replace));
	        }
	    }

		$this->mod->triggerEvent("playerTempBanned", array($this->guid, $reason, $time ? $time : $this->mod->getCV("kickban", "pbtempbanduration"), $kicker));

		return true;
	}

	public function isProtected() {
        $admin = $this->mod->getAdminByGuid($this->guid);
		if (!$admin) return false;
		return (bool) $admin["protected"];
	}

	public function getAllowedCommands() {
	    return $this->mod->getGroupCommands($this->getGroup());
	}

	public function setProtection($bool) {
	    $bool = (bool)$bool;
	    if ($this->isProtected() && $bool) {
	        return true;
	    }
	    if (!$this->isProtected() && !$bool) {
	        return true;
	    }
	    return $this->mod->updateAdmin($this->guid, array("protected" => (int)$bool));

	}

	public function getLastVictim() {
	    if (!$this->lastvictim || !array_key_exists($this->lastvictim, $this->players)) {
	        return false;
	    }
	    return $this->lastvictim;
	}

	public function getLastKiller() {
	    if (!$this->lastkiller || !array_key_exists($this->lastkiller, $this->players)) {
	        return false;
	    }
	    return $this->lastkiller;
	}

	public function setGroup($group) {
	    if ($group == $this->getGroup()) {
	        return true;
	    }
	    if ($group == "default" && $this->getGroup() != "default") {
	        $this->mod->deleteAdmin($this->guid);
	    }
	    elseif ($group != "default" && $this->getGroup() == "default") {
	        $this->mod->addAdmin($this->guid, $group, $this->name, false);
	    }
	    else {
	        $this->mod->updateAdmin($this->guid, array("group"=>$group));
	    }
	}

	public function death($type, $killer, $weapon, $damage, $bodypart) {
	    $this->lastkiller = $killer;
	    $this->lastweapondeath = $weapon;
	    $this->deaths ++;
	    $this->damagetaken += $damage;
        $this->lastdeathwastk = false;

	    if ($type == "teamkill") {
            $this->teamdeaths ++;
            $this->lastdeathwastk = true;
            $this->mod->triggerEvent("playerTeamDeath", array($this->guid, $killer, $weapon, $damage, $bodypart));
	    }
	    elseif ($type == "selfkill") {
	        $this->selfkills ++;
	        $this->lastkiller = $this->guid;
	        $this->lastvictim = $this->guid;
	        $this->lastweaponkill = $weapon;
            $this->lastkillwastk = false;
            $this->mod->triggerEvent("playerSelfKill", array($this->guid, $weapon, $damage, $bodypart));
	    }
	    else {
            $this->mod->triggerEvent("playerDeath", array($this->guid, $killer, $weapon, $damage, $bodypart));
	    }
	}

	public function kill($type, $victim, $weapon, $damage, $bodypart) {
	    $this->lastvictim = $victim;
	    $this->lastweaponkill = $weapon;
        $this->lastkillwastk = false;

	    if ($type == "kill") {
            $this->kills ++;
            $this->damagegiven += $damage;
            if ($weapon[1] == "MOD_HEAD_SHOT") {
                $this->headshots ++;
            }
            $this->mod->triggerEvent("playerKill", array($this->guid, $victim, $weapon, $damage, $bodypart));
	    }
	    elseif ($type == "teamkill") {
            $this->teamdamagegiven += $damage;
	        $this->teamkills ++;
            $this->lastkillwastk = true;
            $this->mod->triggerEvent("playerTeamKill", array($this->guid, $victim, $weapon, $damage, $bodypart));

	    }
	}

	public function damageTaken($type, $attacker, $weapon, $damage, $bodypart) {
        $this->damagetaken += $damage;
	    if ($type == "teamdamage") {
            $this->mod->triggerEvent("playerTeamDamageTaken", array($this->guid, $attacker, $weapon, $damage, $bodypart));
	    }
	    elseif ($type == "damage") {
            $this->mod->triggerEvent("playerDamageTaken", array($this->guid, $attacker, $weapon, $damage, $bodypart));
	    }
	    elseif ($type == "selfdamage") {
            $this->mod->triggerEvent("playerSelfDamage", array($this->guid, $weapon, $damage, $bodypart));
	    }
	}

	public function damageGiven($type, $victim, $weapon, $damage, $bodypart) {
	    if ($type == "teamdamage") {
            $this->teamdamagegiven += $damage;
            $this->mod->triggerEvent("playerTeamDamageGiven", array($this->guid, $victim, $weapon, $damage, $bodypart));
	    }
	    elseif ($type == "damage") {
            $this->damagegiven += $damage;
            $this->mod->triggerEvent("playerDamageGiven", array($this->guid, $victim, $weapon, $damage, $bodypart));
	    }

	}

	public function vehicleDamageGiven($type, $entityid, $weapon, $damage, $bodypart) {
	    if ($type == "teamdamage") {
            $this->teamvehicledamagegiven += $damage;
            $this->mod->triggerEvent("playerTeamVehicleDamageGiven", array($this->guid, $entityid, $weapon, $damage, $bodypart));
	    }
	    elseif ($type == "damage") {
            $this->vehicledamagegiven += $damage;
            $this->mod->triggerEvent("playerVehicleDamageGiven", array($this->guid, $entityid, $weapon, $damage, $bodypart));
	    }
	}

	public function actorsDamageGiven($type, $entityid, $weapon, $damage, $bodypart) {
	   if ($type == "teamdamage") {
            $this->teamactorsdamagegiven += $damage;
            $this->mod->triggerEvent("playerTeamActorsDamageGiven", array($this->guid, $entityid, $weapon, $damage, $bodypart));
	    }
	    elseif ($type == "damage") {
            $this->actorsdamagegiven += $damage;
            $this->mod->triggerEvent("playerActorsDamageGiven", array($this->guid, $entityid, $weapon, $damage, $bodypart));
	    }
	}

	public function getPbid() {
	    return $this->pid + 1;
	}
}



?>