Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements #24

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open

Improvements #24

wants to merge 9 commits into from

Conversation

Oryxel
Copy link

@Oryxel Oryxel commented Sep 4, 2024

Just a new pr, #23

This is the improvements I made for BedrockSkinUtility, that is already got mention here #22

Refactor a lot of code since and replace many with my own version of the implement, since some model/skin/cape translate fine but won't show up and also models that have really unique model that doesn't look like the player won't works. So I just deleted a lot part of the code and reimplement it, works perfect fine after that.

Parsing model is switched to a library I write that allowed support for per-face uv map, and more.
Most of the changes can be listed in #22.

This haven't been tested on GeyserSkinManager but I test it using ViaBedrock instead.

Here is some images after the changes I made:
test3
test1
test2
test4

@@ -23,7 +23,8 @@ public String getRefMapperConfig() {

@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
if (mixinClassName.equals("net.camotoy.bedrockskinutility.client.mixin.CapeFeatureRendererMixin")) {
if (mixinClassName.equals("net.camotoy.bedrockskinutility.client.mixin.CapeFeatureRendererMixin") ||
mixinClassName.equalsIgnoreCase("net.camotoy.bedrockskinutility.client.mixin.AbstractClientPlayer")) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will never be called as the class name is AbstractClientPlayerMixin


import net.minecraft.resources.ResourceLocation;

public record CustomCapeData(ResourceLocation cape) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For one parameter, having a whole class seems unnecessary.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class can be deleted.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class can be deleted.

done

@Redirect(method = "render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;ILnet/minecraft/client/player/AbstractClientPlayer;FFFFFF)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/AbstractClientPlayer;isModelPartShown(Lnet/minecraft/world/entity/player/PlayerModelPart;)Z"))
public boolean isModelPartShown(AbstractClientPlayer instance, PlayerModelPart playerModelPart) {
return SkinManager.getInstance().getCapeData().get(instance.getUUID()) != null;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can just be a containsKey call.

import java.util.UUID;

@Mixin(Entity.class)
public abstract class EntityMixin {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be an unused class.

@Oryxel
Copy link
Author

Oryxel commented Sep 6, 2024

These are the changes that you requested, EntityMixin is there so I can get UUID from AbstractClientPlayerMixin.

@Camotoy
Copy link
Owner

Camotoy commented Sep 7, 2024

Instead, can you extend AbstractClientPlayerMixin from Entity or another class? That should also do the job and keep things to one file.

@Oryxel
Copy link
Author

Oryxel commented Sep 7, 2024

Instead, can you extend AbstractClientPlayerMixin from Entity or another class? That should also do the job and keep things to one file.

That should do it, is there anything else?


// Construct a list of all bones we need to translate
List<JsonObject> bones = new ArrayList<>();
if (info.getGeometryRaw() == null || info.getGeometryRaw().isEmpty())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brackets

}
}
}
if (geometry == null)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brackets

final List<ModelPart.Cube> cuboids = new ArrayList<>();
float pivotX = (float) bone.pivot()[0], pivotY = (float) bone.pivot()[1], pivotZ = (float) bone.pivot()[2];
Bone parentBone = null;
if (!bone.parent().isEmpty())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brackets

if (parentBone != null) {
// This appears to be a difference between Bedrock and Java - pivots are carried over for us
part.setPos((float) (pivotX - parentBone.pivot()[0]), (float) (pivotY - parentBone.pivot()[1]), (float) (pivotZ - parentBone.pivot()[2]));
} else part.setPos(pivotX, pivotY, pivotZ);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brackets

