Skip to content

Commit

Permalink
Merge pull request #44 from project-fika/dev
Browse files Browse the repository at this point in the history
Dev > Main (DO NOT MERGE)
  • Loading branch information
Lacyway authored May 15, 2024
2 parents c8a0843 + 9facf63 commit 544ac8a
Show file tree
Hide file tree
Showing 39 changed files with 967 additions and 466 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ private static void PatchPostfix(BulletClass flareCartridge)

if (gameWorld != null && points && _usableFlares.Any(x => x == flareCartridge.Template._id))
{
gameWorld.gameObject.AddComponent<FikaAirdropsManager>().isFlareDrop = true;
FikaAirdropsManager airdropsManager = gameWorld.gameObject.AddComponent<FikaAirdropsManager>();
airdropsManager.isFlareDrop = true;
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions Fika.Core/AkiSupport/Airdrops/Utils/FikaItemFactoryUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ public FikaItemFactoryUtil()

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

if (Singleton<FikaAirdropsManager>.Instantiated)
if (Singleton<FikaAirdropsManager>.Instance != null)
{
Singleton<FikaAirdropsManager>.Instance.ClientLootBuilt = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ protected override MethodBase GetTargetMethod()

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

foreach (CanvasGroup canvasGroup in ____waterAndFoodCanvasGroups)
{
canvasGroup.SetUnlockStatus(true, true);
}

instance = __instance;

____randomWeatherToggle.Bind(new Action<bool>(ToggleWeather));
Expand Down
24 changes: 15 additions & 9 deletions Fika.Core/Coop/Airdrops/FikaAirdropsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ public class FikaAirdropsManager : MonoBehaviour
protected void Awake()
{
Logger = BepInEx.Logging.Logger.CreateLogSource("FikaAirdropsManager");
Logger.LogInfo("Initializing...");
if (Singleton<FikaAirdropsManager>.Instantiated)
Logger.LogInfo(isFlareDrop ? "Initializing from flare..." : "Initializing...");
if (Singleton<FikaAirdropsManager>.Instance != null)
{
Logger.LogWarning("Another manager already exists, destroying old...");
if (airdropPlane != null)
Expand All @@ -57,17 +57,13 @@ protected void Awake()
Destroy(AirdropBox.gameObject);
}
Destroy(Singleton<FikaAirdropsManager>.Instance);
Singleton<FikaAirdropsManager>.Release(Singleton<FikaAirdropsManager>.Instance);
}
Singleton<FikaAirdropsManager>.Create(this);
}

protected void OnDestroy()
{
if (Singleton<FikaAirdropsManager>.Instantiated)
{
Singleton<FikaAirdropsManager>.Release(Singleton<FikaAirdropsManager>.Instance);
}
Logger.LogWarning("Destroying AirdropsManager");
}

protected async void Start()
Expand Down Expand Up @@ -99,6 +95,15 @@ protected async void Start()
if (!AirdropParameters.AirdropAvailable)
{
Logger.LogInfo("Airdrop is not available, destroying manager...");

GenericPacket packet = new()
{
NetId = 0,
PacketType = EPackageType.RemoveAirdropManager
};

Singleton<FikaServer>.Instance.SendDataToAll(new(), ref packet, DeliveryMethod.ReliableOrdered);

Destroy(this);
return;
}
Expand Down Expand Up @@ -150,7 +155,7 @@ public void SendParamsToClients()
LookPoint = airdropPlane.newRotation
};
NetDataWriter writer = new();
Singleton<FikaServer>.Instance.SendDataToAll(writer, ref airdropPacket, LiteNetLib.DeliveryMethod.ReliableOrdered);
Singleton<FikaServer>.Instance.SendDataToAll(writer, ref airdropPacket, DeliveryMethod.ReliableOrdered);
}

protected async void FixedUpdate()
Expand Down Expand Up @@ -261,7 +266,7 @@ private void StartBox()
{
AirdropParameters.BoxSpawned = true;
Vector3 pointPos = AirdropParameters.RandomAirdropPoint;
Vector3 dropPos = new Vector3(pointPos.x, AirdropParameters.DropHeight, pointPos.z);
Vector3 dropPos = new(pointPos.x, AirdropParameters.DropHeight, pointPos.z);
AirdropBox.gameObject.SetActive(true);
AirdropBox.StartCoroutine(AirdropBox.DropCrate(dropPos));
}
Expand Down Expand Up @@ -304,6 +309,7 @@ private void BuildLootContainer(FikaAirdropConfigModel config)

