Skip to content

Commit 544ac8a

Browse files
authored
Merge pull request #44 from project-fika/dev
Dev > Main (DO NOT MERGE)
2 parents c8a0843 + 9facf63 commit 544ac8a

39 files changed

+967
-466
lines changed

Fika.Core/AkiSupport/Airdrops/Patches/FikaAirdropFlarePatch.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ private static void PatchPostfix(BulletClass flareCartridge)
2525

2626
if (gameWorld != null && points && _usableFlares.Any(x => x == flareCartridge.Template._id))
2727
{
28-
gameWorld.gameObject.AddComponent<FikaAirdropsManager>().isFlareDrop = true;
28+
FikaAirdropsManager airdropsManager = gameWorld.gameObject.AddComponent<FikaAirdropsManager>();
29+
airdropsManager.isFlareDrop = true;
2930
}
3031
}
3132
}

Fika.Core/AkiSupport/Airdrops/Utils/FikaItemFactoryUtil.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ public FikaItemFactoryUtil()
2424

2525
public void BuildContainer(LootableContainer container, FikaAirdropConfigModel config, string dropType)
2626
{
27-
var containerId = config.ContainerIds[dropType];
28-
if (itemFactory.ItemTemplates.TryGetValue(containerId, out var template))
27+
string containerId = config.ContainerIds[dropType];
28+
if (itemFactory.ItemTemplates.TryGetValue(containerId, out ItemTemplate template))
2929
{
3030
Item item = itemFactory.CreateItem(containerId, template._id, null);
31+
item.Id = Singleton<GameWorld>.Instance.MainPlayer.GClass2761_0.NextId;
3132
LootItem.CreateLootContainer(container, item, "CRATE", Singleton<GameWorld>.Instance);
3233
}
3334
else
@@ -69,7 +70,7 @@ public async void AddLoot(LootableContainer container, FikaAirdropLootResultMode
6970
await Singleton<PoolManager>.Instance.LoadBundlesAndCreatePools(PoolManager.PoolsCategory.Raid, PoolManager.AssemblyType.Local, resources, JobPriority.Immediate, null, PoolManager.DefaultCancellationToken);
7071
}
7172

72-
if (Singleton<FikaAirdropsManager>.Instantiated)
73+
if (Singleton<FikaAirdropsManager>.Instance != null)
7374
{
7475
Singleton<FikaAirdropsManager>.Instance.ClientLootBuilt = true;
7576
}

Fika.Core/AkiSupport/Overrides/OfflineRaidSettingsMenuPatchOverride.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ protected override MethodBase GetTargetMethod()
2121

2222
[PatchPostfix]
2323
private static void PatchPostfix(RaidSettingsWindow __instance, UiElementBlocker ____coopModeBlocker, List<CanvasGroup> ____weatherCanvasGroups,
24-
UpdatableToggle ____randomTimeToggle, UpdatableToggle ____randomWeatherToggle)
24+
UpdatableToggle ____randomTimeToggle, UpdatableToggle ____randomWeatherToggle, List<CanvasGroup> ____waterAndFoodCanvasGroups)
2525
{
2626
// Always disable the Coop Mode checkbox
2727
____coopModeBlocker.SetBlock(true, "Co-op is always enabled in Fika");
@@ -31,6 +31,11 @@ private static void PatchPostfix(RaidSettingsWindow __instance, UiElementBlocker
3131
weatherCanvasGroups = ____weatherCanvasGroups;
3232
}
3333

34+
foreach (CanvasGroup canvasGroup in ____waterAndFoodCanvasGroups)
35+
{
36+
canvasGroup.SetUnlockStatus(true, true);
37+
}
38+
3439
instance = __instance;
3540

3641
____randomWeatherToggle.Bind(new Action<bool>(ToggleWeather));

Fika.Core/Coop/Airdrops/FikaAirdropsManager.cs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ public class FikaAirdropsManager : MonoBehaviour
4444
protected void Awake()
4545
{
4646
Logger = BepInEx.Logging.Logger.CreateLogSource("FikaAirdropsManager");
47-
Logger.LogInfo("Initializing...");
48-
if (Singleton<FikaAirdropsManager>.Instantiated)
47+
Logger.LogInfo(isFlareDrop ? "Initializing from flare..." : "Initializing...");
48+
if (Singleton<FikaAirdropsManager>.Instance != null)
4949
{
5050
Logger.LogWarning("Another manager already exists, destroying old...");
5151
if (airdropPlane != null)
@@ -57,17 +57,13 @@ protected void Awake()
5757
Destroy(AirdropBox.gameObject);
5858
}
5959
Destroy(Singleton<FikaAirdropsManager>.Instance);
60-
Singleton<FikaAirdropsManager>.Release(Singleton<FikaAirdropsManager>.Instance);
6160
}
6261
Singleton<FikaAirdropsManager>.Create(this);
6362
}
6463

