Westwud1 / QuickStack

10 stars 5 forks source link

Multiplayer functionality. Works in Host+Client or in Dedicated Server #3

Closed misterperson closed 2 years ago

misterperson commented 2 years ago

Fix for #2

I've only tested this shallowly on a private server and private hosted session with another person, but this handles locking containers, making sure they are actually accessible, etc. Everything is still mostly client-sided because Clients are authoritative about their bags.

Source/Patches.cs Client: Clicks UI button to initiate a quickstack / restock

Source/NetPackages/NetPackageFindOpenableContainers.cs Server: Receives request and populates a list of allowed containers, marking them all as in-use. The list is populated with a center and offsets. The offsets are in bytes to try and reduce bandwidth where possible, but limits the max stackRadius to 127. No checks are made, and probably should be.

Source/NetPackages/NetPackageDoQuickStack.cs Client: Quickstacks / restocks into all containers and notifies server they can be unlocked as-if the UI was double-clicked

Source/NetPackages/NetPackageUnlockContainers.cs Server: Marks all containers listed as not in-use

There's still the question of what double-clicking the UI button should do or if the player should press a modifier key in multiplayer or whether a cooldown on either button is warranted.

misterperson commented 2 years ago

I built the Debug version by accident

misterperson commented 2 years ago

Okay, in my experience actually using this, the restock button using FillAndCreate is pretty bad. Filling my inventory full of bullets bad.

Westwud1 commented 2 years ago

Thank you for taking the time to do this. I don't have anyone to test the multiplayer functionality with.

I did some testing and singleplayer seems to be working fine as before.

For multiplayer, I've set the quicstack/restock buttons to be always visible and fired up a dedicated server to test it. I didn't see any issues, but that might be because there's no latency.

The double clicking on the UI should be doing what it's currently doing. The first click should be FillOnly, and a second click (within 2 seconds) should be FillAndCreate. What would happen if you just added the code like on singleplayer?

XUiM_LootContainer.EItemMoveKind moveKind = XUiM_LootContainer.EItemMoveKind.FillOnly;
if (unscaledTime - lastClickTime < 2.0f)
    moveKind = XUiM_LootContainer.EItemMoveKind.FillAndCreate;

This would first send a request for FillOnly and if you click again within 2 second, it would send another one for FillAndCreate. Would this cause any issues? I'm assuming the first request would have to finish first (and that might take some time with higher latency) which is why you removed it.

Finally, looking at the code, the hotkeys Alt+Z and Alt+X seem to use the singleplayer function regardless if it's a server or not. I would recommend reverting Patches.cs changes and leave it as it was, then create 4 more functions in Quickstack.cs: QuickStackSP, QuickStackMP, MoveQuickRestockSP and MoveQuickRestockMP. Move the code from QuickStack to QuickStackSP (same for restock) and do the isSinglePlayer check there:

if (ConnectionManager.Instance.IsSinglePlayer)
    QuickStackSP();
else
    QuickStackMP();

I would also remove the _stackRadius parameter as it seems redundant since you always call it with QuickStack.stackRadius.

All things considered, great work, this seems really promising. Hopefully you can fix the restock issue :)

misterperson commented 2 years ago

There are actually 3 version of quick stacking because the host can't send a NetPackage to themselves. There's SinglePlayer, Multiplayer (Client), and Multiplayer (Host).

But I will bring those function calls out of #Patches.cs and continue making tweaks

misterperson commented 2 years ago

My friends and I used this build for about 8 hours yesterday with no issue, except that not having double-click functionality meant that quick restock was filling everyone's inventory and wasn't safely pressable.