Coder Social home page Coder Social logo

valence-rs / valence Goto Github PK

View Code? Open in Web Editor NEW
2.4K 2.4K 124.0 6.3 MB

A Rust framework for building Minecraft servers.

Home Page: http://valence.rs/

License: MIT License

Rust 94.25% Java 3.50% Shell 0.08% SCSS 0.28% CSS 0.56% JavaScript 0.91% HTML 0.42%
bevy ecs game gamedev hacktoberfest minecraft rust server

valence's People

Contributors

bafbi avatar dani162 avatar dependabot[bot] avatar dyc3 avatar earthcomputer avatar emortaldev avatar emperialdev avatar gingeh avatar guac42 avatar icrayix avatar ioannuwu avatar jackcrumpleys avatar jadedblueeyes avatar jenya705 avatar leodog896 avatar mrlnhi avatar natanalt avatar pepperoni21 avatar ponaskovas avatar qualterz avatar rj00a avatar sandrohc avatar sekky61 avatar selfmadesystem avatar sesemueller avatar tachibanayui avatar terminatornl avatar tert0 avatar ustuej avatar wugwugg 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

valence's Issues

GitHub workflow with more checks

I set up github workflows to run cargo build and cargo test on push to main.

Here are some other things it should check for:

  • cargo clippy warnings
  • cargo fmt changes
  • broken doc links

Accurate entity hitboxes

entity.rs has a function called hitbox which, as you can guess, returns the Axis-aligned bounding box of an entity.

Extracting correct hitbox data automatically appears to be infeasible because it depends on the entity's state and varies wildly between different entity types. This info will have to be filled in manually.

Right now there is a bunch of placeholder data and some todo!s.

Packet rate limiting

Currently there is no rate limit for serverbound packets. I'm not sure what the best way to do this is. We should investigate how vanilla MC does it.

Inventory and Items

The lack of inventory and items can no longer be ignored. I will be working on this next.

  • Item data extractor
  • Item code generator
  • Inventory packets
  • Inventory client events
  • inventory.rs?
  • New example

Extractor has no docs

Just tried to build and use the extractor mod, got this crash report

---- Minecraft Crash Report ----
// Don't do that.

Time: 2022-09-27 18:23:58
Description: Initializing game

java.lang.RuntimeException: Could not execute entrypoint stage 'main' due to errors, provided by 'valence_extractor'!
	at net.fabricmc.loader.impl.entrypoint.EntrypointUtils.lambda$invoke0$0(EntrypointUtils.java:51)
	at net.fabricmc.loader.impl.util.ExceptionUtil.gatherExceptions(ExceptionUtil.java:33)
	at net.fabricmc.loader.impl.entrypoint.EntrypointUtils.invoke0(EntrypointUtils.java:49)
	at net.fabricmc.loader.impl.entrypoint.EntrypointUtils.invoke(EntrypointUtils.java:35)
	at net.fabricmc.loader.impl.game.minecraft.Hooks.startClient(Hooks.java:52)
	at net.minecraft.class_310.<init>(class_310.java:459)
	at net.minecraft.client.main.Main.method_44604(Main.java:205)
	at net.minecraft.client.main.Main.main(Main.java:51)
	at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:461)
	at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74)
	at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.polymc.impl.OneSixLauncher.invokeMain(OneSixLauncher.java:104)
	at org.polymc.impl.OneSixLauncher.launchWithMainClass(OneSixLauncher.java:175)
	at org.polymc.impl.OneSixLauncher.launch(OneSixLauncher.java:185)
	at org.polymc.EntryPoint.listen(EntryPoint.java:144)
	at org.polymc.EntryPoint.main(EntryPoint.java:74)
Caused by: java.lang.NoClassDefFoundError: net/minecraft/world/BlockView
	at dev._00a.valence_extractor.Main.onInitialize(Main.java:43)
	at net.fabricmc.loader.impl.entrypoint.EntrypointUtils.invoke0(EntrypointUtils.java:47)
	... 17 more
