Update documentation folder

This commit is contained in:
FlorianMichael 2023-11-27 22:02:41 +01:00
parent ddec37d8c8
commit c94421bfd0
No known key found for this signature in database
GPG Key ID: C2FB87E71C425126
16 changed files with 155 additions and 94 deletions

View File

@ -12,7 +12,7 @@
</div>
# Why another protocol translator?
ViaFabricPlus is a deep integration of ViaVersion on the Fabric platform, unlike the classic Via* implementations, ViaFabricPlus implements many changes that can't be fixed on protocol level (old animations, old movement/swimming, collisions and general rendering changes).
ViaFabricPlus is a deep integration of ViaVersion on the Fabric platform, it implements many changes that can't be fixed on protocol level (old animations, old movement/swimming, collisions and general rendering changes).
At the time of writing, VFP is the only protocol translation platform for the client with which you can play on all Minecraft multiplayer versions with many QoL features and get the feel of the old versions.
### Supported Server versions
- Release (1.0.0 - 1.20.3 snapshot)
@ -60,17 +60,9 @@ At the time of writing, VFP is the only protocol translation platform for the cl
</details>
# For developers and translators
Contributions in the form of pull requests are always welcome, please just stick to my code style and make sure your code is easy to update and compatible with other mods.
### Contributions in the form of pull requests are always welcome, [here](docs/UPDATE_INSTRUCTIONS.md) are some guidelines for contributing to the project.
#### A detailed TODO list can be found at the class header of [this](https://github.com/ViaVersion/ViaFabricPlus/blob/main/src/main/java/de/florianmichael/viafabricplus/ViaFabricPlus.java) file.
### Translations
Translations for other languages are always welcome, in **~/resources/assets/viafabricplus/lang** you can find all translations, <br>
if you know a language well, feel free to make a PR and add translations for that language <br>
### Changes to the code base
If you want to make changes to the code base, please make sure that your changes are compatible with other mods and that they are easy to update.
Also, please follow my code style and make sure that cursed parts of your code are documented :tm:
A detailed TODO List can be found at the class header of [this](https://github.com/ViaVersion/ViaFabricPlus/blob/main/src/main/java/de/florianmichael/viafabricplus/ViaFabricPlus.java) file.
### Dependencies
For compiling only! **You do not need to install these!**

View File

@ -1,87 +1,64 @@
# Developer API
There is no real addon base, to create addons you can simply use the event system, which uses Fabric's Event-API.
```java
public class ViaFabricPlusExampleAddon implements ClientModInitializer {
ViaFabricPlus provides various events and APIs for developers to use. This page explains how to use them.
@Override
public void onInitializeClient() {
ChangeProtocolVersionCallback.EVENT.register(versionEnum -> {
System.out.println("Version changed to " + versionEnum.getName());
});
}
}
## Events
ViaFabricPlus events are using the [Fabric Event API](https://fabricmc.net/wiki/tutorial:events). You can register to them like this:
```java
ChangeProtocolVersionCallback.EVENT.register(versionEnum -> {
System.out.println("Version changed to " + versionEnum.getName());
});
```
#### ViaFabricPlus has 7 events at the moment:
### ViaFabricPlus has 7 events at the moment
| Callback class name | Description |
|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ChangeProtocolVersionCallback | Called when the user changes the target version in the screen, or if you connect to a server for which a specific version has been selected, you disconnect, the event for the actual version is also called. |
| FinishMinecraftLoadCallback | Called when Minecraft is finished with loading all its components |
| FinishViaVersionStartupCallback | Called when ViaVersion is loaded and ready to use |
| InitializeSettingsCallback | Called after the default setting groups are loaded and before the setting config is loaded |
| DisconnectCallback | Called when the user disconnects from a server. |
| PostGameLoadCallback | Called when Minecraft is finished with loading all its components |
| PostViaVersionLoadCallback | Called when ViaVersion is loaded and ready to use |
| RegisterSettingsCallback | Called after the default setting groups are loaded and before the setting config is loaded |
| LoadClassicProtocolExtensionCallback | Called when the classic server sends the protocol extensions (only in **c0.30 CPE**) |
| PreLoadCallback | Called before everything (Pre-pre load) |
| DisconnectConnectionCallback | Called when the user disconnects from a server. |
| LoadCallback | Called at the earliest point ViaFabricPlus is injecting too |
### General API
#### Add CustomPayload channels for versions below 1.13
## ViaVersion internals
### Add CustomPayload channels for versions below 1.13
In order to receive custom payloads with custom channels in versions below 1.13, you need to register them, that's what you do:
```java
Protocol1_13To1_12_2.MAPPINGS.getChannelMappings().put("FML|HS", "fml:hs");
```
#### Get the release version of a material:
### Check if an item exists in a specific version
```java
final VersionRange range = ItemReleaseVersionDefinition.INSTANCE.getItemMap().get(Items.WRITABLE_BOOK); // If an item does not appear in the item map, it has always existed
final VersionRange range = ItemRegistryDiff.ITEM_DIFF.get(Items.WRITABLE_BOOK); // If an item does not appear in the item map, it has always existed
// The Range class then contains all versions in which the item occurs.
// https://github.com/ViaVersion/ViaLoader
if (ItemRegistryDiff.contains(Items.STONE, VersionRange.andOlder(VersionEnum.r1_8))) {
// Do something
}
```
#### Creating own settings for the settings screen:
### Creating own settings for the settings screen
```java
public class ExampleSettingGroup extends SettingGroup {
public static final ExampleSettingGroup INSTANCE = new ExampleSettingGroup();
private static final ExampleSettingGroup instance = new ExampleSettingGroup();
public final BooleanSetting test = new BooleanSetting("Test", false);
public final BooleanSetting test = new BooleanSetting(this, Text.of("Test"), false);
public ExampleSettingGroup() {
super("Example");
}
public static ExampleSettingGroup global() {
return instance;
}
}
```
and then you register the setting group in your onLoad method:
and then you register the setting group in your onLoad method
```java
PreLoadCallback.EVENT.register(() -> {
ViaFabricPlus.INSTANCE.getSettingsSystem().addGroup(ExampleSettingGroup.INSTANCE);
RegisterSettingsCallback.EVENT.register(state -> {
if (state == RegisterSettingsCallback.State.POST) {
ViaFabricPlus.global().getSettingsManager().addGroup(ExampleSettingGroup.INSTANCE);
}
});
```
#### Implementing custom classic protocol extensions:
```java
public class ExampleExtensionSupport implements ClientModInitializer {
public static ClientboundPacketsc0_30cpe EXT_CLICK_DISTANCE;
@Override
public void onInitializeClient() {
PreLoadCallback.EVENT.register(() -> {
CustomClassicProtocolExtensions.allowExtension(ClassicProtocolExtension.CLICK_DISTANCE); // Register extension as supported
EXT_CLICK_DISTANCE = CustomClassicProtocolExtensions.createNewPacket(ClassicProtocolExtension.CLICK_DISTANCE, 0x12, (user, buf) -> buf.readShort());
});
FinishViaLoadingBaseStartupCallback.EVENT.register(() -> {
Via.getManager().getProtocolManager().getProtocol(Protocolc0_30toc0_30cpe.class).registerClientbound(EXT_CLICK_DISTANCE, null, new PacketHandlers() {
@Override
protected void register() {
handler(wrapper -> {
wrapper.cancel();
final short distance = wrapper.read(Type.SHORT);
// Do your stuff...
});
}
}, true);
});
}
}
```

View File

@ -0,0 +1,59 @@
# Updating instructions for the project
## Update translation files
Translation files are located in `src/main/resources/assets/viafabricplus/lang/`. To update them, you need to do the following:
1. Copy the `en_us.json` file and rename it to the language code of the language you want to update (e.g. `de_de.json` for German)
2. Translate all values in the file to the language you want to update
3. Do not change the keys of the values, only the values themselves
4. Do not change the formatting of the file (e.g. the spaces between the keys and values or the order of the keys)
5. Try to be consistent with Minecraft language files.
6. Take a look at UN's guidelines for Gender-inclusive language: https://www.un.org/en/gender-inclusive-language/guidelines.shtml
7. Create a pull request and wait for it to be reviewed and merged.
8. You're done, congrats!
## Add a new feature or fix a bug
1. Create a new branch for your feature/bugfix (e.g. `feature/fix-xyz` or `fix/fix-xyz`)
2. Implement your feature/bugfix and make sure it works correctly
3. Clean your code and make sure it is readable and understandable (e.g. use proper variable names)
4. Use the Google java code style (https://google.github.io/styleguide/javaguide.html) and format your code accordingly
5. If you're changing API, make sure to update the documentation in the `docs` folder, add javadocs to your code and don't break backwards compatibility if not necessary
6. Increment the version number in `gradle.properties` by at least a patch version (e.g. 1.0.0 -> 1.0.1)
7. Create a pull request and wait for it to be reviewed and merged.
8. You're done, congrats!
## Update to a new Minecraft version
1. Update all upstream versions in `gradle.properties`. The main versions you need to update are:
- `minecraft_version`
- `yarn_mappings`
- `loader_version`
- `fabric_api_version`
- `viaversion_version`
- `viabackwards_version`
- `mod_menu_version`
2. Update the `NATIVE_VERSION` field in the ProtocolHack class to the new version
3. Check all mixins in the injection package if they still apply correctly, here is a list of some critical ones:
- `MixinClientPlayerEntity#removeBl8Boolean`
- `MixinClientWorld#tickEntity` and `MixinClientWorld#tickPassenger`
- `MixinPlayer#getBlockBreakingSpeed`
4. Decompile the game source code with the tool of your choice.
5. Check all data dumps and diffs in the fixes/data package and update them if necessary, here is a list of some critical ones:
- `ResourcePackHeaderDiff` (add the new version at the top of the list)
- `ItemRegistryDiff` (add all new items/blocks added in the new version)
6. Diff the game code with the code of the previous version (e.g. using git) and implement all changes that could be relevant for ViaFabricPlus, those are:
- General logic changes (e.g. `if (a && b)` -> `if (b || a)`)
- Changes to the movement code (e.g. `player.yaw` -> `player.headYaw`)
- Networking changes (e.g. sending a new packet / changing the packet structure)
- Changes to visuals (e.g. animation changes)
- Note: ViaVersion already implements most gameplay related changes for us, but you should always check for edge-cases. Since ViaVersion
is primarily a server side plugin, it does not take care of client-side related / deeper changes.
=> If you are unsure if a change is relevant, ask in the ViaVersion discord, in general you should only implement changes
which could be detected by a server side anti cheat.
7. Check the ViaVersion/upstream protocol implementation for issues and report them if necessary or if these issues can't be fixed,
without tons of work, implement a workaround in ViaFabricPlus.
8. Run the game and check all GUIs and other visuals for issues.
9. Clean your code and make sure it is readable and understandable, clientside fixes are sorted by their protocol versions, having
newer fixes at the top of the file.
10. Increment the version number in `gradle.properties` by at least a minor version (e.g. 1.0.0 -> 1.1.0)
11. Create a pull request and wait for it to be reviewed and merged.
12. You're done, congrats!

View File

@ -1,7 +1,9 @@
# Settings and GUI
In the multiplayer screen you will find the ViaFabricPlus button in the upper left corner by default, it is the main button,
click on it, and you will see the Protocol selection, there you can choose the Minecraft version you want to connect to,
in the upper left corner you can go to the Settings.
# Usage for ViaFabricPlus
## Introduction
At the top left of the multiplayer screen is the ViaFabricPlus button, with it you can enter the main menu of the mod
where you can change the settings and set the protocol version, the position of the button can be changed in the
Settings -> General -> multiplayer screen button orientation.
![](preview/multiplayer.png)
![](preview/protocol.png)
@ -18,18 +20,32 @@ You can use the ViaVersion commands with **/viafabricplus** or **/viaversion**,
- **/viafabricplus settime <Time (Long)>** - Changes the Clientside World Time, available from: **c0.28-c0.30**
- **/viafabricplus listextensions** - Displays all classic protocol extensions, available in: **c0.30 CPE**
### Settings are optional settings that can turn fixes on and off, originally they were used for debugging<br>
### Settings<br>
For users only the settings in the **General**, **Bedrock**, **Authentication** and **Visual** tab are relevant, the other settings are only for developers, you should not change the settings in the **Debug** tab if you don't know what you are doing.
![](preview/settings.png)
## Bedrock edition
### Configuring the protocol translation libraries
To change the protocol translation settings/features you can look into the ViaLoader folder. You can find 4 config files there depending on the platforms loaded:
- viaversion.yml (ViaVersion)
- viabackwards.yml (ViaBackwards)
- vialegacy.yml (ViaLegacy)
- viabedrock.yml (ViaBedrock)
On it's first launch, ViaFabricPlus will generate the config files with proper default values. Don't touch the config files if you don't know what you are doing.
## Debug HUD
The debug HUD can be enabled in the settings, it shows some useful information about the connection and the protocol translation.
![](preview/debug_hud.png)
### Bedrock edition
Keep in mind that the Java -> Bedrock support is still in beta phase, and therefore many things are not implemented
yet and there is no guarantee that everything will work as it should.
To log in to a Bedrock account you can press the button **"Click to set account for Bedrock edition"** in the settings,
then you can log in via device login, the account logged in there will be stored in **~/ViaFabricPlus/bedrock.account**.
then you can log in via device login, the account logged in there will be stored in **/minecraft./config/viafabricplus/accounts.json**.
## ClassiCube and BetaCraft integration
### ClassiCube and BetaCraft integration
In the main GUI there is an extra button for ClassiCube and BetaCraft, both buttons send API requests to the respective platforms to get the respective server list.
## BetaCraft
![](preview/betacraft.png)
@ -38,4 +54,5 @@ In the main GUI there is an extra button for ClassiCube and BetaCraft, both butt
![](preview/classicube.png)
For ClassiCube you need an account, which you can make on the official website (https://www.classicube.net/), in case ClassiCube requires MultiFactor, an extra GUI will open in ViaFabricPlus.
![](preview/classicube-login.png)
![](preview/classicube_login.png)
The ClassiCube account will be stored in **/minecraft./config/viafabricplus/accounts.json**.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 382 KiB

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 393 KiB

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

BIN
docs/preview/debug_hud.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 746 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 371 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 397 KiB

After

Width:  |  Height:  |  Size: 149 KiB

View File

@ -26,6 +26,7 @@ import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.item.Item;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.data.ClassicProtocolExtension;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.storage.ExtensionProtocolMetadataStorage;
import net.raphimc.vialoader.util.VersionEnum;
import net.raphimc.vialoader.util.VersionRange;
import java.util.ArrayList;
@ -39,8 +40,8 @@ import static net.raphimc.vialoader.util.VersionRange.*;
public class ItemRegistryDiff {
private static final Map<Item, VersionRange> ITEM_DIFF = new HashMap<>();
private static final List<Item> EXTENDED_CLASSIC_ITEMS = new ArrayList<>();
public static final Map<Item, VersionRange> ITEM_DIFF = new HashMap<>();
public static final List<Item> EXTENDED_CLASSIC_ITEMS = new ArrayList<>();
static {
ITEM_DIFF.put(CHERRY_LOG, andNewer(r1_20tor1_20_1));
@ -1355,6 +1356,10 @@ public class ItemRegistryDiff {
// https://minecraft.gamepedia.com/Java_Edition_version_history
}
/**
* @param item The item to check
* @return true if the item exists in the current version, false otherwise, this will also check for CPE items (CustomBlocks V1 extension)
*/
public static boolean keepItem(final Item item) {
if (ProtocolHack.getTargetVersion().equals(c0_30cpe)) {
final ClientPlayNetworkHandler handler = MinecraftClient.getInstance().getNetworkHandler();
@ -1362,7 +1367,7 @@ public class ItemRegistryDiff {
// Don't drop any items if the connection is not established yet
return true;
}
final ExtensionProtocolMetadataStorage extensionProtocol = ((IClientConnection)handler.getConnection()).viaFabricPlus$getUserConnection().get(ExtensionProtocolMetadataStorage.class);
final ExtensionProtocolMetadataStorage extensionProtocol = ((IClientConnection) handler.getConnection()).viaFabricPlus$getUserConnection().get(ExtensionProtocolMetadataStorage.class);
if (extensionProtocol == null) { // Should never happen
return false;
}
@ -1371,7 +1376,16 @@ public class ItemRegistryDiff {
}
}
return !ITEM_DIFF.containsKey(item) || ITEM_DIFF.get(item).contains(ProtocolHack.getTargetVersion());
return contains(item, ProtocolHack.getTargetVersion());
}
/**
* @param item The item to check
* @param version The version to check
* @return true if the item is present in the version, false otherwise
*/
public static boolean contains(final Item item, final VersionEnum version) {
return !ITEM_DIFF.containsKey(item) || ITEM_DIFF.get(item).contains(version);
}
}

View File

@ -31,6 +31,7 @@ import java.util.HashMap;
import java.util.Map;
public class ResourcePackHeaderDiff {
private final static Map<VersionEnum, GameVersion> GAME_VERSION_DIFF = new HashMap<>();
static {

View File

@ -72,7 +72,7 @@ public abstract class MixinDebugHud {
information.add("");
// Title
information.add(ChatUtil.PREFIX + Formatting.GRAY + " " + ViaFabricPlusMixinPlugin.VFP_VERSION);
information.add(ChatUtil.PREFIX + Formatting.RESET + " " + ViaFabricPlusMixinPlugin.VFP_VERSION);
// common
final ProtocolInfo info = userConnection.getProtocolInfo();

View File

@ -70,39 +70,40 @@ public abstract class MixinConnectScreen_1 {
return instance.getPort();
}
@Inject(method = "run", at = @At(value = "INVOKE", target = "Lio/netty/channel/ChannelFuture;syncUninterruptibly()Lio/netty/channel/ChannelFuture;", shift = At.Shift.AFTER))
@Inject(method = "run", at = @At(value = "INVOKE", target = "Lio/netty/channel/ChannelFuture;syncUninterruptibly()Lio/netty/channel/ChannelFuture;", remap = false, shift = At.Shift.AFTER))
private void setupConnectionSessions(CallbackInfo ci, @Local ClientConnection clientConnection) {
final UserConnection userConnection = ((IClientConnection) clientConnection).viaFabricPlus$getUserConnection();
if (userConnection == null) return;
if (userConnection == null) {
return;
}
final VersionEnum targetVersion = ProtocolHack.getTargetVersion();
final var targetVersion = ProtocolHack.getTargetVersion();
if (targetVersion.isBetweenInclusive(VersionEnum.r1_19, VersionEnum.r1_19_1tor1_19_2)) {
final var keyPair = MinecraftClient.getInstance().getProfileKeys().fetchKeyPair().join().orElse(null);
if (keyPair != null) {
final PlayerPublicKey.PublicKeyData publicKeyData = keyPair.publicKey().data();
final var publicKeyData = keyPair.publicKey().data();
final var uuid = MinecraftClient.getInstance().getSession().getUuidOrNull();
final UUID playerUuid = MinecraftClient.getInstance().getSession().getUuidOrNull();
userConnection.put(new ChatSession1_19_1(playerUuid, keyPair.privateKey(), new ProfileKey(publicKeyData.expiresAt().toEpochMilli(), publicKeyData.key().getEncoded(), publicKeyData.keySignature())));
userConnection.put(new ChatSession1_19_1(uuid, keyPair.privateKey(), new ProfileKey(publicKeyData.expiresAt().toEpochMilli(), publicKeyData.key().getEncoded(), publicKeyData.keySignature())));
if (targetVersion == VersionEnum.r1_19) {
final var legacyKey = ((ILegacyKeySignatureStorage) (Object) publicKeyData).viafabricplus$getLegacyPublicKeySignature();
if (legacyKey != null) {
userConnection.put(new ChatSession1_19_0(playerUuid, keyPair.privateKey(), new ProfileKey(publicKeyData.expiresAt().toEpochMilli(), publicKeyData.key().getEncoded(), legacyKey)));
} else {
ViaFabricPlus.global().getLogger().error("Failed to fetch legacy key, can't setup ChatSession");
userConnection.put(new ChatSession1_19_0(uuid, keyPair.privateKey(), new ProfileKey(publicKeyData.expiresAt().toEpochMilli(), publicKeyData.key().getEncoded(), legacyKey)));
}
}
} else {
ViaFabricPlus.global().getLogger().error("Failed to fetch keyPair, can't setup ChatSession");
ViaFabricPlus.global().getLogger().error("Could not get public key signature. " + targetVersion.getName() + " with secure-profiles enabled will not work!");
}
} else if (targetVersion == VersionEnum.bedrockLatest) {
var bedrockSession = ViaFabricPlus.global().getSaveManager().getAccountsSave().refreshAndGetBedrockAccount();
final var bedrockSession = ViaFabricPlus.global().getSaveManager().getAccountsSave().refreshAndGetBedrockAccount();
if (bedrockSession != null) {
final var deviceId = bedrockSession.getMcChain().getXblXsts().getInitialXblSession().getXblDeviceToken().getId();
final var playFabId = bedrockSession.getPlayFabToken().getPlayFabId();
final var mcChain = bedrockSession.getMcChain();
userConnection.put(new AuthChainData(mcChain.getMojangJwt(), mcChain.getIdentityJwt(), mcChain.getPublicKey(), mcChain.getPrivateKey(), deviceId, playFabId));
} else {
ViaFabricPlus.global().getLogger().warn("Could not get Bedrock account, joining online mode servers will not work!");
}
}
}