6564
protected void OnDestroy()
6665
{
67-
if (Singleton<FikaAirdropsManager>.Instantiated)
68-
{
69-
Singleton<FikaAirdropsManager>.Release(Singleton<FikaAirdropsManager>.Instance);
70-
}
66+
Logger.LogWarning("Destroying AirdropsManager");
7167
}
7268

7369
protected async void Start()
@@ -99,6 +95,15 @@ protected async void Start()
9995
if (!AirdropParameters.AirdropAvailable)
10096
{
10197
Logger.LogInfo("Airdrop is not available, destroying manager...");
98+
99+
GenericPacket packet = new()
100+
{
101+
NetId = 0,
102+
PacketType = EPackageType.RemoveAirdropManager
103+
};
104+
105+
Singleton<FikaServer>.Instance.SendDataToAll(new(), ref packet, DeliveryMethod.ReliableOrdered);
106+
102107
Destroy(this);
103108
return;
104109
}
@@ -150,7 +155,7 @@ public void SendParamsToClients()
150155
LookPoint = airdropPlane.newRotation
151156
};
152157
NetDataWriter writer = new();
153-
Singleton<FikaServer>.Instance.SendDataToAll(writer, ref airdropPacket, LiteNetLib.DeliveryMethod.ReliableOrdered);
158+
Singleton<FikaServer>.Instance.SendDataToAll(writer, ref airdropPacket, DeliveryMethod.ReliableOrdered);
154159
}
155160

156161
protected async void FixedUpdate()
@@ -261,7 +266,7 @@ private void StartBox()
261266
{
262267
AirdropParameters.BoxSpawned = true;
263268
Vector3 pointPos = AirdropParameters.RandomAirdropPoint;
264-
Vector3 dropPos = new Vector3(pointPos.x, AirdropParameters.DropHeight, pointPos.z);
269+
Vector3 dropPos = new(pointPos.x, AirdropParameters.DropHeight, pointPos.z);
265270
AirdropBox.gameObject.SetActive(true);
266271
AirdropBox.StartCoroutine(AirdropBox.DropCrate(dropPos));
267272
}
@@ -304,6 +309,7 @@ private void BuildLootContainer(FikaAirdropConfigModel config)
304309

305310
public void ReceiveBuildLootContainer(AirdropLootPacket packet)
306311
{
312+
Logger.LogInfo("Received loot container parameters");
307313
rootItem = packet.RootItem;
308314
ContainerId = packet.ContainerId;
309315
}

Fika.Core/Coop/BotClasses/BotMovementContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public sealed class BotMovementContext : MovementContext
1111