Caused by: java.lang.ClassNotFoundException: net.minecraft.world.BlockView
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	at net.fabricmc.loader.impl.launch.knot.KnotClassDelegate.loadClass(KnotClassDelegate.java:226)
	at net.fabricmc.loader.impl.launch.knot.KnotClassLoader.loadClass(KnotClassLoader.java:145)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	... 19 more


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Thread: Render thread
Stacktrace:
	at net.fabricmc.loader.impl.entrypoint.EntrypointUtils.lambda$invoke0$0(EntrypointUtils.java:51)
	at net.fabricmc.loader.impl.util.ExceptionUtil.gatherExceptions(ExceptionUtil.java:33)
	at net.fabricmc.loader.impl.entrypoint.EntrypointUtils.invoke0(EntrypointUtils.java:49)
	at net.fabricmc.loader.impl.entrypoint.EntrypointUtils.invoke(EntrypointUtils.java:35)
	at net.fabricmc.loader.impl.game.minecraft.Hooks.startClient(Hooks.java:52)
	at net.minecraft.class_310.<init>(class_310.java:459)

-- Initialization --
Details:
	Modules: 
Stacktrace:
	at net.minecraft.client.main.Main.method_44604(Main.java:205)
	at net.minecraft.client.main.Main.main(Main.java:51)
	at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:461)
	at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74)
	at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.polymc.impl.OneSixLauncher.invokeMain(OneSixLauncher.java:104)
	at org.polymc.impl.OneSixLauncher.launchWithMainClass(OneSixLauncher.java:175)
	at org.polymc.impl.OneSixLauncher.launch(OneSixLauncher.java:185)
	at org.polymc.EntryPoint.listen(EntryPoint.java:144)
	at org.polymc.EntryPoint.main(EntryPoint.java:74)