for (Map.Entry<String, PartInfo> entry : stringToPart.entrySet()) {
if (entry.getValue().parent != null) {
PartInfo parentPart = stringToPart.get(entry.getValue().parent);
if (parentPart != null)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brackets

if (parentPart != null)
parentPart.children.put(entry.getKey(), entry.getValue().part);
else {
if (root != null && entry.getValue().part != root.part) // put to root if you can't find the parent.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brackets

return new BedrockPlayerEntityModel<>(root.part);
} catch (Exception e) {
LOGGER.error("Error while parsing geometry into model!", e);
if (root == null)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brackets

case "leftLeg" -> "left_leg";
case "rightLeg" -> "right_leg";
// it can be lowercase, use lowercase...
return switch (name.toLowerCase()) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toLowerCase(Locale.ROOT)

}

public void handle(BaseSkinInfo payload) {
if (payload == null)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brackets

}

public void handle(SkinData payload, ClientPlayNetworking.Context context) {
if (payload == null)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brackets


// Convert Bedrock JSON geometry into a class format that Java understands
BedrockPlayerEntityModel<AbstractClientPlayer> model = GeometryUtil.bedrockGeoToJava(info);
if (model == null)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brackets


stringToPart.put(name, new PartInfo(adjustFormatting(parent), part, children));
// Please lowercase this, it can be lowercase...
switch (name.toLowerCase()) { // Also do this with the overlays? Those are final, though.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toLowerCase(Locale.ROOT)


@Redirect(method = "render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;ILnet/minecraft/client/player/AbstractClientPlayer;FFFFFF)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/AbstractClientPlayer;isModelPartShown(Lnet/minecraft/world/entity/player/PlayerModelPart;)Z"))
public boolean isModelPartShown(AbstractClientPlayer instance, PlayerModelPart playerModelPart) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the cape will show up? Look at the code and after double check it seems like it is needed for the cape to show up.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redirecting this means that Java capes won't show because our cape map won't include official Java player capes. Also, this isModelPartShown redirects to player entity data and not anything in the rendering system. Is there an instance where this was actually needed?

Copy link
Author

@Oryxel Oryxel Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redirecting this means that Java capes won't show because our cape map won't include official Java player capes. Also, this isModelPartShown redirects to player entity data and not anything in the rendering system. Is there an instance where this was actually needed?

Added so now it also check for isModelPartShown, it used to check if the client should render a certain player cape, which in isModelPartShown it get entity data which is normally sent my by the server as my knowledge. Which is not going to get send on ViaBedrock, and maybe GeyserMC which I don't know.

I double check and do some debugging and the cape seems to not showing up without this part of code, if you have any doubt just debug it yourself.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this part of the code. I understand its use, but I don't want to erase the functionality of hiding a cape if Geyser ever decides to utilize it (technically, a server can already hide the cape of a player if it so desires). I have ran this by RK.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this part of the code. I understand its use, but I don't want to erase the functionality of hiding a cape if Geyser ever decides to utilize it (technically, a server can already hide the cape of a player if it so desires). I have ran this by RK.

Done.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it as you requested.

@Oryxel Oryxel requested a review from Camotoy September 11, 2024 15:39
@Camotoy
Copy link
Owner

Camotoy commented Sep 15, 2024

Getting around to testing this. I have an HD skin from the Bloom marketplace pack (should be free), and there's a portion of the overalls on the chest that aren't showing.
However... can you elaborate on why you changed the format of how skins are stored? It seems that the Java skin the server sends is now liable to leaking out. (And I can't send a screenshot of what I mean)

@Oryxel
Copy link
Author

Oryxel commented Sep 15, 2024

Getting around to testing this. I have an HD skin from the Bloom marketplace pack (should be free), and there's a portion of the overalls on the chest that aren't showing. However... can you elaborate on why you changed the format of how skins are stored? It seems that the Java skin the server sends is now liable to leaking out. (And I can't send a screenshot of what I mean)

I'm not sure what happening about HD skins that you talking about, but the reason I changed how skins are stored because a lot of models and skins refused to show up even tho server still send them

These one for example which I already show up there.
image

@Oryxel
Copy link
Author

Oryxel commented Sep 15, 2024

I will test it with the bloom skins to see what wrong

@Oryxel
Copy link
Author

Oryxel commented Sep 15, 2024

Getting around to testing this. I have an HD skin from the Bloom marketplace pack (should be free), and there's a portion of the overalls on the chest that aren't showing. However... can you elaborate on why you changed the format of how skins are stored? It seems that the Java skin the server sends is now liable to leaking out. (And I can't send a screenshot of what I mean)

Found the issues, the HD skin Bloom needed custom geometry, but when the client received it it's just "null", so it applied skin without geometry, results the skin missing some parts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants