diff --git a/.github/scripts/thunderstore_bundle.js b/.github/scripts/thunderstore_bundle.js index 8ef552151..c88252313 100644 --- a/.github/scripts/thunderstore_bundle.js +++ b/.github/scripts/thunderstore_bundle.js @@ -123,7 +123,7 @@ function generateManifest() { BEPINEX_DEPENDENCY, `nebula-${apiPluginInfo.name}-${apiPluginInfo.version}`, "PhantomGamers-IlLine-1.0.0", - "CommonAPI-CommonAPI-1.5.5", + "CommonAPI-CommonAPI-1.5.6", "starfi5h-BulletTime-1.2.9", ], website_url: "https://github.com/hubastard/nebula" diff --git a/CHANGELOG.md b/CHANGELOG.md index b615f72d9..13c8aae02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ ## Changelog +0.8.12: + +- @PhantomGamers: Remove exe targeting to support game pass version +- @starfi5h: Fix errors about logistic bots +- @starfi5h: Add -load-latest launch option for dedicated server + 0.8.11: - @starfi5h: Added support for DSP 0.9.27 along with syncing for the new logistics distribution system diff --git a/NebulaModel/Packets/Logistics/DispenserCourierPacket.cs b/NebulaModel/Packets/Logistics/DispenserCourierPacket.cs index 979bdbdca..e7780b629 100644 --- a/NebulaModel/Packets/Logistics/DispenserCourierPacket.cs +++ b/NebulaModel/Packets/Logistics/DispenserCourierPacket.cs @@ -2,14 +2,16 @@ { public class DispenserCourierPacket { + public int PlanetId { get; set; } public int PlayerId { get; set; } public int DispenserId { get; set; } public int ItemId { get; set; } public int ItemCount { get; set; } public DispenserCourierPacket() { } - public DispenserCourierPacket(int playerId, int dispenserId, int itemId, int itemCount) + public DispenserCourierPacket(int planetId, int playerId, int dispenserId, int itemId, int itemCount) { + PlanetId = planetId; PlayerId = playerId; DispenserId = dispenserId; ItemId = itemId; diff --git a/NebulaModel/Utils/IPUtils.cs b/NebulaModel/Utils/IPUtils.cs index e545af5a9..573774276 100644 --- a/NebulaModel/Utils/IPUtils.cs +++ b/NebulaModel/Utils/IPUtils.cs @@ -1,14 +1,13 @@ -using BepInEx; -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Net; using System.Net.Http; using System.Net.Sockets; +using System.Text; using System.Threading.Tasks; using System.Timers; -using static NebulaModel.Utils.IPUtils; namespace NebulaModel.Utils { @@ -121,11 +120,50 @@ public static async Task GetPortStatus(ushort port) { string response = await client.GetStringAsync($"https://ifconfig.co/port/{port}"); Dictionary jObject = MiniJson.Deserialize(response) as Dictionary; - if (!IsIPv4((string)jObject["ip"])) + if (IsIPv4((string)jObject["ip"])) { - return Status.Unsupported.ToString(); + return (bool)jObject["reachable"] ? PortStatus.Open.ToString() : PortStatus.Closed.ToString() + "(IPv4)"; + } + else + { + // if client has IPv6, extra test for IPv4 port status + string result = ((bool)jObject["reachable"] ? PortStatus.Open.ToString() : PortStatus.Closed.ToString()) + "(IPv6) "; + try + { + IPAddress iPv4Address = null; + foreach (IPAddress ip in Dns.GetHostEntry(string.Empty).AddressList) + { + if (ip.AddressFamily == AddressFamily.InterNetwork) + { + string str = ip.ToString(); + if (!str.StartsWith("127.0") && !str.StartsWith("192.168")) + { + iPv4Address = ip; + break; + } + } + } + if (iPv4Address != null) + { + // TODO: More respect about rate limit? + HttpWebRequest httpWebRequest = HttpWebRequest.Create($"https://ifconfig.co/port/{port}") as HttpWebRequest; + httpWebRequest.Timeout = 5000; + httpWebRequest.ServicePoint.BindIPEndPointDelegate = (servicePoint, remoteEndPoint, retryCount) => new IPEndPoint(iPv4Address, 0); + + using WebResponse webResponse = await httpWebRequest.GetResponseAsync(); + using Stream stream = webResponse.GetResponseStream(); + using StreamReader readStream = new(stream, Encoding.UTF8); + response = readStream.ReadToEnd(); + jObject = MiniJson.Deserialize(response) as Dictionary; + result += ((bool)jObject["reachable"] ? PortStatus.Open.ToString() : PortStatus.Closed.ToString()) + "(IPv4)"; + } + } + catch(Exception e) + { + Logger.Log.Warn(e); + } + return result; } - return (bool)jObject["reachable"] ? PortStatus.Open.ToString() : PortStatus.Closed.ToString(); } catch (Exception e) { diff --git a/NebulaNetwork/PacketProcessors/Logistics/DispenserCourierProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/DispenserCourierProcessor.cs index 379055689..b140de336 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/DispenserCourierProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/DispenserCourierProcessor.cs @@ -1,10 +1,8 @@ using NebulaAPI; -using NebulaModel.Logger; using NebulaModel.Networking; using NebulaModel.Packets; using NebulaModel.Packets.Logistics; using NebulaWorld; -using System; namespace NebulaNetwork.PacketProcessors.Logistics { @@ -15,7 +13,11 @@ public override void ProcessPacket(DispenserCourierPacket packet, NebulaConnecti { PlanetFactory factory = GameMain.mainPlayer.factory; DispenserComponent[] pool = factory?.transport.dispenserPool; - if (pool != null && packet.DispenserId > 0 && packet.DispenserId < pool.Length && pool[packet.DispenserId].id == packet.DispenserId) + if (GameMain.mainPlayer.planetId != packet.PlanetId || pool == null) + { + return; + } + if (packet.DispenserId > 0 && packet.DispenserId < pool.Length && pool[packet.DispenserId] != null) { DispenserComponent dispenser = pool[packet.DispenserId]; Multiplayer.Session.Couriers.AddCourier(packet.PlayerId, factory.entityPool[dispenser.entityId].pos, packet.ItemId, packet.ItemCount); diff --git a/NebulaNetwork/PacketProcessors/Logistics/ILSUpdateSlotDataProcessor.cs b/NebulaNetwork/PacketProcessors/Logistics/ILSUpdateSlotDataProcessor.cs index 1caf07c9a..50ac329b5 100644 --- a/NebulaNetwork/PacketProcessors/Logistics/ILSUpdateSlotDataProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Logistics/ILSUpdateSlotDataProcessor.cs @@ -9,46 +9,9 @@ namespace NebulaNetwork.PacketProcessors.Logistics [RegisterPacketProcessor] internal class ILSUpdateSlotDataProcessor : PacketProcessor { - private readonly IPlayerManager playerManager; - public ILSUpdateSlotDataProcessor() - { - playerManager = Multiplayer.Session.Network.PlayerManager; - } - public override void ProcessPacket(ILSUpdateSlotData packet, NebulaConnection conn) { - if (IsHost) - { - PlanetData pData = null; - // PLS - if (packet.StationGId == 0) - { - pData = GameMain.galaxy.PlanetById(packet.PlanetId); - } - else // ILS - { - if (packet.StationGId < GameMain.data.galacticTransport.stationPool.Length) - { - StationComponent stationComponent = GameMain.data.galacticTransport.stationPool[packet.StationGId]; - if (stationComponent != null) - { - pData = GameMain.galaxy.PlanetById(stationComponent.planetId); - } - } - } - - if (pData != null) - { - playerManager.SendPacketToStar(packet, pData.star.id); - } - - Multiplayer.Session.Ships.UpdateSlotData(packet); - } - - if (IsClient) - { - Multiplayer.Session.Ships.UpdateSlotData(packet); - } + Multiplayer.Session.Ships.UpdateSlotData(packet); } } } diff --git a/NebulaNetwork/PacketProcessors/Planet/PlanetDetailRequestProcessor.cs b/NebulaNetwork/PacketProcessors/Planet/PlanetDetailRequestProcessor.cs index 660c8da8c..61d2df08a 100644 --- a/NebulaNetwork/PacketProcessors/Planet/PlanetDetailRequestProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Planet/PlanetDetailRequestProcessor.cs @@ -3,6 +3,7 @@ using NebulaModel.Networking; using NebulaModel.Packets; using NebulaModel.Packets.Planet; +using System; using System.Threading.Tasks; namespace NebulaNetwork.PacketProcessors.Planet @@ -22,30 +23,38 @@ public override void ProcessPacket(PlanetDetailRequest packet, NebulaConnection planetData.calculating = true; Task.Run(() => { - // Modify from PlanetModelingManager.PlanetCalculateThreadMain() - HighStopwatch highStopwatch = new HighStopwatch(); - highStopwatch.Begin(); - planetData.data = new PlanetRawData(planetData.precision); - planetData.modData = planetData.data.InitModData(planetData.modData); - planetData.data.CalcVerts(); - planetData.aux = new PlanetAuxData(planetData); - PlanetAlgorithm planetAlgorithm = PlanetModelingManager.Algorithm(planetData); - planetAlgorithm.GenerateTerrain(planetData.mod_x, planetData.mod_y); - planetAlgorithm.CalcWaterPercent(); - if (planetData.type != EPlanetType.Gas) + try { - planetAlgorithm.GenerateVegetables(); - planetAlgorithm.GenerateVeins(); + // Modify from PlanetModelingManager.PlanetCalculateThreadMain() + HighStopwatch highStopwatch = new HighStopwatch(); + highStopwatch.Begin(); + planetData.data = new PlanetRawData(planetData.precision); + planetData.modData = planetData.data.InitModData(planetData.modData); + planetData.data.CalcVerts(); + planetData.aux = new PlanetAuxData(planetData); + PlanetAlgorithm planetAlgorithm = PlanetModelingManager.Algorithm(planetData); + planetAlgorithm.GenerateTerrain(planetData.mod_x, planetData.mod_y); + planetAlgorithm.CalcWaterPercent(); + if (planetData.type != EPlanetType.Gas) + { + planetAlgorithm.GenerateVegetables(); + planetAlgorithm.GenerateVeins(); + } + planetData.CalculateVeinGroups(); + planetData.GenBirthPoints(); + planetData.NotifyCalculated(); + conn.SendPacket(new PlanetDetailResponse(planetData.id, planetData.runtimeVeinGroups ?? Array.Empty(), planetData.landPercent)); + Log.Info($"PlanetCalculateThread:{planetData.displayName} time:{highStopwatch.duration:F4}s"); + } + catch (Exception e) + { + Log.Warn($"Error when calculating {planetData.displayName}"); + Log.Warn(e); } - planetData.CalculateVeinGroups(); - planetData.GenBirthPoints(); - planetData.NotifyCalculated(); - conn.SendPacket(new PlanetDetailResponse(planetData.id, planetData.runtimeVeinGroups, planetData.landPercent)); - Log.Info($"PlanetCalculateThread:{planetData.displayName} time:{highStopwatch.duration:F4}s"); }); return; } - conn.SendPacket(new PlanetDetailResponse(planetData.id, planetData.runtimeVeinGroups, planetData.landPercent)); + conn.SendPacket(new PlanetDetailResponse(planetData.id, planetData.runtimeVeinGroups ?? Array.Empty(), planetData.landPercent)); } } } diff --git a/NebulaNetwork/PacketProcessors/Planet/PlanetDetailResponseProcessor.cs b/NebulaNetwork/PacketProcessors/Planet/PlanetDetailResponseProcessor.cs index a992f327b..5c16137ef 100644 --- a/NebulaNetwork/PacketProcessors/Planet/PlanetDetailResponseProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Planet/PlanetDetailResponseProcessor.cs @@ -28,15 +28,18 @@ public override void ProcessPacket(PlanetDetailResponse packet, NebulaConnection planet = GameMain.galaxy.PlanetById(packet.PlanetDataID); } - if (planet.veinGroups == null || planet.veinGroups.Length != packet.VeinCounts.Length) + if (packet.VeinCounts.Length > 0) { - planet.veinGroups = new VeinGroup[packet.VeinCounts.Length]; - } - for (int i = 1; i < planet.veinGroups.Length; i++) - { - planet.veinGroups[i].type = (EVeinType)packet.VeinTypes[i]; - planet.veinGroups[i].count = packet.VeinCounts[i]; - planet.veinGroups[i].amount = packet.VeinAmounts[i]; + if (planet.veinGroups == null || planet.veinGroups.Length != packet.VeinCounts.Length) + { + planet.veinGroups = new VeinGroup[packet.VeinCounts.Length]; + } + for (int i = 1; i < planet.veinGroups.Length; i++) + { + planet.veinGroups[i].type = (EVeinType)packet.VeinTypes[i]; + planet.veinGroups[i].count = packet.VeinCounts[i]; + planet.veinGroups[i].amount = packet.VeinAmounts[i]; + } } planet.landPercent = packet.LandPercent; planet.landPercentDirty = false; diff --git a/NebulaNetwork/PlayerManager.cs b/NebulaNetwork/PlayerManager.cs index 6c1ebe6c9..7615bc28b 100644 --- a/NebulaNetwork/PlayerManager.cs +++ b/NebulaNetwork/PlayerManager.cs @@ -263,7 +263,7 @@ public void SendRawPacketToPlanet(byte[] rawPacket, int planetId, INebulaConnect foreach (KeyValuePair kvp in connectedPlayers) { INebulaPlayer player = kvp.Value; - if (!!player.Connection.Equals(exclude)) + if (!player.Connection.Equals(exclude)) { player.SendPacket(packet); } diff --git a/NebulaPatcher/NebulaPlugin.cs b/NebulaPatcher/NebulaPlugin.cs index 7fb1763a0..06ab5c62a 100644 --- a/NebulaPatcher/NebulaPlugin.cs +++ b/NebulaPatcher/NebulaPlugin.cs @@ -13,16 +13,13 @@ using NebulaWorld.SocialIntegration; using System; using System.Net; -#if DEBUG using System.IO; -#endif using System.Reflection; using UnityEngine; namespace NebulaPatcher { [BepInPlugin(PluginInfo.PLUGIN_ID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] - [BepInProcess("DSPGAME.exe")] [BepInDependency(CommonAPIPlugin.GUID)] [CommonAPISubmoduleDependency(nameof(ProtoRegistry), nameof(CustomKeyBindSystem))] public class NebulaPlugin : BaseUnityPlugin, IMultiplayerMod @@ -63,6 +60,28 @@ private void Awake() } } + if (args[i] == "-load-latest") + { + loadArgExists = true; + string[] files = Directory.GetFiles(GameConfig.gameSaveFolder, "*" + GameSave.saveExt, SearchOption.TopDirectoryOnly); + long[] times = new long[files.Length]; + string[] names = new string[files.Length]; + for (int j = 0; j < files.Length; j++) + { + FileInfo fileInfo = new(files[j]); + times[j] = fileInfo.LastWriteTime.ToFileTime(); + names[j] = fileInfo.Name.Substring(0, fileInfo.Name.Length - GameSave.saveExt.Length); + } + if (files.Length > 0) + { + Array.Sort(times, names); + saveName = names[files.Length - 1]; + Log.Info($">> Loading save {saveName}"); + NebulaWorld.GameStates.GameStatesManager.ImportedSaveName = saveName; + didLoad = true; + } + } + if (args[i] == "-ups" && i + 1 < args.Length) { if (int.TryParse(args[i + 1], out int value)) @@ -81,7 +100,14 @@ private void Awake() { if (loadArgExists) { - Log.Error($">> Can't find save with name {saveName}! Exiting..."); + if (saveName != string.Empty) + { + Log.Error($">> Can't find save with name {saveName}! Exiting..."); + } + else + { + Log.Error($">> Can't find any save in the folder! Exiting..."); + } } else { diff --git a/NebulaPatcher/Patches/Dynamic/Dedicated_Server_Patch.cs b/NebulaPatcher/Patches/Dynamic/Dedicated_Server_Patch.cs index e1086afa1..73464d805 100644 --- a/NebulaPatcher/Patches/Dynamic/Dedicated_Server_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/Dedicated_Server_Patch.cs @@ -129,5 +129,15 @@ public static void DysonSwarmSetSailCapacity_Prefix(DysonSwarm __instance) __instance.swarmInfoBuffer = null; } } + + + // From user report + [HarmonyPrefix] + [HarmonyPatch(typeof(UnityEngine.UI.Graphic), nameof(UnityEngine.UI.Graphic.DoMeshGeneration))] + [HarmonyPatch(typeof(UnityEngine.UI.Graphic), nameof(UnityEngine.UI.Graphic.DoLegacyMeshGeneration))] + public static bool DoMeshGeneration_Prefix() + { + return false; + } } } diff --git a/NebulaPatcher/Patches/Dynamic/GameData_Patch.cs b/NebulaPatcher/Patches/Dynamic/GameData_Patch.cs index 6f4ac8bdb..8a8bf7ffc 100644 --- a/NebulaPatcher/Patches/Dynamic/GameData_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/GameData_Patch.cs @@ -291,7 +291,7 @@ public static void GameTick_Postfix(GameData __instance, long time) return; } - Multiplayer.Session.Couriers.GameTick(time); + Multiplayer.Session.Couriers.GameTick(); if (Multiplayer.Session.LocalPlayer.IsHost) { diff --git a/NebulaPatcher/Patches/Dynamic/UIMainMenu_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIMainMenu_Patch.cs index 30b3139fd..3b7ed1b90 100644 --- a/NebulaPatcher/Patches/Dynamic/UIMainMenu_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIMainMenu_Patch.cs @@ -57,6 +57,14 @@ public static void _OnOpen_Postfix() AddMultiplayerJoinMenu(); } + [HarmonyPostfix] + [HarmonyPatch(nameof(UIMainMenu.OnUpdateLogButtonClick))] + public static void OnUpdateLogButtonClick_Postfix(UIMainMenu __instance) + { + // Return to main menu when update log is opened + OnMultiplayerBackButtonClick(); + } + // Main Menu private static void AddMultiplayerButton() { diff --git a/NebulaPatcher/Patches/Transpilers/DispenserComponent_Transpiler.cs b/NebulaPatcher/Patches/Transpilers/DispenserComponent_Transpiler.cs index 65cff9066..08986c03a 100644 --- a/NebulaPatcher/Patches/Transpilers/DispenserComponent_Transpiler.cs +++ b/NebulaPatcher/Patches/Transpilers/DispenserComponent_Transpiler.cs @@ -119,7 +119,8 @@ public static void IdleCourierToWork(DispenserComponent dispenser) if (Multiplayer.IsActive) { Multiplayer.Session.Network.SendPacketToLocalPlanet( - new DispenserCourierPacket(Multiplayer.Session.LocalPlayer.Id, + new DispenserCourierPacket(GameMain.mainPlayer.planetId, + Multiplayer.Session.LocalPlayer.Id, dispenser.id, dispenser.workCourierDatas[dispenser.workCourierCount].itemId, dispenser.workCourierDatas[dispenser.workCourierCount].itemCount)); diff --git a/NebulaPatcher/Patches/Transpilers/StationComponent_Transpiler.cs b/NebulaPatcher/Patches/Transpilers/StationComponent_Transpiler.cs index 818cb918a..be7216c9f 100644 --- a/NebulaPatcher/Patches/Transpilers/StationComponent_Transpiler.cs +++ b/NebulaPatcher/Patches/Transpilers/StationComponent_Transpiler.cs @@ -427,6 +427,34 @@ IEnumerable Transpiler(IEnumerable instruction matcher.SetAndAdvance(OpCodes.Nop, null); } + // Switch itemCount in ShipData when ship arrive destination to display correct color + // Currently the render only test if itemCount > 0 so we can give it a dummy positive value + // c# 1241: + // ptr3.direction = -1; + // >> Insert ptr3.itemCount = ptr3.itemCount > 0 ? 0 : 1; + matcher + .MatchForward(true, + new CodeMatch(OpCodes.Ldloc_S), + new CodeMatch(OpCodes.Ldc_I4_M1), + new CodeMatch(OpCodes.Stfld)) + .Advance(1) + .Insert( + new CodeInstruction(OpCodes.Ldloc_S, matcher.InstructionAt(-3).operand), + new CodeInstruction(OpCodes.Ldloc_S, matcher.InstructionAt(-3).operand), + new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ShipData), "itemCount")), + new CodeInstruction(OpCodes.Ldc_I4_0, null), + new CodeInstruction(OpCodes.Stfld, AccessTools.Field(typeof(ShipData), "itemCount")) + ) + .Advance(3) //OpCodes.Ldc_I4_0 + .CreateLabel(out Label labelTo0) + .CreateLabelAt(matcher.Pos + 1, out Label labelEnd) + .Insert( + new CodeInstruction(OpCodes.Ldc_I4_0, null), + new CodeInstruction(OpCodes.Bgt_S, labelTo0), + new CodeInstruction(OpCodes.Ldc_I4_1, null), + new CodeInstruction(OpCodes.Br_S, labelEnd) + ); + return matcher.InstructionEnumeration(); } diff --git a/NebulaPatcher/Patches/Transpilers/UIVersionText_Transpiler.cs b/NebulaPatcher/Patches/Transpilers/UIVersionText_Transpiler.cs index ea43bb4af..1fedb5b76 100644 --- a/NebulaPatcher/Patches/Transpilers/UIVersionText_Transpiler.cs +++ b/NebulaPatcher/Patches/Transpilers/UIVersionText_Transpiler.cs @@ -21,7 +21,16 @@ public static IEnumerable Refresh_Transpiler(IEnumerable i.opcode == OpCodes.Call && ((MethodInfo)i.operand).Name == "get_usernameAndSuffix") + ); + } + + if (codeMatcher.IsInvalid) + { + NebulaModel.Logger.Log.Warn("UIVersionText.Refresh_Transpiler failed. Mod version not compatible with game version."); return instructions; } diff --git a/NebulaWorld/Logistics/CourierManager.cs b/NebulaWorld/Logistics/CourierManager.cs index 0e16b9fff..b03cbc3b7 100644 --- a/NebulaWorld/Logistics/CourierManager.cs +++ b/NebulaWorld/Logistics/CourierManager.cs @@ -1,5 +1,4 @@ -using NebulaAPI; -using NebulaModel.Logger; +using NebulaModel.Logger; using System; using System.Collections.Generic; using UnityEngine; @@ -78,115 +77,126 @@ private void DeterminePosition() } } - public void GameTick(long time) + public void GameTick() { if (CourierCount <= 0 || GameMain.mainPlayer.factory == null) { return; } - DeterminePosition(); - - // Calculate extra couriers position for animation - for (int j = 0; j < CourierCount; j++) + try { - if (CourierDatas[j].maxt <= 0f) - { - continue; - } - if (!PlayerPostions.ContainsKey(CourierDatas[j].endId)) - { - // player does not exist, mark to remove later on - CourierDatas[j].maxt = 0; - continue; - } - if (CourierDatas[j].direction > 0f) // (CourierDatas[j].endId < 0 && CourierDatas[j].direction > 0f) + DeterminePosition(); + + // Calculate extra couriers position for animation + for (int j = 0; j < CourierCount; j++) { - Vector3 EntityPos = EntityPositions[j]; - ref Vector3 courierPtr = ref CourierDatas[j].end; - Vector3 playerPos = PlayerPostions[CourierDatas[j].endId]; - Vector3 vector1 = playerPos - courierPtr; - Vector3 vector2 = playerPos - EntityPos; - float courierToPlayerDist = vector1.magnitude; - float entityToPlayerDist = vector2.magnitude; - float courierHeight = courierPtr.magnitude; - float playerHeight = playerPos.magnitude; - if (courierToPlayerDist < 1.4f) + if (CourierDatas[j].maxt <= 0f) + { + continue; + } + if (!PlayerPostions.ContainsKey(CourierDatas[j].endId)) { - float entityHeight = EntityPos.magnitude; - double cosValue = (double)(EntityPos.x * playerPos.x + EntityPos.y * playerPos.y + EntityPos.z * playerPos.z) / (entityHeight * playerHeight); - if (cosValue < -1.0) + // player does not exist, mark to remove later on + CourierDatas[j].maxt = 0; + continue; + } + if (CourierDatas[j].direction > 0f) // (CourierDatas[j].endId < 0 && CourierDatas[j].direction > 0f) + { + Vector3 EntityPos = EntityPositions[j]; + ref Vector3 courierPtr = ref CourierDatas[j].end; + Vector3 playerPos = PlayerPostions[CourierDatas[j].endId]; + Vector3 vector1 = playerPos - courierPtr; + Vector3 vector2 = playerPos - EntityPos; + float courierToPlayerDist = vector1.magnitude; + float entityToPlayerDist = vector2.magnitude; + float courierHeight = courierPtr.magnitude; + float playerHeight = playerPos.magnitude; + if (courierToPlayerDist < 1.4f) { - cosValue = -1.0; + float entityHeight = EntityPos.magnitude; + double cosValue = (double)(EntityPos.x * playerPos.x + EntityPos.y * playerPos.y + EntityPos.z * playerPos.z) / (entityHeight * playerHeight); + if (cosValue < -1.0) + { + cosValue = -1.0; + } + else if (cosValue > 1.0) + { + cosValue = 1.0; + } + // courier reach player + CourierDatas[j].begin = EntityPos; + CourierDatas[j].maxt = (float)(Math.Acos(cosValue) * ((entityHeight + playerHeight) * 0.5)); + CourierDatas[j].maxt = (float)Math.Sqrt((double)(CourierDatas[j].maxt * CourierDatas[j].maxt) + (entityHeight - playerHeight) * (entityHeight - playerHeight)); + CourierDatas[j].t = CourierDatas[j].maxt; } - else if (cosValue > 1.0) + else { - cosValue = 1.0; + CourierDatas[j].begin = courierPtr; + float progress = courierSpeed * 0.016666668f / courierToPlayerDist; + if (progress > 1f) + { + progress = 1f; + } + Vector3 vector3 = new(vector1.x * progress, vector1.y * progress, vector1.z * progress); + float totalTime = courierToPlayerDist / courierSpeed; + if (totalTime < 0.03333333f) + { + totalTime = 0.03333333f; + } + float deltaHeight = (playerHeight - courierHeight) / totalTime * 0.016666668f; + courierPtr += vector3; + courierPtr = courierPtr.normalized * (courierHeight + deltaHeight); + if (entityToPlayerDist > CourierDatas[j].maxt) + { + CourierDatas[j].maxt = entityToPlayerDist; + } + CourierDatas[j].t = courierToPlayerDist; + if (CourierDatas[j].t >= CourierDatas[j].maxt * 0.99f) + { + CourierDatas[j].t = CourierDatas[j].maxt * 0.99f; + } } - // courier reach player - CourierDatas[j].begin = EntityPos; - CourierDatas[j].maxt = (float)(Math.Acos(cosValue) * ((entityHeight + playerHeight) * 0.5)); - CourierDatas[j].maxt = (float)Math.Sqrt((double)(CourierDatas[j].maxt * CourierDatas[j].maxt) + (entityHeight - playerHeight) * (entityHeight - playerHeight)); - CourierDatas[j].t = CourierDatas[j].maxt; } else { - CourierDatas[j].begin = courierPtr; - float progress = courierSpeed * 0.016666668f / courierToPlayerDist; - if (progress > 1f) - { - progress = 1f; - } - Vector3 vector3 = new(vector1.x * progress, vector1.y * progress, vector1.z * progress); - float totalTime = courierToPlayerDist / courierSpeed; - if (totalTime < 0.03333333f) - { - totalTime = 0.03333333f; - } - float deltaHeight = (playerHeight - courierHeight) / totalTime * 0.016666668f; - courierPtr += vector3; - courierPtr = courierPtr.normalized * (courierHeight + deltaHeight); - if (entityToPlayerDist > CourierDatas[j].maxt) - { - CourierDatas[j].maxt = entityToPlayerDist; - } - CourierDatas[j].t = courierToPlayerDist; - if (CourierDatas[j].t >= CourierDatas[j].maxt * 0.99f) - { - CourierDatas[j].t = CourierDatas[j].maxt * 0.99f; - } + CourierDatas[j].t += 0.016666668f * courierSpeed * CourierDatas[j].direction; + } + + + if (CourierDatas[j].t >= CourierDatas[j].maxt) + { + // Courier reach remote player, swtich item count to display color change + CourierDatas[j].itemCount = CourierDatas[j].itemCount > 0 ? 0 : 10; + CourierDatas[j].t = CourierDatas[j].maxt; + CourierDatas[j].direction = -1f; + } + else if (CourierDatas[j].t <= 0f) + { + // Courier back to home + CourierDatas[j].maxt = 0; } } - else - { - CourierDatas[j].t += 0.016666668f * courierSpeed * CourierDatas[j].direction; - } - - - if (CourierDatas[j].t >= CourierDatas[j].maxt) - { - // Courier reach remote player - CourierDatas[j].t = CourierDatas[j].maxt; - CourierDatas[j].direction = -1f; - } - else if (CourierDatas[j].t <= 0f) + + // Remove marked couriers + int i = 0; + for (int j = 0; j < CourierCount; j++) { - // Courier back to home - CourierDatas[j].maxt = 0; + if (CourierDatas[j].maxt > 0) + { + CourierDatas[i] = CourierDatas[j]; + EntityPositions[i] = EntityPositions[j]; + i++; + } } + CourierCount = i; } - - // Remove marked couriers - int i = 0; - for (int j = 0; j < CourierCount; j++) + catch (Exception ex) { - if (CourierDatas[j].maxt > 0) - { - CourierDatas[i++] = CourierDatas[j]; - EntityPositions[i++] = EntityPositions[j]; - } + Log.Warn("Remote couriers error! Count: " + CourierCount); + Log.Warn(ex); + CourierCount = 0; } - CourierCount = i; } } diff --git a/NebulaWorld/Logistics/ILSShipManager.cs b/NebulaWorld/Logistics/ILSShipManager.cs index 6b7a22db3..b0ec652da 100644 --- a/NebulaWorld/Logistics/ILSShipManager.cs +++ b/NebulaWorld/Logistics/ILSShipManager.cs @@ -201,8 +201,7 @@ public void AddTakeItem(ILSShipAddTake packet) int Inc; stationComponent.TakeItem(ref itemId, ref itemCount, out Inc); // we need to update the ShipData here too, luckily our transpiler sends the workShipDatas index in the inc field - stationComponent.workShipDatas[packet.Inc].itemCount = itemCount; - stationComponent.workShipDatas[packet.Inc].inc = Inc; + // update: ShipDatas.itemCount only use for rendering color, so we let clients handle it } } } @@ -229,25 +228,21 @@ public void UpdateStorage(ILSUpdateStorage packet) public void UpdateSlotData(ILSUpdateSlotData packet) { - PlanetData pData = null; + PlanetFactory factory = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory; StationComponent stationComponent = null; - if (packet.StationGId == 0) // PLS + if (factory != null) // only update station slot for loaded factories { - pData = GameMain.galaxy.PlanetById(packet.PlanetId); - stationComponent = pData?.factory?.transport?.stationPool[packet.StationId]; - } - else // ILS - { - if (packet.StationGId < GameMain.data.galacticTransport.stationPool.Length) - { - stationComponent = GameMain.data.galacticTransport.stationPool[packet.StationGId]; - } + stationComponent = factory.transport.stationPool[packet.StationId]; } if (stationComponent?.slots != null) { stationComponent.slots[packet.Index].storageIdx = packet.StorageIdx; + if (stationComponent.gid != packet.StationGId) + { + NebulaModel.Logger.Log.Warn($"Station gid mismatch! local:{stationComponent.gid} remote:{packet.StationGId}"); + } } } } diff --git a/version.json b/version.json index 98d5fcf9d..e64be5445 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "0.8.11", + "version": "0.8.12", "assemblyVersion": { "precision": "build" },