-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 300197e
Showing
9 changed files
with
439 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
LBAntiHacks - A (not so) simple plugin for adding AntiHacks to your server | ||
====== |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
name: LBAntiHacks | ||
main: LBAntiHacks\Main | ||
version: 0.0.1 | ||
api: [1.4.0] | ||
load: | ||
author: LBSG | ||
description: Lifeboat AntiHacks Plugin For All | ||
website: https://lbsg.net | ||
commands: | ||
lbantihacks: | ||
description: "Manages LBAntiHacks" | ||
aliases: [ah, antihacks] | ||
usage: "/lbantihacks <command> <args>" | ||
permission: lbantihacks | ||
permissions: | ||
lbantihacks: | ||
default: op | ||
description: "Commands that handle all things AntiHacks" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Whether or not to disable antihacks | ||
lbantihacks: true | ||
|
||
# Whether or not the antihacks can | ||
# be managed by anyone other than OP | ||
onlyOp: true | ||
|
||
# Array of usernames to a whitelist | ||
users: | ||
humerusj | ||
williamtdr | ||
brandon15811 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?php | ||
|
||
namespace AntiHack; | ||
|
||
use pocketmine\plugin\Plugin; | ||
use pocketmine\Server; | ||
|
||
use AntiHack\AntiHackEventListener; | ||
use AntiHack\AntiHackTick; | ||
|
||
/** | ||
* Base class for antihack add-on, | ||
* calls event listener and task | ||
*/ | ||
class AntiHack { | ||
/**@var array*/ | ||
public $hackScore = array(); | ||
/** @var AntiHack */ | ||
static private $instance; | ||
//protected | ||
private function __construct() {} | ||
private function __clone() {} | ||
public function __destruct() {} | ||
|
||
/** | ||
* | ||
* implementation of singleton pattern | ||
* | ||
* @return AntiHack | ||
*/ | ||
static public function getInstance() { | ||
if (is_null(self::$instance)) { | ||
self::$instance = new self(); | ||
} | ||
return self::$instance; | ||
} | ||
|
||
/** | ||
* Enable EventKistener and Task | ||
* | ||
* @param Plugin $plugin | ||
*/ | ||
static public function enable(Plugin $plugin) { | ||
self::getInstance(); | ||
Server::getInstance()->getPluginManager()->registerEvents( | ||
new AntiHackEventListener(), $plugin | ||
); | ||
|
||
Server::getInstance()->getScheduler()->scheduleRepeatingTask( | ||
new AntiHackTick(), 40 | ||
); | ||
Server::getInstance()->getScheduler()->scheduleRepeatingTask( | ||
new AntiHackSuspicionTick(), 20 * 60 | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
<?php | ||
|
||
namespace AntiHack; | ||
|
||
use pocketmine\event\player\PlayerMoveEvent; | ||
use pocketmine\event\player\PlayerQuitEvent; | ||
use pocketmine\event\entity\EntityMotionEvent; | ||
use pocketmine\event\player\PlayerBucketFillEvent; | ||
use pocketmine\Player; | ||
use pocketmine\event\Listener; | ||
use AntiHack\AntiHack; | ||
|
||
/** | ||
* Antihack listener search for non-allowed actions like: | ||
* flying, fast movings, fill bucket with lava | ||
*/ | ||
class AntiHackEventListener implements Listener { | ||
const PLAYER_MAX_SPEED = 8; | ||
/**@var AntiHack*/ | ||
private $plugin; | ||
/**@var array*/ | ||
private $flyPlayers = array(); | ||
/**@var array*/ | ||
private $movePlayers = array(); | ||
|
||
public function __construct() { | ||
$this->plugin = AntiHack::getInstance(); | ||
} | ||
|
||
/** | ||
* @param EntityMotionEvent $event | ||
*/ | ||
public function onEntityMotion(EntityMotionEvent $event){ | ||
$player = $event->getEntity(); | ||
if($player instanceof Player){ | ||
if(isset($this->movePlayers[$player->getId()])){ | ||
$this->movePlayers[$player->getId()]["freeze"] = 2; | ||
} | ||
|
||
} | ||
} | ||
|
||
/** | ||
* Look for flying and extraspeed players, increment their hack score | ||
* | ||
* @param PlayerMoveEvent $event | ||
*/ | ||
public function onPLayerMove(PlayerMoveEvent $event) { | ||
//http://minecraft.gamepedia.com/Transportation | ||
$player = $event->getPlayer(); | ||
$dY = (int)(round($event->getTo()->getY() - $event->getFrom()->getY(), 3) * 1000); | ||
if($player->airTicks > 20 && $dY >= 0){ | ||
$maxY = $player->getLevel()->getHighestBlockAt(floor($event->getTo()->getX()), floor($event->getTo()->getZ())); | ||
if($event->getTo()->getY() - 5 > $maxY) { | ||
$score = ($event->getTo()->getY() - $maxY) / 5; | ||
if(isset($this->plugin->hackScore[$player->getId()])){ | ||
$this->plugin->hackScore[$player->getId()]["score"] += $score; | ||
if(!isset($this->plugin->hackScore[$player->getId()]["reason"]["Fly"])){ | ||
$this->plugin->hackScore[$player->getId()]["reason"]["Fly"] = "Fly"; | ||
} | ||
} else{ | ||
$this->plugin->hackScore[$player->getId()] = array(); | ||
$this->plugin->hackScore[$player->getId()]["score"] = $score; | ||
$this->plugin->hackScore[$player->getId()]["integral"] = 0; | ||
$this->plugin->hackScore[$player->getId()]["reason"] = array("Fly" => "Fly"); | ||
$this->plugin->hackScore[$player->getId()]["suspicion"] = 0; | ||
} | ||
} | ||
} | ||
|
||
//fly vertical speed | ||
|
||
if($dY > 0 && $dY % 375 == 0) { | ||
if(isset($this->flyPlayers[$player->getId()])){ | ||
$this->flyPlayers[$player->getId()]++; | ||
} else{ | ||
$this->flyPlayers[$player->getId()] = 1; | ||
} | ||
}else{ | ||
$this->flyPlayers[$player->getId()] = 0; | ||
} | ||
|
||
if($this->flyPlayers[$player->getId()] >= 3){ | ||
$flyPoint = $this->flyPlayers[$player->getId()]; | ||
$this->flyPlayers[$player->getId()] = 0; | ||
if(isset($this->plugin->hackScore[$player->getId()])){ | ||
$this->plugin->hackScore[$player->getId()]["score"] += $flyPoint; | ||
if(!isset($this->plugin->hackScore[$player->getId()]["reason"]["Vertical speed"])){ | ||
$this->plugin->hackScore[$player->getId()]["reason"]["Vertical speed"] = "Vertical speed"; | ||
} | ||
} else{ | ||
$this->plugin->hackScore[$player->getId()] = array(); | ||
$this->plugin->hackScore[$player->getId()]["score"] = $flyPoint; | ||
$this->plugin->hackScore[$player->getId()]["integral"] = 0; | ||
$this->plugin->hackScore[$player->getId()]["reason"] = array("Vertical speed" => "Vertical speed"); | ||
$this->plugin->hackScore[$player->getId()]["suspicion"] = 0; | ||
} | ||
} | ||
if(!isset($this->movePlayers[$player->getId()])){ | ||
$this->movePlayers[$player->getId()] = array(); | ||
$this->movePlayers[$player->getId()]["time"] = time(); | ||
$this->movePlayers[$player->getId()]["distance"] = 0; | ||
} | ||
if($this->movePlayers[$player->getId()]["time"] != time()){ | ||
if(!isset($this->movePlayers[$player->getId()]["freeze"]) || $this->movePlayers[$player->getId()]["freeze"] < 1){ | ||
if($this->movePlayers[$player->getId()]["distance"] > self::PLAYER_MAX_SPEED * 1.1){ | ||
if(isset($this->plugin->hackScore[$player->getId()])){ | ||
$this->plugin->hackScore[$player->getId()]["score"] += ($this->movePlayers[$player->getId()]["distance"] - 4) / 4; | ||
if(!isset($this->plugin->hackScore[$player->getId()]["reason"]["Speed"])){ | ||
$this->plugin->hackScore[$player->getId()]["reason"]["Speed"] = "Speed"; | ||
} | ||
} else{ | ||
$this->plugin->hackScore[$player->getId()] = array(); | ||
$this->plugin->hackScore[$player->getId()]["score"] =($this->movePlayers[$player->getId()]["distance"] - 4) / 4; | ||
$this->plugin->hackScore[$player->getId()]["integral"] = 0; | ||
$this->plugin->hackScore[$player->getId()]["reason"] = array("Speed" => "Speed"); | ||
$this->plugin->hackScore[$player->getId()]["suspicion"] = 0; | ||
} | ||
} | ||
} else{ | ||
$this->movePlayers[$player->getId()]["freeze"]--; | ||
} | ||
$this->movePlayers[$player->getId()]["time"] = time(); | ||
$this->movePlayers[$player->getId()]["distance"] = 0; | ||
} | ||
|
||
$oldPos= $event->getFrom(); | ||
$newPos = $event->getTo(); | ||
$this->movePlayers[$player->getId()]["distance"] += sqrt(($newPos->getX() - $oldPos->getX()) ** 2 + ($newPos->getZ() - $oldPos->getZ()) ** 2); | ||
} | ||
|
||
/** | ||
* remove player from class data fields | ||
* | ||
* @param PlayerQuitEvent $event | ||
*/ | ||
public function onPlayerQuit(PlayerQuitEvent $event) { | ||
$player = $event->getPlayer(); | ||
unset($this->movePlayers[$player->getId()]); | ||
unset($this->flyPlayers[$player->getId()]); | ||
unset($this->plugin->hackScore[$player->getId()]); | ||
} | ||
|
||
/** | ||
* Cancel cause of lava pour men | ||
* | ||
* @param PlayerBucketFillEvent $event | ||
*/ | ||
public function onPlayerBucketFill(PlayerBucketFillEvent $event) { | ||
$event->setCancelled(true); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
namespace AntiHack; | ||
|
||
use AntiHack\AntiHack; | ||
use pocketmine\scheduler\Task; | ||
|
||
/** | ||
* Make permanent checks for cheaters | ||
*/ | ||
class AntiHackSuspicionTick extends Task { | ||
/**@var AntiHack*/ | ||
private $plugin; | ||
|
||
|
||
public function __construct() { | ||
$this->plugin = AntiHack::getInstance(); | ||
} | ||
|
||
/** | ||
* @param $currentTick | ||
*/ | ||
public function onRun($currentTick) { | ||
foreach ($this->plugin->hackScore as $playerId => $data){ | ||
if($data["suspicion"] > 0){ | ||
$this->plugin->hackScore[$playerId]["suspicion"] --; | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<?php | ||
namespace AntiHack; | ||
|
||
use AntiHack\AntiHack; | ||
use pocketmine\scheduler\Task; | ||
use pocketmine\Server; | ||
|
||
/** | ||
* Make permanent checks for cheaters | ||
*/ | ||
class AntiHackTick extends Task { | ||
/**@var AntiHack*/ | ||
private $plugin; | ||
/**@var string*/ | ||
private $serverIp; | ||
/**@var string*/ | ||
private $serverName; | ||
/**@var string*/ | ||
private $path; | ||
|
||
|
||
public function __construct() { | ||
$this->plugin = AntiHack::getInstance(); | ||
$this->serverIp = Server::getInstance()->getIp(); | ||
$this->serverName = "server"; | ||
$this->path = Server::getInstance()->getDataPath() . "logs/"; | ||
} | ||
|
||
/** | ||
* Kick player if his hack score is maximum, | ||
* or unset hack score for honest players | ||
* | ||
* @param $currentTick | ||
*/ | ||
public function onRun($currentTick) { | ||
$players = Server::getInstance()->getDefaultLevel()->getPlayers(); | ||
foreach ($this->plugin->hackScore as $playerId => $data){ | ||
$this->plugin->hackScore[$playerId]["integral"] += $data["score"] - 1; | ||
if($this->plugin->hackScore[$playerId]["integral"] < 0) { | ||
$this->plugin->hackScore[$playerId]["integral"] = 0; | ||
} | ||
if($data["score"] >= 3) { | ||
$this->plugin->hackScore[$playerId]["suspicion"]++; | ||
} | ||
$log = str_pad(date("G:i"), 12) . str_pad($players[$playerId]->getName(), 20) . str_pad("SCORE: " . round($this->plugin->hackScore[$playerId]["score"], 2), 20) . str_pad("HINT: " . round($this->plugin->hackScore[$playerId]["integral"], 2), 20) . str_pad("SUS: " . $this->plugin->hackScore[$playerId]["suspicion"], 20) . "REASON: " . implode("/", $this->plugin->hackScore[$playerId]["reason"]) . "\n"; | ||
$filename = $this->path . date('Y.m.d') . '_' . $this->serverName . '_hack.txt'; | ||
if(!file_exists($filename)) { | ||
$title = "#Hacking Log File\n#HINT = Hacking Integration\n#SCORE = Hacking score\n#SUS = How much they are supected of hacking.\n" | ||
. str_pad("Time (UTC)", 12) . str_pad("Player Name", 20) . str_pad("Hacking Score", 20) . str_pad("Hacking Integration", 20) . str_pad("Suspicion Count", 20) ."Reason\n"; | ||
@file_put_contents($filename, $title, FILE_APPEND | LOCK_EX); | ||
} | ||
if($this->plugin->hackScore[$playerId]["integral"] > 0) { | ||
@file_put_contents($filename, $log, FILE_APPEND | LOCK_EX); | ||
} | ||
|
||
$scoreToKick = 5; | ||
if($this->plugin->hackScore[$playerId]["suspicion"] >= 8){ | ||
$scoreToKick = 3; | ||
} elseif($this->plugin->hackScore[$playerId]["suspicion"] >= 4 ){ | ||
$scoreToKick = 4; | ||
} | ||
|
||
if($players[$playerId]->hackingFlag) { | ||
$scoreToKick--; | ||
} | ||
if(strpos($players[$playerId]->getName(), 'hack') !== false || strpos($players[$playerId]->getName(), 'hqck') !== false) { | ||
$scoreToKick--; | ||
} | ||
|
||
if($this->plugin->hackScore[$playerId]["integral"] > $scoreToKick){ | ||
$log = str_pad(date("G:i"), 12) . str_pad($players[$playerId]->getName(), 20) . str_pad("", 20) . str_pad("HINT: " . round($this->plugin->hackScore[$playerId]["integral"], 2), 20) . str_pad("SUS: " . $this->plugin->hackScore[$playerId]["suspicion"], 20) . "Player kicked \n"; | ||
//$log = date("G:i") . " " . str_pad($players[$playerId]->getName(), 20) . " HINT: " . round($this->plugin->hackScore[$playerId]["integral"], 2) . " SUS: " . $this->plugin->hackScore[$playerId]["suspicion"] . " Player kicked \n"; | ||
@file_put_contents($filename, $log, FILE_APPEND | LOCK_EX); | ||
$players[$playerId]->kick("Cheating is not permitted here. Sorry!"); | ||
} elseif($this->plugin->hackScore[$playerId]["integral"] <= 0 && $this->plugin->hackScore[$playerId]["suspicion"] <= 0){ | ||
unset($this->plugin->hackScore[$playerId]); | ||
} else{ | ||
$this->plugin->hackScore[$playerId]["score"] = 0; | ||
$this->plugin->hackScore[$playerId]["reason"] = array(); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.