Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 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,37 @@ 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 bool TryGetNetworkedStationControllerHandlingNetworkedJob(out NetworkedStationController networkedStationController)
{
networkedStationController = NetworkedStationController.stationControllerToNetworkedStationController.Values.ToArray().FirstOrDefault(sc => sc.NetworkedJobs.Contains(this));
return (networkedStationController == null) ? false : true;
}

public void AddReport(NetworkedItem item)
{
if (item == null || !item.UsefulItem)
Expand Down Expand Up @@ -357,6 +404,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 @@ -166,7 +166,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 @@ -195,8 +195,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 @@ -210,6 +210,9 @@ static string GetFuse(uint netId)

private readonly Dictionary<uint, ServerPlayer> portAuthority = [];

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

#endregion

#region Client Variables
Expand Down Expand Up @@ -850,14 +853,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 @@ -875,7 +893,7 @@ private void Server_SendBrakeStates()
);
}

private void Server_SendCouplers()
public void Server_SendCouplers()
{
if (!sendCouplers)
return;
Expand Down Expand Up @@ -906,7 +924,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