Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor UpgradeEntityRequests and DestructEntityRequests #379

Merged
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
4 changes: 1 addition & 3 deletions NebulaModel/Packets/Factory/DestructEntityRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@ public class DestructEntityRequest
{
public int PlanetId { get; set; }
public int ObjId { get; set; }
public int ProtoId { get; set; }
public int AuthorId { get; set; }

public DestructEntityRequest() { }
public DestructEntityRequest(int planetId, int objId, int protoId, int authorId)
public DestructEntityRequest(int planetId, int objId, int authorId)
{
AuthorId = authorId;
PlanetId = planetId;
ObjId = objId;
ProtoId = protoId;
}
}
}
6 changes: 5 additions & 1 deletion NebulaModel/Packets/Factory/UpgradeEntityRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ public class UpgradeEntityRequest
{
public int PlanetId { get; set; }
public int ObjId { get; set; }
public int Grade { get; set; }
public int UpgradeProtoId { get; set; }
public int AuthorId { get; set; }

public UpgradeEntityRequest() { }
public UpgradeEntityRequest(int planetId, int objId, int upgradeProtoId)
public UpgradeEntityRequest(int planetId, int objId, int grade, int upgradeProtoId, int authorId)
{
PlanetId = planetId;
ObjId = objId;
Grade = grade;
UpgradeProtoId = upgradeProtoId;
AuthorId = authorId;
}
}
}
45 changes: 0 additions & 45 deletions NebulaPatcher/Patches/Dynamic/PlanetFactory_Patch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,51 +61,6 @@ public static bool BuildFinally_Prefix(PlanetFactory __instance, Player player,
return LocalPlayer.IsMasterClient || FactoryManager.EventFromServer;
}


[HarmonyPrefix]
[HarmonyPatch("DismantleFinally")]
public static bool DismantleFinally_Prefix(PlanetFactory __instance, Player player, int objId, ref int protoId)
{
if (!SimulatedWorld.Initialized)
return true;

// TODO: handle if 2 clients or if host and client trigger a destruct of the same object at the same time

// If the object is a prebuild, remove it from the prebuild request list
if (LocalPlayer.IsMasterClient && objId < 0)
{
if (!FactoryManager.ContainsPrebuildRequest(__instance.planetId, -objId))
{
Log.Warn($"DestructFinally was called without having a corresponding PrebuildRequest for the prebuild {-objId} on the planet {__instance.planetId}");
return false;
}

FactoryManager.RemovePrebuildRequest(__instance.planetId, -objId);
}

if (LocalPlayer.IsMasterClient || !FactoryManager.EventFromServer)
{
LocalPlayer.SendPacket(new DestructEntityRequest(__instance.planetId, objId, protoId, FactoryManager.PacketAuthor == -1 ? LocalPlayer.PlayerId : FactoryManager.PacketAuthor));
}

return LocalPlayer.IsMasterClient || FactoryManager.EventFromServer;
}

[HarmonyPrefix]
[HarmonyPatch("UpgradeFinally")]
public static bool UpgradeFinally_Prefix(PlanetFactory __instance, Player player, int objId, ItemProto replace_item_proto)
{
if (!SimulatedWorld.Initialized)
return true;

if (LocalPlayer.IsMasterClient || !FactoryManager.EventFromServer)
{
LocalPlayer.SendPacket(new UpgradeEntityRequest(__instance.planetId, objId, replace_item_proto.ID));
}

return LocalPlayer.IsMasterClient || FactoryManager.EventFromServer;
}

