Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Humerus committed Jun 14, 2016
0 parents commit 300197e
Show file tree
Hide file tree
Showing 9 changed files with 439 additions and 0 deletions.
Empty file added .gitignore
Empty file.
2 changes: 2 additions & 0 deletions README.md
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
======
18 changes: 18 additions & 0 deletions plugin.yml
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"
12 changes: 12 additions & 0 deletions resources/config.yml
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
56 changes: 56 additions & 0 deletions src/AntiHack/AntiHack.php
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
);
}
}
152 changes: 152 additions & 0 deletions src/AntiHack/AntiHackEventListener.php
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);
}
}
30 changes: 30 additions & 0 deletions src/AntiHack/AntiHackSuspicionTick.php
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"] --;
}
}
}

}
83 changes: 83 additions & 0 deletions src/AntiHack/AntiHackTick.php
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();
}
}
}
}
Loading

0 comments on commit 300197e

Please sign in to comment.