【Bukkit】【Spigot】リーチハックの対策の方法

リーチハック、意外とたちが悪いハックです。

これに遭遇したら攻撃が当たりません!

エンティティがダメージを受けた時にそのソース元(プレイヤー)からの距離を計算し、規定の値以上の時はリーチハックとして警告するプラグインを作ってみます。

対策方法

エンティティがダメージを受けた時のイベント

EntityDamageByEntityEventを使用します。

// 最大のリーチ
public static double final MAX_REACH = 3.45D;

@EventHandler
public void onDamage(EntityDamageByEntityEvent event){
// 攻撃元がプレイヤーであるか
if (event.getDamager() instanceof Player) {
// プレイヤーであったとき、
// 対象との距離を計算する
double range = event.getDamager().getLocation().distance(event.getEntity().getLocation());
if (range > MAX_REACH) {
// 最大のリーチを超えてます
Bukkit.broadcastMessage("Reach !!!");
}
}
}

このコードは高低差を考慮していないものになります。

高低差を考慮するには以下のようなコードを加える必要があります。

// 高低差の確認
double rangeY = Math.abs(event.getDamager().getLocation().getY() - event.getEntity().getLocation().getY());

if (rangeY > MAX_REACH) {
// これはハック
} else {
// 単純な距離を計算する
}

【Bukkit】【Spigot】スピードハック対策の方法

スピードハックは最もよく知られているハックであり、一番対策がしやすいのかなとも思います。

 

プレイヤーの動きを検知する

Bukkit プラグインは

イベントの発火

プラグイン側で処理

という流れとなっており、プレイヤーが動いた時の専用のイベントがあります。

そのイベントを使用してハックかどうかの検査を行います。

@EventHandler
public void onMove(PlayerMoveEvent event){
// ここで処理を行います
}

 

しかしこのままだと顔が動いただけでもイベントが発火するため移動していなくても処理が行われてしまいます。

それを防ぐために

if (event.getFrom().getBlockX() != event.getTo().getBlockX()
|| event.getFrom().getBlockY() != event.getTo().getBlockY()
|| event.getFrom().getBlockZ() != event.getTo().getBlockZ()){
// ここで処理を行う
}

↑のコードを追加することで、X、Y、Zのいずれかが動いた時(移動したとき)に処理を行うことができるので、多少ラグを軽減できると思います。

※重い処理を行う際は非同期で処理しましょう

 

さて本題の処理の部分です。

初めにプレイヤーのダッシュ時の速度を変数として保存しておきます。

※ないと思いますが、バージョンアップで移動速度が変わるかもしれないので

public static double final MAX_SPEED = 0.666D;

次にプレイヤーの移動距離を計算し、ダッシュ時の速度を超えている場合はロールバック処理を行います。

// 移動距離の計算
if (event.getFrom().distance(event.getTo()) > MAX_SPEED){
// ダッシュ時の速度を超えているので
// ロールバック処理を行う
event.setCancelled(true);
// ※イベントをキャンセルすることで移動できなくなる
}

最後に全体のソースコードになります。

public static double final MAX_SPEED = 0.666D;
@EventHandler
public void onMove(PlayerMoveEvent event){
if (event.getFrom().getBlockX() != event.getTo().getBlockX()
|| event.getFrom().getBlockY() != event.getTo().getBlockY()
|| event.getFrom().getBlockZ() != event.getTo().getBlockZ()){
if (event.getFrom().distance(event.getTo()) > MAX_SPEED){
event.setCancelled(true);
}
}
}

 

このコードは完全ではないです。

例えば、シフトをしているときやクモの巣、水の中にいるとき、など細かく条件を加えていくことでより詳細にハックかどうかを確認しなければいけません。

また、PVPサーバーでこのコードを使うと、ロールバックを沢山して動けなくなる可能性があります。

なぜなら殴られた時のノックバックによって移動速度(ベクトル)が加算され、MAX_SPEEDを超えてしまうためです。

このコードは改良の余地がたくさんあります。

ぜひこのコードを参考にして独自の対ハックプラグインを作ってみてください。

Spigot1.14.4 のクラッシュの直し方

Spigot 1.14.4 のスタートアップ処理の際に、クラッシュすることがあります。

その原因と対策方法を紹介します。

原因

バージョンがアップしたことによって、1.14.4に対応していないプラグインがエラーを吐き出すことが多いです。

また、”ラグ”を引き起こす処理の重いプラグインを使用すると、エラーが発生します。

対策方法

プラグインを最新バージョンに更新することで直ることがあります。

”ラグ”を引き起こす重いプラグインは極力使用しないことをおすすめします。

またサーバー自体も常に最新の状態にし、バックアップを取ることをおすすめします。

 

☆必要最低限のプラグインのみ使用する

Multiverse-Core のエラーについて

Multiverse-Core で 「/mv create <world> normal」等のコマンドでワールドの作成/読み込み時にサーバーがクラッシュすることがあります。

少し前まではこのようなことはなかったのですが、プラグインを新たに導入したあたりから発生したので、この問題の原因はサーバーの処理能力に影響するのかもしれません。

独立したサーバー状況だといいのですが、複数のサーバーを一台のサーバーで動作させる場合かなりきついかもしれないです。

最新バージョンより安定性をとるのであれば、1.12.2にバージョンダウンすることをおすすめします。(プラグインも安定しているものが多いので)