LibNetworkStack's base library.
First off: this isn't completely designed around minecraft, so if you are only interested in using this in a normal
minecraft networking you probably want to read the javadoc for the
alexiil.mc.lib.net.impl package as well.
There are a few main concepts:
- Network ID organisation
- Contextual parent network ID's
- Dynamic parent network ID's
- Data network ID's
- Signal network ID's
Network ID organisation
Network ID's are organised into a tree: the root node is always a
and the child nodes can either extend
ParentNetIdBase (for organising
NetIdBase (for sending data).
Every ID has a name, usually in the form "mod_id:mod_specific_name", however it is only important that the name not collide with other children of the same parent. These names are used to assign integer ID's to each network ID so that the full name doesn't have to be sent with each and every packet, so they must be the same at both ends!
Each individual connection has it's own
associated with it: this stores the current network ID registry, any caches, and handles reading and writing packets
out to the underlying connection.
There is a second base type: a
BufferedConnection, which will buffer
(or queue) packets until it's next "tick". This is generally a large performance optimisation if you need to send a
lot of smaller packets.
Contextual parent network ID's
In addition to organising all network nodes, any parent type that extends
ParentNetIdSingle can also write out data for it's represented object. For example you might have a network ID for a
BlockEntity, and then several children of that block entity that all need to communicate with the same entity on the
Dynamic parent network ID's
It is occasionally useful for an object to be contained within multiple different types of object, for example a buildcraft combustion engine might be contained within a block entity, or used in a flying robot. Dynamic network ID's allows the same object to communicate even if it doesn't necessarily have a single path upwards to the root.
Unlike normal ID's the dynamic parent must know the child that it will be sending, rather than the child needing to know the parent.
||The parent for a specific
||The child which doesn't know what is it's parent, but the object itself must have some way to obtain it's current
parent is via
||The per-instance link object that holds both the parent and the child network ID and objects.|
Data network ID's
These allow you to send and receive between 1 and 65,536 bytes of binary data. If you know the exact length of the
data to be sent you can pre-specify it in the constructor, or you can allow using a shorter (or longer) maximum
packet length by calling either
Data ID's come in two variants: either untyped (which are somewhat comparable to the "static" java modifier for methods), or typed, which require (and will deserialise) an object for them to be called upon.
Signal network ID's
These are very similar to data network ID's, except they won't write any data out: instead the mere presence of this packet should convey all of the information required. Two variants exist: typed and untyped depending on whether the parent has a contextual object or not.
These are a slightly more niche feature, but still useful nonetheless. Essentially these offer a way to create a registry of objects to/from integer ID's on a per-connection, per-use basis. This can help avoid a situation where you need to reliably sync a (possibly large) registry of id's right at the start of a network connection, especially if not all of those ID's will be used over it's duration.
The only class associated with caches is
NetObjectCache, and it's usage is
simple: Just create a new
ParentNetId, then pass in a hash/equals and network
serialiser implementation. (Alternatively if your data can be mapped to/from an
then you can use the function based factory:
To send an ID you can then call
get the ID that will be sent. (Note that the ID's *are* buffered by default, so you must only use them in a buffered
connection, or call
On the receiving end you can call
NetObjectCache.getObj(ActiveConnection, int) to obtain
the original object (although it will return null if the entry isn't present - either if it hasn't sent yet or you
passed it the wrong ID.
To enable debugging (also known as log spam) you can add the option "-Dlibnetworkstack.debug=true" to the launch arguments. (You can also debug caches separately with "-Dlibnetworkstack.cache.debug=true").
ClassDescriptionAn active game connection to a single receiver (and with a single sender).Debug variant of
NetByteBufthat writes the method calls to ensure that it's a perfect mirror.Unchecked exception that's thrown when one of the types doesn't match.A networking related method that wrote data to the buffer.DynamicNetId<T>DynamicNetLink<P,
C>The container objectThe side of an
ActiveMinecraftConnection.Various utilities for reading and writing dataSpecial
PacketByteBufclass that provides methods specific to "offset" reading and writing - like writing a single bit to the stream, and auto-compacting it with similar bits into a single byte.A leaf node that will send and receive messages.NetIdDataK<T>Base class for
NetIdSignal.NetIdSignalK<T>NetIdTyped<T>NetKeyMapper<T>NetKeyMapper.OfEnum<E extends Enum<E>>ParentDynamicNetId<P,
parent nodethat doesn't write any header information for it's children: the static context (given by the
IMsgWriteCtx) should be enough.The base type for all parent nodes - that is nodes used for organising the data that is sent (or for writing header information), but you can't send or receive data through this.ParentNetIdCast<Super,
Sub extends Super>ParentNetIdDuel<Parent, T>ParentNetIdExtractor<Parent, T>A
parent nodethat writes out the context for the receiver to obtain the same object.The base class for all networking ID's.