Net message help

Hi there I need to read an entity from a net message and then use that same entity outside of the message, is this possible? Or do you have any other solutions? Thanks for your help.(I’m sending the entity form the client to the server) Apparently you can’t “multi network” an entity, like keep sending it through net messages, so this is why I am having a problem.

You can set up a network receiver to use a callback.

So… Here is an example of networking: https://dl.dropboxusercontent.com/u/26074909/tutoring/networking/networking_booleans.lua.html

To network an entity, you can do 1 of 2 things.

net.WriteEntity( ent )
and
net.ReadEntity( ent )

The issue with doing it this way, is if the client has never been close enough to the entity it may return NULL.

I recommend networking the ent:EntIndex( ), storing data that way if you want to store data. But since you want to call something on the entity the Write/Read should be ok ( as long as you’re close enough )…

If you’re networking from client to server, then there won’t be any issues.

What I am actually doing is this:
client->server->client->sevrer
I need to network a specific player to the server, but I have a separate function that needs to use the same exact player entity that is being networked. These need to execute in a specific order and running the function when receiving the net message would ruin the process order. This is why I need to retrieve the exact player out of the net message somehow so my other function can use it.

If you go client > server; then the receiver function( message_length, player_that_sent_message ) argument can be used unless you’re referencing a different player.

Can you tell us “exactly” what you’re doing? There may be a quicker way / hook for it already.

Basically 1 player does something, another player confirms it, and the server takes action based on the second players choice(all of this is through derma).

Ah, sort of like a trade-menu?

Yeah, you would need client > server interaction before server sends to one or both.

https://dl.dropboxusercontent.com/u/26074909/tutoring/_redistributable/acecooldev_base/documentation/acecooldev_base_added_classes_or_metatable_objects/class_networking_overview.txt

One of the reasons I coded the Client-to-client passthrough:
// Helper Function - When the client SendToClients another client, the data is routed through a
// pass-through on the server, and then sent to the client. This is the only way this can be done
// but having a helper function do this allows for code to be created quicker which handles trading
// and other functionality.
function networking:SendToClient( _name, _client, … )

Is for stuff like that. I’ll be releasing a lightweight version of this soon.

You shouldn’t have any issues sending an entity from a to b to c to b. Make sure the data is being stored so that it can be recalled.

If you’re sending the first-client to the server, you can just send a blank message. net.Receive( “name”, function( len, ply ) end ); can use ply to send it to the other client. The second client can confirm in the receive ( or put it somewhere until they confirm ) and it can go back to the server.

You could pass the EntIndex too if you wanted to. The client could use Entity( entindex ) to grab the entity in question.

If you want to show us your netcode, we may be able to improve on it. Also the DoClick functions ( which is where I’m assuming the networking from client > server occurs after confirmation ).

I don’t have any examples / tutorials on this yet, but I may put one together because trade-windows or client-client communication is pretty common.

Well this is what I am doing:
original net.send from first client:


net.Start("ask")
net.WriteEntity(v)--v is the player
net.SendToServer()

server to client net message:


net.Receive("ask",function()
net.Start("Request")
net.WriteEntity(net.ReadEntity())
net.Send(net.ReadEntity())
end)

client to server net message:


net.Receive("Request",function()
net.Start("Answer")
net.WriteEntity(net.ReadEntity())
net.SendToServer()
end)

And then in the answer net.receive I try and put it into a table as a test and it returns nil.

Are these clients very far away?

The reason I ask, is because if a client has never come within a certain distance of another entity, the client will see the entity as NULL. When the user comes within range, that user then “knows” about the entity and won’t forget it; but if out of PVS, then no updates will be sent for position, etc…

You may be better of using the v:EntIndex( ) or whatever…

First client… question, are you sending LocalPlayer( ) to server? Or is v a different client?

v is a separate client, and I have tried this with players who are right next to me.
Also what you are describing kind of sounds like when a player is dormant.

I noticed something in your code

You net.ReadEntity() twice in your receiver function but only net.WriteEntity() once in your message. Since you can write multiple Entities in a single message net.ReadEntity() may be called multiple times in a message, and the items must be read in the same order as which you wrote them in, so you’re calling net.Send() with a nil argument. When you want to use a single item you read from a message several times you’ll need to save it as a variable
[lua]net.Receive( “ask”, function()

local ply = net.ReadEntity()
net.Start( "Request" )
	net.WriteEntity( ply )
net.Send( ply )

end )[/lua]

[editline]2nd September 2014[/editline]

Furthermore, a server side net.Receive() will receive one more argument than on the client; the player object who sent the message. This means you never need to net.WriteEntity( LocalPlayer() ), which seems like what you are doing, instead, you can do something like this instead.
Client
[lua]net.Start( “ask” )
net.SendToServer()
[/lua]
Server
[lua]net.Receive( “ask”, function( len, ply ) – First argument is the length of the message (in bytes I believe) and the second is the player who sent the message

local ply = net.ReadEntity()
net.Start( "Request" )
	net.WriteEntity( ply )
net.Send( ply )

end )[/lua]

That’s what I am doing, I just removed it from the examples I posted to simplify the code.
But now that you mention it I can see how it could cause confusion.

Then try localising the entities you are writing/receiving and ensure that they are all valid.

Yea I basically just posted that as an example, this is one of my full net.Receive:


net.Receive("Ask",function(l,ply)
local v = net.ReadEntity()
net.Start("Request")
net.WriteEntity(v)
net.Send(v)
end)

(And yes I use indentation but the formatting fucks it up.)

[editline]2nd September 2014[/editline]

Any idea how I’d network EntIndex()?

net.WriteUInt

How would I decipher that though?
I am using:


net.WriteUInt(v:EntIndex())

But I need to know how to tell what player that is.

Remember to include bit length as second argument in the write function, as well as the same bit length when you read it. To get the entity if you have the entindex you can use Entity(entindex)

When I try using writeuint it just errors:
number expected, got no value

Paste the exact error.

bad argument #2 to ‘WriteUInt’ (number expected, got no value)

As I mentioned, you need to add the bit length of the integer you’re sending as argument #2 in net.WriteUInt.

[lua]
– For writing
net.WriteUInt(v:EntIndex(), 16)
– For reading
net.ReadUInt(16)
– To convert the entindex to entity
local ent = Entity(net.ReadUInt(16))
[/lua]