Coder Social home page Coder Social logo

hhvmcraft's Introduction

logo

Works on PHP 7.0.0 RC6 and HHVM 3.10.1!

Build Status

A Minecraft Beta 1.7.3 Server implemented in PHP, based off of Truecraft's implementation. Powered by ReactPHP (with some parts patched).

demo

The goal of this project is not to be a fully-functional server, but rather a proof-of-concept for PHP and HHVM.

Installation?

You need composer!

composer install

and

php server.php or hhvm server.php!

Make sure you're using the b1.7.3 client! Check the Allow use of Old Beta Minecraft Versions.

Why?

This is a little coding exercise/project, it's not intended to be a serious application. :)

As you can tell, this is not the most performant implementation. It's being developed in a way that's fast to code, and readable.

I am also not a PHP programmer, or an advanced-level programmer, nor do I know much about socket programming! ;)

So if you have any comments or if you have any crazy fun/interesting ideas for me to consider, please feel free to create an Github issue!

Current Progress

View Things to make functional demo!

Libraries used

Evenement - Event Dispatching Library
ReactPHP - Low-level async event-driven library for PHP.
PHPUnit - PHP Testing Framework
Monolog - Logging Framework

hhvmcraft's People

Contributors

andrewvy avatar lungyiing avatar mbonneau avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hhvmcraft's Issues

Packets to Implement

  • Packets\EntityEquipmentPacket (S)
  • Packets\PlayerDiggingPacket
  • Packets\HoldingChangePacket
  • Packets\UseBedPacket (S)
  • Packets\PlayerActionPacket
  • Packets\PickupSpawnPacket (S)
  • Packets\CollectItemPacket (S)
  • Packets\SpawnGenericEntityPacket
  • Packets\SpawnMobPacket
  • Packets\SpawnPaintingPacket
  • Packets\DestroyEntityPacket
  • Packets\UselessEntityPacket
  • Packets\EntityRelativeMovePacket
  • Packets\EntityLookPacket
  • Packets\EntityLookAndRelativeMovePacket
  • Packets\EntityStatusPacket
  • Packets\AttachEntityPacket
  • Packets\BulkBlockChangePacket
  • Packets\BlockChangePacket
  • Packets\BlockActionPacket
  • Packets\ExplosionPacket
  • Packets\SoundEffectPacket
  • Packets\EnvironmentStatePacket
  • Packets\LightningPacket
  • Packets\OpenWindowPacket
  • Packets\CloseWindowPacket
  • Packets\ClickWindowPacket
  • Packets\SetSlotPacket
  • Packets\UpdateProgressPacket
  • Packets\TransactionStatusPacket
  • Packets\UpdateSignPacket
  • Packets\MapDataPacket
  • Packets\UpdateStatisticPacket

Performance

After running only 30 seconds, everything seems to slow down to a crawl. Packets get delayed. Let's pin-point where this is occurring! xdebug has recently released support for PHP 7 in a beta release. So it may be worth looking into for profiling.

time based on microseconds:

image

Here, you can see places where I'm moving around, creating lots of packets, which spikes it up 1200 ฮผs (barely anything)

image

WritePacket procedure looks normal:

image

Rolling Loop HandlePacket measures the time between each handlePacket.

image

Everything looks stable so far. Nothing to cause such a huge slowdown/delay.

PHP Issues/Painpoints

Some points to talk about in a post-mortem blog post:

Classes And Namespaces

This was a fun one to get my head wrapped around. PHP's namespacing isn't "bad". But it's also not good. Part of why it's not so great is probably due to "internal" PHP ideology, or perhaps wasn't well implemented.

You have to specify a file and require it one by one. (Or take the time to make an autoload script.) And then you have to also declare the namespace. It seems a bit redundant, but that may just be my "high-level programmer" spoiledness with having everything imported automatically. ;)

In some ways, I can understand why you would want to import each file one by one. It makes sure you know what namespaces you're importing. But also, I really just wish there was a wildcard import.. ):

C-style, C-libraries, but little C-positives?

