using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ServerSideMap")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ServerSideMap")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("38A5EB8E-7BF4-43B7-9806-9C0DD82AB865")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ServerSideMap;
public static class CommandsPinUpsync
{
[HarmonyPatch(typeof(Chat), "InputText")]
private class ChatPatchInputText
{
private static bool Prefix(Chat __instance, TMP_InputField ___m_input)
{
string text = ___m_input.text;
if (text.ToLower().Equals("/convertpins ignorelocaldupes"))
{
UtilityPin.UploadAllPins(removeDupes: true);
return false;
}
if (text.ToLower().Equals("/convertpins"))
{
UtilityPin.UploadAllPins();
return false;
}
if (text.ToLower().Equals("/deletealllocalpins"))
{
UtilityPin.DeleteLocalPins();
return false;
}
if (text.ToLower().Equals("/downloadpins"))
{
UtilityPin.DownloadPins();
return false;
}
return true;
}
}
}
public static class Hotkeys
{
[HarmonyPatch(typeof(Player), "Update")]
private class PlayerInputPatch
{
private static void Postfix(Player __instance)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
if (Store.HasKeyConvertAll() && Input.GetKeyDown(Store.GetKeyConvertAll()))
{
Utility.Log("Hotkey: GetKeyConvertAll");
UtilityPin.UploadAllPins();
}
if (Store.HasKeyConvertIgnoreDupes() && Input.GetKeyDown(Store.GetKeyConvertIgnoreDupes()))
{
Utility.Log("Hotkey: GetKeyConvertIgnoreDupes");
UtilityPin.UploadAllPins(removeDupes: true);
}
}
}
}
public static class Store
{
public static ConfigEntry<bool> EnableMapShare;
public static ConfigEntry<bool> EnablePinShare;
public static ConfigEntry<float> DuplicatePinRadius;
public static ConfigEntry<string> sKeyConvertAll;
private static bool hasKeyConvertAll;
private static KeyCode KeyConvertAll;
public static ConfigEntry<string> sKeyConvertIgnoreDupes;
private static bool hasKeyConvertIgnoreDupes;
private static KeyCode KeyConvertIgnoreDupes;
public static bool ServerPinShare;
public static bool IsSharingMap()
{
return EnableMapShare.Value;
}
public static bool IsSharingPin()
{
if (ServerPinShare || _ZNet.IsServer(_ZNet._instance))
{
return EnablePinShare.Value;
}
return false;
}
public static float GetDuplicatePinRadius()
{
return DuplicatePinRadius.Value;
}
public static void InitHotkeys()
{
hasKeyConvertAll = Enum.TryParse<KeyCode>(sKeyConvertAll.Value, out KeyConvertAll);
hasKeyConvertIgnoreDupes = Enum.TryParse<KeyCode>(sKeyConvertIgnoreDupes.Value, out KeyConvertIgnoreDupes);
}
public static bool HasKeyConvertAll()
{
return hasKeyConvertAll;
}
public static KeyCode GetKeyConvertAll()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
return KeyConvertAll;
}
public static bool HasKeyConvertIgnoreDupes()
{
return hasKeyConvertIgnoreDupes;
}
public static KeyCode GetKeyConvertIgnoreDupes()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
return KeyConvertIgnoreDupes;
}
}
public static class ExplorationDatabase
{
[HarmonyPatch(typeof(Minimap), "Explore", new Type[]
{
typeof(Vector3),
typeof(float)
})]
private class MinimapPatchExploreInterval
{
private static void Postfix(Minimap __instance)
{
if (_dirty)
{
object value = Traverse.Create((object)__instance).Field("m_fogTexture").GetValue();
((Texture2D)((value is Texture2D) ? value : null)).Apply();
_dirty = false;
}
}
}
private static bool _dirty;
public static bool[] Explored;
public const int MapSize = 2048;
public const int MapSizeSquared = 4194304;
private static List<PinData> ServerPins = new List<PinData>();
public static List<PinData> ClientPins = new List<PinData>();
public static ZPackage Default()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
ZPackage val = new ZPackage();
val.Write(3);
val.Write(2048);
for (int i = 0; i < 4194304; i++)
{
val.Write(false);
}
val.Write(0);
val.SetPos(0);
return val;
}
public static ZPackage PackPins(List<PinData> pins)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Expected I4, but got Unknown
ZPackage val = new ZPackage();
val.Write(pins.Count);
foreach (PinData pin in pins)
{
val.Write(pin.Name);
val.Write(pin.Pos);
val.Write((int)pin.Type);
val.Write(pin.Checked);
}
val.SetPos(0);
Utility.Log("Packing pins: " + pins.Count);
return val;
}
public static List<PinData> UnpackPins(ZPackage z)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
List<PinData> list = new List<PinData>();
int num = z.ReadInt();
for (int i = 0; i < num; i++)
{
PinData item = new PinData
{
Name = z.ReadString(),
Pos = z.ReadVector3(),
Type = (PinType)z.ReadInt(),
Checked = z.ReadBool()
};
list.Add(item);
}
return list;
}
public static ZPackage PackPin(PinData pin, bool skipSetPos = false)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected I4, but got Unknown
ZPackage val = new ZPackage();
val.Write(pin.Name);
val.Write(pin.Pos);
val.Write((int)pin.Type);
val.Write(pin.Checked);
if (!skipSetPos)
{
val.SetPos(0);
}
return val;
}
public static PinData UnpackPin(ZPackage z)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
return new PinData
{
Name = z.ReadString(),
Pos = z.ReadVector3(),
Type = (PinType)z.ReadInt(),
Checked = z.ReadBool()
};
}
public static List<PinData> GetPins()
{
return ServerPins;
}
public static void AddPin(PinData pin)
{
ServerPins.Add(pin);
}
public static void RemovePinEqual(PinData needle)
{
foreach (PinData item in ServerPins.ToList())
{
if (UtilityPin.ArePinsEqual(item, needle))
{
ServerPins.Remove(item);
}
}
}
public static void SetPinState(PinData needle, bool state)
{
foreach (PinData item in ServerPins.ToList())
{
if (UtilityPin.ArePinsEqual(item, needle))
{
item.Checked = state;
}
}
}
public static void SetMapData(ZPackage mapData)
{
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
ServerPins.Clear();
mapData.ReadInt();
int num = mapData.ReadInt();
bool[] array = new bool[num * num];
for (int i = 0; i < num * num; i++)
{
array[i] = mapData.ReadBool();
}
int num2 = mapData.ReadInt();
for (int j = 0; j < num2; j++)
{
PinData item = new PinData
{
Name = mapData.ReadString(),
Pos = mapData.ReadVector3(),
Type = (PinType)mapData.ReadInt(),
Checked = mapData.ReadBool()
};
ServerPins.Add(item);
}
Explored = array;
}
public static ZPackage GetMapData()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Expected I4, but got Unknown
ZPackage val = new ZPackage();
val.Write(3);
val.Write(2048);
bool[] explored = Explored;
foreach (bool flag in explored)
{
val.Write(flag);
}
val.Write(ServerPins.Count);
Utility.Log("Map saved. Pin Count: " + ServerPins.Count);
foreach (PinData serverPin in ServerPins)
{
val.Write(serverPin.Name);
val.Write(serverPin.Pos);
val.Write((int)serverPin.Type);
val.Write(serverPin.Checked);
}
return val;
}
public static void SetExplored(int x, int y)
{
Explored[y * 2048 + x] = true;
}
public static bool GetExplored(int x, int y)
{
return Explored[y * 2048 + x];
}
public static bool GetExplored(int idx)
{
return Explored[idx];
}
public static bool[] GetExplorationArray()
{
return Explored;
}
public static void MergeExplorationArray(bool[] arr, int startIndex, int size)
{
for (int i = 0; i < size; i++)
{
Explored[startIndex + i] = arr[i] || Explored[startIndex + i];
}
}
public static ZPackage PackBoolArray(bool[] arr, int chunkId, int startIndex, int size)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
ZPackage val = new ZPackage();
val.Write(chunkId);
byte b = 0;
int num = 0;
for (int i = startIndex; i < startIndex + size; i++)
{
if (arr[i])
{
byte b2 = (byte)(1 << num);
b |= b2;
}
num++;
if (num >= 8)
{
val.Write(b);
b = 0;
num = 0;
}
}
if (num > 0)
{
val.Write(b);
}
return val;
}
public static bool[] UnpackBoolArray(ZPackage z, int length)
{
bool[] array = new bool[length];
for (int i = 0; i < length; i += 8)
{
byte b = z.ReadByte();
array[i] = (b & 1) != 0;
array[i + 1] = (b & 2) != 0;
array[i + 2] = (b & 4) != 0;
array[i + 3] = (b & 8) != 0;
array[i + 4] = (b & 0x10) != 0;
array[i + 5] = (b & 0x20) != 0;
array[i + 6] = (b & 0x40) != 0;
array[i + 7] = (b & 0x80) != 0;
}
return array;
}
public static void OnReceiveMapData(ZRpc client, ZPackage mapData)
{
mapData.SetPos(0);
int x = mapData.ReadInt();
int y = mapData.ReadInt();
object value = Traverse.Create(typeof(Minimap)).Field("m_instance").GetValue();
_dirty = _Minimap.Explore((Minimap)((value is Minimap) ? value : null), x, y) || _dirty;
}
}
public class PinData
{
public string Name;
public PinType Type;
public Vector3 Pos;
public bool Checked;
}
public static class ExplorationMapSync
{
[HarmonyPatch(typeof(Minimap), "Explore", new Type[]
{
typeof(int),
typeof(int)
})]
private class MinimapPatchExplore
{
private static void Postfix(int x, int y, bool __result)
{
if (__result && !_blockExplore && Store.IsSharingMap())
{
if (_ZNet.IsServer(_ZNet._instance))
{
OnClientExplore(null, x, y);
return;
}
object value = Traverse.Create(typeof(ZNet)).Field("m_instance").GetValue();
_ZNet.GetServerRPC((ZNet)((value is ZNet) ? value : null)).Invoke("OnClientExplore", new object[2] { x, y });
}
}
}
[HarmonyPatch(typeof(Minimap), "SetMapData", new Type[] { typeof(byte[]) })]
private class MinimapPatchSetMapData
{
private static void Prefix()
{
_blockExplore = true;
}
private static void Postfix(Minimap __instance)
{
_blockExplore = false;
}
}
private static bool _blockExplore;
public static void OnClientExplore(ZRpc client, int x, int y)
{
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Expected O, but got Unknown
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Expected O, but got Unknown
if (!Store.IsSharingMap())
{
return;
}
ExplorationDatabase.SetExplored(x, y);
object value = Traverse.Create(typeof(ZNet)).Field("m_instance").GetValue();
foreach (ZNetPeer item in Traverse.Create((value is ZNet) ? value : null).Field("m_peers").GetValue() as List<ZNetPeer>)
{
if (item.IsReady() && item.m_rpc != client)
{
ZPackage val = new ZPackage();
val.Write(x);
val.Write(y);
item.m_rpc.Invoke("OnReceiveMapData", new object[1] { val });
}
}
ZPackage val2 = new ZPackage();
val2.Write(x);
val2.Write(y);
ExplorationDatabase.OnReceiveMapData(null, val2);
}
}
public class InitialMapSync
{
[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
private class ZnetPatchRPC_PeerInfo
{
private static void Postfix(ZRpc rpc, ZNet __instance)
{
if (Store.IsSharingMap() && __instance.IsServer())
{
SendChunkToClient(rpc, 0);
}
}
}
[HarmonyPatch(typeof(Minimap), "SetMapData", new Type[] { typeof(byte[]) })]
private class MinimapPatchSetMapData
{
private static void Postfix(Minimap __instance)
{
if (Store.IsSharingMap() && _ZNet.IsServer(_ZNet._instance))
{
SendChunkToClient(null, 0);
}
}
}
private static int CHUNKS = 64;
public static void OnReceiveMapDataInitial(ZRpc client, ZPackage mapData)
{
if (!Store.IsSharingMap())
{
return;
}
mapData.SetPos(0);
int num = mapData.ReadInt();
bool[] array = ExplorationDatabase.UnpackBoolArray(mapData, 4194304 / CHUNKS);
int num2 = num * (4194304 / CHUNKS);
for (int i = 0; i < array.Length; i++)
{
if (array[i])
{
_Minimap.Explore(_Minimap._instance, (num2 + i) % 2048, (num2 + i) / 2048);
}
}
object value = Traverse.Create((object)_Minimap._instance).Field("m_fogTexture").GetValue();
((Texture2D)((value is Texture2D) ? value : null)).Apply();
((MonoBehaviour)_ZNet._instance).StartCoroutine(SendChunkToServer(client, num));
}
public static void OnClientInitialData(ZRpc client, ZPackage mapData)
{
if (Store.IsSharingMap())
{
mapData.SetPos(0);
int num = mapData.ReadInt();
int startIndex = num * (4194304 / CHUNKS);
int num2 = 4194304 / CHUNKS;
ExplorationDatabase.MergeExplorationArray(ExplorationDatabase.UnpackBoolArray(mapData, num2), startIndex, num2);
SendChunkToClient(client, num + 1);
}
}
private static void SendChunkToClient(ZRpc client, int chunk)
{
if (chunk < CHUNKS)
{
int size = 4194304 / CHUNKS;
int startIndex = chunk * (4194304 / CHUNKS);
ZPackage val = ExplorationDatabase.PackBoolArray(ExplorationDatabase.GetExplorationArray(), chunk, startIndex, size);
if (client == null)
{
OnReceiveMapDataInitial(null, val);
return;
}
client.Invoke("OnReceiveMapDataInitial", new object[1] { val });
}
}
private static IEnumerator SendChunkToServer(ZRpc client, int chunk)
{
if (chunk >= CHUNKS)
{
yield break;
}
int size = 4194304 / CHUNKS;
int startIndex = chunk * (4194304 / CHUNKS);
bool[] arr = Traverse.Create((object)_Minimap._instance).Field("m_explored").GetValue() as bool[];
ZPackage z = ExplorationDatabase.PackBoolArray(arr, chunk, startIndex, size);
if (client == null)
{
OnClientInitialData(null, z);
yield break;
}
yield return (object)new WaitUntil((Func<bool>)(() => _ZNet.GetServerRPC(_ZNet._instance) != null));
_ZNet.GetServerRPC(_ZNet._instance).Invoke("OnClientInitialData", new object[1] { z });
}
}
public class InitialPinSync
{
[HarmonyPatch(typeof(Minimap), "ClearPins")]
private class MinimapPatchClearPins
{
private static void Postfix(Minimap __instance)
{
ClientAppendPins();
}
}
[HarmonyPatch(typeof(ZNet), "Shutdown")]
private class ZNetPatchShutdown
{
private static void Postfix(ZNet __instance)
{
ExplorationDatabase.ClientPins.Clear();
}
}
[HarmonyPatch(typeof(Minimap), "SetMapData", new Type[] { typeof(byte[]) })]
private class MinimapPatchSetMapData
{
private static void Postfix(Minimap __instance)
{
if (_ZNet.IsServer(_ZNet._instance))
{
SendPinsToClient(null);
}
}
}
[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
private class ZnetPatchRPC_PeerInfo
{
private static void Postfix(ZRpc rpc, ZNet __instance)
{
if (__instance.IsServer())
{
SendPinsToClient(rpc);
}
}
}
public static void OnReceiveInitialDataPin(ZRpc client, ZPackage pinData)
{
Store.ServerPinShare = true;
if (Store.IsSharingPin())
{
List<PinData> list = ExplorationDatabase.UnpackPins(pinData);
Utility.Log("Client received initial pin data by server. Pins: " + list.Count);
ExplorationDatabase.ClientPins = list;
ClientAppendPins();
}
}
private static void ClientAppendPins()
{
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
if (!Store.IsSharingPin())
{
return;
}
Utility.Log("ClientAppendPins " + ExplorationDatabase.ClientPins.Count);
foreach (PinData clientPin in ExplorationDatabase.ClientPins)
{
PinData mapPin = UtilityPin.GetMapPin(clientPin);
if (mapPin != null)
{
_Minimap.RemovePin(_Minimap._instance, mapPin);
}
_Minimap.AddPin(_Minimap._instance, clientPin.Pos, clientPin.Type, clientPin.Name, save: false, clientPin.Checked, 0L, "");
}
}
public static void OnClientInitialDataPin(ZRpc client, ZPackage pinData)
{
Utility.Log("Server received initial pin data by client");
}
private static void SendPinsToClient(ZRpc client)
{
if (Store.IsSharingPin())
{
ZPackage val = ExplorationDatabase.PackPins(ExplorationDatabase.GetPins());
if (client == null)
{
OnReceiveInitialDataPin(null, val);
return;
}
client.Invoke("OnReceiveInitialDataPin", new object[1] { val });
}
}
private static void SendPinsToServer(ZRpc client)
{
List<PinData> obj = Traverse.Create((object)_Minimap._instance).Field("m_pins").GetValue() as List<PinData>;
List<PinData> list = new List<PinData>();
foreach (PinData item in obj)
{
if (item.m_save)
{
list.Add(UtilityPin.ConvertPin(item));
}
}
ZPackage val = ExplorationDatabase.PackPins(list);
if (client == null)
{
OnClientInitialDataPin(null, val);
return;
}
object value = Traverse.Create(typeof(ZNet)).Field("m_instance").GetValue();
_ZNet.GetServerRPC((ZNet)((value is ZNet) ? value : null)).Invoke("OnClientInitialDataPin", new object[1] { val });
}
}
public class PinSync
{
[HarmonyPatch(typeof(Minimap), "OnMapLeftClick")]
private class MinimapPatchOnMapLeftClick
{
private static void Postfix(Minimap __instance)
{
if (LatestClosestPin != null)
{
PinData clientPin = UtilityPin.GetClientPin(LatestClosestPin);
if (clientPin != null)
{
clientPin.Checked = LatestClosestPin.m_checked;
CheckPinOnServer(clientPin, clientPin.Checked);
}
}
}
}
[HarmonyPatch(typeof(Minimap), "OnMapRightClick")]
private class MinimapPatchOnMapRightClick
{
private static void Postfix(Minimap __instance)
{
if (LatestClosestPin != null)
{
PinData clientPin = UtilityPin.GetClientPin(LatestClosestPin);
if (clientPin != null)
{
RemovePinFromServer(clientPin);
}
}
}
}
[HarmonyPatch(typeof(Minimap), "GetClosestPin", new Type[]
{
typeof(Vector3),
typeof(float),
typeof(bool)
})]
private class MinimapPatchGetClosestPin
{
private static void Postfix(Minimap __instance, ref PinData __result, Vector3 pos, float radius, bool mustBeVisible = true)
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
if (!Store.IsSharingPin())
{
return;
}
LatestClosestPin = __result;
PinData pinData = null;
float num = 999999f;
foreach (PinData clientPin in ExplorationDatabase.ClientPins)
{
float num2 = Utils.DistanceXZ(pos, clientPin.Pos);
if ((double)num2 < (double)radius && ((double)num2 < (double)num || pinData == null))
{
pinData = clientPin;
num = num2;
}
}
if (pinData != null)
{
PinData mapPin = UtilityPin.GetMapPin(pinData);
if (__result == null)
{
__result = mapPin;
LatestClosestPin = mapPin;
}
else if (Utils.DistanceXZ(pos, __result.m_pos) > num)
{
__result = mapPin;
LatestClosestPin = mapPin;
}
}
}
}
[HarmonyPatch(typeof(Minimap), "RemovePin", new Type[] { typeof(PinData) })]
private class MinimapPatchRemovePin
{
private static void Postfix(Minimap __instance, PinData pin)
{
}
}
[HarmonyPatch(typeof(Minimap), "OnPinTextEntered")]
private class MinimapPatchOnPinTextEntered
{
private static void Prefix(Minimap __instance, out PinData __state, PinData ___m_namePin)
{
__state = null;
if (___m_namePin != null)
{
__state = ___m_namePin;
}
}
private static void Postfix(Minimap __instance, PinData __state)
{
if (__state != null)
{
SendPinToServer(__state);
}
}
}
private static PinData CurrentPin;
private static PinData LatestClosestPin;
public static void OnClientAddPin(ZRpc client, ZPackage pinData)
{
if (!Store.IsSharingPin())
{
return;
}
pinData.SetPos(0);
object value = Traverse.Create(typeof(ZNet)).Field("m_instance").GetValue();
List<ZNetPeer> obj = Traverse.Create((value is ZNet) ? value : null).Field("m_peers").GetValue() as List<ZNetPeer>;
PinData pin = ExplorationDatabase.UnpackPin(pinData);
ExplorationDatabase.AddPin(pin);
Utility.Log("Server received pin by client");
foreach (ZNetPeer item in obj)
{
if (item.IsReady() && item.m_rpc != client)
{
item.m_rpc.Invoke("OnServerAddPin", new object[1] { ExplorationDatabase.PackPin(pin) });
}
}
if (client != null)
{
OnServerAddPin(null, ExplorationDatabase.PackPin(pin));
}
}
public static void OnServerAddPin(ZRpc client, ZPackage pinData)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
if (Store.IsSharingPin())
{
pinData.SetPos(0);
PinData pinData2 = ExplorationDatabase.UnpackPin(pinData);
_Minimap.AddPin(_Minimap._instance, pinData2.Pos, pinData2.Type, pinData2.Name, save: false, pinData2.Checked, 0L, "");
ExplorationDatabase.ClientPins.Add(pinData2);
Utility.Log("Client received pin by server");
}
}
public static void OnClientRemovePin(ZRpc client, ZPackage pinData)
{
if (!Store.IsSharingPin())
{
return;
}
pinData.SetPos(0);
object value = Traverse.Create(typeof(ZNet)).Field("m_instance").GetValue();
List<ZNetPeer> obj = Traverse.Create((value is ZNet) ? value : null).Field("m_peers").GetValue() as List<ZNetPeer>;
PinData pinData2 = ExplorationDatabase.UnpackPin(pinData);
ExplorationDatabase.RemovePinEqual(pinData2);
Utility.Log("Server deleted pin by client");
foreach (ZNetPeer item in obj)
{
if (item.IsReady() && item.m_rpc != client)
{
item.m_rpc.Invoke("OnServerRemovePin", new object[1] { ExplorationDatabase.PackPin(pinData2) });
}
}
if (client != null)
{
OnServerRemovePin(null, ExplorationDatabase.PackPin(pinData2));
}
}
public static void OnServerRemovePin(ZRpc _, ZPackage pinData)
{
if (!Store.IsSharingPin())
{
return;
}
pinData.SetPos(0);
Utility.Log("Client deleted pin by server");
PinData pinData2 = ExplorationDatabase.UnpackPin(pinData);
foreach (PinData item in ExplorationDatabase.ClientPins.ToList())
{
if (UtilityPin.ArePinsEqual(item, pinData2))
{
ExplorationDatabase.ClientPins.Remove(item);
}
}
PinData mapPin = UtilityPin.GetMapPin(pinData2);
if (mapPin != null)
{
_Minimap.RemovePin(_Minimap._instance, mapPin);
}
}
public static void OnClientCheckPin(ZRpc client, ZPackage data)
{
if (!Store.IsSharingPin())
{
return;
}
data.SetPos(0);
Utility.Log("Server checked pin by client");
PinData pinData = ExplorationDatabase.UnpackPin(data);
bool flag = data.ReadBool();
ExplorationDatabase.SetPinState(pinData, flag);
object value = Traverse.Create(typeof(ZNet)).Field("m_instance").GetValue();
foreach (ZNetPeer item in Traverse.Create((value is ZNet) ? value : null).Field("m_peers").GetValue() as List<ZNetPeer>)
{
if (item.IsReady() && item.m_rpc != client)
{
ZPackage val = ExplorationDatabase.PackPin(pinData, skipSetPos: true);
val.Write(flag);
item.m_rpc.Invoke("OnServerCheckPin", new object[1] { val });
}
}
if (client != null)
{
ZPackage val2 = ExplorationDatabase.PackPin(pinData, skipSetPos: true);
val2.Write(flag);
OnServerCheckPin(null, val2);
}
}
public static void OnServerCheckPin(ZRpc client, ZPackage data)
{
if (!Store.IsSharingPin())
{
return;
}
data.SetPos(0);
Utility.Log("Client checked pin by server");
PinData pin = ExplorationDatabase.UnpackPin(data);
bool @checked = data.ReadBool();
foreach (PinData item in ExplorationDatabase.ClientPins.ToList())
{
if (UtilityPin.ArePinsEqual(item, pin))
{
item.Checked = @checked;
PinData mapPin = UtilityPin.GetMapPin(item);
if (mapPin != null)
{
mapPin.m_checked = @checked;
}
}
}
}
public static void SendPinToServer(PinData pin, bool deletePin = true)
{
if (Store.IsSharingPin())
{
PinData pinData = UtilityPin.ConvertPin(pin);
ZPackage val = ExplorationDatabase.PackPin(pinData);
pin.m_save = !deletePin && pin.m_save;
ExplorationDatabase.ClientPins.Add(pinData);
if (!_ZNet.IsServer(_ZNet._instance))
{
_ZNet.GetServerRPC(_ZNet._instance).Invoke("OnClientAddPin", new object[1] { val });
}
else
{
OnClientAddPin(null, val);
}
}
}
public static void RemovePinFromServer(PinData pin)
{
if (Store.IsSharingPin())
{
ZPackage val = ExplorationDatabase.PackPin(pin);
ExplorationDatabase.ClientPins.Remove(pin);
if (!_ZNet.IsServer(_ZNet._instance))
{
_ZNet.GetServerRPC(_ZNet._instance).Invoke("OnClientRemovePin", new object[1] { val });
}
else
{
OnClientRemovePin(null, val);
}
}
}
public static void CheckPinOnServer(PinData pin, bool state)
{
if (Store.IsSharingPin())
{
ZPackage val = ExplorationDatabase.PackPin(pin, skipSetPos: true);
val.Write(state);
val.SetPos(0);
if (!_ZNet.IsServer(_ZNet._instance))
{
_ZNet.GetServerRPC(_ZNet._instance).Invoke("OnClientCheckPin", new object[1] { val });
}
else
{
OnClientCheckPin(null, val);
}
}
}
}
public class SaveWorld
{
[HarmonyPatch(typeof(ZNet), "LoadWorld")]
private class ZnetPatchLoadMap
{
private static void Postfix(ZNet __instance)
{
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Expected O, but got Unknown
object value = Traverse.Create(typeof(ZNet)).Field("m_world").GetValue();
string text = Path.ChangeExtension(((World)((value is World) ? value : null)).GetDBPath(), null);
Utility.Log("World .explored save path: " + text);
string text2 = text + ".mod.serversidemap.explored";
string text3 = text2 + ".beforehs";
if (File.Exists(text2) && !File.Exists(text3))
{
File.Copy(text2, text3);
}
FileStream input;
try
{
input = File.OpenRead(text2);
}
catch
{
GenerateDefaultExploredFile(__instance);
return;
}
BinaryReader binaryReader = new BinaryReader(input);
byte[] array = binaryReader.ReadAllBytes();
binaryReader.Dispose();
if (array.Length == 0)
{
Utility.Log("Existing explored file is 0 bytes. Generating new one.");
GenerateDefaultExploredFile(__instance);
}
else
{
ExplorationDatabase.SetMapData(new ZPackage(array));
Utility.Log("loaded from existing explore file");
}
}
}
[HarmonyPatch(typeof(ZNet), "SaveWorldThread")]
private class ZnetPatchSaveWorldThread
{
private static void Postfix()
{
byte[] array = ExplorationDatabase.GetMapData().GetArray();
if (array.Length == 0)
{
Utility.Log("Explored data is zero bytes. Refusing to save.");
return;
}
object value = Traverse.Create(typeof(ZNet)).Field("m_world").GetValue();
string text = Path.ChangeExtension(((World)((value is World) ? value : null)).GetDBPath(), null);
string path = text + ".mod.serversidemap.explored";
Utility.Log("World .explored save path: " + text);
FileStream fileStream = File.Create(path);
BinaryWriter binaryWriter = new BinaryWriter(fileStream);
binaryWriter.Write(array);
binaryWriter.Flush();
fileStream.Flush(flushToDisk: true);
fileStream.Close();
fileStream.Dispose();
}
}
public static void GenerateDefaultExploredFile(ZNet __instance)
{
ExplorationDatabase.SetMapData(ExplorationDatabase.Default());
Utility.Log("new explore file generated");
__instance.Save(true, false, false);
}
}
[BepInPlugin("eu.mydayyy.plugins.serversidemap", "ServerSideMap", "1.3.12.0")]
public class ServerSideMap : BaseUnityPlugin
{
[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
private class ZnetPatchOnNewConnection
{
private static void Postfix(ZNetPeer peer, ZNet __instance)
{
if (__instance.IsServer())
{
Utility.Log("Registered Server Events");
if (Store.IsSharingMap())
{
peer.m_rpc.Register<int, int>("OnClientExplore", (Action<ZRpc, int, int>)ExplorationMapSync.OnClientExplore);
peer.m_rpc.Register<ZPackage>("OnClientInitialData", (Action<ZRpc, ZPackage>)InitialMapSync.OnClientInitialData);
}
peer.m_rpc.Register<ZPackage>("OnClientInitialDataPin", (Action<ZRpc, ZPackage>)InitialPinSync.OnClientInitialDataPin);
peer.m_rpc.Register<ZPackage>("OnClientAddPin", (Action<ZRpc, ZPackage>)PinSync.OnClientAddPin);
peer.m_rpc.Register<ZPackage>("OnClientRemovePin", (Action<ZRpc, ZPackage>)PinSync.OnClientRemovePin);
peer.m_rpc.Register<ZPackage>("OnClientCheckPin", (Action<ZRpc, ZPackage>)PinSync.OnClientCheckPin);
}
else
{
Utility.Log("Registered Client Events");
if (Store.IsSharingMap())
{
peer.m_rpc.Register<ZPackage>("OnReceiveMapData", (Action<ZRpc, ZPackage>)ExplorationDatabase.OnReceiveMapData);
peer.m_rpc.Register<ZPackage>("OnReceiveMapDataInitial", (Action<ZRpc, ZPackage>)InitialMapSync.OnReceiveMapDataInitial);
}
peer.m_rpc.Register<ZPackage>("OnReceiveInitialDataPin", (Action<ZRpc, ZPackage>)InitialPinSync.OnReceiveInitialDataPin);
peer.m_rpc.Register<ZPackage>("OnServerAddPin", (Action<ZRpc, ZPackage>)PinSync.OnServerAddPin);
peer.m_rpc.Register<ZPackage>("OnServerRemovePin", (Action<ZRpc, ZPackage>)PinSync.OnServerRemovePin);
peer.m_rpc.Register<ZPackage>("OnServerCheckPin", (Action<ZRpc, ZPackage>)PinSync.OnServerCheckPin);
}
}
}
private void Awake()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
new Harmony("eu.mydayyy.plugins.serversidemap");
Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
Store.EnableMapShare = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMapShare", true, "Client: Whether or not to participate in sharing the map. Server: Whether or not to allow map sharing");
Store.EnablePinShare = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMarkerShare", false, "Client: Whether or not to participate in sharing markers. Server: Whether or not to allow marker sharing");
Store.DuplicatePinRadius = ((BaseUnityPlugin)this).Config.Bind<float>("PinShare", "DuplicatePinRadius", 15f, "A local pin will not be uploaded if a pin exists in the given radius on the server (when using /convertpins ignorelocaldupes)");
Store.sKeyConvertAll = ((BaseUnityPlugin)this).Config.Bind<string>("Hotkeys", "KeyConvertAll", "", "Hotkey to run /convertpins");
Store.sKeyConvertIgnoreDupes = ((BaseUnityPlugin)this).Config.Bind<string>("Hotkeys", "KeyConvertIgnoreDupes", "", "Hotkey to run /convertpins ignorelocaldupes");
Store.InitHotkeys();
Utility.Log("Store1: " + Store.HasKeyConvertAll());
Utility.Log("Store2: " + Store.HasKeyConvertIgnoreDupes());
}
}
public static class Utility
{
private static ManualLogSource _logInstance = Logger.CreateLogSource("ServerSideMap");
public static void Log(object data)
{
_logInstance.Log((LogLevel)16, data);
}
public static byte[] ReadAllBytes(this BinaryReader reader)
{
using MemoryStream memoryStream = new MemoryStream();
byte[] array = new byte[4096];
int count;
while ((count = reader.Read(array, 0, array.Length)) != 0)
{
memoryStream.Write(array, 0, count);
}
return memoryStream.ToArray();
}
}
public class UtilityPin
{
public static bool ArePinsEqual(PinData pin1, PinData pin2)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
if (pin1.Name == pin2.m_name && pin1.Type == pin2.m_type)
{
return ((Vector3)(ref pin1.Pos)).Equals(pin2.m_pos);
}
return false;
}
public static bool ArePinsEqual(PinData pin1, PinData pin2)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
if (pin1.Name == pin2.Name && pin1.Type == pin2.Type)
{
return ((Vector3)(ref pin1.Pos)).Equals(pin2.Pos);
}
return false;
}
public static bool ArePinsDupes(PinData pin1, PinData pin2, float radius)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
return Utils.DistanceXZ(pin1.m_pos, pin2.Pos) < radius;
}
public static bool LocalPinIsDupe(PinData pin)
{
foreach (PinData clientPin in ExplorationDatabase.ClientPins)
{
if (ArePinsDupes(pin, clientPin, Store.GetDuplicatePinRadius()))
{
return true;
}
}
return false;
}
public static PinData GetMapPin(PinData needle)
{
foreach (PinData item in Traverse.Create((object)_Minimap._instance).Field("m_pins").GetValue() as List<PinData>)
{
if (ArePinsEqual(needle, item))
{
return item;
}
}
return null;
}
public static PinData GetClientPin(PinData needle)
{
foreach (PinData clientPin in ExplorationDatabase.ClientPins)
{
if (ArePinsEqual(clientPin, needle))
{
return clientPin;
}
}
return null;
}
public static PinData ConvertPin(PinData pin)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
return new PinData
{
Name = pin.m_name,
Pos = pin.m_pos,
Type = pin.m_type,
Checked = pin.m_checked
};
}
public static void UploadAllPins(bool removeDupes = false)
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
foreach (PinData item in (Traverse.Create((object)_Minimap._instance).Field("m_pins").GetValue() as List<PinData>).ToList())
{
if (item.m_save && (!removeDupes || !LocalPinIsDupe(item)))
{
PinSync.SendPinToServer(item, deletePin: false);
PinData pinData = ConvertPin(item);
_Minimap.AddPin(_Minimap._instance, pinData.Pos, pinData.Type, pinData.Name, save: false, pinData.Checked, 0L, "");
ExplorationDatabase.ClientPins.Add(pinData);
}
}
}
public static void DeleteLocalPins()
{
foreach (PinData item in (Traverse.Create((object)_Minimap._instance).Field("m_pins").GetValue() as List<PinData>).ToList())
{
if (item.m_save)
{
_Minimap.RemovePin(_Minimap._instance, item);
}
}
}
public static void DownloadPins()
{
foreach (PinData item in ExplorationDatabase.ClientPins.ToList())
{
GetMapPin(item).m_save = true;
}
}
}
[HarmonyPatch]
public class _Minimap
{
[HarmonyPatch(typeof(Minimap), "Awake")]
public static class Awake
{
private static void Postfix(Minimap __instance)
{
_instance = __instance;
Logger.CreateLogSource("ServerSideMap").LogInfo((object)"Minimap awake");
}
}
public static Minimap _instance;
[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
[HarmonyPatch(typeof(Minimap), "Explore", new Type[]
{
typeof(int),
typeof(int)
})]
public static bool Explore(Minimap instance, int x, int y)
{
throw new NotImplementedException();
}
[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
[HarmonyPatch(typeof(Minimap), "AddPin", new Type[]
{
typeof(Vector3),
typeof(PinType),
typeof(string),
typeof(bool),
typeof(bool),
typeof(long),
typeof(string)
})]
public static PinData AddPin(Minimap instance, Vector3 pos, PinType type, string name, bool save, bool isChecked, long owner, string author)
{
throw new NotImplementedException();
}
[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
[HarmonyPatch(typeof(Minimap), "RemovePin", new Type[] { typeof(PinData) })]
public static void RemovePin(Minimap instance, PinData pin)
{
throw new NotImplementedException();
}
}
[HarmonyPatch]
public class _ZNet
{
[HarmonyPatch(typeof(ZNet), "Awake")]
public static class Awake
{
private static void Postfix(ZNet __instance)
{
_instance = __instance;
Logger.CreateLogSource("ServerSideMap").LogInfo((object)"ZNet awake");
Store.ServerPinShare = false;
}
}
public static ZNet _instance;
[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
[HarmonyPatch(typeof(ZNet), "GetServerRPC")]
public static ZRpc GetServerRPC(ZNet instance)
{
throw new NotImplementedException();
}
[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
[HarmonyPatch(typeof(ZNet), "IsServer")]
public static bool IsServer(ZNet instance)
{
throw new NotImplementedException();
}
}