Skip to content
This repository has been archived by the owner on Aug 11, 2020. It is now read-only.

Copied from Zethrith issue #32 - Problems with reinstalling furniture #25

Open
Aivaria opened this issue Apr 5, 2019 · 10 comments
Open

Comments

@Aivaria
Copy link
Contributor

Aivaria commented Apr 5, 2019

src: Zetrith/Multiplayer#32
Selected tools get unselected on other client once the reinstall gets used. I stumbled across this multiples times when playing with a friend myself

@Aivaria
Copy link
Contributor Author

Aivaria commented Apr 5, 2019

im trying to figure this out.
image of ingame debug to trace down the cause
https://puu.sh/Daomh/2e073ce352.png

@MilanDierick
Copy link
Contributor

Please provide a link to an issue in another repository.

@MilanDierick
Copy link
Contributor

@Aivaria Do you have any more information regarding this bug?

@MilanDierick
Copy link
Contributor

MilanDierick commented Apr 7, 2019

@Aivaria I just did some quick digging. I started at OnMainThread:66, the SendCursor method. Then when I start traversing the call stack, following this path: OnMainThread:91 -> Networking:123 -> Networking:164 , I hit the abstract method SendRaw(). This method is overridden by LocalClientConnection, LocalServerConnection, StreamBaseConnection, ReplayConnection and MpNetConnection. When looking at the implementation of LocalClientConnection as an example, we can see that an action is enforced on a MultiplayerServer instance, which passes the data to the HandleReceive method. The data is then to another HandleReceive method, which in turn does some checks on the data, forms a packet and sends it to a PacketHandlers instance. When memory serves right, the PacketHandlers instance is picked up by reflection, and send to the server.

This is as far as I'm going to go for tonight, it's getting late. It always help to start from the bottom and work your way up, instead of searching for specific symbols and then wondering how something interconnects with something else. If you are able to place breakpoints along the path I described, you could find out if any of the underlying network code is buggy, thus causing the deselection the cursor of other clients. If this is not the case, you can keep digging up the call stack, and eventually you will reach the piece of code that instructs other clients to deselect the thing they have currently selected whenever another client reinstalls a piece of furniture.

A good place to start digging as well is the handler on the client side that receives the Client_Cursor packet or the Server_Cursor packets. If you have ensured that the packet itself containing mouse information isn't malformed, the fault most likely lies with the client misinterpreting the updated mouse information of another client, and somehow determining that it needs to deselect something when another client reinstalls a piece of furniture.

A complete list of packets can be found in the Packets enum.

@mattthewaz
Copy link
Collaborator

I would start by trying to confirm if the instruction to deselect came from a data packet or if it was logic occurring on the client side. Like is there server instruction sent to the client to deselect or is it a consequence of some other packet?

@Pecius
Copy link
Contributor

Pecius commented Apr 7, 2019

A good place to start digging as well is the handler on the client side that receives the Client_Cursor packet or the Server_Cursor packets. If you have ensured that the packet itself containing mouse information isn't malformed, the fault most likely lies with the client misinterpreting the updated mouse information of another client, and somehow determining that it needs to deselect something when another client reinstalls a piece of furniture.

That is not correct.
Cursor packets have nothing to do with the game itself, they're there just for the visual effects.
What you're looking for are Designators and everything that may modify user's Selector (including the code of the game itself).

@jacobEAdamson
Copy link
Contributor

My thought is that when handling a Designator from someone else, the mod creates a local version of the Designator that it completes. This might accidentally act to "complete" the Designator the other player is currently using. If that's the case, the current designator's state may need to be saved, the remote designator complete, and then the local designator restored to get the right behavior

@jacobEAdamson
Copy link
Contributor

Yeah, HandleDesignator in MapAsyncTime.cs is most likely the culprit as it calls designator.Finalize. This probably gets rid of the player's selection and selected Designator.

@jacobEAdamson
Copy link
Contributor

jacobEAdamson commented Apr 7, 2019

Wait, I think I found it... Find.DesignatorManager.Deselect(); in Designator_Install

which goes to this code:

public void Deselect()
{
    if (selectedDesignator != null)
    {
        selectedDesignator = null;
        dragger.EndDrag();
    }
}

We may be able to sub out the dragger before calling designator.DesignateSingleCell(cell); for a dummy, and then sub back in the player's after the designation is done.

@MilanDierick
Copy link
Contributor

@jacobEAdamson What exactly do you mean with the term 'sub'?

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

No branches or pull requests

5 participants