What I find funny/awesome/strange is PHP's wrapping of C libraries. Reading the documentation, I can already see the comments that date back to 6+ years ago. Often times, I found it really helpful to just look at the C documentation itself. I would have really loved to see some primitive data types, like byte, short, int, etc.. but that's probably not possible. It's disappointing that they took these out. It makes handling binary/hex data so much harder due to the type of casting that PHP has.

And again with numbers, PHP's conversion is really lackluster and very questionable. hexdec()? dechex()? bin2unicorn()??? A strong foundation for these conversions would make lives so much easier.

CI/CD to a Heroku Instance

Title! I'll buy a heroku instance and host a minecraft server instance. This will be nice for providing a fun testing playground when I'm live streaming development.

Project name change

I'm considering a name change. What should I change to?

Proposals welcome. PR proposals also welcome. :)

Refactor packet reading/writing

AGAIN WITH THE REFACTORING. I know this has been rewritten almost three times now.. but the string concatenation and multiple function calls to parse a packet is really wasteful and SLOW. We should be doing one pack statement, and one unpack statement. Easy.

Except we'll have to redo every packet that's been written so far. ๐Ÿ‘Ž

Example: http://systemsarchitect.net/parsing-binary-data-in-php-on-an-example-with-the-pcap-format/

UPDATE:

fyi, the new internal reading architecture should be client agnostic. The packet buffer should be Stackables in which pthread workers can chew on. We should probably do the same for outgoing clientbound packets, but I don't think that will be too much of a perf increase.

UPDATE 2:

check for inspiration at https://github.com/Poweruser/MinetickMod

Switch to PHP 7.0

This is a no-brainer, and since I'm not working on HHVM support currently (despite the project name). ๐Ÿ’ฏ

  • Better performance
  • Consistent 64-bit support (YES!)
  • Return types (Finally!)
  • and many other goodies that i'm excited for.

Let's see if switching will break anything major.

UPDATE:

Waiting on the event extension to be ported to PHP 7

Things to make functional demo

Required

  • Add EntityManager and create/manage player entities properly.
  • Add Block/Item Provider and all the blocks/items for lookup.
  • Add Region.
  • Add ChunkProvider.
  • Manage player inventories.
  • Send over compressed chunks.
  • Add Item NBT Data.
  • Add read/write floats and doubles

Packets

  • EntityVelocityPacket
  • DestroyEntityPacket
  • WIndowItemsPacket
  • SpawnPositionPacket
  • KeepAlivePacket
  • SetPlayerPositionPacket
  • TimeUpdatePacket
  • EntityTeleportPacket
  • EntityMetadataPacket
  • ChunkPreamblePacket
  • ChunkDataPacket
  • ChatMessagePacket
  • DisconnectPacket
  • PlayerGroundedPacket
  • PlayerPositionPacket
  • PlayerLookPacket
  • PlayerPositionAndLookPacket
  • PlayerDiggingPacket
  • PlayerBlockPlacementPacket
  • ChangeHeldItemPacket
  • PlayerActionPacket
  • ClickWindowPacket
  • CloseWindowPacket

Not really related directly to your project but:

Ive been thinking for a while about making a c recreation of a mc server for beta, i wondered if you could tell me how you approached it and how you found out how packets and stuff work without the source code, because ive been trying to intercept packets with wireshark but all i could get was some hex data that is really hard to interpret, ty in advance.

Remove license information from all the code files

Reasons Why:

  1. Irrelevant with license file in root
  2. Same information in every single file that's unnecessary
  3. Big projects no longer do this and it's old practice, even proprietary open source PHP applications too

Feel free to close this if you disagree.

Server CLI

When executing the script, it should open up a shell interface. Allows simple management commands like kick, ban, give, etc.

XDebug Profiling

Use XDebug to profile and generate flame graphs to pinpoint obvious speed bottlenecks. I don't want to focus too much on performance, but any chunk we can get along the way is added benefit. We definitely get slower and slower with parsing packets over time because our queue fills up.

We are getting bombarded with packets, it's crazily filling up our queue. There's gotta be a better way we can parse this out. Combined unpack statements rather than one by one? Something.

EDIT: xdebug is pending PHP 7 support.

