├── .gitignore
├── src
└── main
│ ├── php
│ ├── GPBMetadata
│ │ ├── Player.php
│ │ ├── Xchange.php
│ │ ├── AnticheatTypes.php
│ │ ├── PlayerWrappers.php
│ │ └── PrimitiveTypes.php
│ └── prokits
│ │ └── xyron
│ │ ├── AnticheatInterface.php
│ │ ├── ConsumeStatus.php
│ │ ├── PlayerLifeData.php
│ │ ├── Judgement.php
│ │ ├── PlayerReceipt.php
│ │ ├── BreakBlockStatus.php
│ │ ├── PlayerEatFoodData.php
│ │ ├── PlayerGameModeData.php
│ │ ├── PlayerInputModeData.php
│ │ ├── GameMode.php
│ │ ├── InputMode.php
│ │ ├── BatchedReportData.php
│ │ ├── PlayerHeldItemChangeData.php
│ │ ├── PlayerEffectData.php
│ │ ├── TimestampedReportData.php
│ │ ├── ReportResponse.php
│ │ ├── BatchedReportResponse.php
│ │ ├── Vec2i.php
│ │ ├── Vec2f.php
│ │ ├── Player.php
│ │ ├── PlayerAttackData.php
│ │ ├── AnticheatClient.php
│ │ ├── PlayerMoveData.php
│ │ ├── PlayerActionData.php
│ │ ├── Vec3i.php
│ │ ├── Vec3f.php
│ │ ├── AxisAlignedBoundingBox.php
│ │ ├── BatchedReportResponseEntry.php
│ │ ├── BlockData.php
│ │ ├── PlayerMotionData.php
│ │ ├── AddPlayerRequest.php
│ │ ├── JudgementData.php
│ │ ├── PlayerBreakBlockData.php
│ │ ├── PlayerPlaceBlockData.php
│ │ ├── DeviceOS.php
│ │ ├── ItemData.php
│ │ ├── PlayerAction.php
│ │ ├── ReportData.php
│ │ ├── AttackData.php
│ │ ├── DamageCause.php
│ │ ├── EffectFeature.php
│ │ ├── ItemFeature.php
│ │ └── BlockFeature.php
│ └── proto
│ ├── anticheat_types.proto
│ ├── xchange.proto
│ ├── primitive_types.proto
│ ├── player_wrappers.proto
│ └── player.proto
├── pmmp_binding
├── plugin.yml
├── composer.json
├── src
│ └── prokits
│ │ └── xyron
│ │ └── loader
│ │ ├── XyronData.php
│ │ └── BufferedDataQueue.php
└── composer.lock
├── nukkit_binding
├── src
│ └── main
│ │ └── java
│ │ └── com
│ │ └── blackjack200
│ │ └── xyron
│ │ └── nukkit
│ │ ├── XyronData.java
│ │ ├── BufferedDataQueue.java
│ │ ├── BufferedDataFlushPool.java
│ │ └── Main.java
└── pom.xml
├── composer.json
├── implementation
├── util.go
├── jump_condition.go
├── default.go
├── speed_air.go
├── speed_ground.go
└── gravity.go
├── main.go
├── pom.xml
├── LICENSE
├── Makefile
├── go.mod
├── java_protobuf
├── pom.xml
└── src
│ └── main
│ └── java
│ └── com
│ └── github
│ └── blackjack200
│ └── xyron
│ └── AnticheatTypes.java
├── composer.lock
├── anticheat
├── violation_buffer.go
├── util.go
├── anticheat.go
├── player.go
└── handlers.go
├── README.md
└── xyron
├── anticheat_types.pb.go
└── xchange_grpc.pb.go
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | vendor
3 | players
4 | world
5 | config.toml
6 | resources
7 | target
8 | *.iml
9 | logs
--------------------------------------------------------------------------------
/src/main/php/GPBMetadata/Player.php:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Blackjack200/Xyron/HEAD/src/main/php/GPBMetadata/Player.php
--------------------------------------------------------------------------------
/src/main/php/GPBMetadata/Xchange.php:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Blackjack200/Xyron/HEAD/src/main/php/GPBMetadata/Xchange.php
--------------------------------------------------------------------------------
/src/main/php/GPBMetadata/AnticheatTypes.php:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Blackjack200/Xyron/HEAD/src/main/php/GPBMetadata/AnticheatTypes.php
--------------------------------------------------------------------------------
/src/main/php/GPBMetadata/PlayerWrappers.php:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Blackjack200/Xyron/HEAD/src/main/php/GPBMetadata/PlayerWrappers.php
--------------------------------------------------------------------------------
/src/main/php/GPBMetadata/PrimitiveTypes.php:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Blackjack200/Xyron/HEAD/src/main/php/GPBMetadata/PrimitiveTypes.php
--------------------------------------------------------------------------------
/pmmp_binding/plugin.yml:
--------------------------------------------------------------------------------
1 | name: XyronLoader
2 | main: prokits\xyron\loader\Loader
3 | version: 0.1.0
4 | api: 5.0.0
5 | author: Blackjack200
6 | load: POSTWORLD
7 | depend:
8 | - libasync
--------------------------------------------------------------------------------
/pmmp_binding/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "blackjack200/xyron-loader",
3 | "type": "project",
4 | "require": {
5 | "blackjack200/xyron": "dev-master",
6 | "ext-grpc": "*",
7 | "ext-pmmpthread": "*"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/pmmp_binding/src/prokits/xyron/loader/XyronData.php:
--------------------------------------------------------------------------------
1 | queue; }
15 | }
--------------------------------------------------------------------------------
/src/main/proto/anticheat_types.proto:
--------------------------------------------------------------------------------
1 | syntax = 'proto3';
2 |
3 | option go_package = "xyron/";
4 | option php_namespace = "prokits\\xyron";
5 | option java_package = "com.github.blackjack200.xyron";
6 | option java_generic_services = true;
7 | option php_generic_services = true;
8 |
9 | package xchange;
10 |
11 | enum Judgement {
12 | DEBUG = 0;
13 | AMBIGUOUS = 1;
14 | TRIGGER = 2;
15 | }
16 |
--------------------------------------------------------------------------------
/nukkit_binding/src/main/java/com/blackjack200/xyron/nukkit/XyronData.java:
--------------------------------------------------------------------------------
1 | package com.blackjack200.xyron.nukkit;
2 |
3 | import com.github.blackjack200.xyron.Xchange;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Getter;
6 |
7 | @AllArgsConstructor
8 | public class XyronData {
9 | @Getter
10 | private Xchange.PlayerReceipt receipt;
11 | @Getter
12 | private BufferedDataQueue queue;
13 | }
14 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "blackjack200/xyron",
3 | "type": "library",
4 | "license": "MIT",
5 | "autoload": {
6 | "psr-4": {
7 | "": [
8 | "src/main/php"
9 | ]
10 | }
11 | },
12 | "authors": [
13 | {
14 | "name": "Blackjack200",
15 | "email": "lx826444126@gmail.com"
16 | }
17 | ],
18 | "require": {
19 | "google/protobuf": "^3.23.4"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/implementation/util.go:
--------------------------------------------------------------------------------
1 | package implementation
2 |
3 | import (
4 | "github.com/blackjack200/xyron/xyron"
5 | "github.com/df-mc/dragonfly/server/block/cube"
6 | "github.com/go-gl/mathgl/mgl64"
7 | "math"
8 | )
9 |
10 | func toVec3(pos *xyron.Vec3F) mgl64.Vec3 {
11 | return mgl64.Vec3{
12 | float64(pos.X),
13 | float64(pos.Y),
14 | float64(pos.Z),
15 | }
16 | }
17 |
18 | func ToRotation(vec3 mgl64.Vec3) cube.Rotation {
19 | pitchRad := math.Asin(-vec3.Y())
20 | m := math.Cos(pitchRad)
21 | yawRad := math.Acos(vec3.Z() / m)
22 | return cube.Rotation{
23 | mgl64.RadToDeg(yawRad),
24 | mgl64.RadToDeg(pitchRad),
25 | }
26 | }
27 |
28 | func isZero(y float64) bool {
29 | return math.Abs(mgl64.Clamp(y, -epsilon, epsilon)) > epsilon
30 | }
31 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | "fmt"
6 | "github.com/blackjack200/xyron/anticheat"
7 | "github.com/blackjack200/xyron/implementation"
8 | "github.com/blackjack200/xyron/xyron"
9 | "github.com/sirupsen/logrus"
10 | "google.golang.org/grpc"
11 | "log"
12 | "net"
13 | )
14 |
15 | func main() {
16 | flag.Parse()
17 | lis, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", 8884))
18 | if err != nil {
19 | log.Fatalf("failed to listen: %v", err)
20 | }
21 | log.Print("Listen")
22 | s := grpc.NewServer()
23 | t, stop := anticheat.NewSimpleAnticheatServer(logrus.New(), implementation.Available)
24 | xyron.RegisterAnticheatServer(s, t)
25 | if err := s.Serve(lis); err != nil {
26 | panic(err)
27 | }
28 | s.Stop()
29 | stop()
30 | }
31 |
--------------------------------------------------------------------------------
/pmmp_binding/src/prokits/xyron/loader/BufferedDataQueue.php:
--------------------------------------------------------------------------------
1 | data[$tick])) {
15 | $this->data[$tick] = [];
16 | }
17 | $this->data[$tick][] = $data;
18 | }
19 |
20 | public function flush(int $tick, Closure &$remove) : Generator {
21 | $tks = [];
22 | foreach ($this->data as $tck => $data) {
23 | if ($tck <= $tick) {
24 | yield $tck => $data;
25 | $tks[] = $tck;
26 | }
27 | }
28 | $remove = function() use ($tks) : void {
29 | foreach ($tks as $tck) {
30 | unset($this->data[$tck]);
31 | }
32 | };
33 | }
34 | }
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.github.blackjack200
8 | xyron
9 | pom
10 | 0.0.1
11 |
12 | nukkit_binding
13 | java_protobuf
14 |
15 |
16 |
17 |
18 |
19 | org.projectlombok
20 | lombok
21 | 1.18.28
22 | provided
23 |
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 AZ1IDJC
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | PHP_BUILD_PLUGIN=`which grpc_php_plugin`
2 | GO_BUILD_PLUGIN=`which protoc-gen-go-grpc`
3 | JAVA_BUILD_PLUGIN=`which protoc-gen-grpc-java`
4 |
5 | PHP_PROTO_OUT="src/main/php"
6 |
7 | GO_PROTO_BASEDIR="./"
8 | GO_PROTO_OUT="xyron"
9 |
10 | JAVA_PROTO_OUT="java_protobuf/src/main/java"
11 |
12 | php:
13 | @mkdir -p $(PHP_PROTO_OUT)
14 | @rm -rdf $(PHP_PROTO_OUT)
15 | @mkdir -p $(PHP_PROTO_OUT)
16 | @cd src/main/proto && protoc --plugin=protoc-gen-grpc=$(PHP_BUILD_PLUGIN) ./*.proto --php_out="../../../$(PHP_PROTO_OUT)" --grpc_out="../../../$(PHP_PROTO_OUT)"
17 |
18 | go:
19 | @rm -rdf $(GO_PROTO_OUT)
20 | @mkdir -p $(GO_PROTO_OUT)
21 | @cd src/main/proto && protoc --plugin=protoc-gen-grpc=$(GO_BUILD_PLUGIN) ./*.proto --go_out="../../../$(GO_PROTO_BASEDIR)" --grpc_out="../../../$(GO_PROTO_BASEDIR)"
22 |
23 | java:
24 | @mkdir -p $(JAVA_PROTO_OUT)
25 | @rm -rdf $(JAVA_PROTO_OUT)
26 | @mkdir -p $(JAVA_PROTO_OUT)
27 | @cd src/main/proto && protoc --plugin=protoc-gen-grpc=$(JAVA_BUILD_PLUGIN) ./*.proto --java_out="../../../$(JAVA_PROTO_OUT)" --grpc_out="../../../$(JAVA_PROTO_OUT)"
28 |
29 | all:
30 | @make php
31 | @make go
32 | @make java
--------------------------------------------------------------------------------
/implementation/jump_condition.go:
--------------------------------------------------------------------------------
1 | package implementation
2 |
3 | import (
4 | "fmt"
5 | "github.com/blackjack200/xyron/anticheat"
6 | "github.com/blackjack200/xyron/xyron"
7 | )
8 |
9 | type JumpCondition struct {
10 | *anticheat.Evaluator
11 | UnstableRate float64
12 | }
13 |
14 | var _ = anticheat.ActionDataHandler(&JumpCondition{})
15 |
16 | func init() {
17 | register(func() any {
18 | return &JumpCondition{
19 | anticheat.NewEvaluator(8, 0.3, 0.8),
20 | 0.9999,
21 | }
22 | })
23 | }
24 |
25 | func (a *JumpCondition) HandleActionData(p *anticheat.InternalPlayer, data *xyron.PlayerActionData) *xyron.JudgementData {
26 | measured := 0.0
27 | newOnGround, _, _, _, _, _, _ := p.CheckGroundState(data.Position)
28 | if data.Action == xyron.PlayerAction_Jump &&
29 | !p.OnGround.Current().Get() &&
30 | !newOnGround &&
31 | p.InAirTick >= 15 {
32 | measured = 1
33 | }
34 | if !p.Location.Current().AllowFlying && !data.Position.AllowFlying {
35 | a.HandleUnstableRate(measured, 0, a.UnstableRate)
36 | }
37 | return &xyron.JudgementData{
38 | Type: "JumpCondition",
39 | Judgement: a.Evaluate(),
40 | Message: fmt.Sprintf("p:%v inAirTick:%v", a.PossibilityString(), p.InAirTick),
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/AnticheatInterface.php:
--------------------------------------------------------------------------------
1 | xchange.Anticheat
9 | */
10 | interface AnticheatInterface
11 | {
12 | /**
13 | * Method addPlayer
14 | *
15 | * @param \prokits\xyron\AddPlayerRequest $request
16 | * @return \prokits\xyron\PlayerReceipt
17 | */
18 | public function addPlayer(\prokits\xyron\AddPlayerRequest $request);
19 |
20 | /**
21 | * Method removePlayer
22 | *
23 | * @param \prokits\xyron\PlayerReceipt $request
24 | * @return \Google\Protobuf\GPBEmpty
25 | */
26 | public function removePlayer(\prokits\xyron\PlayerReceipt $request);
27 |
28 | /**
29 | * Method report
30 | *
31 | * @param \prokits\xyron\ReportData $request
32 | * @return \prokits\xyron\ReportResponse
33 | */
34 | public function report(\prokits\xyron\ReportData $request);
35 |
36 | /**
37 | * Method reportBatched
38 | *
39 | * @param \prokits\xyron\BatchedReportData $request
40 | * @return \prokits\xyron\BatchedReportResponse
41 | */
42 | public function reportBatched(\prokits\xyron\BatchedReportData $request);
43 |
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/ConsumeStatus.php:
--------------------------------------------------------------------------------
1 | xchange.ConsumeStatus
11 | */
12 | class ConsumeStatus
13 | {
14 | /**
15 | * Generated from protobuf enum Start = 0;
16 | */
17 | const Start = 0;
18 | /**
19 | * Generated from protobuf enum Stop = 1;
20 | */
21 | const Stop = 1;
22 |
23 | private static $valueToName = [
24 | self::Start => 'Start',
25 | self::Stop => 'Stop',
26 | ];
27 |
28 | public static function name($value)
29 | {
30 | if (!isset(self::$valueToName[$value])) {
31 | throw new UnexpectedValueException(sprintf(
32 | 'Enum %s has no name defined for value %s', __CLASS__, $value));
33 | }
34 | return self::$valueToName[$value];
35 | }
36 |
37 |
38 | public static function value($name)
39 | {
40 | $const = __CLASS__ . '::' . strtoupper($name);
41 | if (!defined($const)) {
42 | throw new UnexpectedValueException(sprintf(
43 | 'Enum %s has no value defined for name %s', __CLASS__, $name));
44 | }
45 | return constant($const);
46 | }
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/PlayerLifeData.php:
--------------------------------------------------------------------------------
1 | xchange.PlayerLifeData
13 | */
14 | class PlayerLifeData extends \Google\Protobuf\Internal\Message
15 | {
16 | /**
17 | * Generated from protobuf field bool alive = 1;
18 | */
19 | protected $alive = false;
20 |
21 | /**
22 | * Constructor.
23 | *
24 | * @param array $data {
25 | * Optional. Data for populating the Message object.
26 | *
27 | * @type bool $alive
28 | * }
29 | */
30 | public function __construct($data = NULL) {
31 | \GPBMetadata\PlayerWrappers::initOnce();
32 | parent::__construct($data);
33 | }
34 |
35 | /**
36 | * Generated from protobuf field bool alive = 1;
37 | * @return bool
38 | */
39 | public function getAlive()
40 | {
41 | return $this->alive;
42 | }
43 |
44 | /**
45 | * Generated from protobuf field bool alive = 1;
46 | * @param bool $var
47 | * @return $this
48 | */
49 | public function setAlive($var)
50 | {
51 | GPBUtil::checkBool($var);
52 | $this->alive = $var;
53 |
54 | return $this;
55 | }
56 |
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/Judgement.php:
--------------------------------------------------------------------------------
1 | xchange.Judgement
11 | */
12 | class Judgement
13 | {
14 | /**
15 | * Generated from protobuf enum DEBUG = 0;
16 | */
17 | const DEBUG = 0;
18 | /**
19 | * Generated from protobuf enum AMBIGUOUS = 1;
20 | */
21 | const AMBIGUOUS = 1;
22 | /**
23 | * Generated from protobuf enum TRIGGER = 2;
24 | */
25 | const TRIGGER = 2;
26 |
27 | private static $valueToName = [
28 | self::DEBUG => 'DEBUG',
29 | self::AMBIGUOUS => 'AMBIGUOUS',
30 | self::TRIGGER => 'TRIGGER',
31 | ];
32 |
33 | public static function name($value)
34 | {
35 | if (!isset(self::$valueToName[$value])) {
36 | throw new UnexpectedValueException(sprintf(
37 | 'Enum %s has no name defined for value %s', __CLASS__, $value));
38 | }
39 | return self::$valueToName[$value];
40 | }
41 |
42 |
43 | public static function value($name)
44 | {
45 | $const = __CLASS__ . '::' . strtoupper($name);
46 | if (!defined($const)) {
47 | throw new UnexpectedValueException(sprintf(
48 | 'Enum %s has no value defined for name %s', __CLASS__, $name));
49 | }
50 | return constant($const);
51 | }
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/PlayerReceipt.php:
--------------------------------------------------------------------------------
1 | xchange.PlayerReceipt
13 | */
14 | class PlayerReceipt extends \Google\Protobuf\Internal\Message
15 | {
16 | /**
17 | * Generated from protobuf field string internalId = 1;
18 | */
19 | protected $internalId = '';
20 |
21 | /**
22 | * Constructor.
23 | *
24 | * @param array $data {
25 | * Optional. Data for populating the Message object.
26 | *
27 | * @type string $internalId
28 | * }
29 | */
30 | public function __construct($data = NULL) {
31 | \GPBMetadata\Xchange::initOnce();
32 | parent::__construct($data);
33 | }
34 |
35 | /**
36 | * Generated from protobuf field string internalId = 1;
37 | * @return string
38 | */
39 | public function getInternalId()
40 | {
41 | return $this->internalId;
42 | }
43 |
44 | /**
45 | * Generated from protobuf field string internalId = 1;
46 | * @param string $var
47 | * @return $this
48 | */
49 | public function setInternalId($var)
50 | {
51 | GPBUtil::checkString($var, True);
52 | $this->internalId = $var;
53 |
54 | return $this;
55 | }
56 |
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/BreakBlockStatus.php:
--------------------------------------------------------------------------------
1 | xchange.BreakBlockStatus
11 | */
12 | class BreakBlockStatus
13 | {
14 | /**
15 | * Generated from protobuf enum StartBreak = 0;
16 | */
17 | const StartBreak = 0;
18 | /**
19 | * Generated from protobuf enum AbortBreak = 1;
20 | */
21 | const AbortBreak = 1;
22 | /**
23 | * Generated from protobuf enum FinishBreak = 2;
24 | */
25 | const FinishBreak = 2;
26 |
27 | private static $valueToName = [
28 | self::StartBreak => 'StartBreak',
29 | self::AbortBreak => 'AbortBreak',
30 | self::FinishBreak => 'FinishBreak',
31 | ];
32 |
33 | public static function name($value)
34 | {
35 | if (!isset(self::$valueToName[$value])) {
36 | throw new UnexpectedValueException(sprintf(
37 | 'Enum %s has no name defined for value %s', __CLASS__, $value));
38 | }
39 | return self::$valueToName[$value];
40 | }
41 |
42 |
43 | public static function value($name)
44 | {
45 | $const = __CLASS__ . '::' . strtoupper($name);
46 | if (!defined($const)) {
47 | throw new UnexpectedValueException(sprintf(
48 | 'Enum %s has no value defined for name %s', __CLASS__, $name));
49 | }
50 | return constant($const);
51 | }
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/implementation/default.go:
--------------------------------------------------------------------------------
1 | package implementation
2 |
3 | import (
4 | "github.com/blackjack200/xyron/anticheat"
5 | "github.com/blackjack200/xyron/xyron"
6 | )
7 |
8 | var Available = func() []any {
9 | return nil
10 | }
11 |
12 | const epsilon = 0.00001
13 |
14 | func register(newF func() any) {
15 | oldA := Available
16 | Available = func() []any {
17 | return append(oldA(), newF())
18 | }
19 | }
20 |
21 | func clear() {
22 | Available = func() []any {
23 | return nil
24 | }
25 | }
26 |
27 | func isPlayerFreeFalling(p *anticheat.InternalPlayer, futurePos *xyron.EntityPositionData) bool {
28 | if p.Location.Previous() == nil {
29 | return true
30 | }
31 | y := p.Motion.Current().Get().Y()
32 |
33 | tickSinceTeleport := p.Teleport.Current().Duration(p.CurrentTimestamp())
34 | tickSinceFlying := p.Flying.Current().Duration(p.CurrentTimestamp())
35 | tickSinceMotion := p.Motion.Current().Duration(p.CurrentTimestamp())
36 | tickSinceJump := p.Jump.Current().Duration(p.CurrentTimestamp())
37 |
38 | // we shouldn't use "future" data, but this is a special condition, false positives appear when player land and death.
39 | futureOnGround, _, _, _, _, _, _ := p.CheckGroundState(futurePos)
40 | futureImmobile := futurePos.IsImmobile
41 |
42 | if !isZero(y) &&
43 | !p.Location.Current().IsImmobile && !futureImmobile &&
44 | futurePos.Position.Y > -64 &&
45 | tickSinceTeleport > 40 && tickSinceFlying > 10 && tickSinceJump > 15 &&
46 | tickSinceMotion > p.MotionCoolDown &&
47 | p.InAirTick > 15 && !futureOnGround &&
48 | !p.IntersectedLiquid.Current().Get() {
49 | return true
50 | }
51 | return false
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/PlayerEatFoodData.php:
--------------------------------------------------------------------------------
1 | xchange.PlayerEatFoodData
13 | */
14 | class PlayerEatFoodData extends \Google\Protobuf\Internal\Message
15 | {
16 | /**
17 | * Generated from protobuf field .xchange.ConsumeStatus status = 2;
18 | */
19 | protected $status = 0;
20 |
21 | /**
22 | * Constructor.
23 | *
24 | * @param array $data {
25 | * Optional. Data for populating the Message object.
26 | *
27 | * @type int $status
28 | * }
29 | */
30 | public function __construct($data = NULL) {
31 | \GPBMetadata\PlayerWrappers::initOnce();
32 | parent::__construct($data);
33 | }
34 |
35 | /**
36 | * Generated from protobuf field .xchange.ConsumeStatus status = 2;
37 | * @return int
38 | */
39 | public function getStatus()
40 | {
41 | return $this->status;
42 | }
43 |
44 | /**
45 | * Generated from protobuf field .xchange.ConsumeStatus status = 2;
46 | * @param int $var
47 | * @return $this
48 | */
49 | public function setStatus($var)
50 | {
51 | GPBUtil::checkEnum($var, \prokits\xyron\ConsumeStatus::class);
52 | $this->status = $var;
53 |
54 | return $this;
55 | }
56 |
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/PlayerGameModeData.php:
--------------------------------------------------------------------------------
1 | xchange.PlayerGameModeData
13 | */
14 | class PlayerGameModeData extends \Google\Protobuf\Internal\Message
15 | {
16 | /**
17 | * Generated from protobuf field .xchange.GameMode gameMode = 1;
18 | */
19 | protected $gameMode = 0;
20 |
21 | /**
22 | * Constructor.
23 | *
24 | * @param array $data {
25 | * Optional. Data for populating the Message object.
26 | *
27 | * @type int $gameMode
28 | * }
29 | */
30 | public function __construct($data = NULL) {
31 | \GPBMetadata\PlayerWrappers::initOnce();
32 | parent::__construct($data);
33 | }
34 |
35 | /**
36 | * Generated from protobuf field .xchange.GameMode gameMode = 1;
37 | * @return int
38 | */
39 | public function getGameMode()
40 | {
41 | return $this->gameMode;
42 | }
43 |
44 | /**
45 | * Generated from protobuf field .xchange.GameMode gameMode = 1;
46 | * @param int $var
47 | * @return $this
48 | */
49 | public function setGameMode($var)
50 | {
51 | GPBUtil::checkEnum($var, \prokits\xyron\GameMode::class);
52 | $this->gameMode = $var;
53 |
54 | return $this;
55 | }
56 |
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/blackjack200/xyron
2 |
3 | go 1.20
4 |
5 | require (
6 | github.com/df-mc/dragonfly v0.9.9-0.20230714144543-281943e6efc4
7 | github.com/go-gl/mathgl v1.0.0
8 | github.com/pelletier/go-toml v1.9.5
9 | github.com/sirupsen/logrus v1.9.3
10 | google.golang.org/grpc v1.56.2
11 | google.golang.org/protobuf v1.31.0
12 | )
13 |
14 | require (
15 | github.com/brentp/intintmap v0.0.0-20190211203843-30dc0ade9af9 // indirect
16 | github.com/cespare/xxhash v1.1.0 // indirect
17 | github.com/df-mc/atomic v1.10.0 // indirect
18 | github.com/df-mc/goleveldb v1.1.9 // indirect
19 | github.com/df-mc/worldupgrader v1.0.8 // indirect
20 | github.com/golang/protobuf v1.5.3 // indirect
21 | github.com/golang/snappy v0.0.4 // indirect
22 | github.com/google/uuid v1.3.0 // indirect
23 | github.com/klauspost/compress v1.16.7 // indirect
24 | github.com/muhammadmuzzammil1998/jsonc v1.0.0 // indirect
25 | github.com/rogpeppe/go-internal v1.11.0 // indirect
26 | github.com/sandertv/go-raknet v1.12.0 // indirect
27 | github.com/sandertv/gophertunnel v1.31.0 // indirect
28 | go.uber.org/atomic v1.11.0 // indirect
29 | golang.org/x/crypto v0.11.0 // indirect
30 | golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
31 | golang.org/x/image v0.9.0 // indirect
32 | golang.org/x/net v0.12.0 // indirect
33 | golang.org/x/oauth2 v0.10.0 // indirect
34 | golang.org/x/sys v0.10.0 // indirect
35 | golang.org/x/text v0.11.0 // indirect
36 | google.golang.org/appengine v1.6.7 // indirect
37 | google.golang.org/genproto/googleapis/rpc v0.0.0-20230720185612-659f7aaaa771 // indirect
38 | gopkg.in/square/go-jose.v2 v2.6.0 // indirect
39 | )
40 |
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/PlayerInputModeData.php:
--------------------------------------------------------------------------------
1 | xchange.PlayerInputModeData
13 | */
14 | class PlayerInputModeData extends \Google\Protobuf\Internal\Message
15 | {
16 | /**
17 | * Generated from protobuf field .xchange.InputMode inputMode = 1;
18 | */
19 | protected $inputMode = 0;
20 |
21 | /**
22 | * Constructor.
23 | *
24 | * @param array $data {
25 | * Optional. Data for populating the Message object.
26 | *
27 | * @type int $inputMode
28 | * }
29 | */
30 | public function __construct($data = NULL) {
31 | \GPBMetadata\PlayerWrappers::initOnce();
32 | parent::__construct($data);
33 | }
34 |
35 | /**
36 | * Generated from protobuf field .xchange.InputMode inputMode = 1;
37 | * @return int
38 | */
39 | public function getInputMode()
40 | {
41 | return $this->inputMode;
42 | }
43 |
44 | /**
45 | * Generated from protobuf field .xchange.InputMode inputMode = 1;
46 | * @param int $var
47 | * @return $this
48 | */
49 | public function setInputMode($var)
50 | {
51 | GPBUtil::checkEnum($var, \prokits\xyron\InputMode::class);
52 | $this->inputMode = $var;
53 |
54 | return $this;
55 | }
56 |
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/GameMode.php:
--------------------------------------------------------------------------------
1 | xchange.GameMode
11 | */
12 | class GameMode
13 | {
14 | /**
15 | * Generated from protobuf enum Survival = 0;
16 | */
17 | const Survival = 0;
18 | /**
19 | * Generated from protobuf enum Creative = 1;
20 | */
21 | const Creative = 1;
22 | /**
23 | * Generated from protobuf enum Adventure = 2;
24 | */
25 | const Adventure = 2;
26 | /**
27 | * Generated from protobuf enum Spectator = 3;
28 | */
29 | const Spectator = 3;
30 |
31 | private static $valueToName = [
32 | self::Survival => 'Survival',
33 | self::Creative => 'Creative',
34 | self::Adventure => 'Adventure',
35 | self::Spectator => 'Spectator',
36 | ];
37 |
38 | public static function name($value)
39 | {
40 | if (!isset(self::$valueToName[$value])) {
41 | throw new UnexpectedValueException(sprintf(
42 | 'Enum %s has no name defined for value %s', __CLASS__, $value));
43 | }
44 | return self::$valueToName[$value];
45 | }
46 |
47 |
48 | public static function value($name)
49 | {
50 | $const = __CLASS__ . '::' . strtoupper($name);
51 | if (!defined($const)) {
52 | throw new UnexpectedValueException(sprintf(
53 | 'Enum %s has no value defined for name %s', __CLASS__, $name));
54 | }
55 | return constant($const);
56 | }
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/src/main/proto/xchange.proto:
--------------------------------------------------------------------------------
1 | syntax = 'proto3';
2 |
3 | option go_package = "xyron/";
4 | option php_namespace = "prokits\\xyron";
5 | option java_package = "com.github.blackjack200.xyron";
6 | option java_generic_services = true;
7 | option php_generic_services = true;
8 |
9 | package xchange;
10 |
11 | import "google/protobuf/empty.proto";
12 | import "player_wrappers.proto";
13 | import "player.proto";
14 | import "anticheat_types.proto";
15 |
16 | message PlayerReceipt {
17 | string internalId = 1;
18 | }
19 |
20 | message TimestampedReportData {
21 | repeated WildcardReportData data = 1;
22 | }
23 |
24 | message AddPlayerRequest{
25 | Player player = 1;
26 | //timestamp->report data
27 | map data = 2;
28 | }
29 |
30 | message ReportData{
31 | PlayerReceipt player = 1;
32 | double latency = 2;
33 | //timestamp->report data
34 | map data = 3;
35 | }
36 |
37 | message ReportResponse{
38 | repeated JudgementData judgements = 1;
39 | }
40 |
41 | message BatchedReportData{
42 | repeated ReportData data = 1;
43 | }
44 |
45 | message BatchedReportResponseEntry{
46 | PlayerReceipt player = 1;
47 | repeated JudgementData judgements = 2;
48 | }
49 |
50 | message BatchedReportResponse{
51 | repeated BatchedReportResponseEntry data = 1;
52 | }
53 |
54 | message JudgementData{
55 | string type = 1;
56 | Judgement judgement = 2;
57 | string message = 3;
58 | }
59 |
60 | service Anticheat {
61 | rpc AddPlayer(AddPlayerRequest) returns (PlayerReceipt) {}
62 | rpc RemovePlayer(PlayerReceipt) returns (google.protobuf.Empty) {}
63 | rpc Report(ReportData) returns (ReportResponse){}
64 | rpc ReportBatched(BatchedReportData) returns (BatchedReportResponse){}
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/InputMode.php:
--------------------------------------------------------------------------------
1 | xchange.InputMode
11 | */
12 | class InputMode
13 | {
14 | /**
15 | * Generated from protobuf enum MouseKeyboard = 0;
16 | */
17 | const MouseKeyboard = 0;
18 | /**
19 | * Generated from protobuf enum Touch = 1;
20 | */
21 | const Touch = 1;
22 | /**
23 | * Generated from protobuf enum Gamepad = 2;
24 | */
25 | const Gamepad = 2;
26 | /**
27 | * Generated from protobuf enum MotionController = 3;
28 | */
29 | const MotionController = 3;
30 |
31 | private static $valueToName = [
32 | self::MouseKeyboard => 'MouseKeyboard',
33 | self::Touch => 'Touch',
34 | self::Gamepad => 'Gamepad',
35 | self::MotionController => 'MotionController',
36 | ];
37 |
38 | public static function name($value)
39 | {
40 | if (!isset(self::$valueToName[$value])) {
41 | throw new UnexpectedValueException(sprintf(
42 | 'Enum %s has no name defined for value %s', __CLASS__, $value));
43 | }
44 | return self::$valueToName[$value];
45 | }
46 |
47 |
48 | public static function value($name)
49 | {
50 | $const = __CLASS__ . '::' . strtoupper($name);
51 | if (!defined($const)) {
52 | throw new UnexpectedValueException(sprintf(
53 | 'Enum %s has no value defined for name %s', __CLASS__, $name));
54 | }
55 | return constant($const);
56 | }
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/src/main/proto/primitive_types.proto:
--------------------------------------------------------------------------------
1 | syntax = 'proto3';
2 |
3 | option go_package = "xyron/";
4 | option php_namespace = "prokits\\xyron";
5 | option java_package = "com.github.blackjack200.xyron";
6 | option java_generic_services = true;
7 | option php_generic_services = true;
8 |
9 | package xchange;
10 |
11 | message Vec2f {
12 | float x = 1;
13 | float y = 2;
14 | }
15 |
16 | message Vec2i {
17 | int32 x = 1;
18 | int32 y = 2;
19 | }
20 |
21 | message Vec3f {
22 | float x = 1;
23 | float y = 2;
24 | float z = 3;
25 | }
26 |
27 | message Vec3i {
28 | int32 x = 1;
29 | int32 y = 2;
30 | int32 z = 3;
31 | }
32 |
33 | message AxisAlignedBoundingBox{
34 | Vec3f min = 1;
35 | Vec3f max = 2;
36 | }
37 |
38 | message BlockData {
39 | BlockFeature feature = 1;
40 | Vec3i position = 2;
41 | }
42 |
43 | message BlockFeature {
44 | repeated AxisAlignedBoundingBox collisionBoxes = 2;
45 | float friction = 3;
46 | bool isSolid = 4;
47 | bool isLiquid = 5;
48 | bool isAir = 6;
49 | bool isSlime = 7;
50 | bool isClimbable = 8;
51 | bool isIce = 9;
52 | bool isCobweb = 10;
53 | bool isSweetBerry = 11;
54 | }
55 |
56 | message ItemData {
57 | ItemFeature feature = 1;
58 | string vanillaName = 2;
59 | uint32 count = 3;
60 | }
61 |
62 | message ItemFeature {
63 | bool isArmor = 1;
64 | bool isBlockPlanterItem = 2;
65 | bool isDamageable = 3;
66 | bool isFood = 4;
67 | bool isThrowable = 5;
68 | bool isTool = 6;
69 | bool isBow = 7;
70 | bool isCrossBow = 8;
71 | bool isShield = 9;
72 | }
73 |
74 | message EffectFeature {
75 | int32 amplifier = 1;
76 | bool isSpeed = 2;
77 | bool isHaste = 3;
78 | bool isSlowFalling = 4;
79 | bool isLevitation = 5;
80 | bool isSlowness = 6;
81 | bool isJumpBoost = 7;
82 | }
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/BatchedReportData.php:
--------------------------------------------------------------------------------
1 | xchange.BatchedReportData
13 | */
14 | class BatchedReportData extends \Google\Protobuf\Internal\Message
15 | {
16 | /**
17 | * Generated from protobuf field repeated .xchange.ReportData data = 1;
18 | */
19 | private $data;
20 |
21 | /**
22 | * Constructor.
23 | *
24 | * @param array $data {
25 | * Optional. Data for populating the Message object.
26 | *
27 | * @type array<\prokits\xyron\ReportData>|\Google\Protobuf\Internal\RepeatedField $data
28 | * }
29 | */
30 | public function __construct($data = NULL) {
31 | \GPBMetadata\Xchange::initOnce();
32 | parent::__construct($data);
33 | }
34 |
35 | /**
36 | * Generated from protobuf field repeated .xchange.ReportData data = 1;
37 | * @return \Google\Protobuf\Internal\RepeatedField
38 | */
39 | public function getData()
40 | {
41 | return $this->data;
42 | }
43 |
44 | /**
45 | * Generated from protobuf field repeated .xchange.ReportData data = 1;
46 | * @param array<\prokits\xyron\ReportData>|\Google\Protobuf\Internal\RepeatedField $var
47 | * @return $this
48 | */
49 | public function setData($var)
50 | {
51 | $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \prokits\xyron\ReportData::class);
52 | $this->data = $arr;
53 |
54 | return $this;
55 | }
56 |
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/nukkit_binding/src/main/java/com/blackjack200/xyron/nukkit/BufferedDataQueue.java:
--------------------------------------------------------------------------------
1 | package com.blackjack200.xyron.nukkit;
2 |
3 | import com.github.blackjack200.xyron.AnticheatGrpc;
4 | import com.github.blackjack200.xyron.PlayerWrappers;
5 | import com.github.blackjack200.xyron.Xchange;
6 | import com.google.common.util.concurrent.ListenableFuture;
7 | import lombok.val;
8 |
9 | import java.util.LinkedHashMap;
10 | import java.util.LinkedList;
11 | import java.util.List;
12 | import java.util.Map;
13 |
14 | public class BufferedDataQueue {
15 | private final Map> map = new LinkedHashMap<>(80);
16 |
17 | public synchronized void add(long tick, PlayerWrappers.WildcardReportData wdata) {
18 | if (!map.containsKey(tick)) {
19 | map.put(tick, new LinkedList<>());
20 | }
21 | map.get(tick).add(wdata);
22 | }
23 |
24 | public synchronized ListenableFuture flush(AnticheatGrpc.AnticheatFutureStub c, Xchange.PlayerReceipt p, long tick, double latency) {
25 | val needSend = new LinkedList();
26 | for (val k : map.keySet()) {
27 | if (k <= tick) {
28 | needSend.add(k);
29 | }
30 | }
31 | needSend.sort(Long::compare);
32 | val needSendMap = new LinkedHashMap();
33 | for (val timestamp : needSend) {
34 | needSendMap.put(timestamp, Xchange.TimestampedReportData.newBuilder()
35 | .addAllData(map.get(timestamp)).build());
36 | map.remove(timestamp);
37 | }
38 | val rp = Xchange.ReportData.newBuilder()
39 | .setPlayer(p)
40 | .setLatency(latency)
41 | .putAllData(needSendMap)
42 | .build();
43 | return c.report(rp);
44 | }
45 | }
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/PlayerHeldItemChangeData.php:
--------------------------------------------------------------------------------
1 | xchange.PlayerHeldItemChangeData
13 | */
14 | class PlayerHeldItemChangeData extends \Google\Protobuf\Internal\Message
15 | {
16 | /**
17 | * Generated from protobuf field .xchange.ItemData item = 1;
18 | */
19 | protected $item = null;
20 |
21 | /**
22 | * Constructor.
23 | *
24 | * @param array $data {
25 | * Optional. Data for populating the Message object.
26 | *
27 | * @type \prokits\xyron\ItemData $item
28 | * }
29 | */
30 | public function __construct($data = NULL) {
31 | \GPBMetadata\PlayerWrappers::initOnce();
32 | parent::__construct($data);
33 | }
34 |
35 | /**
36 | * Generated from protobuf field .xchange.ItemData item = 1;
37 | * @return \prokits\xyron\ItemData|null
38 | */
39 | public function getItem()
40 | {
41 | return $this->item;
42 | }
43 |
44 | public function hasItem()
45 | {
46 | return isset($this->item);
47 | }
48 |
49 | public function clearItem()
50 | {
51 | unset($this->item);
52 | }
53 |
54 | /**
55 | * Generated from protobuf field .xchange.ItemData item = 1;
56 | * @param \prokits\xyron\ItemData $var
57 | * @return $this
58 | */
59 | public function setItem($var)
60 | {
61 | GPBUtil::checkMessage($var, \prokits\xyron\ItemData::class);
62 | $this->item = $var;
63 |
64 | return $this;
65 | }
66 |
67 | }
68 |
69 |
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/PlayerEffectData.php:
--------------------------------------------------------------------------------
1 | xchange.PlayerEffectData
13 | */
14 | class PlayerEffectData extends \Google\Protobuf\Internal\Message
15 | {
16 | /**
17 | * Generated from protobuf field repeated .xchange.EffectFeature effect = 1;
18 | */
19 | private $effect;
20 |
21 | /**
22 | * Constructor.
23 | *
24 | * @param array $data {
25 | * Optional. Data for populating the Message object.
26 | *
27 | * @type array<\prokits\xyron\EffectFeature>|\Google\Protobuf\Internal\RepeatedField $effect
28 | * }
29 | */
30 | public function __construct($data = NULL) {
31 | \GPBMetadata\PlayerWrappers::initOnce();
32 | parent::__construct($data);
33 | }
34 |
35 | /**
36 | * Generated from protobuf field repeated .xchange.EffectFeature effect = 1;
37 | * @return \Google\Protobuf\Internal\RepeatedField
38 | */
39 | public function getEffect()
40 | {
41 | return $this->effect;
42 | }
43 |
44 | /**
45 | * Generated from protobuf field repeated .xchange.EffectFeature effect = 1;
46 | * @param array<\prokits\xyron\EffectFeature>|\Google\Protobuf\Internal\RepeatedField $var
47 | * @return $this
48 | */
49 | public function setEffect($var)
50 | {
51 | $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \prokits\xyron\EffectFeature::class);
52 | $this->effect = $arr;
53 |
54 | return $this;
55 | }
56 |
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/TimestampedReportData.php:
--------------------------------------------------------------------------------
1 | xchange.TimestampedReportData
13 | */
14 | class TimestampedReportData extends \Google\Protobuf\Internal\Message
15 | {
16 | /**
17 | * Generated from protobuf field repeated .xchange.WildcardReportData data = 1;
18 | */
19 | private $data;
20 |
21 | /**
22 | * Constructor.
23 | *
24 | * @param array $data {
25 | * Optional. Data for populating the Message object.
26 | *
27 | * @type array<\prokits\xyron\WildcardReportData>|\Google\Protobuf\Internal\RepeatedField $data
28 | * }
29 | */
30 | public function __construct($data = NULL) {
31 | \GPBMetadata\Xchange::initOnce();
32 | parent::__construct($data);
33 | }
34 |
35 | /**
36 | * Generated from protobuf field repeated .xchange.WildcardReportData data = 1;
37 | * @return \Google\Protobuf\Internal\RepeatedField
38 | */
39 | public function getData()
40 | {
41 | return $this->data;
42 | }
43 |
44 | /**
45 | * Generated from protobuf field repeated .xchange.WildcardReportData data = 1;
46 | * @param array<\prokits\xyron\WildcardReportData>|\Google\Protobuf\Internal\RepeatedField $var
47 | * @return $this
48 | */
49 | public function setData($var)
50 | {
51 | $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \prokits\xyron\WildcardReportData::class);
52 | $this->data = $arr;
53 |
54 | return $this;
55 | }
56 |
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/ReportResponse.php:
--------------------------------------------------------------------------------
1 | xchange.ReportResponse
13 | */
14 | class ReportResponse extends \Google\Protobuf\Internal\Message
15 | {
16 | /**
17 | * Generated from protobuf field repeated .xchange.JudgementData judgements = 1;
18 | */
19 | private $judgements;
20 |
21 | /**
22 | * Constructor.
23 | *
24 | * @param array $data {
25 | * Optional. Data for populating the Message object.
26 | *
27 | * @type array<\prokits\xyron\JudgementData>|\Google\Protobuf\Internal\RepeatedField $judgements
28 | * }
29 | */
30 | public function __construct($data = NULL) {
31 | \GPBMetadata\Xchange::initOnce();
32 | parent::__construct($data);
33 | }
34 |
35 | /**
36 | * Generated from protobuf field repeated .xchange.JudgementData judgements = 1;
37 | * @return \Google\Protobuf\Internal\RepeatedField
38 | */
39 | public function getJudgements()
40 | {
41 | return $this->judgements;
42 | }
43 |
44 | /**
45 | * Generated from protobuf field repeated .xchange.JudgementData judgements = 1;
46 | * @param array<\prokits\xyron\JudgementData>|\Google\Protobuf\Internal\RepeatedField $var
47 | * @return $this
48 | */
49 | public function setJudgements($var)
50 | {
51 | $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \prokits\xyron\JudgementData::class);
52 | $this->judgements = $arr;
53 |
54 | return $this;
55 | }
56 |
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/implementation/speed_air.go:
--------------------------------------------------------------------------------
1 | package implementation
2 |
3 | import (
4 | "fmt"
5 | "github.com/blackjack200/xyron/anticheat"
6 | "github.com/blackjack200/xyron/xyron"
7 | "math"
8 | )
9 |
10 | type SpeedAir struct {
11 | *anticheat.Evaluator
12 | PredictionLatitude float64
13 | UnstableRate float64
14 | }
15 |
16 | var _ anticheat.MoveDataHandler = &SpeedAir{}
17 |
18 | func init() {
19 | register(func() any {
20 | return &SpeedAir{
21 | anticheat.NewEvaluator(80, 0.75, 0.96),
22 | 0.05,
23 | 0.997,
24 | }
25 | })
26 | }
27 |
28 | func (g *SpeedAir) HandleMoveData(p *anticheat.InternalPlayer, data *xyron.PlayerMoveData) *xyron.JudgementData {
29 | if !isPlayerFreeFalling(p, data.NewPosition) {
30 | return nil
31 | }
32 | if p.Location.Previous() == nil {
33 | return nil
34 | }
35 | oldPos := toVec3(p.Location.Previous().Position)
36 | pos := toVec3(p.Location.Current().Position)
37 | delta := pos.Sub(oldPos)
38 |
39 | futurePos := toVec3(data.NewPosition.Position)
40 | deltaFuture := futurePos.Sub(oldPos)
41 |
42 | deltaXZ := math.Hypot(delta.X(), delta.Z())
43 | measuredFutureDeltaXZ := math.Hypot(deltaFuture.X(), deltaFuture.Z())
44 | if isZero(futurePos.Sub(pos).Len()) {
45 | return nil
46 | }
47 |
48 | factor := 0.02
49 | if p.Sprinting.Current().Get() {
50 | factor = 0.026
51 | }
52 | predictedMaxDeltaXZ := deltaXZ*0.91 + factor
53 |
54 | if !p.Location.Current().IsFlying &&
55 | !data.NewPosition.IsFlying &&
56 | !p.Location.Current().AllowFlying {
57 | g.HandleRelativeUnstableRate(measuredFutureDeltaXZ, predictedMaxDeltaXZ, g.PredictionLatitude, g.UnstableRate)
58 | }
59 |
60 | equalness := math.Abs(measuredFutureDeltaXZ - predictedMaxDeltaXZ)
61 | return &xyron.JudgementData{
62 | Type: "SpeedAir",
63 | Judgement: g.Evaluate(),
64 | Message: fmt.Sprintf("p:%v pred-xz:%.5f xz:%.5f delta:%.5f", g.PossibilityString(), predictedMaxDeltaXZ, deltaXZ, equalness),
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/php/prokits/xyron/BatchedReportResponse.php:
--------------------------------------------------------------------------------
1 | xchange.BatchedReportResponse
13 | */
14 | class BatchedReportResponse extends \Google\Protobuf\Internal\Message
15 | {
16 | /**
17 | * Generated from protobuf field repeated .xchange.BatchedReportResponseEntry data = 1;
18 | */
19 | private $data;
20 |
21 | /**
22 | * Constructor.
23 | *
24 | * @param array $data {
25 | * Optional. Data for populating the Message object.
26 | *
27 | * @type array<\prokits\xyron\BatchedReportResponseEntry>|\Google\Protobuf\Internal\RepeatedField $data
28 | * }
29 | */
30 | public function __construct($data = NULL) {
31 | \GPBMetadata\Xchange::initOnce();
32 | parent::__construct($data);
33 | }
34 |
35 | /**
36 | * Generated from protobuf field repeated .xchange.BatchedReportResponseEntry data = 1;
37 | * @return \Google\Protobuf\Internal\RepeatedField
38 | */
39 | public function getData()
40 | {
41 | return $this->data;
42 | }
43 |
44 | /**
45 | * Generated from protobuf field repeated .xchange.BatchedReportResponseEntry data = 1;
46 | * @param array<\prokits\xyron\BatchedReportResponseEntry>|\Google\Protobuf\Internal\RepeatedField $var
47 | * @return $this
48 | */
49 | public function setData($var)
50 | {
51 | $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \prokits\xyron\BatchedReportResponseEntry::class);
52 | $this->data = $arr;
53 |
54 | return $this;
55 | }
56 |
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/nukkit_binding/src/main/java/com/blackjack200/xyron/nukkit/BufferedDataFlushPool.java:
--------------------------------------------------------------------------------
1 | package com.blackjack200.xyron.nukkit;
2 |
3 | import cn.nukkit.Server;
4 | import com.google.common.util.concurrent.ListenableFuture;
5 | import lombok.SneakyThrows;
6 | import lombok.val;
7 | import lombok.var;
8 |
9 | import java.util.ArrayList;
10 | import java.util.HashMap;
11 | import java.util.List;
12 | import java.util.Map;
13 | import java.util.concurrent.Future;
14 | import java.util.function.Consumer;
15 |
16 | public class BufferedDataFlushPool {
17 | private final List> futures = new ArrayList<>();
18 | private final Map, Consumer