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

1.20.4 support #179

Open
Libreh opened this issue Feb 28, 2024 · 16 comments
Open

1.20.4 support #179

Libreh opened this issue Feb 28, 2024 · 16 comments

Comments

@Libreh
Copy link

Libreh commented Feb 28, 2024

I was wondering if 1.20.4 support is planned?

@samolego
Copy link
Owner

You can compile branch #rewrite/polymer to get experimental 1.20.4 support

@Libreh
Copy link
Author

Libreh commented Feb 28, 2024

Oh, thanks!

@Musikid-Official
Copy link

Hello, I was planning on doing the same but I have no idea how to compile a Maven repo, can anyone help?

@DivannKokos
Copy link

Hello, I was planning on doing the same but I have no idea how to compile a Maven repo, can anyone help?

i don't know anything about maven, but compiling github is
download https://github.com/samolego/Taterzens/tree/rewrite/polymer branch zip
extract to somewhere
open cmd in that folder
gradlew build
wait (it can take several minutes)
once it is done, jar will be in Taterzens-rewrite-polymer\build\libs folder

warning i'm not a programmer at all but i think it works and i am doing it right

@UntalentedAmateur
Copy link

Hi,

I haven't forked the project (yet), but I'm willing to provide a pull request of the diffs I've ended up making to the polymer branch to get Taterzens running smoothly on 1.20.4.