Add Type Inference/Translation Class

????

PHP is not so great at diving into these different primitive types (It's very good at abstracting them all), we will need something to make it easy to pass in a string of bytes (ByteArray) and translate it into different types.

Chunk Data Packet Problems

 0 : 33 00 00 00 00 00 00 00 00 00 00 09 7f 09 00 00 [3...............]
10 : 00 8d 78 9c ed cd 31 11 00 00 08 04 20 cf ef df [..x...1..... ...]
20 : d9 c5 0e 3a 40 01 92 d5 75 22 7e bf df ef f7 fb [...:@...u"~.....]
30 : fd 7e bf df ef f7 fb fd 7e bf df ef f7 fb fd 7e [.~......~......~]
40 : bf df ef f7 fb fd 7e bf df ef f7 fb fd 7e bf df [......~......~..]
50 : ef f7 fb fd 7e bf df ef f7 fb fd 7e bf df ef f7 [....~......~....]
60 : fb fd 7e bf df ef f7 fb fd 7e bf df ef f7 fb fd [..~......~......]
70 : 7e bf df ef f7 fb fd 7e bf df ef f7 fb fd 7e bf [~......~......~.]
80 : df ef f7 fb fd 7e bf df ef f7 fb fd 7e bf df ef [.....~......~...]
90 : f7 fb fd 7e bf df ef f7 3f f8 07 af 29 1d 01 [...~....?...)..]

This isn't working. It seems the client is reading it wrong. It seems like it's in the correct format though?

breakdown

Packet ID: 33
X: 00 00 00 00
Y: 00 00
Z: 00 00 00 00
Width: 09
Height: 7f
Depth: 09
Chunk Data Length: 00 00 00 8d (141)
Chunk Data:
78 9c ed cd 31 11 00 00 08 04 20 cf ef df d9 c5
0e 3a 40 01 92 d5 75 22 7e bf df ef f7 fb fd 7e
bf df ef f7 fb fd 7e bf df ef f7 fb fd 7e bf df
ef f7 fb fd 7e bf df ef f7 fb fd 7te bf df ef f7
fb fd 7e bf df ef f7 fb fd 7e bf df ef f7 fb fd
7e bf df ef f7 fb fd 7e bf df ef f7 fb fd 7e bf
df ef f7 fb fd 7e bf df ef f7 fb fd 7e bf df ef
f7 fb fd 7e bf df ef f7 fb fd 7e bf df ef f7 fb
fd 7e bf df ef f7 3f f8 07 af 29 1d 01

Client only reads 78 9c ed cd 31 11 00 00 08 04 20 cf ef df d9 c5 0e 3a 40 01 before reading new packet of 92, which doesn't exist. Packet not found id: 146.

Style question?

require "HHVMCraft.Core/Networking/Stream.php";
require "HHVMCraft.Core/Helpers/HexDump.php";
require "HHVMCraft.Core/Entities/PlayerEntity.php";
require "HHVMCraft.Core/Windows/InventoryWindow.php";
require "HHVMCraft.Core/Networking/Packets/ChunkPreamblePacket.php";
require "HHVMCraft.Core/Networking/Packets/ChunkDataPacket.php";
require "HHVMCraft.Core/Networking/Packets/DisconnectPacket.php";
require "HHVMCraft.API/Coordinates2D.php";

Any reason why this is here even though composer should be autoloading, also wondering why it's "HHVMCraft.Core" instead of "HHVMCraft\Core".

Just wondering :)

Keep up the good work ๐Ÿ‘

Add Buffer Class

Abstract reading/writing to and from buffers.

  • Should be able to pass in a buffer to be sent over the socket.
  • Should be able to receive data and put into a buffer.
  • Read from Buffer in all types.
  • Write to Buffer in all types.

API

It would be interesting to have API hooks into the game server.

  • Getting player statistics
  • Keeping track of player history
  • Inventory API
  • Server Status API
  • RCON API

Plugin API System

Who doesn't want to write server-side plugins in PHP? ๐Ÿ‘

We'll need to create a good interface for attaching hooks to certain events. Maybe take a look at Bukkit and model the API after that?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.