-- System Details --
Details:
	Minecraft Version: 1.19.2
	Minecraft Version ID: 1.19.2
	Operating System: Linux (amd64) version 5.4.0-124-generic
	Java Version: 17.0.1, Flathub
	Java VM Version: OpenJDK 64-Bit Server VM (mixed mode, sharing), Flathub
	Memory: 2103863864 bytes (2006 MiB) / 2592079872 bytes (2472 MiB) up to 4294967296 bytes (4096 MiB)
	CPUs: 24
	Processor Vendor: AuthenticAMD
	Processor Name: AMD Ryzen 9 3900X 12-Core Processor
	Identifier: AuthenticAMD Family 23 Model 113 Stepping 0
	Microarchitecture: unknown
	Frequency (GHz): -0.00
	Number of physical packages: 1
	Number of physical CPUs: 12
	Number of logical CPUs: 24
	Graphics card #0 name: TU104 [GeForce RTX 2080 SUPER]
	Graphics card #0 vendor: NVIDIA Corporation (0x10de)
	Graphics card #0 VRAM (MB): 288.00
	Graphics card #0 deviceId: 0x1e81
	Graphics card #0 versionInfo: unknown
	Virtual memory max (MB): 52631.04
	Virtual memory used (MB): 33958.72
	Swap memory total (MB): 20479.00
	Swap memory used (MB): 1086.50
	JVM Flags: 2 total; -Xms512m -Xmx4096m
	Fabric Mods: 
		fabric-api: Fabric API 0.62.0+1.19.2
			fabric-api-base: Fabric API Base 0.4.12+93d8cb8290
			fabric-api-lookup-api-v1: Fabric API Lookup API (v1) 1.6.10+93d8cb8290
			fabric-biome-api-v1: Fabric Biome API (v1) 9.0.18+c6af733c90
			fabric-blockrenderlayer-v1: Fabric BlockRenderLayer Registration (v1) 1.1.21+c6af733c90
			fabric-client-tags-api-v1: Fabric Client Tags 1.0.2+b35fea8390
			fabric-command-api-v1: Fabric Command API (v1) 1.2.12+f71b366f90
			fabric-command-api-v2: Fabric Command API (v2) 2.1.8+93d8cb8290
			fabric-commands-v0: Fabric Commands (v0) 0.2.29+df3654b390
			fabric-containers-v0: Fabric Containers (v0) 0.1.35+df3654b390
			fabric-content-registries-v0: Fabric Content Registries (v0) 3.3.1+624e468e90
			fabric-convention-tags-v1: Fabric Convention Tags 1.1.2+93d8cb8290
			fabric-crash-report-info-v1: Fabric Crash Report Info (v1) 0.2.6+aeb40ebe90
			fabric-data-generation-api-v1: Fabric Data Generation API (v1) 5.2.0+b598f4ac90
			fabric-dimensions-v1: Fabric Dimensions API (v1) 2.1.32+0dd10df690
			fabric-entity-events-v1: Fabric Entity Events (v1) 1.4.19+9ff28f4090
			fabric-events-interaction-v0: Fabric Events Interaction (v0) 0.4.29+c6af733c90
			fabric-events-lifecycle-v0: Fabric Events Lifecycle (v0) 0.2.29+df3654b390
			fabric-game-rule-api-v1: Fabric Game Rule API (v1) 1.0.22+c6af733c90
			fabric-item-api-v1: Fabric Item API (v1) 1.5.8+93d8cb8290
			fabric-item-groups-v0: Fabric Item Groups (v0) 0.3.30+93d8cb8290
			fabric-key-binding-api-v1: Fabric Key Binding API (v1) 1.0.21+93d8cb8290
			fabric-keybindings-v0: Fabric Key Bindings (v0) 0.2.19+df3654b390
			fabric-lifecycle-events-v1: Fabric Lifecycle Events (v1) 2.2.0+33ffe9ec90
			fabric-loot-api-v2: Fabric Loot API (v2) 1.1.4+83a8659290
			fabric-loot-tables-v1: Fabric Loot Tables (v1) 1.1.7+9e7660c690
			fabric-message-api-v1: Fabric Message API (v1) 5.0.4+93d8cb8290
			fabric-mining-level-api-v1: Fabric Mining Level API (v1) 2.1.15+33fbc73890
			fabric-models-v0: Fabric Models (v0) 0.3.18+c6af733c90
			fabric-networking-api-v1: Fabric Networking API (v1) 1.2.5+c6af733c90
			fabric-networking-v0: Fabric Networking (v0) 0.3.22+df3654b390
			fabric-object-builder-api-v1: Fabric Object Builder API (v1) 4.0.12+93d8cb8290
			fabric-particles-v1: Fabric Particles (v1) 1.0.11+79adfe0a90
			fabric-registry-sync-v0: Fabric Registry Sync (v0) 0.9.26+c6af733c90
			fabric-renderer-api-v1: Fabric Renderer API (v1) 1.0.11+c6af733c90
			fabric-renderer-indigo: Fabric Renderer - Indigo 0.6.13+aeb40ebe90
			fabric-renderer-registries-v1: Fabric Renderer Registries (v1) 3.2.21+df3654b390
			fabric-rendering-data-attachment-v1: Fabric Rendering Data Attachment (v1) 0.3.15+aeb40ebe90
			fabric-rendering-fluids-v1: Fabric Rendering Fluids (v1) 3.0.8+c6af733c90
			fabric-rendering-v0: Fabric Rendering (v0) 1.1.23+df3654b390
			fabric-rendering-v1: Fabric Rendering (v1) 1.11.0+73145abb90
			fabric-resource-conditions-api-v1: Fabric Resource Conditions API (v1) 2.0.12+a29562c890
			fabric-resource-loader-v0: Fabric Resource Loader (v0) 0.7.0+93d8cb8290
			fabric-screen-api-v1: Fabric Screen API (v1) 1.0.27+93d8cb8290
			fabric-screen-handler-api-v1: Fabric Screen Handler API (v1) 1.3.1+1cc24b1b90
			fabric-textures-v0: Fabric Textures (v0) 1.0.21+aeb40ebe90
			fabric-transfer-api-v1: Fabric Transfer API (v1) 2.1.1+93d8cb8290
			fabric-transitive-access-wideners-v1: Fabric Transitive Access Wideners (v1) 1.3.1+42d99c3290
		fabricloader: Fabric Loader 0.14.9
		java: OpenJDK 64-Bit Server VM 17
		minecraft: Minecraft 1.19.2
		valence_extractor: Valence Extractor 1.0.0
	Launched Version: 1.19.2
	Backend library: LWJGL version 3.3.1 SNAPSHOT
	Backend API: Unknown
	Window size: <not initialized>
	GL Caps: Using framebuffer using OpenGL 3.2
	GL debug messages: <disabled>
	Using VBOs: Yes
	Is Modded: Definitely; Client brand changed to 'fabric'
	Type: Client (map_client.txt)
	CPU: <unknown>
