Skip to content

Commit

Permalink
fix moving door patching
Browse files Browse the repository at this point in the history
  • Loading branch information
reyqn committed Feb 20, 2023
1 parent ecd45da commit e79b5af
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 38 deletions.
3 changes: 0 additions & 3 deletions ChatCommands/MoveCommandListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ public static void ChatReceived(long sender)
return;
}
var isStackedCabin = cabin.tileX.Value > 1000;
if (!isStackedCabin) {
ModEntry.MovingFarmer = farmer;
}
cabin.humanDoor.Value = isStackedCabin ? new Point(2, 1) : new Point(-1007, -4);
cabin.tilesWide.Value = isStackedCabin ? 5 : -1001;
cabin.tilesHigh.Value = isStackedCabin ? 3 : -1;
Expand Down
85 changes: 53 additions & 32 deletions Harmony/HarmonyPatcher.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CabinStacker.ChatCommands;
using CabinStacker.Helper;
using HarmonyLib;
using Microsoft.Xna.Framework;
using Netcode;
using StardewModdingAPI;
using StardewValley;
using StardewValley.Buildings;
Expand All @@ -15,14 +17,16 @@ namespace CabinStacker.Harmony
internal class HarmonyPatcher
{
private static IMonitor _monitor;
private static IModHelper _helper;

internal static void Initialize(IMonitor monitor, string id)
internal static void Initialize(IMonitor monitor, IModHelper modHelper, string id)
{
_monitor = monitor;
_helper = modHelper;
var harmonyInstance = new HarmonyLib.Harmony(id);
harmonyInstance.Patch(original: AccessTools.Method(typeof(GameServer), nameof(GameServer.sendAvailableFarmhands)), prefix: new HarmonyMethod(typeof(HarmonyPatcher), nameof(SendAvailableFarmhands_Prefix)));
harmonyInstance.Patch(original: AccessTools.Method(typeof(GameServer), nameof(GameServer.sendMessage), new[]{typeof(long), typeof(byte), typeof(Farmer), typeof(object[])}), prefix: new HarmonyMethod(typeof(HarmonyPatcher), nameof(SendMessage3_Prefix)));
harmonyInstance.Patch(original: AccessTools.Method(typeof(GameServer), nameof(GameServer.sendMessage), new[]{typeof(long), typeof(OutgoingMessage)}), prefix: new HarmonyMethod(typeof(HarmonyPatcher), nameof(SendMessage6_Prefix)));
harmonyInstance.Patch(original: AccessTools.Method(typeof(GameServer), nameof(GameServer.sendMessage), new[]{typeof(long), typeof(byte), typeof(Farmer), typeof(object[])}), prefix: new HarmonyMethod(typeof(HarmonyPatcher), nameof(SendMessage_Prefix)));
harmonyInstance.Patch(original: AccessTools.Method(typeof(Multiplayer), nameof(StardewValley.Multiplayer.broadcastLocationDelta)), prefix: new HarmonyMethod(typeof(HarmonyPatcher), nameof(BroadcastLocationDelta_Prefix)));
harmonyInstance.Patch(original: AccessTools.Method(typeof(Building), nameof(Building.updateInteriorWarps)), prefix: new HarmonyMethod(typeof(HarmonyPatcher), nameof(UpdateInteriorWarps_Prefix)));
harmonyInstance.Patch(original: AccessTools.Method(typeof(ChatBox), nameof(ChatBox.receiveChatMessage)), postfix: new HarmonyMethod(typeof(HarmonyPatcher), nameof(ReceiveChatMessage_Postfix)));
}
Expand All @@ -42,7 +46,7 @@ public static bool SendAvailableFarmhands_Prefix() {

private static readonly Multiplayer Multiplayer = new();

public static bool SendMessage3_Prefix(
public static bool SendMessage_Prefix(
long peerId,
byte messageType,
Farmer sourceFarmer,
Expand Down Expand Up @@ -72,48 +76,65 @@ public static bool SendMessage3_Prefix(
}
catch (Exception e)
{
_monitor.Log($"Failed in {nameof(SendMessage3_Prefix)}:\n{e}", LogLevel.Error);
_monitor.Log($"Failed in {nameof(SendMessage_Prefix)}:\n{e}", LogLevel.Error);
return true;
}
}

public static bool SendMessage6_Prefix(
long peerId,
OutgoingMessage message)
public static bool BroadcastLocationDelta_Prefix(GameLocation loc)
{
try
{
if (ModEntry.MovingFarmer?.UniqueMultiplayerID != peerId || message.MessageType != 6 || message.Data.Count != 3 || message.Data[1].ToString() != "Farm") return true;
try {
if (loc is not Farm farm)
return true;

if (loc.Root is null || !loc.Root.Dirty)
return false;

var cabins = farm.buildings.Where(o => o.isCabin && _helper.Reflection.GetField<List<INetSerializable>>(o.NetFields, "fields").GetValue()[10].Dirty).Select(o => o.nameOfIndoors).ToArray();
if (cabins.Length != 1)
return true;

var farmer = Game1.getAllFarmhands().Where(o => o.homeLocation.Value.Equals(cabins[0])).ToArray();

var data = (byte[])message.Data[2];
var data = Multiplayer.writeObjectDeltaBytes(loc.Root);
var strData = Convert.ToHexString(data);
if (!strData.EndsWith("11FCFFFFFCFFFFFF")) return true;

ModEntry.MovingFarmer = null;
if (!strData.Contains("3F0000000F000000") || !strData.Contains("11FCFFFFFCFFFFFF"))
farmer = Array.Empty<Farmer>();

var message = new OutgoingMessage(6, Game1.player, false, loc.Name, data);

data[^32] = 64;
data[^31] = 0;
data[^30] = 0;
data[^29] = 0;
void Action(Farmer f)
{
if (f == Game1.player) return;
Game1.server.sendMessage(f.UniqueMultiplayerID, message);
}

data[^8] = 18;
data[^7] = 252;
data[^6] = 255;
data[^5] = 255;
foreach (var farmers in Game1.otherFarmers.Values.Except(farmer))
Action(farmers);

var obj = new[]
{
message.Data[0],
message.Data[1],
data
};
if (farmer.Length != 1) return false;

var warpIndex = strData.IndexOf("3F0000000F000000", StringComparison.Ordinal)/2;
var doorIndex = strData.IndexOf("11FCFFFFFCFFFFFF", StringComparison.Ordinal)/2;

data[warpIndex] = 64;
data[warpIndex+1] = 0;
data[warpIndex+2] = 0;
data[warpIndex+3] = 0;

data[doorIndex] = 18;
data[doorIndex+1] = 252;
data[doorIndex+2] = 255;
data[doorIndex+3] = 255;

message = new OutgoingMessage(6, Game1.player, false, loc.Name, data);
Action(farmer.First());

Game1.server.sendMessage(peerId, new OutgoingMessage(message.MessageType, message.FarmerID, obj));
return false;
}
catch (Exception e)
{
_monitor.Log($"Failed in {nameof(SendMessage6_Prefix)}:\n{e}", LogLevel.Error);
catch (Exception e) {
_monitor.Log($"Failed in {nameof(BroadcastLocationDelta_Prefix)}:\n{e}", LogLevel.Error);
return true;
}
}
Expand Down
4 changes: 1 addition & 3 deletions ModEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ namespace CabinStacker
{
public class ModEntry : Mod
{
public static Farmer MovingFarmer { get; set; }

public override void Entry(IModHelper helper)
{
HarmonyPatcher.Initialize(Monitor, ModManifest.UniqueID);
HarmonyPatcher.Initialize(Monitor, helper, ModManifest.UniqueID);
helper.Events.GameLoop.UpdateTicked += OnUpdate;
helper.Events.GameLoop.SaveLoaded += OnSaveLoaded;
}
Expand Down

0 comments on commit e79b5af

Please sign in to comment.