Fixes and improvements, no more FindObjectsOfType
This commit is contained in:
1 parent
a740fec7c8
commit
fb002cbf0c
328 files changed
+4318
-299
No files matched your search
@@ -0,0 +1,64 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<ImplicitUsings>disable</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<AssemblyName>PeePeeMod</AssemblyName>
|
||||
<RootNamespace>PeePeeMod</RootNamespace>
|
||||
<AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath>
|
||||
<GameDir Condition="'$(GameDir)' == ''">D:\SteamLibrary\steamapps\common\Skopje83</GameDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="0Harmony">
|
||||
<HintPath>$(GameDir)\BepInEx\core\0Harmony.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="BepInEx.Core">
|
||||
<HintPath>$(GameDir)\BepInEx\core\BepInEx.Core.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="BepInEx.Unity.IL2CPP">
|
||||
<HintPath>$(GameDir)\BepInEx\core\BepInEx.Unity.IL2CPP.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppInterop.Runtime">
|
||||
<HintPath>$(GameDir)\BepInEx\core\Il2CppInterop.Runtime.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="Il2Cppmscorlib">
|
||||
<HintPath>$(GameDir)\BepInEx\interop\Il2Cppmscorlib.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="SkopjeAssembly">
|
||||
<HintPath>$(GameDir)\BepInEx\interop\SkopjeAssembly.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="FishNet.Runtime">
|
||||
<HintPath>$(GameDir)\BepInEx\interop\FishNet.Runtime.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="Archon.SwissArmyLib">
|
||||
<HintPath>$(GameDir)\BepInEx\interop\Archon.SwissArmyLib.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppSystem.Core">
|
||||
<HintPath>$(GameDir)\BepInEx\interop\Il2CppSystem.Core.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>$(GameDir)\BepInEx\interop\UnityEngine.CoreModule.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule">
|
||||
<HintPath>$(GameDir)\BepInEx\interop\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputLegacyModule">
|
||||
<HintPath>$(GameDir)\BepInEx\interop\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,580 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using BepInEx;
|
||||
using BepInEx.Configuration;
|
||||
using BepInEx.Logging;
|
||||
using BepInEx.Unity.IL2CPP;
|
||||
using FishNet;
|
||||
using FishNet.Connection;
|
||||
using FishNet.Managing.Client;
|
||||
using FishNet.Managing.Server;
|
||||
using FishNet.Object;
|
||||
using FishNet.Serializing;
|
||||
using FishNet.Transporting;
|
||||
using HarmonyLib;
|
||||
using Il2CppInterop.Runtime;
|
||||
using Il2CppInterop.Runtime.Injection;
|
||||
using Skopje.Modding;
|
||||
using UnityEngine;
|
||||
|
||||
namespace PeePeeMod
|
||||
{
|
||||
[BepInPlugin(PluginGuid, PluginName, PluginVersion)]
|
||||
public class PeePeePlugin : BasePlugin
|
||||
{
|
||||
public const string PluginGuid = "com.skopje.peepeemod";
|
||||
public const string PluginName = "PeePeeMod";
|
||||
public const string PluginVersion = "1.0.0";
|
||||
|
||||
internal static ManualLogSource LogSource;
|
||||
internal static ConfigEntry<bool> Enabled;
|
||||
internal static ConfigEntry<KeyCode> Key;
|
||||
internal static ConfigEntry<bool> Toggle;
|
||||
|
||||
internal static GameObject Host;
|
||||
|
||||
static Harmony _harmony;
|
||||
static SkopjePlayer _local;
|
||||
static bool _pissing;
|
||||
static bool _latched;
|
||||
static float _nextSend;
|
||||
static int _errors;
|
||||
static bool _loggedInput;
|
||||
|
||||
static Il2CppSystem.Action _onClientStarted;
|
||||
static Il2CppSystem.Action _onClientStopped;
|
||||
static Il2CppSystem.Action<SkopjePlayer> _onPlayerStarted;
|
||||
static Il2CppSystem.Action<SkopjePlayer> _onPlayerStopped;
|
||||
static Il2CppSystem.Action _onGameOver;
|
||||
|
||||
public override void Load()
|
||||
{
|
||||
LogSource = Log;
|
||||
Enabled = Config.Bind("Pee", "Enabled", true, "Hold the key to piss. Everyone in the session sees the stream.");
|
||||
Key = Config.Bind("Pee", "Key", KeyCode.P, "Button that starts pissing.");
|
||||
Toggle = Config.Bind("Pee", "Toggle", false, "Press once to start and again to stop. Off means hold the key, like Postal.");
|
||||
|
||||
ClassInjector.RegisterTypeInIl2Cpp<PeeDriver>();
|
||||
|
||||
_onClientStarted = DelegateSupport.ConvertDelegate<Il2CppSystem.Action>(new Action(OnClientStarted));
|
||||
_onClientStopped = DelegateSupport.ConvertDelegate<Il2CppSystem.Action>(new Action(OnClientStopped));
|
||||
_onPlayerStarted = DelegateSupport.ConvertDelegate<Il2CppSystem.Action<SkopjePlayer>>(new Action<SkopjePlayer>(OnPlayerStarted));
|
||||
_onPlayerStopped = DelegateSupport.ConvertDelegate<Il2CppSystem.Action<SkopjePlayer>>(new Action<SkopjePlayer>(OnPlayerStopped));
|
||||
_onGameOver = DelegateSupport.ConvertDelegate<Il2CppSystem.Action>(new Action(OnGameOver));
|
||||
|
||||
ModAPI.add_OnClientStarted(_onClientStarted);
|
||||
ModAPI.add_OnClientStopped(_onClientStopped);
|
||||
ModAPI.add_OnPlayerStartedClient(_onPlayerStarted);
|
||||
ModAPI.add_OnPlayerStoppedClient(_onPlayerStopped);
|
||||
ModAPI.add_OnGameOver(_onGameOver);
|
||||
|
||||
_harmony = new Harmony(PluginGuid);
|
||||
Patch(AccessTools.Method(typeof(ServerManager), "ParseBroadcast"), nameof(PeeNet.BeforeServerBroadcast));
|
||||
Patch(AccessTools.Method(typeof(ClientManager), "ParseBroadcast"), nameof(PeeNet.BeforeClientBroadcast));
|
||||
|
||||
Host = new GameObject("PeePeeMod");
|
||||
UnityEngine.Object.DontDestroyOnLoad(Host);
|
||||
Host.hideFlags = HideFlags.HideAndDontSave;
|
||||
Host.AddComponent<PeeDriver>();
|
||||
|
||||
LogSource.LogInfo($"{PluginName} {PluginVersion} loaded. Hold {Key.Value} to piss. The stream is a server RPC relayed to every client.");
|
||||
}
|
||||
|
||||
public override bool Unload()
|
||||
{
|
||||
_pissing = false;
|
||||
_latched = false;
|
||||
_local = null;
|
||||
if (_harmony != null)
|
||||
_harmony.UnpatchSelf();
|
||||
if (_onClientStarted != null)
|
||||
ModAPI.remove_OnClientStarted(_onClientStarted);
|
||||
if (_onClientStopped != null)
|
||||
ModAPI.remove_OnClientStopped(_onClientStopped);
|
||||
if (_onPlayerStarted != null)
|
||||
ModAPI.remove_OnPlayerStartedClient(_onPlayerStarted);
|
||||
if (_onPlayerStopped != null)
|
||||
ModAPI.remove_OnPlayerStoppedClient(_onPlayerStopped);
|
||||
if (_onGameOver != null)
|
||||
ModAPI.remove_OnGameOver(_onGameOver);
|
||||
PeeVisual.Clear();
|
||||
PeePlayers.Clear();
|
||||
if (Host != null)
|
||||
{
|
||||
UnityEngine.Object.Destroy(Host);
|
||||
Host = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Patch(System.Reflection.MethodInfo method, string prefix)
|
||||
{
|
||||
if (method == null)
|
||||
{
|
||||
LogSource.LogWarning("Pee RPC hook was not found: " + prefix);
|
||||
return;
|
||||
}
|
||||
|
||||
_harmony.Patch(method, prefix: new HarmonyMethod(typeof(PeeNet), prefix));
|
||||
}
|
||||
|
||||
internal static void Fail(Exception ex)
|
||||
{
|
||||
if (_errors >= 8 || LogSource == null)
|
||||
return;
|
||||
_errors++;
|
||||
LogSource.LogError("PeePeeMod failed: " + ex.Message);
|
||||
}
|
||||
|
||||
internal static void Tick()
|
||||
{
|
||||
SkopjePlayer player = FindLocal();
|
||||
bool want = WantPee(player);
|
||||
Vector3 aim = player != null ? PeeVisual.AimOf(player) : Vector3.forward;
|
||||
|
||||
if (want != _pissing)
|
||||
{
|
||||
_pissing = want;
|
||||
_nextSend = Time.unscaledTime + 0.12f;
|
||||
if (want && player != null)
|
||||
PeeVisual.ShowLocal(player, aim);
|
||||
else if (player != null)
|
||||
PeeVisual.Hide(player.ObjectId);
|
||||
if (player != null)
|
||||
PeeNet.ServerRpc(player, want, aim, true);
|
||||
}
|
||||
else if (want && player != null)
|
||||
{
|
||||
PeeVisual.ShowLocal(player, aim);
|
||||
if (Time.unscaledTime >= _nextSend)
|
||||
{
|
||||
_nextSend = Time.unscaledTime + 0.12f;
|
||||
PeeNet.ServerRpc(player, true, aim, false);
|
||||
}
|
||||
}
|
||||
|
||||
PeeVisual.Tick();
|
||||
}
|
||||
|
||||
static bool WantPee(SkopjePlayer player)
|
||||
{
|
||||
if (Enabled == null || !Enabled.Value || player == null || !CanPee(player))
|
||||
{
|
||||
_latched = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
KeyCode key = Key != null ? Key.Value : KeyCode.None;
|
||||
if (Toggle != null && Toggle.Value)
|
||||
{
|
||||
if (Pressed(key))
|
||||
_latched = !_latched;
|
||||
return _latched;
|
||||
}
|
||||
|
||||
return Held(key);
|
||||
}
|
||||
|
||||
static bool CanPee(SkopjePlayer player)
|
||||
{
|
||||
if (player.IsDead || player.IsFallen || player.IsSpectating || player.IsPaused || player.InInventory)
|
||||
return false;
|
||||
if (player.InsideVehicle != null)
|
||||
return false;
|
||||
return player.NetworkObject != null && player.NetworkObject.IsSpawned;
|
||||
}
|
||||
|
||||
static SkopjePlayer FindLocal()
|
||||
{
|
||||
return _local;
|
||||
}
|
||||
|
||||
static void OnClientStarted()
|
||||
{
|
||||
_pissing = false;
|
||||
_latched = false;
|
||||
}
|
||||
|
||||
static void OnClientStopped()
|
||||
{
|
||||
_pissing = false;
|
||||
_latched = false;
|
||||
_local = null;
|
||||
PeeVisual.Clear();
|
||||
PeePlayers.Clear();
|
||||
}
|
||||
|
||||
static void OnPlayerStarted(SkopjePlayer player)
|
||||
{
|
||||
if (player != null && player.IsOwner)
|
||||
_local = player;
|
||||
PeePlayers.Remember(player);
|
||||
}
|
||||
|
||||
static void OnPlayerStopped(SkopjePlayer player)
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
PeeVisual.Hide(player.ObjectId);
|
||||
PeeVisual.Forget(player.ObjectId);
|
||||
}
|
||||
PeePlayers.Forget(player);
|
||||
if (_local == player)
|
||||
{
|
||||
_local = null;
|
||||
_pissing = false;
|
||||
_latched = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void OnGameOver()
|
||||
{
|
||||
_pissing = false;
|
||||
_latched = false;
|
||||
PeeVisual.Clear();
|
||||
}
|
||||
|
||||
static bool Pressed(KeyCode key)
|
||||
{
|
||||
if (key == KeyCode.None)
|
||||
return false;
|
||||
try
|
||||
{
|
||||
return Input.GetKeyDown(key);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!_loggedInput)
|
||||
{
|
||||
_loggedInput = true;
|
||||
LogSource.LogWarning("Keyboard input is unavailable: " + ex.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool Held(KeyCode key)
|
||||
{
|
||||
if (key == KeyCode.None)
|
||||
return false;
|
||||
try
|
||||
{
|
||||
return Input.GetKey(key);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!_loggedInput)
|
||||
{
|
||||
_loggedInput = true;
|
||||
LogSource.LogWarning("Keyboard input is unavailable: " + ex.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PeeDriver : MonoBehaviour
|
||||
{
|
||||
void Update()
|
||||
{
|
||||
try
|
||||
{
|
||||
PeePeePlugin.Tick();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PeePeePlugin.Fail(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class PeePlayers
|
||||
{
|
||||
static readonly Dictionary<int, SkopjePlayer> _players = new Dictionary<int, SkopjePlayer>();
|
||||
|
||||
public static void Remember(SkopjePlayer player)
|
||||
{
|
||||
if (player == null)
|
||||
return;
|
||||
try
|
||||
{
|
||||
if (player.NetworkObject == null)
|
||||
return;
|
||||
_players[player.ObjectId] = player;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static void Forget(SkopjePlayer player)
|
||||
{
|
||||
if (player == null)
|
||||
return;
|
||||
_players.Remove(player.ObjectId);
|
||||
}
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
_players.Clear();
|
||||
}
|
||||
|
||||
public static SkopjePlayer Find(int objectId)
|
||||
{
|
||||
SkopjePlayer player;
|
||||
if (_players.TryGetValue(objectId, out player))
|
||||
return player;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static class PeeNet
|
||||
{
|
||||
const byte Magic = 0xA7;
|
||||
static readonly ushort Key = Hash("Skopje.PeePeeMod.PeeBroadcast");
|
||||
|
||||
static ushort _seq = 1;
|
||||
static readonly Dictionary<int, float> _relayAt = new Dictionary<int, float>();
|
||||
static bool _loggedRelay;
|
||||
static bool _loggedSeen;
|
||||
|
||||
public static void ServerRpc(SkopjePlayer player, bool active, Vector3 aim, bool reliable)
|
||||
{
|
||||
if (player == null || player.NetworkObject == null || !player.NetworkObject.IsSpawned)
|
||||
return;
|
||||
if (!InstanceFinder.IsClientStarted)
|
||||
return;
|
||||
|
||||
if (aim.sqrMagnitude < 0.0001f)
|
||||
aim = Vector3.forward;
|
||||
else
|
||||
aim.Normalize();
|
||||
|
||||
ushort seq = _seq++;
|
||||
if (_seq == 0)
|
||||
_seq = 1;
|
||||
|
||||
Send(true, reliable ? Channel.Reliable : Channel.Unreliable, player.ObjectId, active, aim, seq);
|
||||
}
|
||||
|
||||
public static bool BeforeServerBroadcast(PooledReader reader, NetworkConnection conn, Channel channel)
|
||||
{
|
||||
int start = reader != null ? reader.Position : 0;
|
||||
int end;
|
||||
int objectId;
|
||||
bool active;
|
||||
Vector3 aim;
|
||||
ushort seq;
|
||||
if (!TryRead(reader, start, out end, out objectId, out active, out aim, out seq))
|
||||
return true;
|
||||
|
||||
try
|
||||
{
|
||||
Relay(conn, channel, objectId, active, aim, seq);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PeePeePlugin.Fail(ex);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool BeforeClientBroadcast(PooledReader reader, Channel channel)
|
||||
{
|
||||
int start = reader != null ? reader.Position : 0;
|
||||
int end;
|
||||
int objectId;
|
||||
bool active;
|
||||
Vector3 aim;
|
||||
ushort seq;
|
||||
if (!TryRead(reader, start, out end, out objectId, out active, out aim, out seq))
|
||||
return true;
|
||||
|
||||
try
|
||||
{
|
||||
ObserversRpc(objectId, active, aim, seq);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PeePeePlugin.Fail(ex);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void Relay(NetworkConnection conn, Channel channel, int objectId, bool active, Vector3 aim, ushort seq)
|
||||
{
|
||||
if (conn == null || !conn.IsAuthenticated || !InstanceFinder.IsServerStarted)
|
||||
return;
|
||||
|
||||
SkopjePlayer player = PeePlayers.Find(objectId);
|
||||
if (player == null || !Owns(player, conn))
|
||||
return;
|
||||
if (active && !Allow(conn.ClientId))
|
||||
return;
|
||||
|
||||
if (!_loggedRelay && PeePeePlugin.LogSource != null)
|
||||
{
|
||||
_loggedRelay = true;
|
||||
PeePeePlugin.LogSource.LogInfo("Pee server RPC accepted. Relaying to observers.");
|
||||
}
|
||||
|
||||
Send(false, channel, objectId, active, aim, seq);
|
||||
}
|
||||
|
||||
static void ObserversRpc(int objectId, bool active, Vector3 aim, ushort seq)
|
||||
{
|
||||
SkopjePlayer player = PeePlayers.Find(objectId);
|
||||
if (player == null || player.IsOwner)
|
||||
return;
|
||||
if (!PeeVisual.Accept(objectId, seq))
|
||||
return;
|
||||
|
||||
if (!_loggedSeen && PeePeePlugin.LogSource != null)
|
||||
{
|
||||
_loggedSeen = true;
|
||||
PeePeePlugin.LogSource.LogInfo("Pee observers RPC received.");
|
||||
}
|
||||
|
||||
if (active)
|
||||
PeeVisual.ShowRemote(player, aim);
|
||||
else
|
||||
PeeVisual.Hide(objectId);
|
||||
}
|
||||
|
||||
static bool Owns(SkopjePlayer player, NetworkConnection conn)
|
||||
{
|
||||
if (player.Owner == conn)
|
||||
return true;
|
||||
return player.OwnerId == conn.ClientId;
|
||||
}
|
||||
|
||||
static bool Allow(int clientId)
|
||||
{
|
||||
float now = Time.unscaledTime;
|
||||
float last;
|
||||
if (_relayAt.TryGetValue(clientId, out last) && now - last < 0.05f)
|
||||
return false;
|
||||
_relayAt[clientId] = now;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Send(bool toServer, Channel channel, int objectId, bool active, Vector3 aim, ushort seq)
|
||||
{
|
||||
var manager = InstanceFinder.NetworkManager;
|
||||
if (manager == null || manager.TransportManager == null)
|
||||
return;
|
||||
if (toServer && !InstanceFinder.IsClientStarted)
|
||||
return;
|
||||
if (!toServer && !InstanceFinder.IsServerStarted)
|
||||
return;
|
||||
|
||||
PooledWriter data = WriterPool.Retrieve();
|
||||
PooledWriter writer = WriterPool.Retrieve();
|
||||
try
|
||||
{
|
||||
data.WriteByte(Magic);
|
||||
data.WriteInt32(objectId);
|
||||
data.WriteBoolean(active);
|
||||
data.WriteUInt16(seq);
|
||||
data.WriteSingle(aim.x);
|
||||
data.WriteSingle(aim.y);
|
||||
data.WriteSingle(aim.z);
|
||||
|
||||
writer.WriteUInt16((ushort)PacketId.Broadcast);
|
||||
writer.WriteUInt16(Key);
|
||||
writer.WriteInt32(data.Length);
|
||||
writer.WriteArraySegment(data.GetArraySegment());
|
||||
|
||||
var segment = writer.GetArraySegment();
|
||||
if (toServer)
|
||||
manager.TransportManager.SendToServer((byte)channel, segment, true, DataOrderType.Default);
|
||||
else
|
||||
manager.TransportManager.SendToClients((byte)channel, segment, true);
|
||||
}
|
||||
finally
|
||||
{
|
||||
WriterPool.Store(data);
|
||||
WriterPool.Store(writer);
|
||||
}
|
||||
}
|
||||
|
||||
static bool TryRead(PooledReader reader, int start, out int end, out int objectId, out bool active, out Vector3 aim, out ushort seq)
|
||||
{
|
||||
end = start;
|
||||
objectId = 0;
|
||||
active = false;
|
||||
aim = Vector3.forward;
|
||||
seq = 0;
|
||||
if (reader == null)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
if (reader.Remaining < 2)
|
||||
return false;
|
||||
|
||||
ushort key = reader.ReadUInt16();
|
||||
if (key != Key)
|
||||
{
|
||||
reader.Position = start;
|
||||
return false;
|
||||
}
|
||||
|
||||
int length = reader.ReadInt32();
|
||||
int payload = reader.Position;
|
||||
if (length < 1 || length > 128 || reader.Remaining < length)
|
||||
{
|
||||
reader.Position = start;
|
||||
return false;
|
||||
}
|
||||
|
||||
end = payload + length;
|
||||
if (reader.ReadByte() != Magic)
|
||||
{
|
||||
reader.Position = start;
|
||||
return false;
|
||||
}
|
||||
|
||||
objectId = reader.ReadInt32();
|
||||
active = reader.ReadBoolean();
|
||||
seq = reader.ReadUInt16();
|
||||
aim = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
|
||||
reader.Position = end;
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PeePeePlugin.Fail(ex);
|
||||
try
|
||||
{
|
||||
reader.Position = start;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static ushort Hash(string text)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
uint hash = 2166136261;
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
hash *= 16777619;
|
||||
hash ^= text[i];
|
||||
}
|
||||
|
||||
return (ushort)((hash >> 16) ^ hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,546 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace PeePeeMod
|
||||
{
|
||||
static class PeeVisual
|
||||
{
|
||||
const int Steps = 20;
|
||||
const int Droplets = 10;
|
||||
const float StepTime = 0.04f;
|
||||
const float Speed = 7.5f;
|
||||
const float SplatterLife = 0.25f;
|
||||
static readonly Color PeeColor = new Color(1f, 0.92f, 0.05f, 1f);
|
||||
|
||||
static readonly Dictionary<int, Stream> _streams = new Dictionary<int, Stream>();
|
||||
static readonly Dictionary<int, ushort> _seq = new Dictionary<int, ushort>();
|
||||
static readonly List<Puddle> _puddles = new List<Puddle>();
|
||||
static readonly List<int> _dropIds = new List<int>();
|
||||
static readonly Vector3[] _points = new Vector3[Steps];
|
||||
|
||||
static Mesh _sphere;
|
||||
static Mesh _cube;
|
||||
static Material _material;
|
||||
static MaterialPropertyBlock _block;
|
||||
|
||||
sealed class Stream
|
||||
{
|
||||
public int Id;
|
||||
public SkopjePlayer Player;
|
||||
public bool Local;
|
||||
public Vector3 Aim;
|
||||
public float Heard;
|
||||
public Transform Hips;
|
||||
public bool SearchedHips;
|
||||
public GameObject Root;
|
||||
public LineRenderer Line;
|
||||
public Transform[] Drops;
|
||||
public float[] Seeds;
|
||||
}
|
||||
|
||||
sealed class Puddle
|
||||
{
|
||||
public GameObject Object;
|
||||
public float Born;
|
||||
public Vector3 Scale;
|
||||
}
|
||||
|
||||
public static Vector3 AimOf(SkopjePlayer player)
|
||||
{
|
||||
if (player != null && player.IsOwner && player.SkopjeFPSCamera != null && player.SkopjeFPSCamera.mainCamera != null)
|
||||
return player.SkopjeFPSCamera.mainCamera.transform.forward;
|
||||
if (player != null && player.IsOwner && Camera.main != null)
|
||||
return Camera.main.transform.forward;
|
||||
|
||||
Transform body = Body(player);
|
||||
if (body == null)
|
||||
return Vector3.forward;
|
||||
return (body.forward + Vector3.down * 0.45f).normalized;
|
||||
}
|
||||
|
||||
public static void ShowLocal(SkopjePlayer player, Vector3 aim)
|
||||
{
|
||||
Show(player, aim, true);
|
||||
}
|
||||
|
||||
public static void ShowRemote(SkopjePlayer player, Vector3 aim)
|
||||
{
|
||||
Show(player, aim, false);
|
||||
}
|
||||
|
||||
public static bool Accept(int objectId, ushort seq)
|
||||
{
|
||||
ushort last;
|
||||
if (!_seq.TryGetValue(objectId, out last))
|
||||
{
|
||||
_seq[objectId] = seq;
|
||||
return true;
|
||||
}
|
||||
|
||||
ushort delta = (ushort)(seq - last);
|
||||
if (delta == 0 || delta >= 32768)
|
||||
return false;
|
||||
|
||||
_seq[objectId] = seq;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void Forget(int objectId)
|
||||
{
|
||||
_seq.Remove(objectId);
|
||||
}
|
||||
|
||||
public static void Hide(int objectId)
|
||||
{
|
||||
Stream stream;
|
||||
if (!_streams.TryGetValue(objectId, out stream))
|
||||
return;
|
||||
_streams.Remove(objectId);
|
||||
DestroyStream(stream);
|
||||
}
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
foreach (Stream stream in _streams.Values)
|
||||
DestroyStream(stream);
|
||||
_streams.Clear();
|
||||
_seq.Clear();
|
||||
|
||||
for (int i = 0; i < _puddles.Count; i++)
|
||||
{
|
||||
if (_puddles[i].Object != null)
|
||||
UnityEngine.Object.Destroy(_puddles[i].Object);
|
||||
}
|
||||
|
||||
_puddles.Clear();
|
||||
}
|
||||
|
||||
public static void Tick()
|
||||
{
|
||||
float now = Time.unscaledTime;
|
||||
_dropIds.Clear();
|
||||
foreach (KeyValuePair<int, Stream> pair in _streams)
|
||||
{
|
||||
Stream stream = pair.Value;
|
||||
if (stream.Player == null)
|
||||
{
|
||||
_dropIds.Add(pair.Key);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!stream.Local && now - stream.Heard > 0.5f)
|
||||
{
|
||||
_dropIds.Add(pair.Key);
|
||||
continue;
|
||||
}
|
||||
|
||||
Draw(stream);
|
||||
}
|
||||
|
||||
for (int i = 0; i < _dropIds.Count; i++)
|
||||
Hide(_dropIds[i]);
|
||||
|
||||
for (int i = _puddles.Count - 1; i >= 0; i--)
|
||||
{
|
||||
Puddle puddle = _puddles[i];
|
||||
if (puddle.Object == null)
|
||||
{
|
||||
_puddles.RemoveAt(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
float age = now - puddle.Born;
|
||||
if (age >= SplatterLife)
|
||||
{
|
||||
UnityEngine.Object.Destroy(puddle.Object);
|
||||
_puddles.RemoveAt(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
float shrink = 1f - (age / SplatterLife);
|
||||
puddle.Object.transform.localScale = puddle.Scale * Mathf.Max(0.2f, shrink);
|
||||
}
|
||||
}
|
||||
|
||||
static void Show(SkopjePlayer player, Vector3 aim, bool local)
|
||||
{
|
||||
if (player == null || player.NetworkObject == null || !player.NetworkObject.IsSpawned)
|
||||
return;
|
||||
if (aim.sqrMagnitude < 0.0001f)
|
||||
aim = Vector3.forward;
|
||||
else
|
||||
aim.Normalize();
|
||||
|
||||
Stream stream;
|
||||
if (!_streams.TryGetValue(player.ObjectId, out stream) || stream == null)
|
||||
{
|
||||
stream = Create(player);
|
||||
_streams[player.ObjectId] = stream;
|
||||
}
|
||||
|
||||
stream.Player = player;
|
||||
stream.Local = local;
|
||||
stream.Aim = aim;
|
||||
stream.Heard = Time.unscaledTime;
|
||||
}
|
||||
|
||||
static Stream Create(SkopjePlayer player)
|
||||
{
|
||||
EnsureArt();
|
||||
var stream = new Stream();
|
||||
stream.Id = player.ObjectId;
|
||||
stream.Player = player;
|
||||
stream.Root = new GameObject("PeeStream");
|
||||
if (PeePeePlugin.Host != null)
|
||||
stream.Root.transform.SetParent(PeePeePlugin.Host.transform, false);
|
||||
|
||||
var lineObject = new GameObject("Stream");
|
||||
lineObject.transform.SetParent(stream.Root.transform, false);
|
||||
stream.Line = lineObject.AddComponent<LineRenderer>();
|
||||
stream.Line.positionCount = 0;
|
||||
stream.Line.startWidth = 0.035f;
|
||||
stream.Line.endWidth = 0.018f;
|
||||
stream.Line.numCapVertices = 4;
|
||||
stream.Line.numCornerVertices = 3;
|
||||
stream.Line.useWorldSpace = true;
|
||||
stream.Line.shadowCastingMode = ShadowCastingMode.Off;
|
||||
stream.Line.receiveShadows = false;
|
||||
stream.Line.lightProbeUsage = LightProbeUsage.Off;
|
||||
stream.Line.reflectionProbeUsage = ReflectionProbeUsage.Off;
|
||||
if (_material != null)
|
||||
{
|
||||
stream.Line.material = _material;
|
||||
Paint(stream.Line.material);
|
||||
}
|
||||
stream.Line.startColor = PeeColor;
|
||||
stream.Line.endColor = PeeColor;
|
||||
Paint(stream.Line);
|
||||
|
||||
stream.Drops = new Transform[Droplets];
|
||||
stream.Seeds = new float[Droplets];
|
||||
for (int i = 0; i < Droplets; i++)
|
||||
{
|
||||
stream.Drops[i] = MakeDrop(stream.Root.transform, 0.04f);
|
||||
stream.Seeds[i] = i / (float)Droplets;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
static void Draw(Stream stream)
|
||||
{
|
||||
if (stream.Line == null)
|
||||
return;
|
||||
|
||||
Vector3 aim = stream.Aim.sqrMagnitude > 0.0001f ? stream.Aim.normalized : Vector3.forward;
|
||||
Vector3 origin = Origin(stream, aim);
|
||||
Vector3 velocity = aim * Speed;
|
||||
Vector3 pos = origin;
|
||||
int count = 0;
|
||||
bool landed = false;
|
||||
RaycastHit landing = default;
|
||||
|
||||
for (int i = 0; i < Steps; i++)
|
||||
{
|
||||
Vector3 next = pos + velocity * StepTime + 0.5f * Physics.gravity * (StepTime * StepTime);
|
||||
velocity += Physics.gravity * StepTime;
|
||||
RaycastHit hit;
|
||||
if (HitWorld(pos, next, stream.Player.transform, out hit))
|
||||
{
|
||||
_points[i] = hit.point;
|
||||
count = i + 1;
|
||||
landed = true;
|
||||
landing = hit;
|
||||
break;
|
||||
}
|
||||
|
||||
_points[i] = next;
|
||||
pos = next;
|
||||
count = i + 1;
|
||||
}
|
||||
|
||||
if (count < 2)
|
||||
return;
|
||||
|
||||
stream.Line.positionCount = count;
|
||||
for (int i = 0; i < count; i++)
|
||||
stream.Line.SetPosition(i, _points[i]);
|
||||
|
||||
float now = Time.time;
|
||||
for (int i = 0; i < stream.Drops.Length; i++)
|
||||
{
|
||||
if (stream.Drops[i] == null)
|
||||
continue;
|
||||
float travel = Mathf.Repeat(now * 1.7f + stream.Seeds[i], 1f);
|
||||
Vector3 at = Along(_points, count, travel);
|
||||
Vector3 side = Vector3.Cross(aim, Vector3.up);
|
||||
if (side.sqrMagnitude < 0.0001f)
|
||||
side = Vector3.right;
|
||||
side.Normalize();
|
||||
at += side * Mathf.Sin((now + stream.Seeds[i]) * 16f) * 0.015f;
|
||||
stream.Drops[i].position = at;
|
||||
float size = Mathf.Lerp(0.025f, 0.048f, travel);
|
||||
stream.Drops[i].localScale = new Vector3(size, size, size);
|
||||
}
|
||||
|
||||
if (landed)
|
||||
SpawnPuddle(landing);
|
||||
}
|
||||
|
||||
static Vector3 Origin(Stream stream, Vector3 aim)
|
||||
{
|
||||
SkopjePlayer player = stream.Player;
|
||||
if (player != null && player.IsOwner && !BodyVisible(player))
|
||||
{
|
||||
Camera cam = null;
|
||||
if (player.SkopjeFPSCamera != null)
|
||||
cam = player.SkopjeFPSCamera.mainCamera;
|
||||
if (cam == null)
|
||||
cam = Camera.main;
|
||||
if (cam != null)
|
||||
return cam.transform.position + cam.transform.forward * 0.55f - cam.transform.up * 0.28f;
|
||||
}
|
||||
|
||||
Transform hips = Hips(stream);
|
||||
Vector3 at = hips != null ? hips.position : (player != null ? player.transform.position + Vector3.up * 0.85f : aim);
|
||||
return at + aim * 0.16f + Vector3.down * 0.06f;
|
||||
}
|
||||
|
||||
static Transform Hips(Stream stream)
|
||||
{
|
||||
if (stream.SearchedHips)
|
||||
return stream.Hips;
|
||||
|
||||
stream.SearchedHips = true;
|
||||
Transform body = Body(stream.Player);
|
||||
if (body == null)
|
||||
return null;
|
||||
|
||||
Transform[] all = body.GetComponentsInChildren<Transform>(true);
|
||||
if (all == null)
|
||||
return null;
|
||||
|
||||
for (int i = 0; i < all.Length; i++)
|
||||
{
|
||||
string name = all[i].name;
|
||||
if (name.IndexOf("hip", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("pelvis", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
stream.Hips = all[i];
|
||||
return stream.Hips;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static Transform Body(SkopjePlayer player)
|
||||
{
|
||||
if (player == null)
|
||||
return null;
|
||||
if (player.ThirdPerson != null)
|
||||
return player.ThirdPerson.transform;
|
||||
return player.transform;
|
||||
}
|
||||
|
||||
static bool BodyVisible(SkopjePlayer player)
|
||||
{
|
||||
Renderer renderer = player != null ? player.ThirdPersonRenderer : null;
|
||||
return renderer != null && renderer.enabled && renderer.gameObject.activeInHierarchy;
|
||||
}
|
||||
|
||||
static bool HitWorld(Vector3 from, Vector3 to, Transform ignore, out RaycastHit closest)
|
||||
{
|
||||
closest = default;
|
||||
Vector3 delta = to - from;
|
||||
float dist = delta.magnitude;
|
||||
if (dist < 0.001f)
|
||||
return false;
|
||||
|
||||
RaycastHit[] hits = Physics.RaycastAll(from, delta / dist, dist, Physics.DefaultRaycastLayers, QueryTriggerInteraction.Ignore);
|
||||
if (hits == null || hits.Length == 0)
|
||||
return false;
|
||||
|
||||
float best = float.MaxValue;
|
||||
bool found = false;
|
||||
for (int i = 0; i < hits.Length; i++)
|
||||
{
|
||||
Collider collider = hits[i].collider;
|
||||
if (collider == null)
|
||||
continue;
|
||||
Transform hit = collider.transform;
|
||||
if (ignore != null && (hit == ignore || hit.IsChildOf(ignore)))
|
||||
continue;
|
||||
if (hits[i].distance < best)
|
||||
{
|
||||
best = hits[i].distance;
|
||||
closest = hits[i];
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static Vector3 Along(Vector3[] points, int count, float t)
|
||||
{
|
||||
if (count <= 1)
|
||||
return points[0];
|
||||
|
||||
float total = 0f;
|
||||
for (int i = 1; i < count; i++)
|
||||
total += Vector3.Distance(points[i - 1], points[i]);
|
||||
|
||||
float want = total * Mathf.Clamp01(t);
|
||||
float walked = 0f;
|
||||
for (int i = 1; i < count; i++)
|
||||
{
|
||||
float seg = Vector3.Distance(points[i - 1], points[i]);
|
||||
if (walked + seg >= want)
|
||||
{
|
||||
float u = seg < 0.0001f ? 0f : (want - walked) / seg;
|
||||
return Vector3.Lerp(points[i - 1], points[i], u);
|
||||
}
|
||||
|
||||
walked += seg;
|
||||
}
|
||||
|
||||
return points[count - 1];
|
||||
}
|
||||
|
||||
static void SpawnPuddle(RaycastHit hit)
|
||||
{
|
||||
EnsureArt();
|
||||
if (_cube == null || _material == null)
|
||||
return;
|
||||
|
||||
var puddle = new GameObject("PeePuddle");
|
||||
var filter = puddle.AddComponent<MeshFilter>();
|
||||
filter.sharedMesh = _cube;
|
||||
var renderer = puddle.AddComponent<MeshRenderer>();
|
||||
renderer.sharedMaterial = _material;
|
||||
renderer.shadowCastingMode = ShadowCastingMode.Off;
|
||||
renderer.receiveShadows = false;
|
||||
Paint(renderer);
|
||||
|
||||
Vector3 normal = hit.normal.sqrMagnitude > 0.001f ? hit.normal : Vector3.up;
|
||||
puddle.transform.position = hit.point + normal * 0.02f;
|
||||
puddle.transform.rotation = Quaternion.FromToRotation(Vector3.up, normal) * Quaternion.Euler(0f, UnityEngine.Random.Range(0f, 360f), 0f);
|
||||
float width = UnityEngine.Random.Range(0.16f, 0.3f);
|
||||
puddle.transform.localScale = new Vector3(width, 0.012f, width * UnityEngine.Random.Range(0.75f, 1.15f));
|
||||
|
||||
_puddles.Add(new Puddle
|
||||
{
|
||||
Object = puddle,
|
||||
Born = Time.unscaledTime,
|
||||
Scale = puddle.transform.localScale,
|
||||
});
|
||||
}
|
||||
|
||||
static Transform MakeDrop(Transform parent, float size)
|
||||
{
|
||||
var drop = new GameObject("Drop");
|
||||
drop.transform.SetParent(parent, false);
|
||||
drop.transform.localScale = Vector3.one * size;
|
||||
var filter = drop.AddComponent<MeshFilter>();
|
||||
filter.sharedMesh = _sphere;
|
||||
var renderer = drop.AddComponent<MeshRenderer>();
|
||||
renderer.sharedMaterial = _material;
|
||||
renderer.shadowCastingMode = ShadowCastingMode.Off;
|
||||
renderer.receiveShadows = false;
|
||||
Paint(renderer);
|
||||
return drop.transform;
|
||||
}
|
||||
|
||||
static void Paint(Renderer renderer)
|
||||
{
|
||||
if (renderer == null || _material == null)
|
||||
return;
|
||||
if (_block == null)
|
||||
_block = new MaterialPropertyBlock();
|
||||
_block.SetColor("_BaseColor", PeeColor);
|
||||
_block.SetColor("_Color", PeeColor);
|
||||
_block.SetColor("_EmissionColor", PeeColor);
|
||||
renderer.SetPropertyBlock(_block);
|
||||
}
|
||||
|
||||
static void Paint(Material material)
|
||||
{
|
||||
if (material == null)
|
||||
return;
|
||||
if (material.HasProperty("_BaseColor"))
|
||||
material.SetColor("_BaseColor", PeeColor);
|
||||
if (material.HasProperty("_Color"))
|
||||
material.SetColor("_Color", PeeColor);
|
||||
material.color = PeeColor;
|
||||
if (material.HasProperty("_EmissionColor"))
|
||||
{
|
||||
material.EnableKeyword("_EMISSION");
|
||||
material.SetColor("_EmissionColor", PeeColor * 1.4f);
|
||||
}
|
||||
}
|
||||
|
||||
static Shader YellowShader()
|
||||
{
|
||||
Shader shader = Shader.Find("Universal Render Pipeline/Unlit");
|
||||
if (shader == null)
|
||||
shader = Shader.Find("Universal Render Pipeline/Particles/Unlit");
|
||||
if (shader == null)
|
||||
shader = Shader.Find("Unlit/Color");
|
||||
if (shader == null)
|
||||
shader = Shader.Find("Sprites/Default");
|
||||
return shader;
|
||||
}
|
||||
|
||||
static void EnsureArt()
|
||||
{
|
||||
if (_material != null && _sphere != null && _cube != null)
|
||||
return;
|
||||
|
||||
if (_material == null)
|
||||
{
|
||||
Shader shader = YellowShader();
|
||||
if (shader != null)
|
||||
{
|
||||
_material = new Material(shader);
|
||||
Paint(_material);
|
||||
}
|
||||
}
|
||||
|
||||
if (_sphere == null)
|
||||
{
|
||||
var temp = GameObject.CreatePrimitive(PrimitiveType.Sphere);
|
||||
var filter = temp.GetComponent<MeshFilter>();
|
||||
if (filter != null)
|
||||
_sphere = filter.sharedMesh;
|
||||
if (_material == null)
|
||||
{
|
||||
var renderer = temp.GetComponent<MeshRenderer>();
|
||||
if (renderer != null && renderer.sharedMaterial != null)
|
||||
{
|
||||
_material = new Material(renderer.sharedMaterial);
|
||||
Paint(_material);
|
||||
}
|
||||
}
|
||||
|
||||
UnityEngine.Object.Destroy(temp);
|
||||
}
|
||||
|
||||
if (_cube == null)
|
||||
{
|
||||
var temp = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
var filter = temp.GetComponent<MeshFilter>();
|
||||
if (filter != null)
|
||||
_cube = filter.sharedMesh;
|
||||
UnityEngine.Object.Destroy(temp);
|
||||
}
|
||||
}
|
||||
|
||||
static void DestroyStream(Stream stream)
|
||||
{
|
||||
if (stream != null && stream.Root != null)
|
||||
UnityEngine.Object.Destroy(stream.Root);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v6.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v6.0": {
|
||||
"PeePeeMod/1.0.0": {
|
||||
"runtime": {
|
||||
"PeePeeMod.dll": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"PeePeeMod/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v6.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v6.0": {
|
||||
"PeePeeMod/1.0.0": {
|
||||
"runtime": {
|
||||
"PeePeeMod.dll": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"PeePeeMod/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
|
||||
@@ -0,0 +1,22 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("PeePeeMod")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+a740fec7c87ba4b24aefb7faf991fc5b69c71bd4")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("PeePeeMod")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("PeePeeMod")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
// Generated by the MSBuild WriteCodeFragment class.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
042143fd6e55d3b1da1d22ef48ebe9715cf4e7d7ac9bf7803b296a5ee63c4992
|
||||
@@ -0,0 +1,18 @@
|
||||
is_global = true
|
||||
build_property.TargetFramework = net6.0
|
||||
build_property.TargetFrameworkIdentifier = .NETCoreApp
|
||||
build_property.TargetFrameworkVersion = v6.0
|
||||
build_property.TargetPlatformMinVersion =
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property.EntryPointFilePath =
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property.RootNamespace = PeePeeMod
|
||||
build_property.ProjectDir = C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\
|
||||
build_property.EnableComHosting =
|
||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||
build_property.EffectiveAnalysisLevelStyle = 6.0
|
||||
build_property.EnableCodeStyleSeverity =
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
bf5a809bc5290d85ff4eaa6eb565029fadf1e296987627646bf69f559f7d6af7
|
||||
@@ -0,0 +1,12 @@
|
||||
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\bin\Debug\net6.0\PeePeeMod.deps.json
|
||||
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\bin\Debug\net6.0\PeePeeMod.dll
|
||||
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\bin\Debug\net6.0\PeePeeMod.pdb
|
||||
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\PeePeeMod.csproj.AssemblyReference.cache
|
||||
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\PeePeeMod.GeneratedMSBuildEditorConfig.editorconfig
|
||||
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\PeePeeMod.AssemblyInfoInputs.cache
|
||||
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\PeePeeMod.AssemblyInfo.cs
|
||||
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\PeePeeMod.csproj.CoreCompileInputs.cache
|
||||
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\PeePeeMod.dll
|
||||
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\refint\PeePeeMod.dll
|
||||
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\PeePeeMod.pdb
|
||||
C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Debug\net6.0\ref\PeePeeMod.dll
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"format": 1,
|
||||
"restore": {
|
||||
"C:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\PeePeeMod.csproj": {}
|
||||
},
|
||||
"projects": {
|
||||
"C:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\PeePeeMod.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "C:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\PeePeeMod.csproj",
|
||||
"projectName": "PeePeeMod",
|
||||
"projectPath": "C:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\PeePeeMod.csproj",
|
||||
"packagesPath": "C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget",
|
||||
"outputPath": "C:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\andre\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net6.0"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net6.0": {
|
||||
"framework": "net6.0",
|
||||
"targetAlias": "net6.0",
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
},
|
||||
"restoreAuditProperties": {
|
||||
"enableAudit": "true",
|
||||
"auditLevel": "low",
|
||||
"auditMode": "direct"
|
||||
},
|
||||
"SdkAnalysisLevel": "10.0.300"
|
||||
},
|
||||
"frameworks": {
|
||||
"net6.0": {
|
||||
"framework": "net6.0",
|
||||
"targetAlias": "net6.0",
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"downloadDependencies": [
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App.Ref",
|
||||
"version": "[6.0.36, 6.0.36]"
|
||||
},
|
||||
{
|
||||
"name": "Microsoft.NETCore.App.Ref",
|
||||
"version": "[6.0.36, 6.0.36]"
|
||||
},
|
||||
{
|
||||
"name": "Microsoft.WindowsDesktop.App.Ref",
|
||||
"version": "[6.0.36, 6.0.36]"
|
||||
}
|
||||
],
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.301\\RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\AppData\Local\Temp\cursor-sandbox-cache\a0404811fc6e51c4c5761fd11591789f\nuget</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\andre\AppData\Local\Temp\cursor-sandbox-cache\a0404811fc6e51c4c5761fd11591789f\nuget</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\andre\AppData\Local\Temp\cursor-sandbox-cache\a0404811fc6e51c4c5761fd11591789f\nuget\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
|
||||
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
|
||||
@@ -0,0 +1,22 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("PeePeeMod")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+a740fec7c87ba4b24aefb7faf991fc5b69c71bd4")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("PeePeeMod")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("PeePeeMod")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
// Generated by the MSBuild WriteCodeFragment class.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
28d4c1c7ae8943c05a1dedfb4700405538fa7546a623ddf92593e82cfa96b1f7
|
||||
@@ -0,0 +1,18 @@
|
||||
is_global = true
|
||||
build_property.TargetFramework = net6.0
|
||||
build_property.TargetFrameworkIdentifier = .NETCoreApp
|
||||
build_property.TargetFrameworkVersion = v6.0
|
||||
build_property.TargetPlatformMinVersion =
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property.EntryPointFilePath =
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property.RootNamespace = PeePeeMod
|
||||
build_property.ProjectDir = C:\Users\andre\Desktop\SkopjeMods\PeePeeMod\
|
||||
build_property.EnableComHosting =
|
||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||
build_property.EffectiveAnalysisLevelStyle = 6.0
|
||||
build_property.EnableCodeStyleSeverity =
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
158ef05a991a20f52832317d92222c477cff0bb43c44738ef5ef154dfc745156
|
||||
@@ -0,0 +1,12 @@
|
||||
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\PeePeeMod.csproj.AssemblyReference.cache
|
||||
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\PeePeeMod.GeneratedMSBuildEditorConfig.editorconfig
|
||||
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\PeePeeMod.AssemblyInfoInputs.cache
|
||||
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\PeePeeMod.AssemblyInfo.cs
|
||||
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\PeePeeMod.csproj.CoreCompileInputs.cache
|
||||
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\bin\Release\net6.0\PeePeeMod.deps.json
|
||||
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\bin\Release\net6.0\PeePeeMod.dll
|
||||
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\bin\Release\net6.0\PeePeeMod.pdb
|
||||
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\PeePeeMod.dll
|
||||
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\refint\PeePeeMod.dll
|
||||
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\PeePeeMod.pdb
|
||||
c:\Users\andre\Desktop\SkopjeMods\PeePeeMod\obj\Release\net6.0\ref\PeePeeMod.dll
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"version": 4,
|
||||
"targets": {
|
||||
"net6.0": {}
|
||||
},
|
||||
"libraries": {},
|
||||
"projectFileDependencyGroups": {
|
||||
"net6.0": []
|
||||
},
|
||||
"packageFolders": {
|
||||
"C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget": {}
|
||||
},
|
||||
"project": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "c:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\PeePeeMod.csproj",
|
||||
"projectName": "PeePeeMod",
|
||||
"projectPath": "c:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\PeePeeMod.csproj",
|
||||
"packagesPath": "C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget",
|
||||
"outputPath": "c:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\andre\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net6.0"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net6.0": {
|
||||
"framework": "net6.0",
|
||||
"targetAlias": "net6.0",
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
},
|
||||
"restoreAuditProperties": {
|
||||
"enableAudit": "true",
|
||||
"auditLevel": "low",
|
||||
"auditMode": "direct"
|
||||
},
|
||||
"SdkAnalysisLevel": "10.0.300"
|
||||
},
|
||||
"frameworks": {
|
||||
"net6.0": {
|
||||
"framework": "net6.0",
|
||||
"targetAlias": "net6.0",
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"downloadDependencies": [
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App.Ref",
|
||||
"version": "[6.0.36, 6.0.36]"
|
||||
},
|
||||
{
|
||||
"name": "Microsoft.NETCore.App.Ref",
|
||||
"version": "[6.0.36, 6.0.36]"
|
||||
},
|
||||
{
|
||||
"name": "Microsoft.WindowsDesktop.App.Ref",
|
||||
"version": "[6.0.36, 6.0.36]"
|
||||
}
|
||||
],
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.301\\RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "KG8EvkIN5Ys=",
|
||||
"success": true,
|
||||
"projectFilePath": "C:\\Users\\andre\\Desktop\\SkopjeMods\\PeePeeMod\\PeePeeMod.csproj",
|
||||
"expectedPackageFiles": [
|
||||
"C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget\\microsoft.netcore.app.ref\\6.0.36\\microsoft.netcore.app.ref.6.0.36.nupkg.sha512",
|
||||
"C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget\\microsoft.windowsdesktop.app.ref\\6.0.36\\microsoft.windowsdesktop.app.ref.6.0.36.nupkg.sha512",
|
||||
"C:\\Users\\andre\\AppData\\Local\\Temp\\cursor-sandbox-cache\\a0404811fc6e51c4c5761fd11591789f\\nuget\\microsoft.aspnetcore.app.ref\\6.0.36\\microsoft.aspnetcore.app.ref.6.0.36.nupkg.sha512"
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
Reference in new issue
Block a user