#@!@# Game crashed! Crash report saved to: #@!@# /home/carson/.var/app/org.polymc.PolyMC/data/PolyMC/instances/Valence dev (extractor)/.minecraft/crash-reports/crash-2022-09-27_18.23.58-client.txt
Process exited with code 255.

Packet inspector breaks with Vanilla Server

I've tried to use packet_inspector with conway and it works just fine.

But when using a vanilla server, the inspector errors out with:

Connection to 127.0.0.1:45158 ended with: decoding packet: failed to read field `verify_token` from struct `EncryptionRequest`: Length of array is out of bounds while decoding (got 4, needed 16..=16)

The server is PaperMC 1.19.2-183 and I'm using a vanilla client

Wall blocks not placed right

Right now if you place a torch on the wall the client will show a ghost wall torch, but when you update it, it will go back to a normal torch. And this is also true for all other blocks that have a wall variant.

I think it would be easy to just check for the diffrent blocks that have a wall variant, and then just return the right variant based on the direction. Mabye also for the rotational blocks, e.g. logs etc.

I propose something like:

// this will be inside ClientEvent::InteractWithBlock
let state = match block_kind {
    BlockKind::Torch => face_wall_block(face, BlockState::TORCH, BlockState::WALL_TORCH),
    BlockKind::OakLog => face_directional_block(face, BlockState::OAK_LOG),
    ...
    kind => BlockState::from_kind(kind),
};

world.chunks.set_block_state(
    place_at,
    state,
);

// This will be outside impl Config
fn face_wall_block(face: BlockFace, normal: BlockState, wall: BlockState) -> BlockState {
    match face {
        BlockFace::Bottom => normal,
        BlockFace::Top => normal,
        BlockFace::North => wall.set(PropName::Facing, PropValue::North),
        BlockFace::South => wall.set(PropName::Facing, PropValue::South),
        BlockFace::West => wall.set(PropName::Facing, PropValue::West),
        BlockFace::East => wall.set(PropName::Facing, PropValue::East),
    }
}

fn face_directional_block(face: BlockFace, block: BlockState) -> BlockState {
    match face {
        BlockFace::Bottom | BlockFace::Top => block.set(PropName::Axis, PropValue::Y),
        BlockFace::North | BlockFace::South => block.set(PropName::Axis, PropValue::Z),
        BlockFace::West | BlockFace::East => block.set(PropName::Axis, PropValue::X),
    }
}

How should Valence be versioned?

I don't believe the Valence API will ever be in a stable state if we assume the following:

  1. We only target the most recent version of MC.
  2. Updating to a new version of MC is a breaking change.
  3. New MC versions can be released at any time and cause anything to break.

With that in mind, it might be better to just start at version 1.0.0 instead of releasing 0.x.y versions as is usually done in the Rust ecosystem.

