[1.187.204] Dedicated Server Ignoring FactionStateChanged

Thraxus shared this bug 15 months ago
Solved

Dedicated Servers are ignoring the calls to at least the following faction related methods:

MyAPIGateway.Session.Factions.DeclareWar
MyAPIGateway.Session.Factions.SendPeaceRequest
MyAPIGateway.Session.Factions.AcceptPeace
These methods can be utilized on the client connection, which will then sync to the server, but cannot be invoked directly on the server. I wrote the following mod to demonstrate this issue: https://steamcommunity.com/sharedfiles/filedetails/?id=1502198252If any of the above methods are invoked on the dedicated server, the server ignores the call and MyAPIGateway.Session.Factions.FactionStateChanged is never triggered. If the client invokes the above methods, the server will acknowledge the call, change faction states appropriately, and report those states back to the client.


STR:

Download the mod to a dedicated server (must be dedicated, cannot be SP or local MP)

Create your own player-only faction

1) Enter "/sfm factionStatus" in chat - this will show you your current status to the default "friendly" faction (should be hostile at this point)

2) Enter "/sfm serverResetFactions" in chat, notice the messaged displayed. Check the faction tab and you will see no actual faction relation changes (will still be hostile at this point) - this code is run on the DS.

3) Enter "/sfm clientResetFactions" in chat, notice the messages displayed now (different from step 2). Check the faction tab and you will see that instead of hostile, you are now neutral with "CIVL". This code is run from the client. The messages displayed show that the server first acknowledges the faction change request (blue text), the client messages are displayed (red text), then the client is updated with the new faction state (blue text again). The blue text was not present in the server message because the server failed to process the faction status change, so the FactionStateChanged event was never triggered.

4) This can be repeated with war declaration as well using "/sfm serverWar Tag1 Tag2" or "/sfm clientWar Tag1 Tag2". You will notice that the FactionStateChanged event is never triggered when using the server directly. Only the client will trigger the FactionStateChanged event on the server.

Comments (7)

photo
1

As a note, this is a Modding API related issue. It's not reliant on any specific mod or random set of wack-a-mole variables to reproduce.

photo
1

I also replicated this, at least with DeclareWar, it can't be used from DS side.


And why is this an issue you may wonder? Because server needs to be able to change faction statuses without needing a client to act as a messenger, that makes it also a security hole.


Here's an alternate STR:

1. Load a DS world with this mod: https://steamcommunity.com/sharedfiles/filedetails/?id=1503083979

2. Join your DS.

3. Create a faction with ABC tag (not part of the issue, just to replicate faster).

4. Make peace with the civilian factions.

5. Type in chat: /svwar abc civ2

6. Check status in the factions window, you should see that there's no war between you and Civilian2.

7. Optional, check faction status with /relation abc civ2 - it shows that info from both server side and client side.


Also another optional thing you can check (I didn't test it, I was thinking about the possibility just now) is to see if you can cause war between civ1 and civ2 from your client.

Type in chat: /clwar civ1 civ2

If that works then any client can effectively tell the server to cause any factions to go to war, which is a security hole.

photo
1

"Also another optional thing you can check (I didn't test it, I was thinking about the possibility just now) is to see if you can cause war between civ1 and civ2 from your client.

Type in chat: /clwar civ1 civ2

If that works then any client can effectively tell the server to cause any factions to go to war, which is a security hole."

Friendly reminder: make sure you're not server admin if you try this. Admin rights with regards to AI factions are pretty intense.

photo
2

Affects all FactionStateChange events.

Quite important functionality that is missing now.

photo
3

I think i might have located the problem:

On the DedicatedServer MySession.Static.LocalPlayerId is 0

Just one example here;:

IMyFactionCollection.RemoveFaction(long factionId)

calls

MyFactionCollection.RemoveFaction(factionId);

which calls

MyFactionCollection.SendFactionChange(MyFactionStateChange.RemoveFaction, factionId, factionId, 0L);

which raises

MyMultiplayer.RaiseStaticEvent<MyFactionStateChange, long, long, long, long>((IMyEventOwner s) => new Action<MyFactionStateChange, long, long, long, long>(MyFactionCollection.FactionStateChangeRequest), action, fromFactionId, toFactionId, playerId, MySession.Static.LocalPlayerId, default(EndpointId));


Now FactionStateChangeRequest triggers and calls CheckFactionStateChange as first check.

Sadly this switch does not consider the message beeing sent by the server and just blocks all requests if senderId (here always 0) is not the founder of the faction to change

switch (action)
	{
	case MyFactionStateChange.RemoveFaction:
	case MyFactionStateChange.SendPeaceRequest:
	case MyFactionStateChange.CancelPeaceRequest:
	case MyFactionStateChange.AcceptPeace:
	case MyFactionStateChange.DeclareWar:
	case MyFactionStateChange.FactionMemberAcceptJoin:
	case MyFactionStateChange.FactionMemberKick:
	case MyFactionStateChange.FactionMemberPromote:
	case MyFactionStateChange.FactionMemberDemote:
		if (!this.m_factions[fromFactionId].IsLeader(senderId) && !MySession.Static.IsUserAdmin(MySession.Static.Players.TryGetSteamId(senderId)))
		{
			return false;
		}
		break;
	}

photo
2

Hello, Engineers!


Thank you for your feedback! Your topic has been added between considered issues.


We will address all reported issues during future development and we will attempt to fix your issue as soon as possible. We are currently close to a Major release, which is under heavy development and this takes up a lot of our time.


Please keep voting for the issue as it will help us to identify the most serious bugs.


We really appreciate your patience.


Kind Regards


Keen Software House: QA Department

photo
1

So, I'll agree that you / KSH fixed this bug, but why would you fix it like you did? You're allowing both client and server to dictate faction changes, instead of shuttling decision making to the server directly. Now, instead of a centralized location for dealing with FactionStateChange, I have a decentralized mess to untangle. The server should be responsible for ALL game state changes, spawn, and game logic decisions, the client should only be concerned with non-game state issues, like graphics, particles, local GPS, physics, etc.

photo
1

I can't edit my reply, else I'd delete it. My own fix for the broken factions was betraying me in a way I wasn't expecting (and had a hard time finding).

Good job on the fix, sorry for being an ass.

photo