Skip to content
Open
49 changes: 49 additions & 0 deletions Multiplayer/Components/Networking/Jobs/NetworkedJob.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
using DV.CabControls;
using DV.InventorySystem;
using DV.Logic.Job;
using DV.Utils;
using HarmonyLib;
using Multiplayer.API;
using Multiplayer.Components.Networking.World;
using Multiplayer.Networking.Data.Jobs;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace Multiplayer.Components.Networking.Jobs;
Expand Down Expand Up @@ -127,6 +132,9 @@ public NetworkedItem JobReport

private readonly List<NetworkedItem> JobReports = [];

private object[] OnJobTrackChengeEventRegistrator;
private object[] OnJobCarChangedEventRegistrator;

public Guid OwnedBy { get; set; } = Guid.Empty;
public JobValidator JobValidator { get; set; }

Expand Down Expand Up @@ -173,6 +181,14 @@ public void Initialize(Job job, NetworkedStationController station)
job.JobCompleted += OnJobCompleted;
job.JobExpired += OnJobExpired;

if (Multiplayer.PersJobs)
{
OnJobTrackChengeEventRegistrator = [(Action<Job>)OnJobTrackChanged];
OnJobCarChangedEventRegistrator = [(Action<(Job, Car)>)OnJobCarChanged];
Multiplayer.PersJobsJobTrackChangedEventRegMethod.Invoke(null, OnJobTrackChengeEventRegistrator);
Multiplayer.PersJobsJobCarChangedEventRegMethod.Invoke(null, OnJobCarChangedEventRegistrator);
}

// If this is called after Start(), we need to add to cache here
if (gameObject.activeInHierarchy)
{
Expand Down Expand Up @@ -277,6 +293,31 @@ private void OnJobExpired(Job job)
OnJobDirty?.Invoke(this);
}

private void OnJobTrackChanged(Job job)
{
if (job.ID == Job.ID) foreach (var task in job.tasks) NetworkedTask.DoOnActualTask(task, t => { if (NetworkedTask.TryGet(t, out var netTask)) netTask.UpdateDestinationTrack(); });
}

private void OnJobCarChanged((Job, Car) jct)
{
Multiplayer.LogDebug(() => $"OnJobCarChanged() fired for {jct.Item2.ID} in {jct.Item1.ID}");
SingletonBehaviour<CoroutineManager>.Instance.Run(OnJobCarChangedDelayed(jct));
}

private IEnumerator OnJobCarChangedDelayed((Job, Car) jct)
{
if (Multiplayer.PersJobs)
{
if ((bool)Multiplayer.PersJobsResumeCoroRunningField.GetValue(null)) Multiplayer.LogDebug(() => $"Cars still resuming, waiting with job car changes");
//while ((bool)Multiplayer.PersJobsResumeCoroRunningField.GetValue(null)) yield return WaitFor.EndOfFrame;
yield return new WaitUntil(() => (bool)Multiplayer.PersJobsResumeCoroRunningField.GetValue(null) == false);
}
yield return null;
var (job, car) = jct;
if (job.ID == Job.ID) foreach (var task in job.tasks) NetworkedTask.DoOnActualTask(task, t => { if (((t.GetType() != typeof(ParallelTasks)) && (t.GetType() != typeof(SequentialTasks))) && (NetworkedTask.TryGet(t, out var netTask))) netTask.UpdateCar(car); });
yield break;
}

public void AddReport(NetworkedItem item)
{
if (item == null || !item.UsefulItem)
Expand Down Expand Up @@ -357,6 +398,14 @@ protected void OnDisable()
Job.JobCompleted -= OnJobCompleted;
Job.JobExpired -= OnJobExpired;

if (Multiplayer.PersJobs)
{
Multiplayer.PersJobsJobTrackChangedEventUnregMethod.Invoke(null, OnJobTrackChengeEventRegistrator);
Multiplayer.PersJobsJobCarChangedEventUnregMethod.Invoke(null, OnJobCarChangedEventRegistrator);
OnJobTrackChengeEventRegistrator = null;
OnJobCarChangedEventRegistrator = null;
}

Destroy(this);
}

Expand Down
29 changes: 27 additions & 2 deletions Multiplayer/Components/Networking/Jobs/NetworkedTask.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using DV.Logic.Job;
using HarmonyLib;
using Multiplayer.Components.Networking.Train;
using System;
using System.Collections.Generic;

Expand Down Expand Up @@ -46,6 +48,18 @@ public static bool TryGetNetId(Task task, out ushort netId)
}
#endregion

public static void DoOnActualTask(Task task, Action<Task> action)
{
if (task is ParallelTasks || task is SequentialTasks)
{
Traverse.Create(task)
.Field("tasks")
.GetValue<IEnumerable<Task>>()
.Do(t => DoOnActualTask(t, action));
}
else action(task);
}

protected override bool IsIdServerAuthoritative => true;