For the initial Valence release, I'll just release it as 0.1.0+mc1.19.2 to be safe.

(The +mc1.19.2 bit at the end there is "build metadata" which is ignored for the purpose of version ordering. It's useful to know what MC version is being targeted.)

Anvil file format support

In a separate valence_anvil crate at the root of the repo, support for anvil should be implemented (Both serialization and deserialization).

I've implemented a partial anvil deserializer before, but... I can't find it.
Here are some things I would expect the library to have:

  • Parallelization through rayon. In my deserializer I parallelized over each region.
  • Support for both encoding and decoding.
  • Chunk data saved to UnloadedChunk.
  • Lazy loading so we don't have to load the whole world into memory at once.

Supporting saves made with older version of the game is probably out of scope. No need to reimplement data fixer upper.

  • Loading
  • Saving

Cryptographic chat support

MC versions 1.19.1 and 1.19.2 added cryptographically verified chat messages which complicates things.

I'm not sure what the API for this should look like.

MinecraftChat drawio4

(The above image might be out of date by now)

Typing in chat causes client to disconnect

Using commit cac348a4b6e788f3ecce24c7559c1789f4c8b402, running example combat.

Server log

[2022-09-05T13:03:17Z TRACE valence::server] entering accept loop
[2022-09-05T13:04:22Z ERROR valence::server] connection to 127.0.0.1:64121 ended: error during play: packet contents were not read completely

How to reproduce

  • Join the server
  • Type a message
  • Get disconnected

This bug occurs in all examples and non-examples.

Proxy Support

Valence should have support for bungeecord and velocity proxies. I think something like this could work in Config.

#[non_exhaustive]
#[derive(Copy, Clone, Eq, PartialEq, Default)]
pub enum ConnectionMode {
    #[default]
    Online,
    Offline,
    Bungeecord,
    Velocity,
}

(Looks like velocity does not support 1.19 currently? What should we do if Valence is updated before the proxies are?)

Valence Website

I don't have any webdev experience. Also, I have the valence.rs domain name.

Edit: Here's what I would expect the website to have once finished:

  • Dedicated page for documentation with a tutorial-like guide (markdown).
  • FAQ page.
  • A clean landing page with the Valence logo and links to github, discord, crates.io, etc. It should have a short summary of Valence's goals and capabilities.
  • A page for announcing releases including patch notes (markdown).
  • Minimal design. Nothing too flashy.
  • Uses the valence.rs domain name.
  • Available in a website directory at the root of the Valence repository. If it would make more sense to be in a separate repo we could discuss that.
  • Hosted on GitHub for easy edits?

Sources of Inspiration

  • Minestom: https://minestom.net/
    I quite like the simplicity of the landing page. I'm indifferent about the use of gitbook for the docs.
  • Feather: https://feathermc.org/
    This one is a bit bare-bones but it's worth mentioning.
  • Rocket: https://rocket.rs/
    Not Minecraft related, but It's got all the ingredients for a good site.

"packet contents were not decoded completely (4 bytes remaining)"

Using commit 2ee9605 (latest main as of 11:50 PM Sat, Sep 3, 2022, PST), on an M1 mac, running example terrain, abridged log follows:

[2022-09-04T06:42:16Z DEBUG valence::protocol::codec] complete packet after partial decode: C2sPlayPacket(UpdateCreativeModeSlot { slot: 36 })
[2022-09-04T06:42:16Z ERROR valence::server] connection to 127.0.0.1:52167 ended: error during play: packet contents were not decoded completely (4 bytes remaining)
[2022-09-04T06:42:22Z DEBUG valence::server] error while flushing packet queue: Broken pipe (os error 32)

Effects

The client is disconnected with a simple message, "Timed Out," while attempting to join.

It stops just short of the "Loading Terrain" stage.

How to reproduce

Use Java client 1.19.2 from the official launcher.

I haven't been able to consistently reproduce it. However, repeatedly joining in-and-out can cause this problem by chance.

But to describe my actions,

  1. Successfully enter the world. Destroy a grass block. Replace it with a stone block.
  2. Quit world.
  3. Attempt to join again.
  4. (Get this error).
  5. Attempt to join again.
  6. (Fail to join due to another cause).
  7. Inventory is cleared, and I'm allowed to join again.

Difficulty reproducing the error

Often I get an initial disconnect with a "deadline has elapsed" error. Afterwards, I keep getting "conflicting UUID" errors so I have to reset the server. So entering the world successfully is kind of chance, and once I get kicked out I will keep getting kicked out, so it has to be perfect every time.

I haven't been able to reproduce this issue twice.

Broken pipe error when repeatedly connecting and disconnecting

Repeatedly connecting to the server and disconnecting while loading will eventually cause Failed to log in: null in the client and

[2022-09-13T22:46:24Z ERROR valence::server] connection to 127.0.0.1:36030 ended: error during login: Broken pipe (os error 32)

In the server.

I'm not sure if this is actually a bug in Valence or expected Linux socket behavior. It would be interesting to test this on different platforms.

Refactor `Slot` so that it's easier to work with

Working with slots is somewhat cumbersome because sometimes you want to represent that the item is present no matter what.

  • Add a new type ItemStack with the fields that are in Slot::Present
  • Change Slot::Present { .. } to Slot::Present(ItemStack)
  • Implement From<Slot> for Option<ItemStack> and vice versa

OR, alternatively we could do this instead:

  • Get rid of slot and just use Option<ItemStack>

Configurable authentication server

The official Mojang authentication server address probably shouldn't be hardcoded. It should default to the official one in Config but be configurable.

Reevaluate strategy for tracking loaded entities and chunks in `Client`.

Entity updates can be stored in a per-chunk buffer. Then clients only need to iterate over visible chunks and the hashmaps in Client can be removed. This will also make the spatial index unnecessary and it can be moved to an optional crate. These changes should improve both memory and CPU usage drastically.

Herobrine Example

I just think this is what we have to do eventually.
On the technical side to show-off fake players with bare-bones AI.
And on a spriritual side to appease the awe-inspiring Herobrine.

To be honest I have no idea what is needed for this and how far we are on the "fake player" front, but I would take a stab on this eventually.

Parse named text colors.

In the text module, text colors can be named like "black", "gold", "red" or they can be a precise six-digit hex color like "#000000".

The current deserializer fails if it encounters one of the named colors, but it should be accepted.

I think it's fine to normalize them to hex colors during serialization though.

The `Text` struct is too large.

cargo clippy often complains that std::mem::size_of::<Text>() is too large. There are a few things that could be done.

  • Stop using Cow<'static, str> everywhere and just use String. We can reintroduce it later if it turns out to be important.
  • Get rid of the Option<bool>s by manually implementing Serialize and Deserialize. Use a bitfield struct with two bits per Option<bool>.

Playground template to try things out quickly without creating an example

Being able to try stuff out from a user's perspective is really important, especially for a library like this. I'm proposing we make a little bit of tooling around a "playground", where people can copy the template and share it to easily reproduce bugs, include in test plans, etc.

Of course, this doesn't replace the need for our examples folder.

Examples:

Are the packet buffers big enough?

in Config there are the functions incoming_packet_capacity and outgoing_packet_capacity. They control the maximum size of the buffers used to hold packets to prevent unbounded memory usage. They reach their maximum when the server is sending packets faster than the client can receive it or vice versa.

Are the default values large enough? I recall stackotter saying he was kicked from terrain.rs with a render distance of 32 because of this. Is this even the right approach to the problem?

Update `aes` and `cfb8` dependencies

aes and cfb8 crates are at 0.8 currently but they are 0.7 in Valence. I tried updating a while back but couldn't figure out how to use the new API (It's very different).

Not much urgency on this one.

Migrate packet names to wiki.vg names

I've had a rule in place that the names of packets should match the names in packets.json. The reason for this was to make updating to new versions using the data extractor easier and to avoid potential legal issues because wiki.vg used the packet names from Mojang's mappings (this has mostly changed).

However, a lot of the yarn names are crap and it's way easier to just use wiki.vg. So we should transition all or most of the packet names to their names on wiki.vg for consistency.

Edit: This should be a gradual process so we don't cause too much pain right now.

"Conflicting UUID" by repeatedly joining server

Java 1.19.2 client (official Minecraft launcher); commit 2ee9605 (main); encrypted.

Example used is terrain.

Summary

Joining the server repeatedly can cause "Conflicting UUID" being logged to the server and kicking the user.

Often paired with Broken pipe (os error 32) (macOS 12.5.1 Monterey) and error during play: deadline has elapsed errors (but not always).

Each time "Conflicting UUID" error happens, the player count goes up by 1. You can check this by going to the server listing in the Minecraft client and hitting "Refresh." Player count is increased by 1.

Reproduction

It often happens by itself.

You can cause this reliably by quickly disconnecting while the client's screen says "Joining World."

Cannot reach server from another host when config address function is not overwritten

Currently we can not reach the server from another host if you not overwrite the ip address in the config.
I think we should document this behavior and maybe also change the default behavior to accept request from all interfaces (use address 0.0.0.0 instead of localhost).