[HarmonyPrefix]
[HarmonyPatch("GameTick")]
public static bool InternalUpdate_Prefix()
Expand Down
51 changes: 51 additions & 0 deletions NebulaPatcher/Patches/Dynamic/PlayerAction_Build_Patch.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using HarmonyLib;
using NebulaModel.Logger;
using NebulaModel.Packets.Factory;
using NebulaWorld;
using NebulaWorld.Factory;
Expand All @@ -8,6 +9,56 @@ namespace NebulaPatcher.Patches.Dynamic
[HarmonyPatch(typeof(PlayerAction_Build))]
class PlayerAction_Build_Patch
{
[HarmonyPrefix]
[HarmonyPatch(nameof(PlayerAction_Build.DoDismantleObject))]
public static bool DoDismantleObject_Prefix(PlayerAction_Build __instance, int objId)
{
if (!SimulatedWorld.Initialized)
{
return true;
}

int planetId = FactoryManager.TargetPlanet != FactoryManager.PLANET_NONE ? FactoryManager.TargetPlanet : __instance.planet?.id ?? -1;
// TODO: handle if 2 clients or if host and client trigger a destruct of the same object at the same time

// If the object is a prebuild, remove it from the prebuild request list
if (LocalPlayer.IsMasterClient && objId < 0)
{
if (!FactoryManager.ContainsPrebuildRequest(planetId, -objId))
{
Log.Warn($"DestructFinally was called without having a corresponding PrebuildRequest for the prebuild {-objId} on the planet {planetId}");
return false;
}

FactoryManager.RemovePrebuildRequest(planetId, -objId);
}


if (LocalPlayer.IsMasterClient || !FactoryManager.EventFromServer)
{
LocalPlayer.SendPacket(new DestructEntityRequest(planetId, objId, FactoryManager.PacketAuthor == -1 ? LocalPlayer.PlayerId : FactoryManager.PacketAuthor));
}

return LocalPlayer.IsMasterClient || FactoryManager.EventFromServer;
}

[HarmonyPrefix]
[HarmonyPatch(nameof(PlayerAction_Build.DoUpgradeObject))]
public static bool DoUpgradeObject_Prefix(PlayerAction_Build __instance, int objId, int grade, int upgrade)
{
if (!SimulatedWorld.Initialized)
{
return true;
}

if (LocalPlayer.IsMasterClient || !FactoryManager.EventFromServer)
{
LocalPlayer.SendPacket(new UpgradeEntityRequest(FactoryManager.TargetPlanet != FactoryManager.PLANET_NONE ? FactoryManager.TargetPlanet : __instance.planet?.id ?? -1, objId, grade, upgrade, FactoryManager.PacketAuthor == -1 ? LocalPlayer.PlayerId : FactoryManager.PacketAuthor));
}

return LocalPlayer.IsMasterClient || FactoryManager.EventFromServer;
}

[HarmonyPrefix]
[HarmonyPatch(nameof(PlayerAction_Build.SetFactoryReferences))]
public static bool SetFactoryReferences_Prefix()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
using HarmonyLib;
using NebulaWorld;
using NebulaWorld.Factory;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;

namespace NebulaPatcher.Patches.Transpiler
{
[HarmonyPatch]
class BuildTool_Common_Transpiler
{
/*
* Replaces
* int num;
* if (@this.player.inhandItemId == id && @this.player.inhandItemCount > 0)
* With
* int num = 1;
* if (@this.player.inhandItemId == id && @this.player.inhandItemCount > 0)
* So that it succeeds when processing another player's request
*/
[HarmonyTranspiler]
[HarmonyPatch(typeof(BuildTool_Click), nameof(BuildTool_Click.CreatePrebuilds))]
[HarmonyPatch(typeof(BuildTool_Path), nameof(BuildTool_Path.CreatePrebuilds))]
[HarmonyPatch(typeof(BuildTool_Inserter), nameof(BuildTool_Inserter.CreatePrebuilds))]
static IEnumerable<CodeInstruction> CreatePrebuilds_Transpiler(IEnumerable<CodeInstruction> instructions)
{
// Set int count = 1 before trying to use hand items or take tail items so that it passes if player did not generate event
var codeMatcher = new CodeMatcher(instructions)
.MatchForward(false,
new CodeMatch(i => i.IsLdarg()),
Expand All @@ -26,8 +38,12 @@ static IEnumerable<CodeInstruction> CreatePrebuilds_Transpiler(IEnumerable<CodeI
return instructions;
}

// num = 1; from within the if statement
var numInstruction = codeMatcher.InstructionAt(11);

return codeMatcher
.InsertAndAdvance(new CodeInstruction(OpCodes.Ldc_I4_1))
.InsertAndAdvance(numInstruction)
.InstructionEnumeration();
}
}
Expand Down
13 changes: 9 additions & 4 deletions NebulaWorld/Factory/DestructEntityRequestManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,26 @@ public class DestructEntityRequestManager
public static void DestructEntityRequest(DestructEntityRequest packet)
{
PlanetData planet = GameMain.galaxy.PlanetById(packet.PlanetId);
PlayerAction_Build pab = GameMain.mainPlayer.controller != null ? GameMain.mainPlayer.controller.actionBuild : null;

// We only execute the code if the client has loaded the factory at least once.
// Else it will get it once it goes to the planet for the first time.
if (planet.factory == null)
// Else they will get it once they go to the planet for the first time.
if (planet?.factory == null || pab == null)
{
return;
}

FactoryManager.TargetPlanet = packet.PlanetId;
FactoryManager.PacketAuthor = packet.AuthorId;
PlanetFactory tmpFactory = pab.factory;
pab.factory = planet.factory;
pab.noneTool.factory = planet.factory;

FactoryManager.AddPlanetTimer(packet.PlanetId);
int protoId = packet.ProtoId;
planet.factory.DismantleFinally(GameMain.mainPlayer, packet.ObjId, ref protoId);
pab.DoDismantleObject(packet.ObjId);

pab.factory = tmpFactory;
pab.noneTool.factory = tmpFactory;
FactoryManager.TargetPlanet = FactoryManager.PLANET_NONE;
FactoryManager.PacketAuthor = -1;
}
Expand Down
14 changes: 10 additions & 4 deletions NebulaWorld/Factory/UpgradeEntityRequestManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,26 @@ public class UpgradeEntityRequestManager
public static void UpgradeEntityRequest(UpgradeEntityRequest packet)
{
PlanetData planet = GameMain.galaxy.PlanetById(packet.PlanetId);
PlayerAction_Build pab = GameMain.mainPlayer.controller != null ? GameMain.mainPlayer.controller.actionBuild : null;

// We only execute the code if the client has loaded the factory at least once.
// Else he will get it once it goes to the planet for the first time.
if (planet.factory == null)
// Else they will get it once they go to the planet for the first time.
if (planet?.factory == null || pab == null)
{
return;
}

FactoryManager.TargetPlanet = packet.PlanetId;
FactoryManager.PacketAuthor = packet.AuthorId;
PlanetFactory tmpFactory = pab.factory;
pab.factory = planet.factory;
pab.noneTool.factory = planet.factory;

FactoryManager.AddPlanetTimer(packet.PlanetId);
ItemProto itemProto = LDB.items.Select(packet.UpgradeProtoId);
planet.factory.UpgradeFinally(GameMain.mainPlayer, packet.ObjId, itemProto);
pab.DoUpgradeObject(packet.ObjId, packet.Grade, packet.UpgradeProtoId, out int _);

pab.factory = tmpFactory;
pab.noneTool.factory = tmpFactory;
FactoryManager.TargetPlanet = FactoryManager.PLANET_NONE;
}
}
Expand Down