Reputation: 463
I am making a game engine with the MonoGame Framework. Since this is a multiplayer game, other players need to know certain information about other players, such as position and velocity, typically for AI reaction.
I am about to implement Lua scripting for player actions. However, I can't currently think of a way to have it so a player cannot modify the other players' information, such as position and name.
For instance, say I have the following property in C#:
public Vector2 Pos { get { return pos; } private set { this.pos = value; } }
private Vector2 pos;
Looks good, right? Well not quite. Say I have a function that returns the closest enemy called GetNearestEnemy()
, which returns another Player. Because the Player class has access to its own properties, I can just as easily do something like this in some other method:
public void DoStuff()
{
Player otherPlayer = GetNearestEnemy();
otherPlayer.Pos = new Vector2(34,151);
}
So I think "maybe I could just pass the instance as a parameter."
public void SetPos(Player instance, Vector2 pos)
{
if (instance != this)
return;
else
this.pos = pos;
}
... and always pass "this" as an argument. However, that also has the same problem: I could just as easily pass GetNearestEnemy()
to the method and I'd be able to set the enemy position.
This is the type of behavior I am trying to prevent. Is there a way to preferably either:
Or is there some other way to approach it that I'm not seeing?
Upvotes: 1
Views: 1074
Reputation:
The original scenario posted can be handled using an interface e.g. IPeerPlayer that only exposes what other players should see and hides other properties (i.e. the other properties would not be in the IPeerPlayer interface.)
Upvotes: 0
Reputation: 307
That won't work. If Pos
is a property with a private setter (as it is) the only way they could change it would be by calling a public method from within otherPlayer
. Something like otherPlayer.SetPos(new Vector2(34,151))
, where SetPos()
is:
public void SetPos(Vector2 NewPos)
{ Pos = NewPos; }
Upvotes: 0
Reputation: 27009
If this is the property and you are worried about being set from elsewhere:
public Vector2 Pos { get { return pos; } private set { this.pos = value; } }
private Vector2 pos;
This will NOT work. So you do not need to worry:
Player otherPlayer = GetNearestEnemy();
otherPlayer.Pos = new Vector2(34,151); // <--- no this will not work
That property can only be set from within the class.
Upvotes: 0
Reputation: 391346
Unfortunately not.
There is no language support for what you want.
Let me be specific about what you want just so that you understand what I answered.
Your question is basically this: Given that I have two instances of an object, and I have properties in this object that have a private setter, is there any language support for ensuring that instance #1 cannot change this private information of instance #2?
And the answer is no.
This will compile and "work":
public class Test
{
public void TestIt(Test t)
{
t.Value = 42;
}
public int Value
{
get;
private set;
}
}
...
var t1 = new Test();
var t2 = new Test();
t1.TestIt(t2); // will "happily" change t2.Value
Basically, the onus is on you to make sure this doesn't happen if you don't want it to happen. There is no language or runtime support to prevent this.
The access modifiers you can use are:
public
: Anyone can access thisprivate
: Only the type can access thisprotected
: Only the type, or a descendant of the type, can access thisinternal
: Any type in the same assembly can access thisinternal protected
: Any type in the same assembly or a descendant, can access thisOther than this, you have no other options. So "only the same instance can access this" does not exist as an access modifier.
Upvotes: 1