valence/src/config.rs

Lines 52 to 60 in 0066883

/// Called once at startup to get the socket address the server will
/// be bound to.
///
/// # Default Implementation
///
/// Returns `127.0.0.1:25565`.
fn address(&self) -> SocketAddr {
SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 25565).into()
}

To override the address we currently have to implement following function:

impl Config for Game {
    ...
    fn address(&self) -> SocketAddr {
        SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 25565).into()
    }
}

See also: https://stackoverflow.com/questions/42435723/rust-tcplistener-does-not-response-outside-request

I can create a pr tomorrow, if needed

Nonblocking Terrain Generation

Now that #37 is merged, we should do terrain generation in terrain.rs outside the update loop. The reason this is needed is because when you join the game, the server is completely frozen while chunks are generated. This also causes stutters while exploring new terrain.

To fix this, we could send ChunkPos and receive UnloadedChunk over channels. A priority queue should be used to generate chunks that are closer to the player first. The rayon thread pool should be used.

Mojang session server unhandled response format

When logging into a valence server, sometimes the log-in process fails with the following error message:
[2022-09-30T13:13:11Z ERROR valence::server] connection to 127.0.0.1:33980 ended: error during login: EOF while parsing a value at line 1 column 0

This is quite hard to reproduce, but I had the most success of reproducing this error when:

  1. Log into the server
  2. Disconnect
  3. Log back in after about 10 minutes.

This is not guaranteed to work, however.

I went through the log-in process and located the origin of this error to be the following line:

let data: AuthResponse = resp.json().await?;

The json() call reads the bytes in the body that is sent back to valence from the Mojang session server.

Under normal circumstances, the Mojang session server return status 200 but in this case it returns status code 204. Furthermore, the Mojang session server does not transmit any content despite sending "content-type": "application/json" in the header fields. This means that when the json() tries to read the bytes in the body, it ends up reading zero bytes and throws an EOF error. (response body = 0 bytes)

I have added the headers and some additional details below (using format!("{:?}", response)):