public Task Task { get; private set; }
Expand Down Expand Up @@ -85,13 +99,24 @@ protected override void OnDestroy()

public void SetState(TaskState newState)
{
if (lastState == newState && lastStartTime == Task.taskStartTime && lastFinishTime == Task.taskFinishTime)
if ((lastState == newState && lastStartTime == Task.taskStartTime && lastFinishTime == Task.taskFinishTime) || !NetworkedJob.TryGetNetId(Task.Job, out var jobNetId))
return;

lastState = newState;
lastStartTime = Task.taskStartTime;
lastFinishTime = Task.taskFinishTime;

NetworkLifecycle.Instance.Server.SendTaskUpdate(NetId, newState, Task.taskStartTime, Task.taskFinishTime);
NetworkLifecycle.Instance.Server.SendTaskUpdate(jobNetId, NetId, newState, Task.taskStartTime, Task.taskFinishTime);
}

public void UpdateDestinationTrack()
{
var destTrackOrNull = Traverse.Create(Task).Field("destinationTrack").GetValue<Track>();
if (destTrackOrNull != null && NetworkedJob.TryGetNetId(Task.Job, out var jobNetId)) NetworkLifecycle.Instance.Server.SendTaskDestTrackUpdate(jobNetId, NetId, destTrackOrNull);
}

public void UpdateCar(Car car)
{
if (NetworkedTrainCar.TryGetNetId(car, out var carNetId) && NetworkedJob.TryGetNetId(Task.Job, out var jobNetId)) NetworkLifecycle.Instance.Server.SendTaskCarUpdate(jobNetId, NetId, carNetId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ private void Server_TickSet(Trainset set, uint tick)
// If we can locate the networked car, we'll add to the ticks counter and check if any tracks are dirty
if (NetworkedTrainCar.TryGetFromTrainCar(trainCar, out NetworkedTrainCar netTC) && netTC != null)
{
if (netTC.doNotUpdate) return;
maxTicksReached |= netTC.TicksSinceSync >= MAX_UNSYNC_TICKS; //Even if the car is stationary, if the max ticks has been exceeded we will still sync
anyTracksDirty |= netTC.BogieTracksDirty;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ private static void Couple(in TrainsetSpawnPart spawnPart, TrainCar trainCar, bo
HandleCoupling(spawnPart.RearCoupling, trainCar.rearCoupler);
}

private static void HandleCoupling(CouplingData couplingData, Coupler currentCoupler)
public static void HandleCoupling(CouplingData couplingData, Coupler currentCoupler)
{

CouplingData cd = couplingData;
Expand Down
40 changes: 29 additions & 11 deletions Multiplayer/Components/Networking/Train/NetworkedTrainCar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ static string GetFuse(uint netId)
private bool cargoIsLoading;
public byte CargoModelIndex = byte.MaxValue;
private bool carHealthDirty;
private bool sendCouplers;
private bool sendCables;
public bool sendCouplers;
public bool sendCables;

public bool IsDestroying;

Expand All @@ -216,6 +216,9 @@ static string GetFuse(uint netId)
// Control authority tracking
private readonly Dictionary<uint, ServerPlayer> portAuthority = [];

public bool doNotUpdate = true;
public uint? startTick = null;

#endregion

#region Client Variables
Expand Down Expand Up @@ -867,14 +870,29 @@ private void Server_OnTick(uint tick)
if (UnloadWatcher.isUnloading)
return;

Server_SendBrakeStates();
Server_SendCouplers();
Server_SendCables();
Server_SendCargoState();
Server_SendCargoHealthUpdate();
Server_SendCarHealthState();
if (!startTick.HasValue)
{
startTick = tick;
Server_SendCargoState();
Server_SendCargoHealthUpdate();
Server_SendCarHealthState();
}

if (!doNotUpdate)
{
Server_SendBrakeStates();
Server_SendCouplers();
Server_SendCables();
Server_SendCargoState();
Server_SendCargoHealthUpdate();
Server_SendCarHealthState();

TicksSinceSync++; //keep track of last full sync
TicksSinceSync++; //keep track of last full sync
}
else
{
if ((tick - startTick > 120) && !((bool)Multiplayer.PersJobsResumeCoroRunningField?.GetValue(null) == true)) doNotUpdate = false;
}
}

private void Server_SendBrakeStates()
Expand All @@ -892,7 +910,7 @@ private void Server_SendBrakeStates()
);
}

private void Server_SendCouplers()
public void Server_SendCouplers()
{
if (!sendCouplers)
return;
Expand Down Expand Up @@ -923,7 +941,7 @@ private void Server_SendCouplers()
NetworkLifecycle.Instance.Server.SendCockState(NetId, TrainCar.rearCoupler, TrainCar.rearCoupler.IsCockOpen);
}

private void Server_SendCables()
public void Server_SendCables()
{
if (!sendCables)
return;
Expand Down
Loading