public void ReceiveBuildLootContainer(AirdropLootPacket packet)
{
Logger.LogInfo("Received loot container parameters");
rootItem = packet.RootItem;
ContainerId = packet.ContainerId;
}
Expand Down
2 changes: 1 addition & 1 deletion Fika.Core/Coop/BotClasses/BotMovementContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public sealed class BotMovementContext : MovementContext

public override void ApplyGravity(ref Vector3 motion, float deltaTime, bool stickToGround)
{
if (!Bot.isStarted)
if (!Bot.isStarted || Bot.AIData.BotOwner.BotState == EBotState.NonActive)
{
return;
}
Expand Down
3 changes: 1 addition & 2 deletions Fika.Core/Coop/BotClasses/CoopBotInventoryController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ public override void Execute(GClass2837 operation, [CanBeNull] Callback callback
packet.ItemControllerExecutePacket = new()
{
CallbackId = operation.Id,
OperationBytes = opBytes,
InventoryId = ID
OperationBytes = opBytes
};

CoopBot.PacketSender?.InventoryPackets?.Enqueue(packet);
Expand Down
200 changes: 180 additions & 20 deletions Fika.Core/Coop/ClientClasses/CoopClientInventoryController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
using EFT;
using EFT.InventoryLogic;
using EFT.UI;
using Fika.Core.Coop.Matchmaker;
using Fika.Core.Coop.Players;
using Fika.Core.Networking;
using JetBrains.Annotations;
using System.IO;
using UnityEngine;

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

public override void Execute(GClass2837 operation, [CanBeNull] Callback callback)
{
base.Execute(operation, callback);

// Do not replicate picking up quest items, throws an error on the other clients
if (operation is GClass2839 pickupOperation)
if (MatchmakerAcceptPatches.IsServer)
{
if (pickupOperation.Item.Template.QuestItem)
HostInventoryOperationManager operationManager = new(this, operation, callback);
if (vmethod_0(operationManager.operation))
{
operationManager.operation.vmethod_0(operationManager.HandleResult);

// Do not replicate picking up quest items, throws an error on the other clients
if (operation is GClass2839 pickupOperation)
{
if (pickupOperation.Item.Template.QuestItem)
{
return;
}
}

// TODO: Check for glass increments
if (operation is GClass2870)
{
return;
}

InventoryPacket packet = new()
{
HasItemControllerExecutePacket = true
};

using MemoryStream memoryStream = new();
using BinaryWriter binaryWriter = new(memoryStream);
binaryWriter.WritePolymorph(GClass1632.FromInventoryOperation(operation, false));
byte[] opBytes = memoryStream.ToArray();
packet.ItemControllerExecutePacket = new()
{
CallbackId = operation.Id,
OperationBytes = opBytes
};

CoopPlayer.PacketSender?.InventoryPackets?.Enqueue(packet);

return;
}
operationManager.operation.Dispose();
operationManager.callback?.Fail($"Can't execute {operationManager.operation}", 1);
}
else if (MatchmakerAcceptPatches.IsClient)
{
// Do not replicate picking up quest items, throws an error on the other clients
if (operation is GClass2839 pickupOperation)
{
if (pickupOperation.Item.Template.QuestItem)
{
base.Execute(operation, callback);
return;
}
}

InventoryPacket packet = new()
{
HasItemControllerExecutePacket = true
};

ClientInventoryOperationManager clientOperationManager = new()
{
operation = operation,
callback = callback,
inventoryController = this
};

clientOperationManager.callback ??= new Callback(ClientPlayer.Control0.Class1400.class1400_0.method_0);
uint operationNum = AddOperationCallback(operation, new Callback<EOperationStatus>(clientOperationManager.HandleResult));

using MemoryStream memoryStream = new();
using BinaryWriter binaryWriter = new(memoryStream);
binaryWriter.WritePolymorph(GClass1632.FromInventoryOperation(operation, false));
byte[] opBytes = memoryStream.ToArray();
packet.ItemControllerExecutePacket = new()
{
CallbackId = operationNum,
OperationBytes = opBytes
};

CoopPlayer.PacketSender?.InventoryPackets?.Enqueue(packet);
}
}

private uint AddOperationCallback(GClass2837 operation, Callback<EOperationStatus> callback)
{
ushort id = operation.Id;
CoopPlayer.OperationCallbacks.Add(id, callback);
return id;
}

private class HostInventoryOperationManager(CoopClientInventoryController inventoryController, GClass2837 operation, Callback callback)
{
public readonly CoopClientInventoryController inventoryController = inventoryController;
public GClass2837 operation = operation;
public readonly Callback callback = callback;

public void HandleResult(IResult result)
{
if (!result.Succeed)
{
FikaPlugin.Instance.FikaLogger.LogError($"[{Time.frameCount}][{inventoryController.Name}] {inventoryController.ID} - Local operation failed: {operation.Id} - {operation}\r\nError: {result.Error}");
}
callback?.Invoke(result);
}
}

InventoryPacket packet = new()
private class ClientInventoryOperationManager
{
public EOperationStatus? serverOperationStatus;
public EOperationStatus? localOperationStatus;
public GClass2837 operation;
public Callback callback;
public CoopClientInventoryController inventoryController;

public void HandleResult(Result<EOperationStatus> result)
{
HasItemControllerExecutePacket = true
};

using MemoryStream memoryStream = new();
using BinaryWriter binaryWriter = new(memoryStream);
binaryWriter.WritePolymorph(GClass1632.FromInventoryOperation(operation, false));
byte[] opBytes = memoryStream.ToArray();
packet.ItemControllerExecutePacket = new()
ClientInventoryCallbackManager callbackManager = new()
{
clientOperationManager = this,
result = result
};

if (callbackManager.result.Succeed)
{
EOperationStatus value = callbackManager.result.Value;
if (value == EOperationStatus.Started)
{
localOperationStatus = EOperationStatus.Started;
serverOperationStatus = EOperationStatus.Started;
operation.vmethod_0(new Callback(callbackManager.HandleResult), true);
return;
}
if (value == EOperationStatus.Finished)
{
serverOperationStatus = EOperationStatus.Finished;
if (localOperationStatus == serverOperationStatus)
{
operation.Dispose();
callback.Succeed();
return;
}
}
}
else
{
FikaPlugin.Instance.FikaLogger.LogError($"{inventoryController.ID} - Client operation rejected by server: {operation.Id} - {operation}\r\nReason: {callbackManager.result.Error}");
serverOperationStatus = EOperationStatus.Failed;
localOperationStatus = EOperationStatus.Failed;
operation.Dispose();
callback.Invoke(callbackManager.result);
}
}
}

private class ClientInventoryCallbackManager
{
public Result<EOperationStatus> result;
public ClientInventoryOperationManager clientOperationManager;

public void HandleResult(IResult executeResult)
{
CallbackId = operation.Id,
OperationBytes = opBytes,
InventoryId = ID
};
if (!executeResult.Succeed && (executeResult.Error is not "skipped skippable" or "skipped _completed"))
{
FikaPlugin.Instance.FikaLogger.LogError($"{clientOperationManager.inventoryController.ID} - Client operation critical failure: {clientOperationManager.inventoryController.ID} - {clientOperationManager.operation}\r\nError: {executeResult.Error}");
}

clientOperationManager.localOperationStatus = EOperationStatus.Finished;

CoopPlayer.PacketSender?.InventoryPackets?.Enqueue(packet);
if (clientOperationManager.localOperationStatus == clientOperationManager.serverOperationStatus)
{
clientOperationManager.operation.Dispose();
clientOperationManager.callback.Invoke(result);
return;
}

if (clientOperationManager.serverOperationStatus != null)
{
if (clientOperationManager.serverOperationStatus == EOperationStatus.Failed)
{
clientOperationManager.operation.Dispose();
clientOperationManager.callback.Invoke(result);
}
}
}
}
}
}
}
4 changes: 2 additions & 2 deletions Fika.Core/Coop/Components/CoopExfilManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal class CoopExfilManager : MonoBehaviour
private ExfiltrationPoint[] exfiltrationPoints;
private CarExtraction carExfil = null;

void Awake()
protected void Awake()
{
game = gameObject.GetComponent<CoopGame>();
playerHandlers = [];
Expand All @@ -30,7 +30,7 @@ void Awake()
carExfil = FindObjectOfType<CarExtraction>();
}

void Update()
protected void Update()
{
if (exfiltrationPoints == null)
{
Expand Down
Loading

0 comments on commit 544ac8a

Please sign in to comment.