1212
public override void ApplyGravity(ref Vector3 motion, float deltaTime, bool stickToGround)
1313
{
14-
if (!Bot.isStarted)
14+
if (!Bot.isStarted || Bot.AIData.BotOwner.BotState == EBotState.NonActive)
1515
{
1616
return;
1717
}

Fika.Core/Coop/BotClasses/CoopBotInventoryController.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ public override void Execute(GClass2837 operation, [CanBeNull] Callback callback
3030
packet.ItemControllerExecutePacket = new()
3131
{
3232
CallbackId = operation.Id,
33-
OperationBytes = opBytes,
34-
InventoryId = ID
33+
OperationBytes = opBytes
3534
};
3635

3736
CoopBot.PacketSender?.InventoryPackets?.Enqueue(packet);

Fika.Core/Coop/ClientClasses/CoopClientInventoryController.cs

Lines changed: 180 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
using EFT;
44
using EFT.InventoryLogic;
55
using EFT.UI;
6+
using Fika.Core.Coop.Matchmaker;
67
using Fika.Core.Coop.Players;
78
using Fika.Core.Networking;
89
using JetBrains.Annotations;
910
using System.IO;
11+
using UnityEngine;
1012

1113
namespace Fika.Core.Coop.ClientClasses
1214
{
@@ -30,34 +32,192 @@ public override void CallMalfunctionRepaired(Weapon weapon)
3032

3133
public override void Execute(GClass2837 operation, [CanBeNull] Callback callback)
3234
{
33-
base.Execute(operation, callback);
34-
35-
// Do not replicate picking up quest items, throws an error on the other clients
36-
if (operation is GClass2839 pickupOperation)
35+
if (MatchmakerAcceptPatches.IsServer)
3736
{
38-
if (pickupOperation.Item.Template.QuestItem)
37+
HostInventoryOperationManager operationManager = new(this, operation, callback);
38+
if (vmethod_0(operationManager.operation))
3939
{
40+
operationManager.operation.vmethod_0(operationManager.HandleResult);
41+
42+
// Do not replicate picking up quest items, throws an error on the other clients
43+
if (operation is GClass2839 pickupOperation)
44+
{
45+
if (pickupOperation.Item.Template.QuestItem)
46+
{
47+
return;
48+
}
49+
}
50+
51+
// TODO: Check for glass increments
52+
if (operation is GClass2870)
53+
{
54+
return;
55+
}
56+
57+
InventoryPacket packet = new()
58+
{
59+
HasItemControllerExecutePacket = true
60+
};
61+
62+
using MemoryStream memoryStream = new();
63+
using BinaryWriter binaryWriter = new(memoryStream);
64+
binaryWriter.WritePolymorph(GClass1632.FromInventoryOperation(operation, false));
65+
byte[] opBytes = memoryStream.ToArray();
66+
packet.ItemControllerExecutePacket = new()
67+
{
68+
CallbackId = operation.Id,
69+
OperationBytes = opBytes
70+
};
71+
72+
CoopPlayer.PacketSender?.InventoryPackets?.Enqueue(packet);
73+
4074
return;
4175
}
76+
operationManager.operation.Dispose();
77+
operationManager.callback?.Fail($"Can't execute {operationManager.operation}", 1);
78+
}
79+
else if (MatchmakerAcceptPatches.IsClient)
80+
{
81+
// Do not replicate picking up quest items, throws an error on the other clients
82+
if (operation is GClass2839 pickupOperation)
83+
{
84+
if (pickupOperation.Item.Template.QuestItem)
85+
{
86+
base.Execute(operation, callback);
87+
return;
88+
}
89+
}
90+
91+
InventoryPacket packet = new()
92+
{
93+
HasItemControllerExecutePacket = true
94+
};
95+
96+
ClientInventoryOperationManager clientOperationManager = new()
97+
{
98+
operation = operation,
99+
callback = callback,
100+
inventoryController = this
101+
};
102+
103+
clientOperationManager.callback ??= new Callback(ClientPlayer.Control0.Class1400.class1400_0.method_0);
104+
uint operationNum = AddOperationCallback(operation, new Callback<EOperationStatus>(clientOperationManager.HandleResult));
105+
106+
using MemoryStream memoryStream = new();
107+
using BinaryWriter binaryWriter = new(memoryStream);
108+
binaryWriter.WritePolymorph(GClass1632.FromInventoryOperation(operation, false));
109+
byte[] opBytes = memoryStream.ToArray();
110+
packet.ItemControllerExecutePacket = new()
111+
{
112+
CallbackId = operationNum,
113+
OperationBytes = opBytes
114+
};
115+
116+
CoopPlayer.PacketSender?.InventoryPackets?.Enqueue(packet);
117+
}
118+
}
119+
120+
private uint AddOperationCallback(GClass2837 operation, Callback<EOperationStatus> callback)
121+
{
122+
ushort id = operation.Id;
123+
CoopPlayer.OperationCallbacks.Add(id, callback);
124+
return id;
125+
}
126+
127+
private class HostInventoryOperationManager(CoopClientInventoryController inventoryController, GClass2837 operation, Callback callback)
128+
{
129+
public readonly CoopClientInventoryController inventoryController = inventoryController;
130+
public GClass2837 operation = operation;
131+
public readonly Callback callback = callback;
132+
133+
public void HandleResult(IResult result)
134+
{
135+
if (!result.Succeed)
136+
{
137+
FikaPlugin.Instance.FikaLogger.LogError($"[{Time.frameCount}][{inventoryController.Name}] {inventoryController.ID} - Local operation failed: {operation.Id} - {operation}\r\nError: {result.Error}");
138+
}
139+
callback?.Invoke(result);
42140
}
141+
}
43142

44-
InventoryPacket packet = new()
143+
private class ClientInventoryOperationManager
144+
{
145+
public EOperationStatus? serverOperationStatus;
146+
public EOperationStatus? localOperationStatus;
147+
public GClass2837 operation;
148+
public Callback callback;
149+
public CoopClientInventoryController inventoryController;
150+
151+
public void HandleResult(Result<EOperationStatus> result)
45152
{
46-
HasItemControllerExecutePacket = true
47-
};
48-
49-
using MemoryStream memoryStream = new();
50-
using BinaryWriter binaryWriter = new(memoryStream);
51-
binaryWriter.WritePolymorph(GClass1632.FromInventoryOperation(operation, false));
52-
byte[] opBytes = memoryStream.ToArray();
53-
packet.ItemControllerExecutePacket = new()
153+
ClientInventoryCallbackManager callbackManager = new()
154+
{
155+
clientOperationManager = this,
156+
result = result
157+
};
158+
159+
if (callbackManager.result.Succeed)
160+
{
161+
EOperationStatus value = callbackManager.result.Value;
162+
if (value == EOperationStatus.Started)
163+
{
164+
localOperationStatus = EOperationStatus.Started;
165+
serverOperationStatus = EOperationStatus.Started;
166+
operation.vmethod_0(new Callback(callbackManager.HandleResult), true);
167+
return;
168+
}
169+
if (value == EOperationStatus.Finished)
170+
{
171+
serverOperationStatus = EOperationStatus.Finished;
172+
if (localOperationStatus == serverOperationStatus)
173+
{
174+
operation.Dispose();
175+
callback.Succeed();
176+
return;
177+
}
178+
}
179+
}
180+
else
181+
{
182+
FikaPlugin.Instance.FikaLogger.LogError($"{inventoryController.ID} - Client operation rejected by server: {operation.Id} - {operation}\r\nReason: {callbackManager.result.Error}");
183+
serverOperationStatus = EOperationStatus.Failed;
184+
localOperationStatus = EOperationStatus.Failed;
185+
operation.Dispose();
186+
callback.Invoke(callbackManager.result);
187+
}
188+
}
189+
}
190+
191+
private class ClientInventoryCallbackManager
192+
{
193+
public Result<EOperationStatus> result;
194+
public ClientInventoryOperationManager clientOperationManager;
195+
196+
public void HandleResult(IResult executeResult)
54197
{
55-
CallbackId = operation.Id,
56-
OperationBytes = opBytes,
57-
InventoryId = ID
58-
};
198+
if (!executeResult.Succeed && (executeResult.Error is not "skipped skippable" or "skipped _completed"))
199+
{
200+
FikaPlugin.Instance.FikaLogger.LogError($"{clientOperationManager.inventoryController.ID} - Client operation critical failure: {clientOperationManager.inventoryController.ID} - {clientOperationManager.operation}\r\nError: {executeResult.Error}");
201+
}
202+
203+
clientOperationManager.localOperationStatus = EOperationStatus.Finished;
59204

60-
CoopPlayer.PacketSender?.InventoryPackets?.Enqueue(packet);
205+
if (clientOperationManager.localOperationStatus == clientOperationManager.serverOperationStatus)
206+
{
207+
clientOperationManager.operation.Dispose();
208+
clientOperationManager.callback.Invoke(result);
209+
return;
210+
}
211+
212+
if (clientOperationManager.serverOperationStatus != null)
213+
{
214+
if (clientOperationManager.serverOperationStatus == EOperationStatus.Failed)
215+
{
216+
clientOperationManager.operation.Dispose();
217+
clientOperationManager.callback.Invoke(result);
218+
}
219+
}
220+
}
61221
}
62222
}
63-
}
223+
}

Fika.Core/Coop/Components/CoopExfilManager.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ internal class CoopExfilManager : MonoBehaviour
2121
private ExfiltrationPoint[] exfiltrationPoints;
2222
private CarExtraction carExfil = null;
2323

24-
void Awake()
24+
protected void Awake()
2525
{
2626
game = gameObject.GetComponent<CoopGame>();
2727
playerHandlers = [];
@@ -30,7 +30,7 @@ void Awake()
3030
carExfil = FindObjectOfType<CarExtraction>();
3131
}
3232

33-
void Update()
33+
protected void Update()
3434
{
3535
if (exfiltrationPoints == null)
3636
{

0 commit comments

Comments
 (0)