Response { url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("sessionserver.mojang.com")), port: None, path: "/session/minecraft/hasJoined", query: Some("username=Terminator_NL&serverId=**redacted**&ip=127.0.0.1"), fragment: None }, status: 204, headers: {"cache-control": "no-store", "content-type": "application/json", "x-minecraft-request-id": "859782bb07ebb57b", "x-cache": "CONFIG_NOCACHE", "x-azure-ref": "0Z+s2YwAAAABo/fb1SCwJQZ55W2ymkslNQU1TMDRFREdFMTgxNQBhODc2NTI0My1lMjE0LTQ4NmEtYmFiNC04NDAwMWI0MDA5YzY=", "set-cookie": "ASLBSA=0003af36d910048a208f98008a8d9254c59859f96a40a025a2738de7c22fb2e6c983; path=/; secure", "set-cookie": "ASLBSACORS=0003af36d910048a208f98008a8d9254c59859f96a40a025a2738de7c22fb2e6c983; samesite=none; path=/; secure", "date": "Fri, 30 Sep 2022 13:13:11 GMT"} }

SPECULATION
I am not sure what status code 204 is, or how to handle it. I can only assume that 204 means "It's still valid, just use my previous response" and Mojang expects the minecraft server to cache the authentication responses.

Block entities

Support for block entities should be added to the chunk API.

It looks like there are only a few things that need explicit support from Valence.

  • The text on signs
  • Banner patterns
  • The entity inside of spawners
  • Player data in player heads
  • Maybe some other blocks?

My current idea is to put a HashMap<u32, BlockEntity> in each chunk. The key is the block index and the value is an enum of the possible block states.

Entity yaw (mabye pitch) keeps going up

When you turn around your yaw (and properly also pitch) keeps goining up, so when you print out the player's yaw it is above 180 and if you turn the other way, you can get below -180.

Valence:
Valence
Vanilla:
Vanilla

As you can see, this makes it so that the yaw (and mabye pitch) in the f3 doesn't match client.yaw() and player.yaw().

Test plan

Print out the yaw and compare it to the f3 screen.

Implement weather

There should be a function on Client to change the weather effects it sees. There's probably just a simple packet that needs to be sent.

Spawning entities triggered by client events is really tedious.

This is more of a usability problem, rather than a bug.

Supposed we have the following code:

let player = server.entities.get_mut(client.state.entity_id).unwrap();
while let Some(event) = handle_event_default(client, player) {
    match event {
        ...
    }
}

While inside this loop, it's not possible to call server.entities.insert() without getting this error:

error[E0499]: cannot borrow `*server.entities` as mutable more than once at a time
   --> examples/dropping.rs:211:39
    |
190 |             let player = server.entities.get_mut(client.state.entity_id).unwrap();
    |                          ----------------------------------------------- first mutable borrow occurs here
...
196 |             while let Some(event) = handle_event_default(client, player) {
    |                                                                  ------ first borrow later used here
...
211 |                         let (id, e) = server.entities.insert(EntityKind::Item, ());
    |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here

It's technically possible to work around this, but its really annoying.

Set time of day

There needs to be a function on Client to set the time of day it sees as well as stop time from passing.

How do we stop time from passing? This can be done using a fixed time in the dimension config, but vanilla MC can change this dynamically using the doDaylightCycle gamerule.

Can't join vanilla server through packet_inspector proxy.

How to reproduce

start a vanilla mc server

docker run -e EULA=TRUE -e ONLINE_MODE=false -d -p 25565:25565 --name mc itzg/minecraft-server

run packet inspector

cargo r -r -p packet_inspector -- 127.0.0.1:25566 127.0.0.1:25565

Open mc and connect to localhost:25566
See that you never load into the world

Notes

The disconnect occurs after the server sends the first ChunkData packet. The full error is

Error: Err(
    Error {
        context: "decoding packet after decompressing",
        source: Error {
            context: "failed to read field `block_light_arrays` from struct `ChunkData`",
            source: Error {
                kind: UnexpectedEof,
                message: "failed to fill whole buffer",
            },
        },
    },
)

This is not displayed by the packet inspector logs currently, because UnexpectedEof errors are explicitly ignored with this code.

if let Some(e) = e.downcast_ref::<io::Error>() {
    if e.kind() == ErrorKind::UnexpectedEof {
        return Ok(());
    }
}

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.