What I've managed to achieve / get working / stop breaking sooooo badly:

  • You can summon NPCs!
  • You can unsummon NPCs!
  • NPCs are still NPCs and don't appear in the tab list.
  • Right clicking them (or just clicking them) by accident will no longer crash the server (embarrasing when it's a hidden mod on a public SMP server)
  • Equipping hand and body slots with items works.
  • NPC commands work (I now use this as a very generous single item trader, or I'm now the ultimate schoolyard bully - punching smaller kids until they give me their lunch money).
  • Skin change integration with FabricTailor seems to work, though it NEEDS to be no later than v2.3.1 to be compatible. Skin changes also seem to be persistent between player logons. FabricTailor has its own quirks, but if you can do those incantations correctly, then it will carry across to the NPC integration.

What is stubbornly refusing to play the game:

  • Any sort of GUI... (and hence scarpet profession)
  • Setting NPCs to other types (but I see that code commented out and haven't poked it yet)
  • In-game text doesn't want to read the proper language files, but at least it's not stubbornly breaking the entire mod (which it was at one point).

I've yet to make them walk and talk and fight and love and all that, but to have reliable NPCs that shower me with gifts is more than I really expected to begin with.

It seems, from a lot of digging elsewhere, that the big issue that this mod (and any other mod with added npcs) is that GameProfile (part of the Mojang authlib) changed quite significantly post-1.20, and you can no longer summon NPCs without a UUID. It also seems that the Packet Faker trick stopped working about the same time.

What seems to have worked here is generating a clean UUID in-mod and Minecraft stops complaining (at least in the log files it's not complaining). In the end the total code changes were fairly tiny, but they really seemed to generate a whole host of cascading problems before I stomped them.

Fair warning, this code is the result of a COVID-ravaged mind, so may be full of strange creatures and deluded fixes, but it seems stable and doesn't crash the server when I stare at it hard, so caveat emptor. I don't think anyone was able to tell between the different type of vacant glassy stare that is COVID and code review. One has slightly less drool.

Well, I'm off to ask the curtains why the walls keep moving. They say don't code or commit while drunk. I guess this isn't much different.

@samolego
Copy link
Owner

Doesn't the polymer do all heavylifting now on the rewrite branch, regarding uuids, packets etc? Do you mean anything specific?

@UntalentedAmateur
Copy link

UntalentedAmateur commented May 18, 2024

Uh, maybe? I did say it was the code of a COVID riddled mind. I'll admit I stopped looking for where the fake UID initiation went from the mixin with the polymer branch once I got things running.

The key lines from the server crash(es) that happen with the current polymer branch builds are:

[10:36:46] [Server thread/ERROR]: Encountered an unexpected exception
java.lang.NoClassDefFoundError: Could not initialize class org.samo_lego.taterzens.fabric.gui.EditorGUI
....
....
....
Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.NullPointerException: Profile ID must not be null [in thread "Server thread"]
	at java.util.Objects.requireNonNull(Objects.java:235) ~[?:?]
	at com.mojang.authlib.GameProfile.<init>(GameProfile.java:30) ~[authlib-6.0.52.jar:?]
	at org.samo_lego.taterzens.fabric.gui.EditorGUI.<clinit>(EditorGUI.java:378) ~[taterzens-1.11.7.jar:?]

And this happens whenever you right click on an NPC. If you're in equipment mode, right clicking is fine, it's the rest of the time that it crashes. I initially thought it was due to spawn protection, but it kept happening even when lots of blocks away from spawn.

The line it trips up on is

		GameProfile texturesProfile = new GameProfile(null, "taterzen");

from EditorGUI.java. Yes, I was wondering where the other UUIDs were coming from, but couldn't find the NPC initiation code elsewhere. I checked to see how other mods handled fake players and added a line to generate a random UUID, and then modified the above line to replace null. That stopped the crashes. The section of code where that line is seems to only deal with skin textures, so doesn't explain why the GUI still isn't showing, but it was enough to prevent the right click crash. I can try to find where the UUID is being generated by polymer and make sure it is picked up there (which will make it neater, of course). It also doesn't propagate anywhere else in the mod, and nothing else seems dependent on this specific GameProfile call, so I was confident that generating a one-off UUID would be fine to make things happy.

Then, once I got that to build (and had to change the build version in gradlew.properties or else FabricTailor refused to talk to it), I started seeing this error appear:

[22:46:04] [Server thread/ERROR]: Failed to handle packet net.minecraft.class_2824@221a2b39, suppressing error
java.lang.NullPointerException: Cannot invoke "com.google.gson.JsonObject.has(String)" because "org.samo_lego.taterzens.common.Taterzens.lang" is null

This didn't crash the server (yay!), but npc commands weren't working, and a lot of the mod functionality just didn't want to work. Plus, I didn't want to solve one problem just to leave another one that was going to generate log spam.

I was able to trace this back to the declaration of the language file in Taterzens.java

   /**
    * Language file.
    */
   public static JsonObject lang;

The problem being that lang is never defined or declared anywhere. In the .config file the language file is declared as

"language" = "en_us";

but changing this to "lang" breaks several locations in code where it is looking for "language". Rather than replace all "lang" with "language" (or vice versa) in the code, I found it easiest to add an extra line to TaterConfig.java:

 public String language = "en_us";
	// Add an extra?
   public String lang = "en_us";

Building against this new set of fixes (and tossing my old config file so it could generate the new one) and there were ZERO errors appearing in the logs. I still wasn't seeing stuff appearing from en_us.json, but the npc commands started working correctly. While the lack of a GUI might also explain the scarpet professions issue, I was happy to get a stable and mostly functional build.

I apologise if I've broken logic anywhere, but I'm trying to codewalk in a language I do not know (Java) in order to squash bugs in a codebase that's under significant modification (polymer vs master branch) and which is trying to catch up to poorly documented engine changes that break key mod functionality (mojang GameProfile changes).

The upside is that it was five total lines of code changed (not counting comments), three in EditorGUI (I had to include the UUID import), one in TaterConfig, and ensuring a decent mod_version in gradle.properties.

@UntalentedAmateur
Copy link

UntalentedAmateur commented May 21, 2024

Good news everyone!

No, the COVID hasn't fixed itself. But, that means I've been chasing all sorts of bugs down rabbit holes. And I've met a couple of Cheshire cats.

In trying to create some sort of convoluted mess around the lang definition, I discovered that there's a couple of parts to this that ultimately need fixing. While trying to do a direct read from the .json file that LanguageUtil.java thinks should be default, I discovered that the src folder layout has changed somewhat across the versions, and it's looking in entirely the wrong location for the polymer branch.

So, I gave up on that for a moment to think about it and realised the easy fix to the lang being null issue was just to have

public static JsonObject lang = new JsonObject();

What that has done is actually allowed the GUI to start working...

So, yay!, we now have working GUI as well. I'm still not quite getting the .json language files to read, but I'm not far off.

@UntalentedAmateur
Copy link

Even better!

I have the language files working, and working properly. I fixed the path for the language files. Then I found that the Server Translations API was blocking the jsons from being read for the translate / ingame function.

The files were loaded in-memory, but that API was stopping things. I couldn't see anywhere it was actually used (or what it was), so commented it out of TextUtil.java and it worked brilliantly. I'll upload everything into my forked copy, confirm it works again and then send a pull request back.

The last thing to do is to use the existing UUID where I'd inserted that placeholder and it will be complete.

Sum total of changes is still about half a dozen lines (ignoring all the logging I've been doing to track variables), but @samolego , there's a couple of lines that need to be changed but I'm not sure where you want them to point. Lines 28,29 of LanguageUtil.java, where API_URL and LANG_FILE_URL point. They don't align with the polymer structure.

Personally, I'd remove them in-toto, but they'll need fixing if they're kept.

@UntalentedAmateur
Copy link

With the GUI working, I've looked closer at that problematic GameProfile entry that I'd made the UUID for. All it does is generate the playerheads that act as buttons / selectable items in the GUI...

So, I'm going to leave it as is, and now turn my attention to see if I can get Disguiselib to work.

@samolego
Copy link
Owner

samolego commented May 21, 2024

They don't align with the polymer structure.

What? That's nothing to do with polymer?

The current language system is designed (/was designed) so that if language doesn't exist, it fetches it from GH (if there is one), fallback is english. Then, if server-translations-api is loaded, it doesn't translate keys, otherwise it does.

This was from the forge era, where STAPI doesn't exist. So the whole thing (except for new language fetching) could be removed tbf. And the mod would just bundle the STAPI in the end.

@UntalentedAmateur
Copy link

It's the different structure in the rewrite/polymer branch. So, yeah it's not specifically polymer, but I need to explain that it's a different file structure to the master branch.

There's some relative file references which map to the master branch structure, but it's different for rewrite/polymer. The callbacks to github point to master branch, but this is manipulating the rewrite/polymer branch. Hence leaving it open as to what happens with those callbacks.

I hope that makes more sense.

That makes a lot of sense about the forge and STAPI thing. It wasn't something I wanted to remove carte blanche, as I hadn't found anything that might have still relied upon it and the way it had been declared looked important.

I think it's an absoutely amazing mod and you did an incredible job writing it.

@samolego
Copy link
Owner

Thanks for explaining, I was really confused to what you meant 😅 .

@UntalentedAmateur
Copy link

Unfortunately I haven't been able to get disguiselib to work. It builds fine, and I've even been able to convince the IDEs to allow it to be included, but it seems there's one error deep in disguiselib that trip up taterzens (to do with the minecraft entity class manipulation). I think it keeps throwing out the intermediary class_1299, but that's it and refuses to work.

I can see from the gradle.build that @samolego encountered much the same problem in trying to convince fabric to allow the snapshot / specific commit to be brought in, and I had similar issues with a built version that it wouldn't link. While the fabric gradle build process can fail silently on that stuff (which is annoying), I suspect it was tripping over the error in disguiselib and throwing out the result at that point.

Until there's a new package / updated build actually released through the disguiselib project I don't think I can do any more on getting it working. Sorry.

I have had vastly more success getting trading to work. I've gone down the path of using the scarpet script, since TraderNPCs doesn't integrate at the moment, and I already had carpet installed. I can put more detail over on that repo but, since it gives crucial support to taterzens that a lot of people might be wanting, I'll describe the enhancements here.

It's all still just the one merchants.sc script, but now it filters based on taterzens name. That way if you right click / interact with a non-trader NPC it won't run through the entire script worth of action. It also means that "merchant" trades are filterable to different npcs and not just the case that every npc with the scarpet profession could do every trade.

I've replaced the throw and pickup method with calling a merchant "screen" (what the carpet mod calls the ui billboard you get when engaging with a merchant / opening a chest, etc). It has configurable naming on the merchant trade screen, and will read the trade recipes that you've defined for that particular merchant. Unfortunately, I can't get it to populate the trade offers side of the screen (and I looked for ages on that), but I've got it to properly strip items from inventory / offer once the trade is accepted, and to handle variations from the defined trade level (multiples and partial offers).

The benefit of this approach is dedicated trade offers based on different npc config (name driven at the moment), and even different npcs being able to offer different trades for the same source items. Since it's calling a merchant screen with two offer slots, you can define some nice and detailed trade offers. For example, I have a Forester (and that's the name that triggers that particular trade set) who sells saplings of any tree type for three logs of that tree and three sticks. There's no throwing items, you walk up and right click and trade away. You just need to know what the trades are, since the offers aren't shown. When I change the Forester to a Carpenter, that log and stick trade matches an offer for planks (I was testing to see if I could have the same trade inputs result in different offers from different NPCs).

One issue I encountered, and I really don't know where this originates from, is that the NPC name can sometimes have invisible non-string characters (even when I know the name doesn't have any) and scarpet gets confused at times as to whether it's looking at a string. I'm thinking it's a scarpet issue, but not sure (scarpet is really bad at identifying and dealing with errors). The solution is to cast to a string inside the merchant script and be done with it.

So, what's the final state that I have everything at?

I have taterzens building to 1.20.4. NPCs can be summoned and unsummoned and most interactions with them work. The gui works and you can do pretty much all of the configuration in there. Unfortunately, disguiselib hasn't integrated, so the ability to change the entity type isn't working. Commands work fine, and FabricTailor integrates well (but only to 2.3.1). Skin and equipment changes also are persistent. Permission levels also seem to be working well, too.

With the recent work on the scarpet merchant script as described above, I can now configure server-wide unique per-NPC trading offers that work through a near-standard Minecraft merchant trade screen.

I haven't tested saving and recalling NPCs as presets, but I do have them remaining persistent in my test world (and hidden in my live server) across multiple logins. I also haven't tested making them interact with blocks, but their pathing, movement and posing functions are fine.

I'll push a build integrating the changes I've made, as well as my new merchant.sc script onto a live SMP server (I won't advertise it here, but it's not hard to track down if you look at my various socials) this weekend, so people will be able to see the mod working in a 1.20.4 context with multiple live players at different permissions levels.

@samolego
Copy link
Owner

Good job!
Perhaps UUID would be a suitable choice? As usernames might not be unique.

@UntalentedAmateur
Copy link

UntalentedAmateur commented May 24, 2024

That's a good idea, but I don't know if scarpet sees the UUID with the entity - it only seems to reply with the name when I polled it. You're right that usernames won't always be unique, but that means two same-name NPCs that are also traders will just have the same trades. With UUIDs there's no way to ensure that without a lot of duplication in the script.

Many ways to solve the same problem - I just worked out how to scratch the particular itch I had.

Oh, and I couldn't get traits to work at all, so that would be another option if it was able to work again.

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

No branches or pull requests

5 participants